admin管理员组文章数量:1287856
My babel+webpack config works fine, but the resulting bundle isn't runnable in IE11 as it contains const
declarations. I thought having the es2015
preset was enough to fix this? Running $(npm bin)/babel test/some-es2015.js
produces strict ES5.1 code, so Babel seems to work, but the actual code that borks in IE11 is in modules imported from node_modules
.
When grepping for 'const '
in my resulting bundle I get certain lines like this (the eval is due to eval source mapping btw):
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst validator = __webpack_require__(/*! validator */ \"./node_modules/tb-additional-types/node_modules/validator/index.js\");\nconst t = __webpack_require__(/*! tb */ \"./node_modules/tb/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/tb-additional-types/lib/string/ip.js?");
The important part to note is the stuff such as const validator =
. This isn't ES5.1 syntax. My own code seems to have been transpiled to ES5 just fine. I can see this file in /node_modules/tb-additional-types/lib/string/ip.js
, where they use const
, so this isn't Babel adding const
s, but the source containing them. Most of the other packages are ES5.
So far, I have found that most const
s are from material-ui
and tb-additional-types
.
Babel .babelrc:
{
"pact": false,
"presets": [
"es2015",
"es2017"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}],
"transform-class-properties",
"transform-react-jsx",
"transform-object-rest-spread"
]
}
Webpack config:
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')])]
};
My babel+webpack config works fine, but the resulting bundle isn't runnable in IE11 as it contains const
declarations. I thought having the es2015
preset was enough to fix this? Running $(npm bin)/babel test/some-es2015.js
produces strict ES5.1 code, so Babel seems to work, but the actual code that borks in IE11 is in modules imported from node_modules
.
When grepping for 'const '
in my resulting bundle I get certain lines like this (the eval is due to eval source mapping btw):
eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst validator = __webpack_require__(/*! validator */ \"./node_modules/tb-additional-types/node_modules/validator/index.js\");\nconst t = __webpack_require__(/*! tb */ \"./node_modules/tb/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/tb-additional-types/lib/string/ip.js?");
The important part to note is the stuff such as const validator =
. This isn't ES5.1 syntax. My own code seems to have been transpiled to ES5 just fine. I can see this file in /node_modules/tb-additional-types/lib/string/ip.js
, where they use const
, so this isn't Babel adding const
s, but the source containing them. Most of the other packages are ES5.
So far, I have found that most const
s are from material-ui
and tb-additional-types
.
Babel .babelrc:
{
"pact": false,
"presets": [
"es2015",
"es2017"
],
"plugins": [
["transform-runtime", {
"polyfill": false,
"regenerator": true
}],
"transform-class-properties",
"transform-react-jsx",
"transform-object-rest-spread"
]
}
Webpack config:
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')])]
};
Share
Improve this question
edited Nov 5, 2018 at 15:49
oligofren
asked Nov 5, 2018 at 13:02
oligofrenoligofren
23k17 gold badges111 silver badges202 bronze badges
1
- Related Github discussion – vsync Commented Oct 26, 2020 at 8:52
3 Answers
Reset to default 5My underlying problem was that some Node packages are not written using ES5 syntax, and the Babel transforms did not transform them for some reason. This is a normal issue
Finding why this happened was pretty easy (@Vincent's answer helped); I had exclude: /node_modules/
in the config. Of course, removing this would "fix" the issue, but it would introduce new issues, as the exclude
is there for a reason, as you don't want Babel to process every file in there.
So what you want is this: selective filtering allowing some modules.
Trying to construct a regex that will allow a list of packages under node_modules, but restrict the rest is cumbersome and error prone. Thankfully the Webpack docs describe that the condition rules, of which exclude
is one, can be
- A string: To match the input must start with the provided string. I. e. an absolute directory path, or absolute path to the file.
- A RegExp: It's tested with the input.
- A function: It's called with the input and must return a truthy value to match.
- An array of Conditions: At least one of the Conditions must match.
- An object: All properties must match. Each property has a defined behavior.
Creating such a function is easy! So instead of having exclude: /node_modules
, I changed it to be exclude: excludeCondition
, where excludeCondition
is the following function:
function excludeCondition(path){
const nonEs5SyntaxPackages = [
'material-ui',
'tb-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;
}
This fixed my issue, as there is just a tiny number of packages using ES2015 syntax, so adding them to the allowlist is manageable.
Addendum
Since people ask about the toRoot()
, this is the verbatim code:
/** @returns {String} an absolute path */
function toRoot(rootRelativeDir) {
return path.resolve(__dirname, '..', rootRelativeDir);
}
Adapt to your own needs.
The fuller code:
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 = ['tb-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')])]
};
I had a similar problem and I fixed it by renaming .babelrc.js
to babel.config.js
.
Apparently, .babelrc
has smaller scope than babel.config.js
, if you'd like to read more about that, check out this post:
When to use babel.config.js and .babelrc
The same problem happened to me as well. Some node modules don't provide browser support and target node versions that leverage newer ES syntax.
I came across that handy package that transpiles node modules code:
https://www.npmjs./package/babel-engine-plugin
It solved my problem regarding IE11 support, hope it helps
本文标签: javascriptBabel not transpiling imported nodemodules to ES5includes ES2015 syntaxStack Overflow
版权声明:本文标题:javascript - Babel not transpiling imported node_modules to ES5 - includes ES2015 syntax - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741325806a2372471.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论