我有一个简单的例子,我在一个应用程序中使用es6模块,我想把它们移植到es5中(我不想在浏览器中运行模块,尽管我知道他们的支持率在90%以上)。
我在兜圈子,遇到同样的错误和问题。这是我的设置和我想达到的目的。
//add.js
export function add(x, y) {
return x + y;
}
//multiply.js
export function multiply(x, y) {
return x * y;
}
然后我运行babel来输出 bundle.js
文件,使用 @babel/preset-env
预设。
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"esmodules": true
}
}
]
]
}
输出结果是这样的。
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.add = add;
function add(x, y) {
return x + y;
}
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.multiply = multiply;
function multiply(x, y) {
return x * y;
}
当我运行我的 html
文件的浏览器中,控制台记录了以下错误。bundle.js:3 Uncaught ReferenceError: exports is not defined
我的问题是: babel输出的是什么?是commonjs模块吗?如何让es6模块在浏览器中运行?
"esmodules": true"
是错误的。
当指定 "esmodules": true"
浏览器的目标将被忽略,脚本也不会被转码到es5上。target
现代浏览器对es6模块的处理是原生的,最好的方法是将现代浏览器与传统浏览器(ie11)不同,并加载特定的脚本,如
// low transpiled (loads only in modern browser)
<script type="module" src="/assets/scripts/main.js"></script>
// full transpiled (loads only in legacy browser) --> polyfill this bundle
<script nomodule src="/assets/scripts/main.legacy.js" defer></script>
// https://github.com/unic/darvin-webpack-boilerplate/blob/master/webpack/settings/javascript/babel-config.js
const modern = {
presets: [
["@babel/preset-env", {
// define transpile level
targets: {
browsers: [
"> 1% in EU",
"not ie 11",
"not dead"
]
},
useBuiltIns: "usage",
corejs: 3,
}]
],
plugins: [
"@babel/plugin-syntax-dynamic-import",
"transform-eval"
],
comments: false,
cacheDirectory: path.join(CACHE_PATH, 'babel-loader')
};
const legacy = {
presets: [
["@babel/preset-env", {
// define transpile level
targets: {
browsers: [
"> 1% in CH",
"ie >= 11",
"not dead"
]
},
useBuiltIns: "usage",
corejs: 3,
}]
],
plugins: [
"@babel/plugin-syntax-dynamic-import",
"transform-eval"
],
comments: false,
cacheDirectory: path.join(CACHE_PATH, 'babel-loader')
};
请检查 巴别文件 更多信息。