feat(angular): add support for incremental builds to the webpack-server executor (#10754)
This commit is contained in:
parent
9900ceb7c4
commit
f3a9f55fc7
@ -2999,6 +2999,10 @@
|
||||
"poll": {
|
||||
"type": "number",
|
||||
"description": "Enable and define the file watching poll time period in milliseconds."
|
||||
},
|
||||
"buildLibsFromSource": {
|
||||
"type": "boolean",
|
||||
"description": "Read buildable libraries from source instead of building them separately. If not set, it will take the value specified in the `browserTarget` options, or it will default to `true` if it's also not set in the `browserTarget` options."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
"@nrwl/jest": "file:../jest",
|
||||
"@nrwl/linter": "file:../linter",
|
||||
"@nrwl/storybook": "file:../storybook",
|
||||
"@nrwl/web": "file:../web",
|
||||
"@nrwl/workspace": "file:../workspace",
|
||||
"@phenomnomnominal/tsquery": "4.1.1",
|
||||
"@schematics/angular": "~14.0.0",
|
||||
|
||||
@ -17,4 +17,5 @@ export interface Schema {
|
||||
hmr?: boolean;
|
||||
watch?: boolean;
|
||||
poll?: number;
|
||||
buildLibsFromSource?: boolean;
|
||||
}
|
||||
|
||||
@ -102,6 +102,10 @@
|
||||
"poll": {
|
||||
"type": "number",
|
||||
"description": "Enable and define the file watching poll time period in milliseconds."
|
||||
},
|
||||
"buildLibsFromSource": {
|
||||
"type": "boolean",
|
||||
"description": "Read buildable libraries from source instead of building them separately. If not set, it will take the value specified in the `browserTarget` options, or it will default to `true` if it's also not set in the `browserTarget` options."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -1,31 +1,38 @@
|
||||
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
|
||||
import {
|
||||
BuilderContext,
|
||||
BuilderOutput,
|
||||
createBuilder,
|
||||
} from '@angular-devkit/architect';
|
||||
import {
|
||||
DevServerBuilderOptions,
|
||||
serveWebpackBrowser,
|
||||
} from '@angular-devkit/build-angular/src/builders/dev-server';
|
||||
executeDevServerBuilder,
|
||||
} from '@angular-devkit/build-angular';
|
||||
import { JsonObject } from '@angular-devkit/core';
|
||||
import {
|
||||
joinPathFragments,
|
||||
parseTargetString,
|
||||
readAllWorkspaceConfiguration,
|
||||
Workspaces,
|
||||
readCachedProjectGraph,
|
||||
} from '@nrwl/devkit';
|
||||
import { WebpackNxBuildCoordinationPlugin } from '@nrwl/web/src/plugins/webpack-nx-build-coordination-plugin';
|
||||
import {
|
||||
calculateProjectDependencies,
|
||||
createTmpTsConfig,
|
||||
DependentBuildableProjectNode,
|
||||
} from '@nrwl/workspace/src/utilities/buildable-libs-utils';
|
||||
import { existsSync } from 'fs';
|
||||
import { isNpmProject } from 'nx/src/project-graph/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { merge } from 'webpack-merge';
|
||||
import { resolveCustomWebpackConfig } from '../utilities/webpack';
|
||||
import { normalizeOptions } from './lib';
|
||||
import type { Schema } from './schema';
|
||||
|
||||
export function executeWebpackServerBuilder(
|
||||
schema: Schema,
|
||||
rawOptions: Schema,
|
||||
context: BuilderContext
|
||||
) {
|
||||
process.env.NX_TSCONFIG_PATH = joinPathFragments(
|
||||
context.workspaceRoot,
|
||||
'tsconfig.base.json'
|
||||
);
|
||||
|
||||
const options = normalizeOptions(schema);
|
||||
): Observable<BuilderOutput> {
|
||||
const options = normalizeOptions(rawOptions);
|
||||
const workspaceConfig = readAllWorkspaceConfiguration();
|
||||
|
||||
const parsedBrowserTarget = parseTargetString(options.browserTarget);
|
||||
@ -34,28 +41,89 @@ export function executeWebpackServerBuilder(
|
||||
parsedBrowserTarget.target
|
||||
];
|
||||
|
||||
const selectedConfiguration = parsedBrowserTarget.configuration
|
||||
const buildTargetConfiguration = parsedBrowserTarget.configuration
|
||||
? buildTarget.configurations[parsedBrowserTarget.configuration]
|
||||
: buildTarget.defaultConfiguration
|
||||
? buildTarget.configurations[buildTarget.defaultConfiguration]
|
||||
: buildTarget.options;
|
||||
: undefined;
|
||||
|
||||
const buildLibsFromSource =
|
||||
options.buildLibsFromSource ??
|
||||
buildTargetConfiguration?.buildLibsFromSource ??
|
||||
buildTarget.options.buildLibsFromSource ??
|
||||
true;
|
||||
|
||||
const customWebpackConfig: { path: string } =
|
||||
selectedConfiguration.customWebpackConfig ??
|
||||
buildTargetConfiguration?.customWebpackConfig ??
|
||||
buildTarget.options.customWebpackConfig;
|
||||
|
||||
let pathToWebpackConfig: string;
|
||||
if (customWebpackConfig && customWebpackConfig.path) {
|
||||
const pathToWebpackConfig = joinPathFragments(
|
||||
pathToWebpackConfig = joinPathFragments(
|
||||
context.workspaceRoot,
|
||||
customWebpackConfig.path
|
||||
);
|
||||
|
||||
if (existsSync(pathToWebpackConfig)) {
|
||||
return serveWebpackBrowser(
|
||||
options as DevServerBuilderOptions,
|
||||
context as any,
|
||||
{
|
||||
if (!existsSync(pathToWebpackConfig)) {
|
||||
throw new Error(
|
||||
`Custom Webpack Config File Not Found!\nTo use a custom webpack config, please ensure the path to the custom webpack file is correct: \n${pathToWebpackConfig}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let dependencies: DependentBuildableProjectNode[];
|
||||
if (!buildLibsFromSource) {
|
||||
const buildTargetTsConfigPath =
|
||||
buildTargetConfiguration?.tsConfig ?? buildTarget.options.tsConfig;
|
||||
const result = calculateProjectDependencies(
|
||||
readCachedProjectGraph(),
|
||||
context.workspaceRoot,
|
||||
context.target.project,
|
||||
parsedBrowserTarget.target,
|
||||
context.target.configuration
|
||||
);
|
||||
dependencies = result.dependencies;
|
||||
const updatedTsConfig = createTmpTsConfig(
|
||||
joinPathFragments(context.workspaceRoot, buildTargetTsConfigPath),
|
||||
context.workspaceRoot,
|
||||
result.target.data.root,
|
||||
dependencies
|
||||
);
|
||||
process.env.NX_TSCONFIG_PATH = updatedTsConfig;
|
||||
|
||||
// We can't just pass the tsconfig path in memory to the angular builder
|
||||
// function because we can't pass the build target options to it, the build
|
||||
// targets options will be retrieved by the builder from the project
|
||||
// configuration. Therefore, we patch the method in the context to retrieve
|
||||
// the target options to overwrite the tsconfig path to use the generated
|
||||
// one with the updated path mappings.
|
||||
const originalGetTargetOptions = context.getTargetOptions;
|
||||
context.getTargetOptions = async (target) => {
|
||||
const options = await originalGetTargetOptions(target);
|
||||
options.tsConfig = updatedTsConfig;
|
||||
return options;
|
||||
};
|
||||
}
|
||||
|
||||
return executeDevServerBuilder(options as DevServerBuilderOptions, context, {
|
||||
webpackConfiguration: async (baseWebpackConfig) => {
|
||||
if (!buildLibsFromSource) {
|
||||
const workspaceDependencies = dependencies
|
||||
.filter((dep) => !isNpmProject(dep.node))
|
||||
.map((dep) => dep.node.name);
|
||||
baseWebpackConfig.plugins.push(
|
||||
new WebpackNxBuildCoordinationPlugin(
|
||||
`nx run-many --target=${
|
||||
parsedBrowserTarget.target
|
||||
} --projects=${workspaceDependencies.join(',')}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!pathToWebpackConfig) {
|
||||
return baseWebpackConfig;
|
||||
}
|
||||
|
||||
const customWebpackConfiguration = resolveCustomWebpackConfig(
|
||||
pathToWebpackConfig,
|
||||
buildTarget.options.tsConfig
|
||||
@ -70,26 +138,14 @@ export function executeWebpackServerBuilder(
|
||||
if (typeof config === 'function') {
|
||||
return config(
|
||||
baseWebpackConfig,
|
||||
selectedConfiguration,
|
||||
buildTargetConfiguration,
|
||||
context.target
|
||||
);
|
||||
} else {
|
||||
return merge(baseWebpackConfig, config);
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Custom Webpack Config File Not Found!\nTo use a custom webpack config, please ensure the path to the custom webpack file is correct: \n${pathToWebpackConfig}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return serveWebpackBrowser(
|
||||
options as DevServerBuilderOptions,
|
||||
context as any
|
||||
);
|
||||
return merge(baseWebpackConfig, config);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export default createBuilder<JsonObject & Schema>(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user