feat(rspack): add support for non-buildable libraries in external dependencies (#30606)
Parity with https://github.com/nrwl/nx/pull/30538
This commit is contained in:
parent
4015d4cfe2
commit
32b48a3a04
@ -19,6 +19,7 @@ import { getTerserEcmaVersion } from './get-terser-ecma-version';
|
|||||||
import nodeExternals = require('webpack-node-externals');
|
import nodeExternals = require('webpack-node-externals');
|
||||||
import { NormalizedNxAppRspackPluginOptions } from './models';
|
import { NormalizedNxAppRspackPluginOptions } from './models';
|
||||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
import { isBuildableLibrary } from './is-lib-buildable';
|
||||||
|
|
||||||
const IGNORED_RSPACK_WARNINGS = [
|
const IGNORED_RSPACK_WARNINGS = [
|
||||||
/The comment file/i,
|
/The comment file/i,
|
||||||
@ -350,7 +351,40 @@ function applyNxDependentConfig(
|
|||||||
options.externalDependencies === 'all'
|
options.externalDependencies === 'all'
|
||||||
) {
|
) {
|
||||||
const modulesDir = `${options.root}/node_modules`;
|
const modulesDir = `${options.root}/node_modules`;
|
||||||
externals.push(nodeExternals({ modulesDir }));
|
const graph = options.projectGraph;
|
||||||
|
const projectName = options.projectName;
|
||||||
|
|
||||||
|
const deps = graph?.dependencies?.[projectName] ?? [];
|
||||||
|
|
||||||
|
// Collect non-buildable TS project references so that they are bundled
|
||||||
|
// in the final output. This is needed for projects that are not buildable
|
||||||
|
// but are referenced by buildable projects. This is needed for the new TS
|
||||||
|
// solution setup.
|
||||||
|
const nonBuildableWorkspaceLibs = isUsingTsSolution
|
||||||
|
? deps
|
||||||
|
.filter((dep) => {
|
||||||
|
const node = graph.nodes?.[dep.target];
|
||||||
|
if (!node || node.type !== 'lib') return false;
|
||||||
|
|
||||||
|
const hasBuildTarget = 'build' in (node.data?.targets ?? {});
|
||||||
|
|
||||||
|
if (hasBuildTarget) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is no build target we check the package exports to see if they reference
|
||||||
|
// source files
|
||||||
|
return !isBuildableLibrary(node);
|
||||||
|
})
|
||||||
|
.map(
|
||||||
|
(dep) => graph.nodes?.[dep.target]?.data?.metadata?.js?.packageName
|
||||||
|
)
|
||||||
|
.filter((name): name is string => !!name)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
externals.push(
|
||||||
|
nodeExternals({ modulesDir, allowlist: nonBuildableWorkspaceLibs })
|
||||||
|
);
|
||||||
} else if (Array.isArray(options.externalDependencies)) {
|
} else if (Array.isArray(options.externalDependencies)) {
|
||||||
externals.push(function (ctx, callback: Function) {
|
externals.push(function (ctx, callback: Function) {
|
||||||
if (options.externalDependencies.includes(ctx.request)) {
|
if (options.externalDependencies.includes(ctx.request)) {
|
||||||
|
|||||||
58
packages/rspack/src/plugins/utils/is-lib-buildable.ts
Normal file
58
packages/rspack/src/plugins/utils/is-lib-buildable.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { type ProjectGraphProjectNode } from '@nx/devkit';
|
||||||
|
|
||||||
|
function isSourceFile(path: string): boolean {
|
||||||
|
return ['.ts', '.tsx', '.mts', '.cts'].some((ext) => path.endsWith(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBuildableExportMap(packageExports: any): boolean {
|
||||||
|
if (!packageExports || Object.keys(packageExports).length === 0) {
|
||||||
|
return false; // exports = {} → not buildable
|
||||||
|
}
|
||||||
|
|
||||||
|
const isCompiledExport = (value: unknown): boolean => {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return !isSourceFile(value);
|
||||||
|
}
|
||||||
|
if (typeof value === 'object' && value !== null) {
|
||||||
|
return Object.entries(value).some(([key, subValue]) => {
|
||||||
|
if (
|
||||||
|
key === 'types' ||
|
||||||
|
key === 'development' ||
|
||||||
|
key === './package.json'
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
return typeof subValue === 'string' && !isSourceFile(subValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (packageExports['.']) {
|
||||||
|
return isCompiledExport(packageExports['.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.entries(packageExports).some(
|
||||||
|
([key, value]) => key !== '.' && isCompiledExport(value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the library is buildable.
|
||||||
|
* @param node from the project graph
|
||||||
|
* @returns boolean
|
||||||
|
*/
|
||||||
|
export function isBuildableLibrary(node: ProjectGraphProjectNode): boolean {
|
||||||
|
if (!node.data.metadata?.js) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const { packageExports, packageMain } = node.data.metadata.js;
|
||||||
|
// if we have exports only check this else fallback to packageMain
|
||||||
|
if (packageExports) {
|
||||||
|
return isBuildableExportMap(packageExports);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
typeof packageMain === 'string' &&
|
||||||
|
packageMain !== '' &&
|
||||||
|
!isSourceFile(packageMain)
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user