Troubleshoot Convert to Inferred Migration
Nx comes with plugins that automatically infer tasks (i.e. Project Crystal) for your projects based on the configuration of different tools. Inference plugins come with many benefits, such as reduced boilerplate and access to features such as task splitting. To make the transition easier for existing projects that are not yet using inference plugins, many plugins provide the convert-to-inferred
generator that will switch from executor-based tasks to inferred tasks.
To see a list of the available migration generators, run:
❯
nx g convert-to-inferred
This will prompt you to choose a plugin to run the migration for.
Although the convert-to-inferred
generator should work for most projects, there are situations that require additional changes to be done by hand. If you run into issues that are not covered on this page, please open an issue on GitHub.
Error: The nx plugin did not find a project inside...
This error occurs when a configuration file matching the tooling cannot be found. For example, Vite works with vite.config.ts
(or .js
, .cts
, .mts
, etc.). If you've named your configuration file to something unconventional, you must rename it back to the standard naming convention before running the migration generator again.
For example, if you have a apps/demo/vite.custom.ts
file and are running nx g @nx/vite:convert-to-inferred
, you must first rename the file to apps/demo/vite.config.ts
before running the generator.
Remix: Unsupported outputPath
Option
The outputPath
option from @nx/remix:build
is ignored because it often leads to ESM errors when the output path is outside the project root. The ESM error occurs because the root package.json
may not have "type": "module"
set, which means that the compiled ESM code will fail to run. To guarantee that serve
works, we migrate the outputs to the Remix defaults (build
and public/build
inside the project root). If you have custom directories already defined in your Remix config, it will continue to be used.
To change the outputs after the migration, edit the remix config file, and look for serverBuildPath
and assetsBuildDirectory
and set it to the locations you want.
1// ...
2export default {
3 assetsBuildDirectory: '../../dist/apps/demo/public/build',
4 serverBuildPath: '../../dist/apps/demo/build/index.js',
5 // ...
6};
7
Note that you will need to address potential ESM issues that may arise. For example, change the root package.json
to "type": "module"
.
Remix: Unsupported generatePackageJson
and generateLockFile
Options
The generatePackageJson
and generateLockFile
options in @nx/remix:build
cannot currently be migrated. There is support for this feature in the Nx Vite plugin, so in the future we may be able to support it if using Remix+Vite.
Storybook: Conflicting staticDir
Options
Using staticDir
for both @nx/storybook:build-storybook
and @nx/storybook:storybook
executor options will result in the one from build-storybook
being used in the resulting .storybook/main.ts
file. It is not possible for us to support both automatically.
If you need to differentiate staticDir
between build and serve, then consider putting logic into your main.ts
file directly.
1// ...
2const config: StorybookConfig = {
3 // ...
4 staticDirs:
5 process.env.NODE_ENV === 'production'
6 ? ['../static-prod']
7 : ['../static-dev'],
8};
9
10export default config;
11
Vite: Unsupported proxyConfig
Option
Projects that used the proxyConfig
option of @nx/vite:dev-server
will need to inline the proxy configuration from the original file into vite.config.ts
.
For example, if you previously used this in proxy.config.json
:
1{
2 "/api/*": {
3 "target": "http://localhost:3333"
4 }
5}
6
Then, you will need to add this entry to your vite.config.ts
file:
1export default defineConfig({
2 //...
3 server: {
4 // ...
5 proxy: {
6 '/api': {
7 target: 'http://localhost:3333',
8 },
9 },
10 },
11});
12
Webpack: Project Cannot Be Migrated
Projects that use Nx-enhanced Webpack configuration files cannot be migrated to use Webpack CLI. Nx-enhanced configuration files that contain composePlugins
and withNx
require the @nx/webpack:webpack
executor to work.
To solve this issue, run nx g @nx/webpack:convert-config-to-webpack-plugin
first, and then try again.
Webpack: Usage of useLegacyNxPlugin
When converting from Nx-enhanced to basic Webpack configuration, we add the useLegacyNxPlugin
utility to ensure that the functionality of your existing configuration continues to function normally. We recommend that you refactor the configuration such that useLegacyNxPlugin
is not needed.
For example, if you previously added plugins using the configuration function.
1// webpack.config.old.js
2modules.exports = (config) => {
3 config.plugins.push(new SomePlugin());
4 return config;
5};
6
Then, we recommend that you move the plugin entry to the new configuration file, in the plugins
option.
1module.exports = async () => ({
2 devServer: devServerOptions,
3 plugins: [new NxAppWebpackPlugin(pluginOptions), new SomePlugin()],
4});
5
If you need to apply configuration changes after NxAppWebpackPlugin
is applied, then you can create a plugin object as follows.
1module.exports = async () => ({
2 devServer: devServerOptions,
3 plugins: [
4 new NxAppWebpackPlugin(pluginOptions),
5 {
6 apply(compiler) {
7 const babelLoader = compiler.options.module.rules.find(
8 (rule) =>
9 rule &&
10 typeof rule !== 'string' &&
11 rule.loader?.toString().includes('babel-loader')
12 );
13
14 // do something with `babelLoader...
15 },
16 },
17 ],
18});
19