Reputation: 257
I'm trying to refactor client javascript in my nodejs/express application using CommonJS + Webpack modules.
With Webpack I build a 'bundle.js' made of two js files where I defined the two modules following CommongJS syntax. But on window.onload of the page I get a nice 'TypeError: moveTo.logHelloWorld is not a function" error.
Where am I wrong?
Webpack configuration:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: ['./public/js/common.js', './public/js/moveTo.js'],
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.min.js'
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : []
}
moveTo.js
var moveTo = {};
console.log("moveTo.js loaded...");
moveTo.logHelloWorld = function(){
console.console.log("Hello World logHelloWorld() from moveTo client Javascript!");
};
module.exports = moveTo;
moveTo.handlebars
<div>MoveTo</div>
<script type="text/javascript">
window.onload = function(){
console.log("ON LOAD...");
moveTo.logHelloWorld();
}
</script>
and finally in the main template I included the bundle.js built with Webpack:
<script src="/bundle.min.js" type="text/javascript"></script>
And this is the error I got:
UPDATE: How to use multiple client js files Suppose I would like to add another test.js file with its own module like so:
test.js
var test = {};
console.log("test.js loaded...");
test.logHelloWorld = function(){
console.log("Hello World logHelloWorld() from TEST client Javascript!");
};
module.exports = test;
And then in Webpack config:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: ['./public/js/common.js', './public/js/moveTo.js', './public/js/test.js'],
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.min.js',
library: ["moveTo", "test"] //This is not working.
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : []
}
How may I get this to work?
UPDATE:
This is what i get using the suggested webpack configuration
Apparently there is no way to have a single bundle.js and get it to work with different javascript files. This is the only thing I reached so far with the precious help of @hazardous:
webpack.config.js
var webpack = require('webpack');
var path = require('path');
// ['./public/js/common.js', './public/js/moveTo.js', './public/js/test.js'],
module.exports = {
entry: './public/js/t3toolbox.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.min.js',
library: ["t3toolbox", "[name]"]
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : []
}
t3toolbox.js
var t3toolbox = {}; // Global App NameSpace
var test = require('./test.js');
var moveTo = require('./moveTo.js');
t3toolbox.moveTo = moveTo;
t3toolbox.test = test;
module.exports = t3toolbox;
moveTo.js
var moveTo = {};
console.log("moveTo.js loaded...");
moveTo.logHelloWorld = function(){
console.log("Hello World logHelloWorld() from MOVETO client Javascript!");
};
module.exports = moveTo;
test.js
var test = {};
console.log("test.js loaded...");
test.logHelloWorld = function(){
console.log("Hello World logHelloWorld() from TEST client Javascript!");
};
module.exports = test;
moveTo.handlebars
moveTo<script type="text/javascript">
window.onload = function(){
console.log("ON LOAD...");
t3toolbox.main.moveTo.logHelloWorld();
t3toolbox.main.test.logHelloWorld();
}
</script>
As you can see you still have to use the main after t3toolbox. I never accomplished the configuration where you end up with
var mylibrary = {
moveTO: {/*...*/},
test: {/*...*/}
}
It always end up with:
var mylibrary = {
main: {
moveTo: {/*...*/},
test: {/*...*/}
}
}
Upvotes: 0
Views: 280
Reputation: 10837
Try adding library
to output
configuration, like so -
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: ['./public/js/common.js', './public/js/moveTo.js'],
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.min.js',
library: 'moveTo'
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : []
}
If your library has several exported entities, use this -
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: ['./public/js/common.js', './public/js/moveTo.js'],
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.min.js',
library: ["mylibrary", "[name]"]
},
plugins: process.env.NODE_ENV === 'production' ? [
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
] : []
}
This example is based on https://github.com/webpack/webpack/blob/master/examples/multi-part-library/webpack.config.js#L10.
This example configuration will create an export of this form:
var mylibrary : {
"common": {/* exports from common */},
"moveTo": {/* exports from moveTo */}
}
So you can use them in your code using mylibrary.common
, mylibrary.moveTo
etc.
If you don't want to club all of your imports in "mylibrary", you can change the library
to -
library:"[name]"
This will create separate var moveTo = ...
and var test = ...
exports.
Upvotes: 1