nx icon indicating copy to clipboard operation
nx copied to clipboard

Browserslist config seems does not work for @nrwl/web:rollup executor

Open luokuning opened this issue 3 years ago • 4 comments

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

luokuning avatar May 15 '22 12:05 luokuning

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

rudfoss avatar May 27 '22 14:05 rudfoss

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

marwan38 avatar Jun 20 '22 01:06 marwan38

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.

ianldgs avatar Jun 29 '22 12:06 ianldgs

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"
  }
}

rudfoss avatar Sep 19 '22 12:09 rudfoss

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']
};

dosentmatter avatar Nov 22 '22 22:11 dosentmatter

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.

github-actions[bot] avatar Mar 21 '23 02:03 github-actions[bot]