If I'm using webpack, I can create a program using CommonJS module syntax
#File: src-client/entry-point.js
helloWorld1 = require('./hello-world');
alert(helloWorld1.getMessage());
#File: src-client/hello-world.js
var toExport = {};
toExport.getMessage = function(){
return 'Hello Webpack';
}
module.exports = toExport;
I can also create a program using ES6/ES2015 module syntax.
#File: src-client/entry-point.js
import * as helloWorld2 from './hello-world2';
alert(helloWorld2.getMessage());
#File: src-client/hello-world2.js
var getMessage = function(){
return 'Hello ES2015';
};
export {getMessage};
Both of the above programs compile and run (in browser) without issue. However, if I try to mix and match the syntax
#File: src-client/entry-point.js
helloWorld1 = require('./hello-world');
import * as helloWorld2 from './hello-world2';
alert(helloWorld1.getMessage());
alert(helloWorld2.getMessage());
Webpack itself will happily compile the program
$ ./node_modules/webpack/bin/webpack.js src-client/entry-point.js pub/bundle.js
Hash: 1ce72fd037a8461e0509
Version: webpack 2.5.1
Time: 72ms
Asset Size Chunks Chunk Names
bundle.js 3.45 kB 0 [emitted] main
[0] ./src-client/hello-world.js 110 bytes {0} [built]
[1] ./src-client/hello-world2.js 80 bytes {0} [built]
[2] ./src-client/entry-point.js 155 bytes {0} [built]
but when I run the program in my browser, I get the following error
Uncaught ReferenceError: helloWorld1 is not defined
at Object.<anonymous> (bundle.js:101)
at __webpack_require__ (bundle.js:20)
at toExport (bundle.js:66)
at bundle.js:69
I didn't expect this to work (I'm not a monster), but it does raise the question of what, exactly, is going on.
When webpack encounters conflicting module syntax like this -- what happens? Does the presence of an import
keyword put webpack into "parse ES2015" mode? Is there a way to force webpack to treat certain files as ES2015 and others as CommonJS? i.e. is there a way for webpack to seamlessly handle a project with modules using multiple standards? Or is the general feeling that you shouldn't do this?
The presence of import
automatically puts the module in strict mode, as defined in the Spec. In strict mode you're not allowed to use a variable that hasn't been defined, whereas in regular mode the variable will implicitly become a global variable. You try to assign the result of require
to helloWorld1
which was not previously defined. You need to declare that variable:
const helloWorld1 = require('./hello-world');
Instead of const
you may also use let
or var
.