Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(webpack): add NxWebpackPlugin that works with normal Webpack configuration #19984

Merged
merged 1 commit into from
Nov 8, 2023

Conversation

jaysoo
Copy link
Member

@jaysoo jaysoo commented Nov 1, 2023

This PR adds three Webpack plugins that can be used in standard webpack.config.js files.

  • NxTsconfigPathsWebpackPlugin- Add support for using workspace libs (via tsconfig paths) but leaves out everything else
  • NxWebpackPlugin - Add support for using TS/TSX, assets, package.json/index.html generation, etc. (basically everything that withNx() and withWeb() does in current setup)
  • NxReactWebpackPlugin - Add support for SVGR (can be opted out), and HMR via Fast Refresh

Note: Existing usages of composePlugins(), withNx(), withWeb(), withReact() will continue to work.

This means that that existing projects with a build such as this in package.json:

{
  "name": "myapp",
  "scripts": {
    "build": "NODE_ENV=production webpack build -c webpack.config.js"
    //...
  },
  //...

Can adopt Nx simply with this in their webpack.config.js file:

const path = require('node:path');
const { NxWebpackPlugin } = require('@nx/webpack');

module.exports = {
  output: {
    path: path.resolve(__dirname, './dist'),
  },
  plugins: [
    new NxWebpackPlugin({
      tsConfig: 'apps/demo/tsconfig.app.json',
      main: 'apps/demo/src/main.tsx',
      index: 'apps/demo/src/index.html',
      assets: ['apps/demo/src/favicon.ico', 'apps/demo/src/assets'],
      styles: ['apps/demo/src/styles.css'],
    })
  ],
};

If user only wants tsconfig paths feature, and want to handle TS/TSX, etc. on their own, then they can use the bare minimal NxTsconfigPathsWebpackPlugin.

const path = require('node:path');
const { NxTsconfigPathsWebpackPlugin } = require('@nx/webpack');

module.exports = {
  target: 'web',
  output: {
    path: path.resolve(__dirname, './dist'),
  },
  plugins: [
    new NxTsconfigPathsWebpackPlugin({
      tsConfig: 'apps/demo/tsconfig.app.json',
    })
  ],
};

If user uses React, they can add the NxReactWebpackPlugin to bring in Fast Refresh support.

const path = require('node:path');
const { NxWebpackPlugin } = require('@nx/webpack');
const { NxReactWebpackPlugin } = require('@nx/react')

module.exports = {
  target: 'web',
  output: {
    path: path.resolve(__dirname, './dist'),
  },
  plugins: [
    new NxWebpackPlugin({
      tsConfig: 'apps/demo/tsconfig.app.json',
      main: 'apps/demo/src/main.tsx',
      index: 'apps/demo/src/index.html',
      assets: ['apps/demo/src/favicon.ico', 'apps/demo/src/assets'],
      styles: ['apps/demo/src/styles.css'],
    }),
    new NxReactWebpackPlugin()
  ],
};

Notes

I previously made withNx, withWeb, and withReact push the new plugins into the config. However, this approach breaks the existing behavior of allowing users to update the config like so:

module.exports = compoesPlugins(withNx(), config => {
  // remove Nx's terser plugin
  config.plugins = config.plugins.filter(p => p.constructor.name !== 'TerserPlugin');
  return config;
});

Since the .apply() method of webpack plugins happen during build time, the configuration phase will no longer contain new rules, etc. Thus, instead of using the new plugins with the with* plugin functions, we just extract a shared function that can be used in the new and old plugins.

TODO

  • Add e2e tests for using standard webpack config.
  • Support users modifying webpack config after our plugins have run. This requires .apply() to be called prior to returning from withNx(), withReact(), etc.

Current Behavior

webpack.config.js files have to export a function rather than config object. This format is only understood by Nx, and makes it awkward to add Nx to existing webpack projects.

Expected Behavior

User can adopt Nx in existing projects by adding either NxWebpackPlugin or NxTsconfigPathsWebpackPlugin.

Related Issue(s)

Fixes #

@jaysoo jaysoo requested review from a team as code owners November 1, 2023 18:32
@jaysoo jaysoo requested a review from mandarini November 1, 2023 18:32
Copy link

vercel bot commented Nov 1, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment
Name Status Preview Updated (UTC)
nx-dev ⬜️ Ignored (Inspect) Visit Preview Nov 8, 2023 3:34pm

@jaysoo jaysoo force-pushed the feat/standard-webpack-plugin branch 2 times, most recently from 43c8a02 to 6919e5b Compare November 3, 2023 14:59
@jaysoo jaysoo force-pushed the feat/standard-webpack-plugin branch 13 times, most recently from e8a3c54 to 58b6804 Compare November 8, 2023 14:34
@jaysoo jaysoo force-pushed the feat/standard-webpack-plugin branch from 58b6804 to b6d4792 Compare November 8, 2023 15:33
@jaysoo jaysoo merged commit 395eb70 into nrwl:master Nov 8, 2023
6 checks passed
Copy link

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants