fix(module-federation): support buildable libs (#20786)

This commit is contained in:
Colum Ferry 2023-12-15 16:07:13 +00:00 committed by GitHub
parent bba1f43032
commit a9a676a570
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 80 additions and 5 deletions

View File

@ -135,6 +135,11 @@
"staticRemotesPort": { "staticRemotesPort": {
"type": "number", "type": "number",
"description": "The port at which to serve the file-server for the static remotes." "description": "The port at which to serve the file-server for the static remotes."
},
"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.",
"x-priority": "important"
} }
}, },
"additionalProperties": false, "additionalProperties": false,

View File

@ -11,6 +11,7 @@ import {
parseTargetString, parseTargetString,
readCachedProjectGraph, readCachedProjectGraph,
type Target, type Target,
targetToTargetString,
} from '@nx/devkit'; } from '@nx/devkit';
import { getRootTsConfigPath } from '@nx/js'; import { getRootTsConfigPath } from '@nx/js';
import type { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils'; import type { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils';
@ -82,6 +83,9 @@ export function executeDevServerBuilder(
buildTargetOptions.buildLibsFromSource ?? buildTargetOptions.buildLibsFromSource ??
true; true;
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = options.buildTarget;
let pathToWebpackConfig: string; let pathToWebpackConfig: string;
if (buildTargetOptions.customWebpackConfig?.path) { if (buildTargetOptions.customWebpackConfig?.path) {
pathToWebpackConfig = joinPathFragments( pathToWebpackConfig = joinPathFragments(
@ -251,6 +255,7 @@ const executorToBuilderMap = new Map<string, string>([
], ],
['@nx/angular:application', '@angular-devkit/build-angular:application'], ['@nx/angular:application', '@angular-devkit/build-angular:application'],
]); ]);
function patchBuilderContext( function patchBuilderContext(
context: BuilderContext, context: BuilderContext,
isUsingEsbuildBuilder: boolean, isUsingEsbuildBuilder: boolean,

View File

@ -1,8 +1,10 @@
import { import {
joinPathFragments, joinPathFragments,
normalizePath, normalizePath,
parseTargetString,
ProjectGraph, ProjectGraph,
readCachedProjectGraph, readCachedProjectGraph,
targetToTargetString,
} from '@nx/devkit'; } from '@nx/devkit';
import type { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils'; import type { DependentBuildableProjectNode } from '@nx/js/src/utils/buildable-libs-utils';
import { WebpackNxBuildCoordinationPlugin } from '@nx/webpack/src/plugins/webpack-nx-build-coordination-plugin'; import { WebpackNxBuildCoordinationPlugin } from '@nx/webpack/src/plugins/webpack-nx-build-coordination-plugin';
@ -57,6 +59,9 @@ export function executeWebpackBrowserBuilder(
...delegateBuilderOptions ...delegateBuilderOptions
} = options; } = options;
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = targetToTargetString({ ...context.target });
const pathToWebpackConfig = const pathToWebpackConfig =
customWebpackConfig?.path && customWebpackConfig?.path &&
joinPathFragments(context.workspaceRoot, customWebpackConfig.path); joinPathFragments(context.workspaceRoot, customWebpackConfig.path);

View File

@ -1,4 +1,8 @@
import { joinPathFragments, normalizePath } from '@nx/devkit'; import {
joinPathFragments,
normalizePath,
targetToTargetString,
} from '@nx/devkit';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
import { relative } from 'path'; import { relative } from 'path';
import { Observable, from } from 'rxjs'; import { Observable, from } from 'rxjs';
@ -96,6 +100,9 @@ export function executeWebpackServerBuilder(
options.buildLibsFromSource ??= true; options.buildLibsFromSource ??= true;
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${options.buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = targetToTargetString({ ...context.target });
if (!options.buildLibsFromSource) { if (!options.buildLibsFromSource) {
const { tsConfigPath } = createTmpTsConfigForBuildableLibs( const { tsConfigPath } = createTmpTsConfigForBuildableLibs(
options.tsConfig, options.tsConfig,

View File

@ -11,6 +11,9 @@ export function normalizeOptions(schema: Schema): NormalizedSchema {
buildTarget ??= (schema as SchemaWithBrowserTarget).browserTarget; buildTarget ??= (schema as SchemaWithBrowserTarget).browserTarget;
delete (schema as SchemaWithBrowserTarget).browserTarget; delete (schema as SchemaWithBrowserTarget).browserTarget;
} }
schema.buildLibsFromSource ??= true;
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${schema.buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = `${buildTarget}`;
return { return {
...schema, ...schema,

View File

@ -23,6 +23,7 @@ interface BaseSchema {
isInitialHost?: boolean; isInitialHost?: boolean;
parallel?: number; parallel?: number;
staticRemotesPort?: number; staticRemotesPort?: number;
buildLibsFromSource?: boolean;
} }
export type SchemaWithBrowserTarget = BaseSchema & { export type SchemaWithBrowserTarget = BaseSchema & {

View File

@ -145,6 +145,11 @@
"staticRemotesPort": { "staticRemotesPort": {
"type": "number", "type": "number",
"description": "The port at which to serve the file-server for the static remotes." "description": "The port at which to serve the file-server for the static remotes."
},
"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.",
"x-priority": "important"
} }
}, },
"additionalProperties": false, "additionalProperties": false,

View File

@ -3,6 +3,7 @@ import {
ExecutorContext, ExecutorContext,
parseTargetString, parseTargetString,
readTargetOptions, readTargetOptions,
targetToTargetString,
} from '@nx/devkit'; } from '@nx/devkit';
import { eachValueFrom } from '@nx/devkit/src/utils/rxjs-for-await'; import { eachValueFrom } from '@nx/devkit/src/utils/rxjs-for-await';
@ -38,6 +39,9 @@ export async function* devServerExecutor(
sourceRoot sourceRoot
); );
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${buildOptions.buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = serveOptions.buildTarget;
// TODO(jack): Figure out a way to port this into NxWebpackPlugin // TODO(jack): Figure out a way to port this into NxWebpackPlugin
if (!buildOptions.buildLibsFromSource) { if (!buildOptions.buildLibsFromSource) {
if (!buildOptions.tsConfig) { if (!buildOptions.tsConfig) {
@ -59,6 +63,8 @@ export async function* devServerExecutor(
target.data.root, target.data.root,
dependencies dependencies
); );
process.env.NX_TSCONFIG_PATH = buildOptions.tsConfig;
} }
let config; let config;

View File

@ -1,4 +1,9 @@
import { ExecutorContext, logger, stripIndents } from '@nx/devkit'; import {
ExecutorContext,
logger,
stripIndents,
targetToTargetString,
} from '@nx/devkit';
import { eachValueFrom } from '@nx/devkit/src/utils/rxjs-for-await'; import { eachValueFrom } from '@nx/devkit/src/utils/rxjs-for-await';
import type { Configuration, Stats } from 'webpack'; import type { Configuration, Stats } from 'webpack';
import { from, of } from 'rxjs'; import { from, of } from 'rxjs';
@ -116,6 +121,13 @@ export async function* webpackExecutor(
? 'production' ? 'production'
: 'development'; : 'development';
process.env.NX_BUILD_LIBS_FROM_SOURCE = `${options.buildLibsFromSource}`;
process.env.NX_BUILD_TARGET = targetToTargetString({
project: context.projectName,
target: context.targetName,
configuration: context.configurationName,
});
if (options.compiler === 'swc') { if (options.compiler === 'swc') {
try { try {
require.resolve('swc-loader'); require.resolve('swc-loader');
@ -146,6 +158,7 @@ export async function* webpackExecutor(
metadata.root, metadata.root,
dependencies dependencies
); );
process.env.NX_TSCONFIG_PATH = options.tsConfig;
} }
// Delete output path before bundling // Delete output path before bundling

View File

@ -1,6 +1,11 @@
import type { ProjectGraph } from '@nx/devkit'; import type { ProjectGraph } from '@nx/devkit';
import type { WorkspaceLibrary } from './models'; import type { WorkspaceLibrary } from './models';
import { readTsPathMappings } from './typescript'; import { readTsPathMappings } from './typescript';
import {
getOutputsForTargetAndConfiguration,
parseTargetString,
} from '@nx/devkit';
import { interpolate } from 'nx/src/tasks-runner/utils';
export function getDependentPackagesForProject( export function getDependentPackagesForProject(
projectGraph: ProjectGraph, projectGraph: ProjectGraph,
@ -57,12 +62,32 @@ function getLibraryImportPath(
library: string, library: string,
projectGraph: ProjectGraph projectGraph: ProjectGraph
): string | undefined { ): string | undefined {
let buildLibsFromSource = true;
if (process.env.NX_BUILD_LIBS_FROM_SOURCE) {
buildLibsFromSource = process.env.NX_BUILD_LIBS_FROM_SOURCE === 'true';
}
const libraryNode = projectGraph.nodes[library];
let sourceRoots = [libraryNode.data.sourceRoot];
if (!buildLibsFromSource && process.env.NX_BUILD_TARGET) {
const buildTarget = parseTargetString(
process.env.NX_BUILD_TARGET,
projectGraph
);
sourceRoots = getOutputsForTargetAndConfiguration(
buildTarget,
{},
libraryNode
);
}
const tsConfigPathMappings = readTsPathMappings(); const tsConfigPathMappings = readTsPathMappings();
const sourceRoot = projectGraph.nodes[library].data.sourceRoot;
for (const [key, value] of Object.entries(tsConfigPathMappings)) { for (const [key, value] of Object.entries(tsConfigPathMappings)) {
if (value.find((path) => path.startsWith(sourceRoot))) { for (const src of sourceRoots) {
return key; if (value.find((path) => path.startsWith(src))) {
return key;
}
} }
} }