Skip to content

Commit

Permalink
feat(webpack): add convertConfigToWebpackPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
ndcunningham committed Jun 14, 2024
1 parent b61546f commit 402c1c6
Show file tree
Hide file tree
Showing 21 changed files with 1,136 additions and 3 deletions.
8 changes: 8 additions & 0 deletions docs/generated/manifests/menus.json
Original file line number Diff line number Diff line change
Expand Up @@ -9851,6 +9851,14 @@
"children": [],
"isExternal": false,
"disableCollapsible": false
},
{
"id": "convert-config-to-webpack-plugin",
"path": "/nx-api/webpack/generators/convert-config-to-webpack-plugin",
"name": "convert-config-to-webpack-plugin",
"children": [],
"isExternal": false,
"disableCollapsible": false
}
],
"isExternal": false,
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/manifests/nx-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -3197,6 +3197,15 @@
"originalFilePath": "/packages/webpack/src/generators/configuration/schema.json",
"path": "/nx-api/webpack/generators/configuration",
"type": "generator"
},
"/nx-api/webpack/generators/convert-config-to-webpack-plugin": {
"description": "Convert the project to use the `NxAppWebpackPlugin` and `NxReactWebpackPlugin`.",
"file": "generated/packages/webpack/generators/convert-config-to-webpack-plugin.json",
"hidden": false,
"name": "convert-config-to-webpack-plugin",
"originalFilePath": "/packages/webpack/src/generators/convert-config-to-webpack-plugin/schema.json",
"path": "/nx-api/webpack/generators/convert-config-to-webpack-plugin",
"type": "generator"
}
},
"path": "/nx-api/webpack"
Expand Down
9 changes: 9 additions & 0 deletions docs/generated/packages-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3162,6 +3162,15 @@
"originalFilePath": "/packages/webpack/src/generators/configuration/schema.json",
"path": "webpack/generators/configuration",
"type": "generator"
},
{
"description": "Convert the project to use the `NxAppWebpackPlugin` and `NxReactWebpackPlugin`.",
"file": "generated/packages/webpack/generators/convert-config-to-webpack-plugin.json",
"hidden": false,
"name": "convert-config-to-webpack-plugin",
"originalFilePath": "/packages/webpack/src/generators/convert-config-to-webpack-plugin/schema.json",
"path": "webpack/generators/convert-config-to-webpack-plugin",
"type": "generator"
}
],
"githubRoot": "https://github.com/nrwl/nx/blob/master",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "convert-config-to-webpack-plugin",
"factory": "./src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin",
"schema": {
"$schema": "https://json-schema.org/schema",
"$id": "NxWebpackConvertConfigToWebpackPlugin",
"description": "Convert existing Webpack project(s) using `@nx/webpack:webpack` executor that uses `withNx` to use `NxAppWebpackPlugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
"title": "Convert Webpack project using withNx to NxAppWebpackPlugin",
"type": "object",
"properties": {
"project": {
"type": "string",
"description": "The project to convert from using the `@nx/webpack:webpack` executor and `withNx` plugin to use `NxAppWebpackPlugin`.",
"x-priority": "important"
},
"skipFormat": {
"type": "boolean",
"description": "Whether to format files at the end of the migration.",
"default": false
}
},
"presets": []
},
"description": "Convert the project to use the `NxAppWebpackPlugin` and `NxReactWebpackPlugin`.",
"implementation": "/packages/webpack/src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin.ts",
"aliases": [],
"hidden": false,
"path": "/packages/webpack/src/generators/convert-config-to-webpack-plugin/schema.json",
"type": "generator"
}
1 change: 1 addition & 0 deletions docs/shared/reference/sitemap.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@
- [generators](/nx-api/webpack/generators)
- [init](/nx-api/webpack/generators/init)
- [configuration](/nx-api/webpack/generators/configuration)
- [convert-config-to-webpack-plugin](/nx-api/webpack/generators/convert-config-to-webpack-plugin)
- [workspace](/nx-api/workspace)
- [documents](/nx-api/workspace/documents)
- [Overview](/nx-api/workspace/documents/overview)
Expand Down
104 changes: 104 additions & 0 deletions e2e/webpack/src/__snapshots__/webpack.legacy.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Webpack Plugin (legacy) should convert withNx webpack config to a standard config using NxWebpackPlugin 1`] = `
"const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
const { NxReactWebpackPlugin } = require('@nx/react/webpack-plugin');
const { nxUseLegacyPlugin } = require('@nx/webpack');
// This file was migrated using @nx/webpack:convert-config-to-webpack-plugin from your './webpack.config.old.js'
// Please check that the options here are correct as they were moved from the old webpack.config.js to this file.
const options = {};
module.exports = async () => ({
plugins: [
new NxAppWebpackPlugin(),
new NxReactWebpackPlugin({
// Uncomment this line if you don't want to use SVGR
// See: https://react-svgr.com/
// svgr: false
}),
await nxUseLegacyPlugin(require('./webpack.config.old'), options),
],
});
"
`;

exports[`Webpack Plugin (legacy) should convert withNx webpack config to a standard config using NxWebpackPlugin 2`] = `
"{
"name": "app3224373",
"$schema": "../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "app3224373/src",
"tags": [],
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"target": "web",
"outputPath": "dist/app3224373",
"compiler": "swc",
"main": "app3224373/src/main.ts",
"tsConfig": "app3224373/tsconfig.app.json",
"webpackConfig": "app3224373/webpack.config.js",
"assets": ["app3224373/src/favicon.ico", "app3224373/src/assets"],
"index": "app3224373/src/index.html",
"baseHref": "/",
"styles": ["app3224373/src/styles.css"],
"scripts": [],
"standardWebpackConfigFunction": true
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"fileReplacements": [
{
"replace": "app3224373/src/environments/environment.ts",
"with": "app3224373/src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"executor": "@nx/webpack:dev-server",
"options": {
"buildTarget": "app3224373:build"
},
"configurations": {
"production": {
"buildTarget": "app3224373:build:production"
}
}
},
"lint": {
"executor": "@nx/eslint:lint"
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "app3224373/jest.config.ts"
}
}
}
}
"
`;

exports[`Webpack Plugin (legacy) should convert withNx webpack config to a standard config using NxWebpackPlugin 3`] = `
"const { composePlugins } = require('@nx/webpack');
// Nx plugins for webpack.
module.exports = composePlugins((config) => {
// Update the webpack config as needed here.
// e.g. \`config.plugins.push(new MyPlugin())\`
return config;
});
"
`;
40 changes: 40 additions & 0 deletions e2e/webpack/src/webpack.legacy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
cleanupProject,
killProcessAndPorts,
newProject,
readFile,
runCLI,
runCommandUntil,
runE2ETests,
Expand Down Expand Up @@ -146,4 +147,43 @@ module.exports = {
}).not.toThrow();
}
});

it('should convert withNx webpack config to a standard config using NxWebpackPlugin', () => {
const appName = 'app3224373'; // Needs to be reserved so that the snapshot projectName matches
runCLI(
`generate @nx/web:app ${appName} --bundler webpack --e2eTestRunner=playwright`
);
updateFile(
`${appName}/src/main.ts`,
`
const root = document.querySelector('proj-root');
if(root) {
root.innerHTML = '<h1>Welcome</h1>'
}
`
);

runCLI(
`generate @nx/webpack:convert-config-to-webpack-plugin --project ${appName}`
);

const webpackConfig = readFile(`${appName}/webpack.config.js`);
const oldWebpackConfig = readFile(`${appName}/webpack.config.old.js`);
const projectJSON = readFile(`${appName}/project.json`);

expect(webpackConfig).toMatchSnapshot();
expect(projectJSON).toMatchSnapshot(); // This file should be updated adding standardWebpackConfigFunction: true

expect(oldWebpackConfig).toMatchSnapshot(); // This file should be renamed and updated to not include `withNx`, `withReact`, and `withWeb`.

expect(() => {
runCLI(`build ${appName}`);
}).not.toThrow();

if (runE2ETests()) {
expect(() => {
runCLI(`e2e ${appName}-e2e`);
}).not.toThrow();
}
});
});
5 changes: 5 additions & 0 deletions packages/webpack/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
"schema": "./src/generators/configuration/schema.json",
"description": "Add webpack configuration to a project.",
"hidden": true
},
"convert-config-to-webpack-plugin": {
"factory": "./src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin",
"schema": "./src/generators/convert-config-to-webpack-plugin/schema.json",
"description": "Convert the project to use the `NxAppWebpackPlugin` and `NxReactWebpackPlugin`."
}
}
}
8 changes: 7 additions & 1 deletion packages/webpack/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { configurationGenerator } from './src/generators/configuration/configuration';
import { NxAppWebpackPlugin } from './src/plugins/nx-webpack-plugin/nx-app-webpack-plugin';
import { NxTsconfigPathsWebpackPlugin as _NxTsconfigPathsWebpackPlugin } from './src/plugins/nx-typescript-webpack-plugin/nx-tsconfig-paths-webpack-plugin';
import { convertConfigToWebpackPluginGenerator } from './src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin';
import { nxUseLegacyPlugin } from './src/plugins/nx-use-legacy-plugin/nx-use-legacy-plugin';

export { configurationGenerator };
export {
configurationGenerator,
convertConfigToWebpackPluginGenerator,
nxUseLegacyPlugin,
};

// Exported for backwards compatibility in case a plugin is using the old name.
/** @deprecated Use `configurationGenerator` instead. */
Expand Down
1 change: 1 addition & 0 deletions packages/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"dependencies": {
"@babel/core": "^7.23.2",
"@phenomnomnominal/tsquery": "~5.0.1",
"ajv": "^8.12.0",
"autoprefixer": "^10.4.9",
"babel-loader": "^9.1.2",
Expand Down
7 changes: 6 additions & 1 deletion packages/webpack/src/executors/dev-server/dev-server.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,12 @@ export async function* devServerExecutor(
);
} else if (userDefinedWebpackConfig) {
// New behavior, we want the webpack config to export object
config = userDefinedWebpackConfig;
// If the config is a function, we assume it's a standard webpack config function and it's async
if (typeof userDefinedWebpackConfig === 'function') {
config = await userDefinedWebpackConfig(process.env.NODE_ENV, {});
} else {
config = userDefinedWebpackConfig;
}
config.devServer ??= devServer;
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/webpack/src/executors/webpack/webpack.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ async function getWebpackConfigs(
configuration: context.configurationName, // backwards compat
});
} else if (userDefinedWebpackConfig) {
if (typeof userDefinedWebpackConfig === 'function') {
// assume it's an async standard webpack config function
// https://webpack.js.org/configuration/configuration-types/#exporting-a-promise
return await userDefinedWebpackConfig(process.env.NODE_ENV, {});
}
// New behavior, we want the webpack config to export object
return userDefinedWebpackConfig;
} else {
Expand Down
Loading

0 comments on commit 402c1c6

Please sign in to comment.