Babel not transpiling node_modules using Laravel Mix - javascript

I am trying to enable support for IE 11 in my application. However, some of my dependencies haven't transpiled the code to es5. Therefor, I tried added one of them to my rules, but it still doesn't transpile that dependency.
This is how I am including my dependency, this time being vue2-google-maps. However the produced code still contains Object.entries after running npm run dev.
mix.webpackConfig({
module: {
rules: [
{
test: /node_modules\/(vue2-google-maps)\/.+\.js$/,
use: [
{
loader: 'babel-loader',
options: mix.config.babel()
}
]
}
]
}
});
mix.js('resources/js/app.js', 'public/js')
.extract()
.babel(['public/js/manifest.js'], 'public/js/manifest.es5.js')
.babel(['public/js/vendor.js'], 'public/js/vendor.es5.js')
.babel(['public/js/app.js'], 'public/js/app.es5.js')
Here is a similar question, but the answer didn't help me yet. Here is another similar question, but there is no answer in that one.
Here is my .babelrc:
{
"presets": [
[
"#babel/preset-env",
{
"targets": { "ie": "10" }
}
]
]
}
What am I doing wrong? Why is not the dependency also transpiled?

Inspect your config with: mix.dump();
b/c your rules and test look good (helpful & worked for me in different scenario).
I'd give a try to mix.babelConfig(<your config>) - seems to be more explicit to me

Related

How to transpile an npm dependency to es5 with babel and webpack?

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"
]
}
},
[...]
]
}

How can I use Node.js CommonJS modules in ES6 import/export modules using babel or webpack?

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.

ThreeJS module is not transpiled by Babel

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

Material-UI have different style result in production mode?

I am writing a React app that uses server-side rendering. I am following the instruction here to set up a file.
Here is my .babelrc configuration file
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": { "version": 3, "proposals": true },
"targets": {
"browsers": "> 1%, not ie 11, not op_mini all",
"node": 13
}
}
],
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-runtime",
[
"import",
{
"libraryName": "#material-ui/icons",
"libraryDirectory": "utils", // default: lib
"camel2DashComponentName": false // default: true
},
"#material-ui/icons"
]
]
}
And this is webpack.config.js file
const path = require("path");
const nodeExternals = require("webpack-node-externals");
const commonConfig = {
devtool: "source-map",
module: {
rules: [{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }]
},
resolve: {
alias: {
"#material-ui/core": "#material-ui/core/es"
}
}
};
module.exports = [
{
...commonConfig,
entry: "./src/client",
output: {
path: path.resolve(__dirname, "public")
}
},
{
...commonConfig,
target: "node",
entry: "./src/server",
output: {
path: path.resolve(__dirname, "server")
},
externals: [nodeExternals()]
}
];
(Here is the full code in CodeSandBox and here is in Github if you want to try out)
The problem appear is when I bundle up the file, in development mode, everything work just fine. But when I try production mode, the CSS part starts to behave weirdly. When the file is first loaded from localhost, it is styled correctly (this happens in a very short time), then the style goes wrong as some styling is missing.
When I try to investigate, I find that all the style that is missing is the part I wrote with makeStyles(). All the built-in styles work just fine.
I tried to remove all the resolve property in webpack.config.js following this post, but it doesn't work. No matter what I try to change that property, nothing happens.
So now the only way I found that can make the app work in production build is to remove the code that removes the styling file (you can find that part at the end of client.js file), but I'm not sure what is the result of doing so.
So my questions are:
What can you suggest the fix for the app?
Why there is such a difference between two modes, development and production? I get that the production mode will include some minification, tree shaking, etc., and the development has most of that except for minification. So why there is a difference?
Edit: I found two possible and workable fixes for this bug: one is to stop removing those CSS files (code that I wrote in client.js file); the other one is to remove the nodeExternal() plugin in webpack.config.js and bundle everything for the server file. What do you think ?
I had a similar issue, although without server-side rendering. It was caused by a different order of stylesheets in dev and prod environments, causing unwanted overwrites. In dev env all stylesheets created by makeStyles() were injected after ALL MUI stylesheets, but in production they were mixed.
Solution:
Add an option: { index: 1 } to all makeStyles() invocations, in order to place those sheets after the MUI sheets which have an index of 0 (by default). This optional argument is passed directly to underlying JSS's jss.createStyleSheet() and dictates the injection order:
const useStyles = makeStyles(
(...), // styles
{ index: 1 }, // optional argument for JSS, to set position after MUI stylesheets
)
(after: https://stackoverflow.com/a/62646041/624597)

preset-env and core-js don't seem to use browserslist

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

Categories

Resources