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');

您也可以使用 letvar

而不是 const