oli*_*ren 4 javascript webpack babeljs
我的 babel+webpack 配置工作正常,但生成的包无法在 IE11 中运行,因为它包含const声明。我认为有es2015预设就足以解决这个问题?运行$(npm bin)/babel test/some-es2015.js会产生严格的 ES5.1 代码,因此 Babel 似乎可以工作,但在 IE11 中运行的实际代码位于从node_modules.
当在我的结果包中 grep 时,'const '我得到这样的某些行(eval 是由于 eval 源映射顺便说一句):
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst validator = __webpack_require__(/*! validator */ \"./node_modules/tcomb-additional-types/node_modules/validator/index.js\");\nconst t = __webpack_require__(/*! tcomb */ \"./node_modules/tcomb/index.js\");\nconst IP = t.refinement(t.String, validator.isIP);\nexports.IP = IP;\nexports.default = IP;\n//# sourceMappingURL=ip.js.map\n\n//# sourceURL=webpack:///./node_modules/tcomb-additional-types/lib/string/ip.js?");
Run Code Online (Sandbox Code Playgroud)
需要注意的重要部分是诸如 之类的内容const validator =。这不是 ES5.1 语法。我自己的代码似乎已经很好地转换为 ES5 了。/node_modules/tcomb-additional-types/lib/string/ip.js我可以在他们使用 的地方看到这个文件const,所以这不是 Babel 添加consts,而是包含它们的源。大多数其他软件包都是 ES5。
到目前为止,我发现大多数consts 都来自material-ui和tcomb-additional-types。
巴别塔.babelrc:
{
"compact": false,
"presets": [
"es2015",
"es2017"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}],
"transform-class-properties",
"transform-react-jsx",
"transform-object-rest-spread"
]
}
Run Code Online (Sandbox Code Playgroud)
网页包配置:
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
/** @returns {String} an absolute path */
function toRoot(rootRelativeDir) {
return path.resolve(__dirname, '..', rootRelativeDir);
}
module.exports = {
entry: ['./src/app.js', './styles/flex.less'].map(toRoot),
output: {
filename: 'bundle.js',
path: toRoot('.webpack/dist')
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {}
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
/* General options are read using .babelrc - only webpack loader specific here */
cacheDirectory: toRoot('.webpack/babel_cache')
}
}
]
}
]
},
plugins: [new CopyWebpackPlugin([toRoot('public')])]
};
Run Code Online (Sandbox Code Playgroud)
我的根本问题是一些 Node 包不是使用 ES5 语法编写的,并且 Babel 转换由于某种原因没有转换它们。这是正常问题
找出发生这种情况的原因非常容易(@Vincent 的回答有帮助);exclude: /node_modules/我在配置里有。当然,删除它会“解决”问题,但它会引入新的问题,因为它的exclude存在是有原因的,因为你不希望 Babel 处理其中的每个文件。
所以你想要的是这样的:选择性过滤允许某些模块。
尝试构建一个正则表达式来允许 node_modules 下的包列表,但限制其余的包是很麻烦且容易出错的。值得庆幸的是,Webpack 文档描述了条件规则(其中exclude之一)可以是
创建这样的函数很容易!所以我没有将exclude: /node_modules改为 ,而是将其改为exclude: excludeCondition,其中excludeCondition有以下函数:
function excludeCondition(path){
const nonEs5SyntaxPackages = [
'material-ui',
'tcomb-additional-types'
]
// DO transpile these packages
if (nonEs5SyntaxPackages.some( pkg => path.match(pkg))) {
return false;
}
// Ignore all other modules that are in node_modules
if (path.match(toRoot("node_modules"))) { return true; }
else return false;
}
Run Code Online (Sandbox Code Playgroud)
这解决了我的问题,因为只有极少数包使用 ES2015 语法,因此将它们添加到允许列表中是可以管理的。
附录
既然人们询问了toRoot(),这是逐字代码:
/** @returns {String} an absolute path */
function toRoot(rootRelativeDir) {
return path.resolve(__dirname, '..', rootRelativeDir);
}
Run Code Online (Sandbox Code Playgroud)
适应您自己的需求。
更完整的代码:
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
/** @returns {String} an absolute path */
function toRoot(rootRelativeDir) {
return path.resolve(__dirname, '..', rootRelativeDir);
}
function excludeCondition(path) {
const nonEs2015Packages = ['tcomb-additional-types', 'material-ui'];
// DO transpile these packages
if (nonEs2015Packages.some(pkg => path.match(pkg))) {
return false;
}
// Ignore all other modules that are in node_modules
return Boolean(path.match(toRoot('node_modules')));
}
module.exports = {
entry: ['./src/app.js', './styles/custom.less', './styles/flex.less', './styles/rc_slider.less'].map(toRoot),
output: {
filename: 'bundle.js',
path: toRoot('.webpack/dist')
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {}
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: excludeCondition,
use: [
{
loader: 'babel-loader',
options: {
/* General options are read using .babelrc - only webpack loader specific here */
cacheDirectory: toRoot('.webpack/babel_cache')
}
}
]
}
]
},
plugins: [new CopyWebpackPlugin([toRoot('public')])]
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7331 次 |
| 最近记录: |