I have to make our website compatible for internet explorer, and it’s quite tricky, as the browser doesn’t understand es6 (arrow functions and the like). I’ve been trying to upgrade webpack and tweak the webpack and babel config to fit our needs. This works great for our own source files, but doesn’t in the node_modules folder. The syntax is not IE compatible if we don’t include it in our babel transpiling, but it also fails if we do transpile the specific node_modules folder that fails (a dependency within the webpack-hot-middleware dependency), giving an error of Uncaught Error: ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead. I’m hoping I just have the wrong babel or webpack settings here, but I've been scraping the interwebz for answers for a while but haven't quite found the solution yet.
I'm using webpack 5 and babel-loader. I have a .babelrc and a webpack.config.js file, here is a snippet from the latter while I try to transpile the failing node_module package:
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: [
{
and: [/node_modules/],
not: [
path.resolve(
__dirname,
"node_modules/webpack-hot-middleware/node_modules/ansi-regex"
)
]
}
],
options: {
babelrc: false,
presets: [
"#babel/preset-react",
["#babel/preset-env", {
"corejs": { "version": 3 },
"useBuiltIns": "usage",
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1",
"ie": "10"
},
}]],
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-transform-arrow-functions"
]
}
},
[...]
]
}
Related
I'm sorry if this is a duplicate (I looked hard using the search tool but nothing came close). Anyone has any ideas how to transpile Node.js CommonJS modules so they can be used within an ES6 import/export project?
I know there's #babel/plugin-transform-modules-commonjs which transpiles ES6 modules into CommonJS form, but I think I'm in need of the opposite. The reason I need this is I have a config file written using Node's module.exports syntax that needs to be imported within a React project built with babel using ES6 modules, but I get a Uncaught TypeError: Cannot assign to read only property 'exports' of object error. Any ideas would be greatly appreciated.
Here's my babelrc.js file:
module.exports = {
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
['#babel/plugin-proposal-class-properties', { loose: true }],
['#babel/plugin-transform-runtime', { regenerator: true }],
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-proposal-optional-chaining'
],
env: {
production: {
plugins: [
[
"transform-react-remove-prop-types",
{ removeImport: true }
],
]
}
}
}
And my webpack config babel loader rule:
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
cacheCompression: false,
envName: isModeProduction ? 'production' : 'development'
}
}
]
},
Thanks to #Thomas Sablik's comment, I found out this was a known webpack issue.
And after poking round and looking up this error, I found this answer on another Stack Overflow which helped me fix it by adding "sourceType": "unambiguous" to my babel configuration.
https://stackoverflow.com/a/56283408/2942765
Thank you Thomas.
The following error is emitted in my Node JS/React JS application after upgrading Node JS to v.12. I'm currently using #babel/core 7.10.1. How should this error be resolved?
Here is my babel.config.js:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
'#babel/preset-react',
'#babel/preset-typescript',
],
plugins: [
'#babel/plugin-proposal-class-properties',
['#babel/plugin-proposal-decorators', { legacy: true }],
'#babel/plugin-proposal-export-default-from',
'#babel/plugin-proposal-export-namespace-from',
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-transform-react-constant-elements',
'#babel/plugin-transform-react-inline-elements',
],
ignore: ['node_modules', 'build'],
};
Try to remove "type": "module" from package.json.
I've spend many hours with no luck and finally found this commend in discussion:
https://github.com/manuelbieh/geolib/issues/208#issuecomment-556994420
You have ignore: ['node_modules', 'build'], maybe, that's the reason?
I had nested package.json files within my application. These package.json files defined dependencies. I believe that parts of the app were being transpiled with different versions of Babel. I flattened my application and removed the nested package.json files. This action solved my problem.
I'm using webpack to bundle React but I still need to transpile our legacy code base written in plain javascript. I've gotten it to work so far but I noticed that since webpack treats every javascript file as an individual bundle it is also injecting its helper methods and polyfills in every file. It would be best if those were only included in the main javascript file and that way reducing the size of the subsequent files.
Is there a way to achieve this?
If anyone's curious how I'm transpiling each legacy js file individually.
glob.sync(PATH).forEach((file) => {
exports.push({
entry: file,
output: {
path: path.resolve(__dirname),
filename: file,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
},
devtool: 'eval',
});
});
I found a way so here's how my set up is currenlty looking.
.babelrc "useBuiltIns": "entry" makes it so you polyfills (and helper methods too?) are only inserted when requested. In other words when you call "import" at the top of the file. This allows me to create a polyfill.js file with nothing in it other than import "core-js"; which turns into a much larger file with all the polyfills I need.
{
"presets": [
[
"#babel/preset-env",
{
"corejs": "3.6.4",
"useBuiltIns": "entry",
"targets": {
"ie": "11"
}
}
],
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/transform-runtime"
],
"sourceType": "unambiguous"
}
the webpack configuration for these files looks like (the exports collection is ultimately assigned to module.exports).
glob
.sync(PATH)
.forEach((file) => {
let config = {
entry: file,
output: {
path: path.resolve(__dirname),
filename: file,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}],
}
};
exports.push(config)
});
needless to say polyfill.js is the first script called in my html.
Im using Three.js as a module, transpiling a code using Babel, packing with WebPack. The problem is that even all the other code is properly transpiled, the three.js module is not and still contains ES6 syntax. Which causes problems in IE11.
.babelrc
{
"presets": [
[
"#babel/preset-env" , {
"targets": {
"ie": "11"
}
}]
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-classes"
]
}
webpack.config
module: {
rules: [
{
test: /\.js$/,
//exclude: /node_modules/,
loaders: ['babel-loader']
},
...
Here I commented out to exclude the node_module folder, but even with that the problem still persists
Any idea what is wrong and how I could get transpiled Threejs module? Thanks a lot
This worked for me:
In the webpack config, set the exclude property like this:
exclude: /node_modules\/(?!(three)\/).*/,.
This forces babel to transpile three no matter what.
Reference: stackoverflow
Cheers
Using the official docs I've been trying to setup an optimal build config using: #babel/preset-env and core-js with a .browserslist file.
As far as I understand the docs, they say that preset-env with useBuiltins:"usage" will update the import 'core-js/stable' statement in my code, to only include the required functions.
However, no matter if I set last 1 chrome version or >1% in NL (which are considerably more and older browsers), the build file is the same size (about 3MB).
What am I missing?
I have a test repo available here: https://github.com/publicJorn/jorns-react-starter
For quick reference, the relevant files:
.babelrc
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": 3, "proposals": true }
}
],
"#babel/preset-react"
],
"plugins": [
[
"#babel/plugin-proposal-object-rest-spread",
{
"useBuiltIns": true
}
],
["#babel/plugin-proposal-class-properties"],
["#babel/plugin-syntax-dynamic-import"],
["babel-plugin-styled-components"]
]
}
webpack part
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
},
.browserslistrc
> 1% in NL
ie 11
not ie < 11
index.js
import 'core-js/stable'
// etc..
If propertie useBuiltIns was usage, core-js will bundle polyfill code what you are using in project.
If useBuiltIns was entry, it will bundle polyfill code by browserslist setting. don't forget import core-js manually.
import 'core-js/stable';
import 'regenerator-runtime/runtime';
Now, usage and entry are both bundle polyfill by browser setting above #babel/core>=7.18