Recently, I have been thinking of moving our build process from Grunt
to webpack-2
. Our code is entirely written in AMD format using requirejs. For the purpose of the demo, I'll post the minimalistic version of our index.js
file we are using.
Here's the link of jQuery-1.6.4 being used by committing the file and loaded via npm. Please excuse this for the time being. jQuery-1.6.4
index.js
define(['jQuery', 'arrayUtils'], function ($, arrayUtils) {
'use strict';
console.log($);
console.log(arrayUtils);
});
Corresponding require-config.js
file:
(function () {
'use strict';
require.config({
baseUrl: '../../src',
waitSeconds: 0,
paths: {
jQuery: '/path to/jquery-1.6.4',
urlUtils: '/path to/urlUtils',
// ...
},
shim: {
jQuery: {
exports: '$'
},
urlUtils: {
exports: 'urlUtils'
},
// ...
}
});
})();
I tried to use our AMD approach but want to bundle everything using webpack-2. I went through the docs and various blogs and came across the config which makes everything worked like a charm except the old-gold jQuery.
Here is the webpack.config.js
var webpack = require('webpack');
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
// Import the plugin:
var path = require('path');
var env = require('yargs').argv.mode;
var outputFile;
var options = {
target: 'this'
};
var libOptions = {
name: 'heatmap-inject',
version: JSON.stringify(require("./package.json").version)
};
var plugins = [];
if (env === 'build') {
plugins.push(new UglifyJsPlugin({
sourceMap: true,
minimize: true
}));
}
// At the end of the file:
module.exports = {
entry: __dirname + '/src/library.js',
devtool: 'source-map',
output: {
path: __dirname + '/dist/webpack',
library: 'library.js',
filename: libOptions.name + '.js', // libOptions.name + (options.target ? '.' + options.target : '') + (env === 'build' ? '.min.js' : '.js')
libraryTarget: options.target || 'umd',
umdNamedDefine: true
},
module: {
rules: [{
test: /(\.js)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015'],
plugins: []
}
}
}, {
enforce: 'pre',
test: /(\.js)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'eslint-loader',
options: {}
}
}, { test: /jQuery/, loader: 'exports-loader?$'
}, { test: /urlUtils/, loader: 'exports-loader?urlUtils'
}]
},
resolve: {
alias: {
'jQuery': 'heatmaps/vendor/jquery-1.6.4',
'urlUtils': 'lib/heatmap/UrlUtils'
},
modules: [
'src/**/*.js',
'src/bower_components',
path.resolve('./src')
],
extensions: ['.js']
},
plugins: plugins
};
The file which is generated by webpack-2
throws an error that $.fn
is not defined i.e. instead of $
being a jQuery function it's a plain empty Object.
Though window.$ is defined and returns the right jQuery function but why not I'm getting the same result for $
. In the case of AMD, I'm getting the correct result since $
is in a closure and returns the 1.6.4 jQuery. Using webpack, it is behaving weirdly.
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
__webpack_require__(1),
__webpack_require__(13)
], __WEBPACK_AMD_DEFINE_RESULT__ = function ($, urlUtils) { ... }
What other things I have tried:
{ test: /jQuery/, loader: 'expose-loader?$'
{ test: /jQuery/, loader: 'exports-loader?jQuery=jQuery,$=jQuery,this=>window'
{ test: /jQuery/, loader: 'exports-loader?this=>window'
{ test: /jQuery/, loader: 'expose-loader?$=jQuery'
Can't use externals
property as it pollutes the thw window.jQuery
and as this library is injected/loaded on user's website, this will break things on the target source.
Please help me! I'm frustrated now with this weird jQuery thing.