Jack Hsu 0ae8665a88
feat(js): infer build-deps and watch-deps targets for incremental builds (#29609)
This PR adds `build-deps` and `watch-deps` targets to buildable JS
projects to help with incremental builds.

A use-case for this is if an app (e.g. Vite React app) has buildable
dependencies that need to be rebuilt when they change.

Say, you create a React app and lib as follows:

```
nx g @nx/react:app apps/react-app --bundler vite 
nx g @nx/react:lib packages/react-lib --bundler vite
```

And import `react-lib` inside the app.

```jsx
import { ReactLib } from '@acme/react-lib';
//...
return <ReactLib />
```

The user can then run:

```
nx watch-deps react-app
```

And then serve the app in another terminal:
```
nx serve react-app
```

Then whenever code is updated for a buildable dependency, it'll be
rebuilt and then reloaded in the app.
2025-01-14 16:13:43 -05:00

96 lines
2.3 KiB
TypeScript

import {
addDependenciesToPackageJson,
createProjectGraphAsync,
formatFiles,
GeneratorCallback,
readNxJson,
Tree,
} from '@nx/devkit';
import { addPluginV1 } from '@nx/devkit/src/utils/add-plugin';
import { createNodes } from '../../plugins/plugin';
import { nxVersion, webpackCliVersion } from '../../utils/versions';
import { Schema } from './schema';
export function webpackInitGenerator(tree: Tree, schema: Schema) {
return webpackInitGeneratorInternal(tree, { addPlugin: false, ...schema });
}
export async function webpackInitGeneratorInternal(tree: Tree, schema: Schema) {
const nxJson = readNxJson(tree);
const addPluginDefault =
process.env.NX_ADD_PLUGINS !== 'false' &&
nxJson.useInferencePlugins !== false;
schema.addPlugin ??= addPluginDefault;
if (schema.addPlugin) {
await addPluginV1(
tree,
await createProjectGraphAsync(),
'@nx/webpack/plugin',
createNodes,
{
buildTargetName: [
'build',
'webpack:build',
'build:webpack',
'webpack-build',
'build-webpack',
],
serveTargetName: [
'serve',
'webpack:serve',
'serve:webpack',
'webpack-serve',
'serve-webpack',
],
previewTargetName: [
'preview',
'webpack:preview',
'preview:webpack',
'webpack-preview',
'preview-webpack',
],
buildDepsTargetName: [
'build-deps',
'webpack:build-deps',
'webpack-build-deps',
],
watchDepsTargetName: [
'watch-deps',
'webpack:watch-deps',
'webpack-watch-deps',
],
},
schema.updatePackageScripts
);
}
let installTask: GeneratorCallback = () => {};
if (!schema.skipPackageJson) {
const devDependencies = {
'@nx/webpack': nxVersion,
'@nx/web': nxVersion,
};
if (schema.addPlugin) {
devDependencies['webpack-cli'] = webpackCliVersion;
}
installTask = addDependenciesToPackageJson(
tree,
{},
devDependencies,
undefined,
schema.keepExistingVersions
);
}
if (!schema.skipFormat) {
await formatFiles(tree);
}
return installTask;
}
export default webpackInitGenerator;