nx
nx copied to clipboard
Browserslist config seems does not work for @nrwl/web:rollup executor
Current Behavior
I'm using @nrwl/web:rollup to build my react library, and I my target is only for last 2 Chrome versions. So I add a browserslist field in the package.json file:
{
"name": "@my-lib/ui",
"version": "0.0.1",
"browserslist": ["last 2 Chrome versions"]
}
and my project.json for this library is looks like the following:
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/ui/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nrwl/web:rollup",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/packages/ui",
"tsConfig": "packages/ui/tsconfig.lib.json",
"project": "packages/ui/package.json",
"entryFile": "packages/ui/src/index.ts",
"external": ["react/jsx-runtime"],
"rollupConfig": ["@nrwl/react/plugins/bundle-rollup", "packages/ui/custom-rollup-swc"],
"compiler": "babel",
"assets": [
{
"glob": "packages/ui/README.md",
"input": ".",
"output": "."
}
]
}
}
}
}
When I run nx build ui, I found that the built js file dist/packages/ui/index.esm.js contains some code imported from core-js, which should not be included in the build file, as I only target last 2 Chrome version (and the library content is just the initial template @nrwl/react:library generated).
I found that the .babelrc presets include@nrwl/react/babel, which include preset @nrwl/web/babel . And @nrwl/web/babel eventually config @babel/preset-env, but I notice that the targets option for @babel/preset-env will be a object:
targets: isModern ? { esmodules: true } : undefined
when isModern is truthy.
So I digged into @babel/preset-env, and it looks like @babel/preset-env will ignore browserslist config when targets is already configured.
Expected Behavior
The build system should respect browserslist config, and in this case, output js files should not contain core-js code.
Steps to Reproduce
This issue may not be prioritized if details are not provided to help us reproduce the issue.
Failure Logs
Environment
Node : 16.15.0
OS : linux x64
yarn : 1.22.18
nx : 14.1.5
@nrwl/angular : Not Found
@nrwl/cypress : 14.1.5
@nrwl/detox : Not Found
@nrwl/devkit : 14.1.5
@nrwl/eslint-plugin-nx : 14.1.5
@nrwl/express : Not Found
@nrwl/jest : 14.1.5
@nrwl/js : 14.1.5
@nrwl/linter : 14.1.5
@nrwl/nest : Not Found
@nrwl/next : Not Found
@nrwl/node : Not Found
@nrwl/nx-cloud : Not Found
@nrwl/nx-plugin : Not Found
@nrwl/react : 14.1.5
@nrwl/react-native : Not Found
@nrwl/schematics : Not Found
@nrwl/storybook : 14.1.5
@nrwl/web : 14.1.5
@nrwl/workspace : 14.1.5
typescript : 4.6.4
rxjs : 6.6.7
I'm seeing the same when editing the .browserslistrc file at the root of the workspace. No matter what I do the polyfills chunk size does not change.
Edit: Tested with a new (latest) nx workspace and a react application with SWC bundling. Apart from still seeing this problem I also have issues with .browserslistrc being ignored. Current package versions:
@nrwl/cli: 14.6.4
@nrwl/react: 14.6.4
@nrwl/web: 14.6.4
Same here. I've been trying to make more sense of it. Using babel/preset-env in debug mode gives these targets:
{
"android": "61",
"chrome": "61",
"edge": "16",
"firefox": "60",
"ios": "10.3",
"node": "13.2",
"opera": "48",
"safari": "10.1",
"samsung": "8.2"
}
Which are pretty old versions. Changing browserlist targets at package.json or even using a .browserslistrc file does not work. Based on the babel docs, they should intersect and work. I need to make a minimal repro without nx to ensure if this caused by nx or has to do with babel and if whether I understood "intersecting" correctly.
EDIT: if this comment is true, then it should work as we expect https://github.com/babel/babel/issues/12903#issuecomment-838261027
EDIT2: I've set up a minimal repro with babel. This issue exists there.
EDIT3: I think the intersection might only work with the targets is added to the top level babel config rather than preset-env https://babeljs.io/docs/en/options#targetsesmodules
I have the same.
Even Object.assign, which is pretty old and widely available, gets polyfilled with 1000+ lines of code.
Arrow functions and async code, though, get outputted as-is.
Setting useBuiltins: false for now.
Adding a .swcrc file to the app root folder with the targets I need seems to work fine. Did a couple of tests and verified that only the required core-js modules are part of the output bundle.
.swcrc
{
"env": {
"targets": [
"last 2 Chrome versions",
"last 2 Firefox versions",
"last 2 Edge major versions",
"last 2 Safari major versions",
"last 2 iOS major versions",
"Firefox ESR",
"not IE 9-11"
],
"mode": "entry"
}
}
A workaround is to use a dynamic .babelrc.js and disable isModern in the caller data. That will cause targets to be set to undefined and allow .browserslistrc to be used.
// .baberc.js
module.exports = (api) => {
api.caller((caller) => {
caller.isModern = false;
});
return {
presets: ['@nrwl/react/babel']
};
This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.