Convert .babelrc to .babelrc.js - javascript

I use Material UI and want to make the bundle size smaller by loading the components on demand.
I've got a Babel config in a .babelrc file.
At the moment the .babelrc looks like this:
{
"presets": ["#babel/preset-env", "#babel/react"],
"plugins": [
["#babel/plugin-syntax-dynamic-import"],
["react-hot-loader/babel"],
["import", {
"libraryName": "antd",
"style": true
}],
[
"#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}
Now I need to add the following:
const plugins = [
[
'babel-plugin-import',
{
'libraryName': '#material-ui/core',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'core'
],
[
'babel-plugin-import',
{
'libraryName': '#material-ui/icons',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'icons'
]
];
module.exports = {plugins};
How can I do that ? It seems that .babelrc works differently to the .babelrc.js

As indicate in https://babeljs.io/docs/en/config-files:
For compatibility reasons, .babelrc is an alias for .babelrc.json.
So your first script is JSON format and the second one is CommonJS.
Mi suggestion is just copy the contents of plugins from your second script inside the "plugins" section of your first one, and use any JSON validation tool to make sure that the result is correct, see [1]
That being said I suggest that you use .babelrc.cjs (CommonJS) format as it is just javascript code can be formated easily using tools like prettier and support some features that JSON does not like comments, see [2]
[1] .babelrc or .babelrc.json
{
"presets": ["#babel/preset-env", "#babel/react"],
"plugins": [
["#babel/plugin-syntax-dynamic-import"],
["react-hot-loader/babel"],
["import", {
"libraryName": "antd",
"style": true
}],
[
"#babel/plugin-transform-runtime",
{
"regenerator": true
}
],
[
"babel-plugin-import",
{
"libraryName": "#material-ui/core",
"libraryDirectory": "esm",
"camel2DashComponentName": false
},
"core"
],
[
"babel-plugin-import",
{
"libraryName": "#material-ui/icons",
"libraryDirectory": "esm",
"camel2DashComponentName": false
},
"icons"
]
]
}
[2] .babelrc.js or .baberc.cjs
{
"presets": ["#babel/preset-env", "#babel/react"],
"plugins": [
["#babel/plugin-syntax-dynamic-import"],
["react-hot-loader/babel"],
["import", {
"libraryName": "antd",
"style": true
}],
[
"#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
const presets
const plugins = [
[
'babel-plugin-import',
{
'libraryName': '#material-ui/core',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'core'
],
[
'babel-plugin-import',
{
'libraryName': '#material-ui/icons',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'icons'
]
];
module.exports = {plugins};

Related

How to properly configure babel for material-ui in Next.js?

DOCS:
https://material-ui.com/guides/minimizing-bundle-size/#development-environment
"Create a .babelrc.js file in the root directory of your project:
const plugins = [
[
'babel-plugin-transform-imports',
{
'#material-ui/core': {
// Use "transform: '#material-ui/core/${member}'," if your bundler does not support ES modules
'transform': '#material-ui/core/esm/${member}',
'preventFullImport': true
},
'#material-ui/icons': {
// Use "transform: '#material-ui/icons/${member}'," if your bundler does not support ES modules
'transform': '#material-ui/icons/esm/${member}',
'preventFullImport': true
}
}
]
];
module.exports = {plugins};"
https://nextjs.org/docs/advanced-features/customizing-babel-config
"To add presets/plugins with custom configuration, do it on the next/babel preset like so:
{
"presets": [
[
"next/babel",
{
"preset-env": {},
"transform-runtime": {},
"styled-jsx": {},
"class-properties": {}
}
]
],
"plugins": []
}"
QUESTION:
How to properly configure babel for material-ui in Next.js ? My implementation below is apparently incorrect as import { ConstructionOutlined } from '#material-ui/icons';is still causing very long load times in dev mode. I observed no error messages when trying the below implementation and variations.
CODE:
{
"presets": [
[
"next/babel",
{
"babel-plugin-transform-imports":
{
"#material-ui/core": {
// Use "transform: '#material-ui/core/${member}'," if your bundler does not support ES modules
"transform": "#material-ui/core/esm/${member}",
"preventFullImport": true
},
"#material-ui/icons": {
// Use "transform: '#material-ui/icons/${member}'," if your bundler does not support ES modules
"transform": "#material-ui/icons/esm/${member}",
"preventFullImport": true
}
}
}
]
],
"plugins": []
}
OR
module.exports = {
presets: [
["next/babel"]
],
plugins: [
[
'babel-plugin-import',
{
'libraryName': '#material-ui/core',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'core'
],
[
'babel-plugin-import',
{
'libraryName': '#material-ui/icons',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
'libraryDirectory': 'esm',
'camel2DashComponentName': false
},
'icons'
],
]
}
OR ELSE ?
I could exactly understand your problem. Follow this.
npm install babel-plugin-import --save-dev
Create a .babelrc file in the root directory of your next.js project with the following content:
{
"presets": ["next/babel"],
"plugins": [
[
'babel-plugin-import',
{
libraryName: '#mui/material',
libraryDirectory: '',
camel2DashComponentName: false,
},
'core',
],
[
'babel-plugin-import',
{
libraryName: '#mui/icons-material',
libraryDirectory: '',
camel2DashComponentName: false,
},
'icons',
],
]
}
Restart your development server.
This above babel configuration will convert
// from
import { Button, TextField } from '#mui/material'; ( great developer experience)
// to
import Button from '#mui/material/Button'; (smaller bundle size means great user experience)
import TextField from '#mui/material/TextField';
As a result, you will notice
faster loading of development server.
smaller bundle size
also faster client navigation with next/link and fallback:true.
Source: Babel config docs
Mui
Next.js
Hope it works for you too!
Adding babel-plugin-transform-imports is what worked for me. My .babelrc file looks like this:
{
"presets": ["next/babel"],
"plugins": [
[
"babel-plugin-transform-imports",
{
"#material-ui/core": {
"transform": "#material-ui/core/${member}",
"preventFullImport": true
},
"#material-ui/icons": {
"transform": "#material-ui/icons/${member}",
"preventFullImport": true
}
}
]
]
}
Try using the non-esm version that you have commented out in your implementation. After doing that the build time dropped significantly for me. I did have to update styles imports for Material UI like they recommend in their documentation as well.

Is it safe to mark prop-types as peer dependency in your react module

How can I export my component's propTypes so when I include this package in my project, IDE can suggest them without affecting my bundle size ?
Or how the user may be able to get rid of them ?
Is it safe to mark prop-types as peeDependency since react includes it ?
I use rollup#1.27.13 and #babel/core#7.7.7 and few other plugins for each of them.
When I remove propTypes using the code bellow, my bundle size is 1.58kb gzipped
{
"presets": [
"#babel/preset-react",
["#babel/preset-env", {
"modules": false
}]
],
"plugins": [
["transform-react-remove-prop-types", {
"removeImport": true
}],
"#babel/plugin-proposal-optional-chaining"
]
}
But when I leave them (and then I can get suggestions by IDE) it jumps to 6.45kb gzipped.
rollup config:
{
input: 'src/index.js',
output: [
{
file: pkg.main,
format: 'cjs'
},
{
file: pkg.module,
format: 'es'
}
],
plugins: [
external(),
babel({
exclude: 'node_modules/**'
}),
resolve(),
commonjs(),
terser()
],
}
Thanks

Uncaught ReferenceError: exports is not defined after Webpack Code Split

I am trying to optimize my webpack bundle size by splitting it into two bundles: webpack-bundle.js, which contains my code, and vendor-bundle.js, which contains node modules and third party libraries. But after I successfully created two bundles, I am getting two errors in the browser regarding both bundles:
Uncaught ReferenceError: exports is not defined at vendor-bundle.self-879f615019647c756dc959f99d735b3a2534b00805364ae6fca0091d1190d62d.js?body=1:1
Uncaught TypeError: Cannot read property 'call' of undefined at I (webpack-bundle.self-78221fc03008c178fe970b69731594f14d651dab84e5cf928beacc805ebde79c.js?body=1:1)
This is my webpack.config.js.
const config = {
"entry": {
"webpack-bundle": "./app/registration",
},
"output": {
filename: "[name].js",
path: pathLib.resolve(__dirname, "../app/assets/webpack"),
},
"module": {
"rules": [
{
"exclude": /node_modules/,
"test": /\.jsx?$/,
"use": {
"loader": "babel-loader",
"options": {
"plugins": [
"#babel/plugin-proposal-class-properties",
["#babel/plugin-proposal-decorators", {"legacy": true}],
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-function-sent",
"#babel/plugin-proposal-json-strings",
"#babel/plugin-proposal-numeric-separator",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-throw-expressions",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-syntax-import-meta",
"#babel/plugin-transform-react-jsx"
],
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
}
}
],
},
"plugins": [
new webpack.ProvidePlugin({
"$": "jquery",
"jQuery": "jquery",
"window.jQuery": "jquery"
}),
new UglifyJsPlugin(),
],
"optimization": {
"splitChunks": {
"cacheGroups": {
"vendor": {
"test": /node_modules/,
"chunks": "all",
"name": "vendor-bundle"
}
}
}
},
"resolve": {
"alias": {
"Lib": pathLib.resolve(__dirname, "app/lib/"),
"Shared": pathLib.resolve(__dirname, "app/shared/")
},
"extensions": [".js", ".jsx"]
},
"target": "node"
};
module.exports = config;
This is my .babelrc:
{
"plugins": [
"#babel/plugin-proposal-class-properties",
["#babel/plugin-proposal-decorators", {"legacy": true}],
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-function-sent",
"#babel/plugin-proposal-json-strings",
"#babel/plugin-proposal-numeric-separator",
"#babel/plugin-proposal-object-rest-spread",
"#babel/plugin-proposal-throw-expressions",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-syntax-import-meta",
"#babel/plugin-transform-react-jsx"
],
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
}
We use React, Rails, React on Rails, and Slim. To load webpack, I'd add this to my application.slim:
= javascript_include_tag 'vendor-bundle'
= javascript_include_tag 'webpack-bundle'
I want to be able to serve the two bundles I created. Is there anything wrong in the way I configured my webpack and split the bundle? Or should I install something else?
At the bottom of your webpack config, you have your target mode set to node
In node, module and module.exports both exist, but these don’t exist in the browser - this is what’s causing the error
If you remove this line, webpack will assume you’re targeting browsers instead, and will also transform this line for you - your bundles should then run in the browser as expected.

Jest, how to ignore test coverage of specific folders?

In my react project I have a root ./styles folder which contains various style objects for styled-components. I do not want these files to show up in the coverage test.
I've tried to hide them like so, but when I run npm run coverage they still show up.
package.json
"jest": {
"setupFilesAfterEnv": [
"<rootDir>/jest.setup.js"
],
"coveragePathIgnorePatterns": [
"<rootDir>/styles/",
"./styles/"
],
"testPathIgnorePatterns": [
"<rootDir>/.next/",
"<rootDir>/node_modules/",
"<rootDir>/styles/",
"./styles/"
],
"transform": {
"^.+\\.(js)$": "babel-jest",
"^.+\\.js?$": "babel-jest",
"^.+\\.ts?$": "babel-jest",
"^.+\\.tsx?$": "babel-jest",
"^.+\\.json5$": "json5-jest"
},
"moduleFileExtensions": [
"js",
"json",
"json5",
"ts",
"tsx"
],
"modulePaths": [
"<rootDir>/components/",
"<rootDir>/pages/",
"<rootDir>/shared/"
]
}
babelrc
{
"env": {
"development": {
"presets": [
"next/babel",
"#zeit/next-typescript/babel"
],
"plugins": [
["styled-components", {"ssr": true, "displayName": true}],
["#babel/plugin-proposal-decorators", {"legacy": true}],
["istanbul",{"exclude": ["styles/*.js"]}]
]
},
"production": {
"presets": [
"next/babel",
"#zeit/next-typescript/babel"
],
"plugins": [
["styled-components", {"ssr": true, "displayName": true}],
["#babel/plugin-proposal-decorators", {"legacy": true}]
]
},
"test": {
"presets": [
"#babel/preset-typescript",
["next/babel", {"preset-env": { "modules": "commonjs" }}]
],
"plugins": [
["styled-components", { "ssr": true, "displayName": true }],
["#babel/plugin-proposal-decorators", { "legacy": true }],
["babel-plugin-sass-vars"]
]
}
}
}
All I needed was this in package.json
"coveragePathIgnorePatterns": [
"<rootDir>/styles/"
],
And removed it from "testPathIgnorePatterns": <- having it both here and in coveragePathIgnorePatterns caused my tests to run forever and styles still showed up.
I also removed this from the .babelrc:
["istanbul",{"exclude": ["styles/*.js"]}]
Add this to your config (package.json):
modulePathIgnorePatterns: ["directoryNameToIgnore"]
or :
modulePathIgnorePatterns: ["/dist/"]
and :
coveragePathIgnorePatterns: ["/styles/"]

Can you use a regex in .babelrc?

Here's what my .babelrc looks like. Obviously it doesn't work because of the regex in a JSON file:
{
"presets": ["es2015", "react"],
"plugins": ["transform-object-rest-spread"],
"only": [
'/client/**/*',
'/server/**/*',
/diy-fe-shared/ // <--- regex here breaks
]
}
Is there a way to use a regex here?
Maybe you can use regex in .babelrc like this: https://github.com/probablyup/markdown-to-jsx
Create .babelrc.js:
const plugins = [
'emotion',
];
if (process.env.NODE_ENV === 'production') {
plugins.push('transform-react-remove-prop-types');
}
module.exports = {
plugins,
presets: [
['es2015', {
loose: true,
modules: process.env.BABEL_ENV === 'esm' ? false : 'commonjs',
}],
'react',
'stage-2',
],
};
Then require .babelrc.js in .babelrc
{
"presets": ["./.babelrc.js"]
}
No, you cannot use regular expressions in .babelrc files. But you can in .babelrc.js files:
Rename your .babelrc to .babelrc.js and export your configuration object:
module.exports = {
"env": {
"production": {
"plugins": [/* Only run if webpack configures babel-loader's options.envName="production" */]
}
},
"presets": ["es2015", "react"],
"plugins": ["transform-object-rest-spread"],
"only": [
'/client/**/*',
'/server/**/*',
/diy-fe-shared/ // <--- regex here works
]
};
https://babeljs.io/docs/en/configuration#babelrcjs

Categories

Resources