You should not move any node package from the node_modules to your directories as brunch can link those in. However the "web/static/vendor/js/jquery.min.js"
(code tags in future? Pictures are horrible to copy/paste text… ) implies that you have another jquery, and same with bootstrap, that is in your ‘order’ section.
Better yet, here is my entire npm package.json
file:
{
"repository": {},
"license": "MIT",
"scripts": {
"deploy": "brunch build --production",
"watch": "brunch watch --stdin"
},
"dependencies": {
"bootstrap": "^4.0.0-alpha.2",
"tether": "~1.3.2",
"bootstrap-select": ">=1.10.0",
"material-design-lite": ">=1.1.3",
"material-design-icons": ">=2.2.3",
"jquery": ">=3.0",
"moment": ">=2.13.0",
"highlight.js": ">=9.5.0",
"phoenix": "file:deps/phoenix",
"phoenix_html": "file:deps/phoenix_html"
},
"devDependencies": {
"babel-brunch": "~6.0.0",
"babel-plugin-transform-object-rest-spread": ">=6.8.0",
"brunch": "~2.8.2",
"clean-css-brunch": "~2.0.0",
"elm-brunch": "0.6.0",
"elmx": "1.0.5",
"css-brunch": "~2.0.0",
"javascript-brunch": "~2.0.0",
"uglify-js-brunch": "~2.0.1"
}
}
And my brunch-config.js file:
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js",
order: {
before: [
"dist/js/jquery.min.js", // I don't think these four are necessary, just old holdovers...
"dist/js/tether.min.js",
"dist/js/bootstrap.min.js",
"dist/js/bootstrap-select.min.js"
],
after: [
"web/static/js/app.js" // concat app.js last
]
}
},
stylesheets: {
joinTo: "css/app.css",
order: {
before: [
"dist/css/tether.min.css",
"dist/css/bootstrap.min.css",
"dist/css/bootstrap-select.min.css",
"dist/material.min.css",
"dist/material.blue-light_blue.min.css",
"iconfont/material-icons.css"
],
after: [
"web/static/css/app.css" // concat app.css last
]
}
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
// This option sets where we should place non-css and non-js assets in.
// By default, we set this to "/web/static/assets". Files in this directory
// will be copied to `paths.public`, which is "priv/static" by default.
assets: /^(web\/static\/assets)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: [
"web/elm",
"web/static",
"test/static"
],
// Where to compile files to
public: "priv/static"
},
// Configure your plugins
plugins: {
babel: {
presets: ['es2015'],
plugins: ["transform-object-rest-spread"],
// Do not use ES6 compiler in vendor code
ignore: [/web\/static\/vendor/],
compact: false
},
uglify: {
mangle: true
},
elmBrunch: {
elmFolder: '.',
mainModules: ['web/elm/MessengerApp.elm', 'web/elm/NotificationsApp.elm'],
// If specified, all mainModules will be compiled to a single file (optional and merged with outputFolder)
outputFolder: 'web/static/js',
outputFile: 'elm.js',
makeParameters: ['--warn']
}
},
modules: {
autoRequire: {
"js/app.js": ["web/static/js/app"]
}
},
npm: {
enabled: true,
whitelist: [
"jquery",
"tether",
"bootstrap",
"bootstrap-select",
"material-design-lite",
"highlight.js",
"phoenix",
"phoenix_html"],
styles: {
bootstrap: ["dist/css/bootstrap.min.css"],
tether: ["dist/css/tether.min.css"],
"material-design-lite": [
"dist/material.min.css",
"dist/material.blue-light_blue.min.css"
],
"material-design-icons": [
"iconfont/material-icons.css"
]
}
}
};
And my entire app.js (give-or-take a touch):
import "phoenix_html"
import $ from "jquery"
import "jquery"
import moment from "moment"
import "bootstrap-select"
// Ugh...
global.jQuery = require("jquery") // Needed for tether or bootstrap...
global.Tether = require("tether")
global.bootstrap = require("bootstrap")
global.moment = moment
import socket from "./socket"
import setup_help from './components/help'
import setup_elm_messenger_app from './elm_apps/messenger'
import setup_elm_notifications_app from './elm_apps/notifications'
$(document).ready(() => {
$('.dropdown-toggle').dropdown()
$('[data-toggle="tooltip"]').tooltip()
setInterval(() => {
$.each($('.rel-time-display'), (index, val) => {
let elem = $(val)
let old_time = elem.text()
let new_time = moment(elem.attr('data-time')).fromNow()
if(old_time != new_time) {
elem.text(new_time)
}
})
},5000);
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
$('.selectpicker').selectpicker('mobile');
}
else {
$('.selectpicker').selectpicker()
}
})
let socket_setup_once = false
socket.onOpen(() => {
$(document).ready(function(){
if(socket_setup_once) return
socket_setup_once = true
setup_help(socket)
setup_elm_notifications_app(document.querySelector('#notifications-container'), socket)
if(setup_elm_messenger_app(undefined, socket)) {
$("#messenger-popup-dropdown").remove()
$("#messenger-popup-button").removeClass('dropdown-toggle')
$("#messenger-popup-button").addClass('disabled')
}
else {
setup_elm_messenger_app(document.querySelector('#messenger-popup-container'), socket)
}
})
})
socket.connect()
And I know that all works. So perhaps use it as an example?