My project requires a few npm modules, which I'm using yarn and webpack to load in. Namely, they are jquery
, bootstrap3
, moment
, jquery-tablesort
, jquery-ujs
, bootstrap-select
, and livestamp
.
Some of those plugins need jQuery to be exposed as the global $ object. I've tried to make webpack do that, but so far I've failed.
My webpack config currently looks like this:
module.exports = {
entry: packPaths.reduce(
(map, entry) => {
const localMap = map;
const namespace = relative(join(entryPath), dirname(entry));
const key = join(namespace, basename(entry, extname(entry)));
localMap[key] = [resolve(entry)];
if (entry.includes('vendor')) {
localMap[key].unshift('babel-polyfill');
}
return localMap;
}, {}
),
output: {
filename: '[name].js',
path: output.path,
publicPath: output.publicPath
},
module: {
rules: [{
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: '$'
}]
}, ...sync(join(loadersDir, '*.js')).map(loader => require(loader))]
},
plugins: [
new webpack.EnvironmentPlugin(JSON.parse(JSON.stringify(env))),
new ExtractTextPlugin(env.NODE_ENV === 'production' ? '[name]-[hash].css' : '[name].css'),
new ManifestPlugin({
publicPath: output.publicPath,
writeToFileEmit: true
})
],
resolve: {
extensions: settings.extensions,
modules: [
resolve(settings.source_path),
'node_modules'
]
},
resolveLoader: {
modules: ['node_modules']
}
};
On the advice in this question, I added the module
section for expose-loader
and removed a previous ProvidePlugin
section that I had tried; neither of these options have worked.
My scripts are included like so (in application.html.erb
):
<%= javascript_pack_tag 'vendor.js', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag "//code.highcharts.com/highcharts.js", "chartkick" %>
There are no other scripts included before or after these three. In vendor.js
:
import * as $ from 'jquery';
window.$ = window.jQuery = $;
import 'bootstrap3'
import 'moment'
import 'jquery-tablesort';
import 'jquery-ujs';
import 'bootstrap-select';
import 'livestamp';
The manual assignment to window.$
also doesn't work. When Bootstrap loads, it gives me this error:
transition.js:59 Uncaught ReferenceError: jQuery is not defined
at Object.<anonymous> (transition.js:59)
at __webpack_require__ (bootstrap bde90632505934e68af9:19)
at Object.module.exports (npm.js:2)
at __webpack_require__ (bootstrap bde90632505934e68af9:19)
at Object.<anonymous> (vendor.js:1)
at __webpack_require__ (bootstrap bde90632505934e68af9:19)
at Object.<anonymous> (runtime.js:736)
at __webpack_require__ (bootstrap bde90632505934e68af9:19)
at bootstrap bde90632505934e68af9:65
at vendor.js:69
(Note the vendor.js
in the last line of the trace there is the compiled vendor.js, i.e. not the one included above but the Webpack result.)
What can I do to fix this?