diff --git a/docs/generated/packages/webpack/documents/webpack-plugins.md b/docs/generated/packages/webpack/documents/webpack-plugins.md index cb2c3d634c..af9057567d 100644 --- a/docs/generated/packages/webpack/documents/webpack-plugins.md +++ b/docs/generated/packages/webpack/documents/webpack-plugins.md @@ -1,9 +1,172 @@ +--- +title: Webpack plugins +description: A guide for webpack plugins that are provided by Nx. +--- + # Webpack plugins -Coming soon. +Nx uses enhanced webpack configuration files (e.g. `webpack.config.js`). These configuration files export a _plugin_ that takes in a webpack +[configuration](https://webpack.js.org/configuration/) object and returns an updated configuration object. Plugins are used by Nx to add +functionality to the webpack build. + +This guide contains information on the plugins provided by Nx. For more information on customizing webpack configuration, refer to the +[configuration guide](/packages/webpack/documents/webpack-config-setup). ## `withNx` +The `withNx` plugin provides common configuration for the build, including TypeScript support and linking workspace libraries (via tsconfig paths). + +### Options + +#### skipTypeChecking + +Type: `boolean` + +Disable type checks (useful to speed up builds). + +### Example + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); + +module.exports = composePlugins(withNx(), (config) => { + // Further customize webpack config + return config; +}); +``` + ## `withWeb` +The `withWeb` plugin adds support for CSS/SASS/Less/Stylus stylesheets, assets (such as images and fonts), and `index.html` processing. + +### Options + +#### baseHref + +Type: `string` + +Base URL for the application being built. + +#### crossOrigin + +Type: `'none' | 'anonymous' | 'use-credentials'` + +"The `crossorigin` attribute to use for generated javascript script tags. One of 'none' | 'anonymous' | 'use-credentials'." + +#### deployUrl + +Type: `string` + +URL where the application will be deployed. + +#### extractCss + +Type: `boolean` + +Extract CSS into a `.css` file. + +#### generateIndexHtml + +Type: `boolean` + +Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated. + +#### index + +Type: `string` + +HTML File which will be contain the application. + +#### postcssConfig + +Type: `string` + +Set a path (relative to workspace root) to a PostCSS config that applies to the app and all libs. Defaults to `undefined`, which auto-detects postcss.config.js files in each `app`. + +#### scripts + +Type: `string[]` + +Paths to scripts (relative to workspace root) which will be included before the main application entry. + +#### stylePreprocessorOptions + +Type: `{ includePaths: string[] }` + +Options to pass to style preprocessors. `includePaths` is a list of paths that are included (e.g. workspace libs with stylesheets). + +#### styles + +Type: `string[]` + +Paths to stylesheets (relative to workspace root) which will be included with the application. + +#### subresourceIntegrity + +Type: `boolean` + +Enables the use of subresource integrity validation. + +### Example + +```js +const { composePlugins, withNx, withWeb } = require('@nrwl/webpack'); + +module.exports = composePlugins( + // always pass withNx() first + withNx(), + // add web functionality + withWeb({ + styles: ['my-app/src/styles.css'], + }), + (config) => { + // Further customize webpack config + return config; + } +); +``` + ## `withReact` + +The `withReact` plugin adds support for React JSX, [SVGR](https://react-svgr.com/), and [Fast Refresh](https://github.com/pmmmwh/react-refresh-webpack-plugin) + +### Options + +The options are the same as [`withWeb`](#with-web) plus the following. + +#### svgr + +Type: `undefined|false` + +SVGR allows SVG files to be imported as React components. Set this to `false` to disable this behavior. + +### Example + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); +const { withReact } = require('@nrwl/react'); + +module.exports = composePlugins( + withNx(), // always pass withNx() first + withReact({ + styles: ['my-app/src/styles.css'], + svgr: true, + postcssConfig: 'my-app/postcss', + }), + (config) => { + // Further customize webpack config + return config; + } +); +``` + +## `withModuleFederation` + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); + +module.exports = composePlugins(withNx(), (config) => { + // Further customize webpack config + return config; +}); +``` diff --git a/docs/shared/packages/webpack/webpack-plugins.md b/docs/shared/packages/webpack/webpack-plugins.md index cb2c3d634c..af9057567d 100644 --- a/docs/shared/packages/webpack/webpack-plugins.md +++ b/docs/shared/packages/webpack/webpack-plugins.md @@ -1,9 +1,172 @@ +--- +title: Webpack plugins +description: A guide for webpack plugins that are provided by Nx. +--- + # Webpack plugins -Coming soon. +Nx uses enhanced webpack configuration files (e.g. `webpack.config.js`). These configuration files export a _plugin_ that takes in a webpack +[configuration](https://webpack.js.org/configuration/) object and returns an updated configuration object. Plugins are used by Nx to add +functionality to the webpack build. + +This guide contains information on the plugins provided by Nx. For more information on customizing webpack configuration, refer to the +[configuration guide](/packages/webpack/documents/webpack-config-setup). ## `withNx` +The `withNx` plugin provides common configuration for the build, including TypeScript support and linking workspace libraries (via tsconfig paths). + +### Options + +#### skipTypeChecking + +Type: `boolean` + +Disable type checks (useful to speed up builds). + +### Example + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); + +module.exports = composePlugins(withNx(), (config) => { + // Further customize webpack config + return config; +}); +``` + ## `withWeb` +The `withWeb` plugin adds support for CSS/SASS/Less/Stylus stylesheets, assets (such as images and fonts), and `index.html` processing. + +### Options + +#### baseHref + +Type: `string` + +Base URL for the application being built. + +#### crossOrigin + +Type: `'none' | 'anonymous' | 'use-credentials'` + +"The `crossorigin` attribute to use for generated javascript script tags. One of 'none' | 'anonymous' | 'use-credentials'." + +#### deployUrl + +Type: `string` + +URL where the application will be deployed. + +#### extractCss + +Type: `boolean` + +Extract CSS into a `.css` file. + +#### generateIndexHtml + +Type: `boolean` + +Generates a `package.json` and pruned lock file with the project's `node_module` dependencies populated for installing in a container. If a `package.json` exists in the project's directory, it will be reused with dependencies populated. + +#### index + +Type: `string` + +HTML File which will be contain the application. + +#### postcssConfig + +Type: `string` + +Set a path (relative to workspace root) to a PostCSS config that applies to the app and all libs. Defaults to `undefined`, which auto-detects postcss.config.js files in each `app`. + +#### scripts + +Type: `string[]` + +Paths to scripts (relative to workspace root) which will be included before the main application entry. + +#### stylePreprocessorOptions + +Type: `{ includePaths: string[] }` + +Options to pass to style preprocessors. `includePaths` is a list of paths that are included (e.g. workspace libs with stylesheets). + +#### styles + +Type: `string[]` + +Paths to stylesheets (relative to workspace root) which will be included with the application. + +#### subresourceIntegrity + +Type: `boolean` + +Enables the use of subresource integrity validation. + +### Example + +```js +const { composePlugins, withNx, withWeb } = require('@nrwl/webpack'); + +module.exports = composePlugins( + // always pass withNx() first + withNx(), + // add web functionality + withWeb({ + styles: ['my-app/src/styles.css'], + }), + (config) => { + // Further customize webpack config + return config; + } +); +``` + ## `withReact` + +The `withReact` plugin adds support for React JSX, [SVGR](https://react-svgr.com/), and [Fast Refresh](https://github.com/pmmmwh/react-refresh-webpack-plugin) + +### Options + +The options are the same as [`withWeb`](#with-web) plus the following. + +#### svgr + +Type: `undefined|false` + +SVGR allows SVG files to be imported as React components. Set this to `false` to disable this behavior. + +### Example + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); +const { withReact } = require('@nrwl/react'); + +module.exports = composePlugins( + withNx(), // always pass withNx() first + withReact({ + styles: ['my-app/src/styles.css'], + svgr: true, + postcssConfig: 'my-app/postcss', + }), + (config) => { + // Further customize webpack config + return config; + } +); +``` + +## `withModuleFederation` + +```js +const { composePlugins, withNx } = require('@nrwl/webpack'); + +module.exports = composePlugins(withNx(), (config) => { + // Further customize webpack config + return config; +}); +``` diff --git a/packages/react/plugins/with-react.ts b/packages/react/plugins/with-react.ts index c5092768f8..bd6a1c91c2 100644 --- a/packages/react/plugins/with-react.ts +++ b/packages/react/plugins/with-react.ts @@ -4,7 +4,9 @@ import type { NxWebpackExecutionContext } from '@nrwl/webpack'; const processed = new Set(); -interface WithReactOptions extends WithWebOptions {} +interface WithReactOptions extends WithWebOptions { + svgr?: false; +} function addHotReload(config: Configuration) { if (config.mode === 'development' && config['devServer']?.hot) { @@ -44,6 +46,10 @@ function removeSvgLoaderIfPresent(config: Configuration) { config.module.rules.splice(svgLoaderIdx, 1); } +/** + * @param {WithReactOptions} pluginOptions + * @returns {NxWebpackPlugin} + */ export function withReact(pluginOptions: WithReactOptions = {}) { return function configure( config: Configuration, @@ -57,28 +63,31 @@ export function withReact(pluginOptions: WithReactOptions = {}) { config = withWeb(pluginOptions)(config, context); addHotReload(config); - removeSvgLoaderIfPresent(config); - config.module.rules.push({ - test: /\.svg$/, - issuer: /\.(js|ts|md)x?$/, - use: [ - { - loader: require.resolve('@svgr/webpack'), - options: { - svgo: false, - titleProp: true, - ref: true, + if (pluginOptions?.svgr !== false) { + removeSvgLoaderIfPresent(config); + + config.module.rules.push({ + test: /\.svg$/, + issuer: /\.(js|ts|md)x?$/, + use: [ + { + loader: require.resolve('@svgr/webpack'), + options: { + svgo: false, + titleProp: true, + ref: true, + }, }, - }, - { - loader: require.resolve('file-loader'), - options: { - name: '[name].[hash].[ext]', + { + loader: require.resolve('file-loader'), + options: { + name: '[name].[hash].[ext]', + }, }, - }, - ], - }); + ], + }); + } // enable webpack node api config.node = { diff --git a/packages/react/src/module-federation/with-module-federation.ts b/packages/react/src/module-federation/with-module-federation.ts index c2faeec1f4..55fa6c0b49 100644 --- a/packages/react/src/module-federation/with-module-federation.ts +++ b/packages/react/src/module-federation/with-module-federation.ts @@ -2,6 +2,7 @@ import { ModuleFederationConfig } from '@nrwl/devkit'; import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph'; import { getModuleFederationConfig } from './utils'; import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); +import type { AsyncNxWebpackPlugin, NxWebpackPlugin } from '@nrwl/webpack'; function determineRemoteUrl(remote: string) { const remoteConfiguration = readCachedProjectConfiguration(remote); @@ -21,7 +22,13 @@ function determineRemoteUrl(remote: string) { }:${port}/remoteEntry.js`; } -export async function withModuleFederation(options: ModuleFederationConfig) { +/** + * @param {ModuleFederationConfig} options + * @return {Promise} + */ +export async function withModuleFederation( + options: ModuleFederationConfig +): Promise { const reactWebpackConfig = require('../../plugins/webpack'); const { sharedDependencies, sharedLibraries, mappedRemotes } = diff --git a/packages/webpack/src/utils/with-nx.ts b/packages/webpack/src/utils/with-nx.ts index 62d76a6613..e7e177cc8d 100644 --- a/packages/webpack/src/utils/with-nx.ts +++ b/packages/webpack/src/utils/with-nx.ts @@ -13,6 +13,7 @@ import { StatsJsonPlugin } from '../plugins/stats-json-plugin'; import { createCopyPlugin } from './create-copy-plugin'; import { GeneratePackageJsonPlugin } from '../plugins/generate-package-json-plugin'; import { getOutputHashFormat } from './hash-format'; +import { NxWebpackPlugin } from './config'; const IGNORED_WEBPACK_WARNINGS = [ /The comment file/i, @@ -24,7 +25,15 @@ const mainFields = ['main', 'module']; const processed = new Set(); -export function withNx(opts?: { skipTypeChecking?: boolean }) { +export interface WithNxOptions { + skipTypeChecking?: boolean; +} + +/** + * @param {WithNxOptions} pluginOptions + * @returns {NxWebpackPlugin} + */ +export function withNx(pluginOptions?: WithNxOptions): NxWebpackPlugin { return function configure( config: Configuration, { @@ -39,7 +48,7 @@ export function withNx(opts?: { skipTypeChecking?: boolean }) { const plugins: WebpackPluginInstance[] = []; - if (!opts?.skipTypeChecking) { + if (!pluginOptions?.skipTypeChecking) { plugins.push( new ForkTsCheckerWebpackPlugin({ typescript: { diff --git a/packages/webpack/src/utils/with-web.ts b/packages/webpack/src/utils/with-web.ts index 4116e998f6..64de7014a4 100644 --- a/packages/webpack/src/utils/with-web.ts +++ b/packages/webpack/src/utils/with-web.ts @@ -12,6 +12,7 @@ import { getOutputHashFormat } from '@nrwl/webpack/src/utils/hash-format'; import { PostcssCliResources } from '@nrwl/webpack/src/utils/webpack/plugins/postcss-cli-resources'; import { normalizeExtraEntryPoints } from '@nrwl/webpack/src/utils/webpack/normalize-entry'; +import { NxWebpackPlugin } from './config'; import { ExtraEntryPointClass, NormalizedWebpackExecutorOptions, @@ -56,7 +57,11 @@ export type MergedOptions = Omit< > & WithWebOptions; -export function withWeb(pluginOptions: WithWebOptions = {}) { +/** + * @param {WithWebOptions} pluginOptions + * @returns {NxWebpackPlugin} + */ +export function withWeb(pluginOptions: WithWebOptions = {}): NxWebpackPlugin { return function configure( config: Configuration, { options: executorOptions, context }: NxWebpackExecutionContext