chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
import {
|
||||
joinPathFragments,
|
||||
normalizePath,
|
||||
ProjectGraph,
|
||||
readCachedProjectGraph,
|
||||
targetToTargetString,
|
||||
} from '@nx/devkit';
|
||||
import type { DependentBuildableProjectNode } from '@nx/js/internal';
|
||||
import { WebpackNxBuildCoordinationPlugin } from '@nx/webpack/internal';
|
||||
import { existsSync } from 'fs';
|
||||
import { isNpmProject } from 'nx/src/project-graph/operators';
|
||||
import { getDependencyConfigs } from 'nx/src/tasks-runner/utils';
|
||||
import { relative } from 'path';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { assertBuilderPackageIsInstalled } from '../../executors/utilities/builder-package';
|
||||
import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs';
|
||||
import {
|
||||
mergeCustomWebpackConfig,
|
||||
resolveIndexHtmlTransformer,
|
||||
} from '../utilities/webpack';
|
||||
import type { BrowserBuilderSchema } from './schema';
|
||||
// This is required to ensure that the webpack version used by the Module Federation is the same as the one used by the builders.
|
||||
const Module = require('module');
|
||||
|
||||
const originalResolveFilename = Module._resolveFilename;
|
||||
const patchedWebpackPath = require.resolve('webpack', {
|
||||
paths: [require.resolve('@angular-devkit/build-angular')],
|
||||
});
|
||||
|
||||
// Override the resolve function
|
||||
Module._resolveFilename = function (request, parent, isMain, options) {
|
||||
// Intercept webpack specifically
|
||||
if (request === 'webpack') {
|
||||
// Force webpack to resolve from your specific path
|
||||
return patchedWebpackPath;
|
||||
}
|
||||
|
||||
// For all other modules, use the original resolver
|
||||
return originalResolveFilename.call(this, request, parent, isMain, options);
|
||||
};
|
||||
|
||||
function shouldSkipInitialTargetRun(
|
||||
projectGraph: ProjectGraph,
|
||||
project: string,
|
||||
target: string
|
||||
): boolean {
|
||||
const allTargetNames = new Set<string>();
|
||||
for (const projectName in projectGraph.nodes) {
|
||||
const project = projectGraph.nodes[projectName];
|
||||
for (const targetName in project.data.targets ?? {}) {
|
||||
allTargetNames.add(targetName);
|
||||
}
|
||||
}
|
||||
|
||||
const projectDependencyConfigs = getDependencyConfigs(
|
||||
{ project, target },
|
||||
{},
|
||||
projectGraph,
|
||||
Array.from(allTargetNames)
|
||||
);
|
||||
|
||||
// if the task runner already ran the target, skip the initial run
|
||||
return projectDependencyConfigs.some(
|
||||
(d) => d.target === target && d.projects === 'dependencies'
|
||||
);
|
||||
}
|
||||
|
||||
export function executeWebpackBrowserBuilder(
|
||||
options: BrowserBuilderSchema,
|
||||
context: import('@angular-devkit/architect').BuilderContext
|
||||
): Observable<import('@angular-devkit/architect').BuilderOutput> {
|
||||
options.buildLibsFromSource ??= true;
|
||||
options.watchDependencies ??= true;
|
||||
|
||||
const {
|
||||
buildLibsFromSource,
|
||||
customWebpackConfig,
|
||||
indexHtmlTransformer,
|
||||
watchDependencies,
|
||||
...delegateBuilderOptions
|
||||
} = options;
|
||||
|
||||
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${buildLibsFromSource}`;
|
||||
process.env.NX_BUILD_TARGET = targetToTargetString({ ...context.target });
|
||||
|
||||
const pathToWebpackConfig =
|
||||
customWebpackConfig?.path &&
|
||||
joinPathFragments(context.workspaceRoot, customWebpackConfig.path);
|
||||
if (pathToWebpackConfig && !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}`
|
||||
);
|
||||
}
|
||||
|
||||
const pathToIndexFileTransformer =
|
||||
indexHtmlTransformer &&
|
||||
joinPathFragments(context.workspaceRoot, indexHtmlTransformer);
|
||||
if (pathToIndexFileTransformer && !existsSync(pathToIndexFileTransformer)) {
|
||||
throw new Error(
|
||||
`File containing Index File Transformer function Not Found!\n Please ensure the path to the file containing the function is correct: \n${pathToIndexFileTransformer}`
|
||||
);
|
||||
}
|
||||
|
||||
let dependencies: DependentBuildableProjectNode[];
|
||||
let projectGraph: ProjectGraph;
|
||||
if (!buildLibsFromSource) {
|
||||
projectGraph = readCachedProjectGraph();
|
||||
const { tsConfigPath, dependencies: foundDependencies } =
|
||||
createTmpTsConfigForBuildableLibs(
|
||||
delegateBuilderOptions.tsConfig,
|
||||
context,
|
||||
{ projectGraph }
|
||||
);
|
||||
dependencies = foundDependencies;
|
||||
delegateBuilderOptions.tsConfig = normalizePath(
|
||||
relative(context.workspaceRoot, tsConfigPath)
|
||||
);
|
||||
}
|
||||
|
||||
assertBuilderPackageIsInstalled('@angular-devkit/build-angular');
|
||||
return from(import('@angular-devkit/build-angular')).pipe(
|
||||
switchMap(({ executeBrowserBuilder }) =>
|
||||
executeBrowserBuilder(delegateBuilderOptions, context as any, {
|
||||
webpackConfiguration: (baseWebpackConfig) => {
|
||||
if (!buildLibsFromSource && delegateBuilderOptions.watch) {
|
||||
const workspaceDependencies = dependencies
|
||||
.filter((dep) => !isNpmProject(dep.node))
|
||||
.map((dep) => dep.node.name);
|
||||
// default for `nx run-many` is --all projects
|
||||
// by passing an empty string for --projects, run-many will default to
|
||||
// run the target for all projects.
|
||||
// This will occur when workspaceDependencies = []
|
||||
if (workspaceDependencies.length > 0) {
|
||||
const skipInitialRun = shouldSkipInitialTargetRun(
|
||||
projectGraph,
|
||||
context.target.project,
|
||||
context.target.target
|
||||
);
|
||||
|
||||
baseWebpackConfig.plugins.push(
|
||||
// Cast away the angular/webpack plugin type difference (webpack versions).
|
||||
new (WebpackNxBuildCoordinationPlugin as any)(
|
||||
`nx run-many --target=${
|
||||
context.target.target
|
||||
} --projects=${workspaceDependencies.join(',')}`,
|
||||
{ skipInitialRun, skipWatchingDeps: !watchDependencies }
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!pathToWebpackConfig) {
|
||||
return baseWebpackConfig;
|
||||
}
|
||||
|
||||
return mergeCustomWebpackConfig(
|
||||
baseWebpackConfig,
|
||||
pathToWebpackConfig,
|
||||
delegateBuilderOptions,
|
||||
context.target
|
||||
);
|
||||
},
|
||||
...(pathToIndexFileTransformer
|
||||
? {
|
||||
indexHtml: resolveIndexHtmlTransformer(
|
||||
pathToIndexFileTransformer,
|
||||
delegateBuilderOptions.tsConfig,
|
||||
context.target
|
||||
),
|
||||
}
|
||||
: {}),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default require('@angular-devkit/architect').createBuilder(
|
||||
executeWebpackBrowserBuilder
|
||||
) as any;
|
||||
Reference in New Issue
Block a user