Webpack 如何处理混搭模块语法
How does Webpack Handle mix-and-match Module Syntax
如果我使用的是 webpack,我可以使用 CommonJS 模块语法创建一个程序
#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;
我还可以使用 ES6/ES2015 模块语法创建程序。
#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};
以上两个程序都可以编译并且运行(在浏览器中)没有问题。但是,如果我尝试混合搭配语法
#File: src-client/entry-point.js
helloWorld1 = require('./hello-world');
import * as helloWorld2 from './hello-world2';
alert(helloWorld1.getMessage());
alert(helloWorld2.getMessage());
Webpack 自己会愉快地编译程序
$ ./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]
但是当我运行浏览器中的程序时,出现以下错误
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
我没想到这会起作用(我不是怪物),但它确实提出了一个问题,到底发生了什么。
当 webpack 遇到像这样的冲突模块语法时——会发生什么? import
关键字的存在是否会使 webpack 进入 "parse ES2015" 模式?有没有办法强制 webpack 将某些文件视为 ES2015 而将其他文件视为 CommonJS?即有没有办法让 webpack 无缝地处理一个使用多种标准的模块的项目?还是普遍认为你不应该这样做?
Webpack 混合使用不同的模块语法应该没有任何问题。
问题是你在 ES2015 模块中隐式声明 helloWorld1
。这些模块,这意味着您不能像在 ES2015 模块中那样声明变量。
将您的行更改为以下行,我相信您的程序会 运行。
let helloWorld1 = require('./hello-world');
import
的存在自动将模块放入 strict mode, as defined in the Spec。在严格模式下,您不允许使用未定义的变量,而在常规模式下,该变量将隐式成为全局变量。您尝试将 require
的结果分配给之前未定义的 helloWorld1
。您需要声明该变量:
const helloWorld1 = require('./hello-world');
您也可以使用 let
或 var
。
而不是 const
如果我使用的是 webpack,我可以使用 CommonJS 模块语法创建一个程序
#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;
我还可以使用 ES6/ES2015 模块语法创建程序。
#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};
以上两个程序都可以编译并且运行(在浏览器中)没有问题。但是,如果我尝试混合搭配语法
#File: src-client/entry-point.js
helloWorld1 = require('./hello-world');
import * as helloWorld2 from './hello-world2';
alert(helloWorld1.getMessage());
alert(helloWorld2.getMessage());
Webpack 自己会愉快地编译程序
$ ./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]
但是当我运行浏览器中的程序时,出现以下错误
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
我没想到这会起作用(我不是怪物),但它确实提出了一个问题,到底发生了什么。
当 webpack 遇到像这样的冲突模块语法时——会发生什么? import
关键字的存在是否会使 webpack 进入 "parse ES2015" 模式?有没有办法强制 webpack 将某些文件视为 ES2015 而将其他文件视为 CommonJS?即有没有办法让 webpack 无缝地处理一个使用多种标准的模块的项目?还是普遍认为你不应该这样做?
Webpack 混合使用不同的模块语法应该没有任何问题。
问题是你在 ES2015 模块中隐式声明 helloWorld1
。这些模块
将您的行更改为以下行,我相信您的程序会 运行。
let helloWorld1 = require('./hello-world');
import
的存在自动将模块放入 strict mode, as defined in the Spec。在严格模式下,您不允许使用未定义的变量,而在常规模式下,该变量将隐式成为全局变量。您尝试将 require
的结果分配给之前未定义的 helloWorld1
。您需要声明该变量:
const helloWorld1 = require('./hello-world');
您也可以使用 let
或 var
。
const