Javascript Webpack如何处理混合和匹配模块语法

Javascript Webpack如何处理混合和匹配模块语法,javascript,webpack,ecmascript-6,commonjs,Javascript,Webpack,Ecmascript 6,Commonjs,如果我使用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 'Hell

如果我使用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
未捕获引用错误:未定义helloWorld1
反对。(bundle.js:101)
at\uuuuu网页包\uuuuuu需要(bundle.js:20)
在toExport(bundle.js:66)
在bundle.js:69
我没想到这会奏效(我不是怪物),但它确实提出了一个问题,到底发生了什么


当webpack遇到这样冲突的模块语法时--会发生什么?出现
import
关键字是否会将webpack置于“parse ES2015”模式?有没有办法强迫webpack将某些文件视为ES2015,而将其他文件视为CommonJS?i、 e.webpack是否有一种方法可以无缝地处理使用多个标准的模块的项目?还是一般人认为不应该这样做?

Webpack在混合不同的模块语法时应该没有任何问题

问题是您在ES2015模块中隐式声明了
helloWorld1
。这些模块,这意味着您不能像在ES2015模块中那样声明变量

将您的行更改为下面的行,我很有信心您的程序将运行

let helloWorld1 = require('./hello-world');

Webpack在混合不同的模块语法时应该没有任何问题

问题是您在ES2015模块中隐式声明了
helloWorld1
。这些模块,这意味着您不能像在ES2015模块中那样声明变量

将您的行更改为下面的行,我很有信心您的程序将运行

let helloWorld1 = require('./hello-world');

出现
import
会自动将模块放入,如中所定义。在严格模式下,不允许使用未定义的变量,而在常规模式下,该变量将隐式成为全局变量。您尝试将
require
的结果分配给先前未定义的
helloWorld1
。您需要声明该变量:

const helloWorld1 = require('./hello-world');

除了
const
之外,您还可以使用
let
var
来代替
import
自动将模块放入,如中所定义。在严格模式下,不允许使用未定义的变量,而在常规模式下,该变量将隐式成为全局变量。您尝试将
require
的结果分配给先前未定义的
helloWorld1
。您需要声明该变量:

const helloWorld1 = require('./hello-world');

除了
const
之外,您还可以使用
let
var

import
编译为
require
,没有冲突;你可以愉快地使用这两种方法。您的问题很可能是期望或使用不存在的全局变量。这还取决于
helloWorld1
的公开方式。它与混合和匹配无关。@Elclans感谢您的关注——但我上面有一个非常简单的示例程序,似乎不起作用?@DaveNewton感谢您的关注——我有上面helloWorld1的源代码——它的公开方式有什么问题吗?
import
编译到
要求
,没有冲突;你可以愉快地使用这两种方法。您的问题很可能是期望或使用不存在的全局变量。这还取决于
helloWorld1
的公开方式。它与混合和匹配无关。@Elclans感谢您的关注——但我上面有一个非常简单的示例程序,它似乎不起作用?@DaveNewton感谢您的关注——我有上面helloWorld1的来源——它的暴露方式有什么问题吗?很清楚,ES6创建了“模块”和“脚本”之间的区别,而作为“模块”的文件会自动严格,正如您所说的。Webpack决定使用
导入
导出
作为一个模块来自动处理文件,而不使用该模块作为脚本来处理文件,这在很大程度上不是规范的一部分。将来很可能会发生变化。例如,节点将不会执行此操作。它将
.mjs
文件视为模块,将
.js
文件视为脚本。从长远来看,Webpack和其他工具很可能会采用这种方式。现在说还为时尚早。要清楚,ES6创建了“模块”和“脚本”之间的区别,而作为“模块”的文件会自动变得严格,正如您所说的。Webpack决定使用
导入
导出
作为一个模块来自动处理文件,而不使用该模块作为脚本来处理文件,这在很大程度上不是规范的一部分。将来很可能会发生变化。例如,节点将不会执行此操作。它将
.mjs
文件视为模块,将
.js
文件视为脚本。从长远来看,Webpack和其他工具很可能会采用这种方式。现在说还为时过早。