Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(js): add swc cli options --strip-leading-paths #22193

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/generated/packages/js/executors/swc.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@
"oneOf": [
{ "type": "string", "enum": ["all", "none"] },
{ "type": "array", "items": { "type": "string" } }
]
],
"x-deprecated": "Make sure all dependencies are buildable by running `nx g @nx/js:setup-build`. This option will be removed in Nx 20."
},
"externalBuildTargets": {
"type": "array",
Expand All @@ -131,6 +132,11 @@
"x-priority": "internal"
}
},
"stripLeadingPaths": {
"type": "boolean",
"description": "Remove leading directory from output (e.g. src). See: https://swc.rs/docs/usage/cli#--strip-leading-paths",
"default": false
},
"required": ["main", "outputPath", "tsConfig"],
"definitions": {
"assetPattern": {
Expand Down
3 changes: 2 additions & 1 deletion docs/generated/packages/js/executors/tsc.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@
"oneOf": [
{ "type": "string", "enum": ["all", "none"] },
{ "type": "array", "items": { "type": "string" } }
]
],
"x-deprecated": "Make sure all dependencies are buildable by running `nx g @nx/js:setup-build`. This option will be removed in Nx 20."
},
"externalBuildTargets": {
"type": "array",
Expand Down
15 changes: 15 additions & 0 deletions e2e/js/src/js-executor-swc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,19 @@ myLib();
}).toString();
expect(result).toContain('x');
}, 240_000);

it('should support --strip-leading-paths option', () => {
const lib = uniq('lib');
runCLI(`generate @nx/js:lib ${lib} --bundler=swc --no-interactive`);

runCLI(`build ${lib} --stripLeadingPaths`);

checkFilesExist(
`dist/libs/${lib}/package.json`,
`dist/libs/${lib}/index.js`,
`dist/libs/${lib}/lib/${lib}.js`,
`dist/libs/${lib}/index.d.ts`,
`dist/libs/${lib}/lib/${lib}.d.ts`
);
});
});
9 changes: 9 additions & 0 deletions packages/js/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,15 @@
"alwaysAddToPackageJson": false
}
}
},
"18.2.5": {
"version": "18.2.5-beta.0",
"packages": {
"@swc/cli": {
"version": "~0.3.12",
"alwaysAddToPackageJson": false
}
}
}
}
}
8 changes: 7 additions & 1 deletion packages/js/src/executors/swc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
"type": "string"
}
}
]
],
"x-deprecated": "Make sure all dependencies are buildable by running `nx g @nx/js:setup-build`. This option will be removed in Nx 20."
},
"externalBuildTargets": {
"type": "array",
Expand All @@ -114,6 +115,11 @@
"x-priority": "internal"
}
},
"stripLeadingPaths": {
"type": "boolean",
"description": "Remove leading directory from output (e.g. src). See: https://swc.rs/docs/usage/cli#--strip-leading-paths",
"default": false
},
"required": ["main", "outputPath", "tsConfig"],
"definitions": {
"assetPattern": {
Expand Down
22 changes: 12 additions & 10 deletions packages/js/src/executors/swc/swc.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { copyPackageJson } from '../../utils/package-json';
import {
NormalizedSwcExecutorOptions,
SwcCliOptions,
SwcExecutorOptions,
} from '../../utils/schema';
import { compileSwc, compileSwcWatch } from '../../utils/swc/compile-swc';
Expand Down Expand Up @@ -59,20 +60,16 @@ function normalizeOptions(
outputPath
);

const projectRootParts = projectRoot.split('/');
// We pop the last part of the `projectRoot` to pass
// the last part (projectDir) and the remainder (projectRootParts) to swc
const projectDir = projectRootParts.pop();
// default to current directory if projectRootParts is [].
// Eg: when a project is at the root level, outside of layout dir
const swcCwd = projectRootParts.join('/') || '.';
// Always execute from root of project, same as with SWC CLI.
const swcCwd = join(root, projectRoot);
const { swcrcPath, tmpSwcrcPath } = getSwcrcPath(options, root, projectRoot);

const swcCliOptions = {
srcPath: projectDir,
destPath: relative(join(root, swcCwd), outputPath),
srcPath: projectRoot,
destPath: relative(swcCwd, outputPath),
swcCwd,
swcrcPath,
stripLeadingPaths: Boolean(options.stripLeadingPaths),
};

return {
Expand Down Expand Up @@ -127,11 +124,16 @@ export async function* swcExecutor(
);

if (!isInlineGraphEmpty(inlineProjectGraph)) {
if (options.stripLeadingPaths) {
throw new Error(`Cannot use --strip-leading-paths with inlining.`);
}

options.projectRoot = '.'; // set to root of workspace to include other libs for type check

// remap paths for SWC compilation
options.swcCliOptions.srcPath = options.swcCliOptions.swcCwd;
options.inline = true;
options.swcCliOptions.swcCwd = '.';
options.swcCliOptions.srcPath = options.swcCliOptions.swcCwd;
options.swcCliOptions.destPath = join(
options.swcCliOptions.destPath.split(normalize('../')).at(-1),
options.swcCliOptions.srcPath
Expand Down
3 changes: 2 additions & 1 deletion packages/js/src/executors/tsc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@
"type": "string"
}
}
]
],
"x-deprecated": "Make sure all dependencies are buildable by running `nx g @nx/js:setup-build`. This option will be removed in Nx 20."
},
"externalBuildTargets": {
"type": "array",
Expand Down
5 changes: 5 additions & 0 deletions packages/js/src/utils/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export interface ExecutorOptions {
external?: 'all' | 'none' | string[];
externalBuildTargets?: string[];
generateLockfile?: boolean;
stripLeadingPaths?: boolean;
}

export interface NormalizedExecutorOptions extends ExecutorOptions {
Expand All @@ -75,6 +76,7 @@ export interface SwcCliOptions {
destPath: string;
swcrcPath: string;
swcCwd: string;
stripLeadingPaths: boolean;
}

export interface NormalizedSwcExecutorOptions
Expand All @@ -84,4 +86,7 @@ export interface NormalizedSwcExecutorOptions
skipTypeCheck: boolean;
swcCliOptions: SwcCliOptions;
tmpSwcrcPath: string;
sourceRoot?: string;
// TODO(v20): remove inline feature
inline?: boolean;
}
62 changes: 46 additions & 16 deletions packages/js/src/utils/swc/compile-swc.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,66 @@
import { cacheDir, ExecutorContext, logger } from '@nx/devkit';
import { exec, execSync } from 'child_process';
import { removeSync } from 'fs-extra';
import { exec, execSync } from 'node:child_process';
import { join } from 'node:path';
import { existsSync, removeSync } from 'fs-extra';
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';
import { NormalizedSwcExecutorOptions, SwcCliOptions } from '../schema';
import { printDiagnostics } from '../typescript/print-diagnostics';
import { runTypeCheck, TypeCheckOptions } from '../typescript/run-type-check';
import { relative } from 'path';

function getSwcCmd(
{ swcrcPath, srcPath, destPath }: SwcCliOptions,
{
swcCliOptions: { swcrcPath, destPath, stripLeadingPaths },
root,
projectRoot,
originalProjectRoot,
sourceRoot,
inline,
}: NormalizedSwcExecutorOptions,
watch = false
) {
const swcCLI = require.resolve('@swc/cli/bin/swc.js');
let inputDir: string;
// TODO(v20): remove inline feature
if (inline) {
inputDir = originalProjectRoot.split('/')[0];
} else {
if (sourceRoot) {
inputDir = relative(projectRoot, sourceRoot);
} else {
// If sourceRoot is not provided, check if `src` exists and use that instead.
// This is important for root projects to avoid compiling too many directories.
inputDir = existsSync(join(root, projectRoot, 'src')) ? 'src' : '.';
}
}

let swcCmd = `node ${swcCLI} ${
// TODO(jack): clean this up when we remove inline module support
// Handle root project
srcPath === '.' ? 'src' : srcPath
} -d ${
srcPath === '.' ? `${destPath}/src` : destPath
} --config-file=${swcrcPath}`;
inputDir || '.'
} -d ${destPath} --config-file=${swcrcPath} ${
stripLeadingPaths ? '--strip-leading-paths' : ''
}`;
return watch ? swcCmd.concat(' --watch') : swcCmd;
}

function getTypeCheckOptions(normalizedOptions: NormalizedSwcExecutorOptions) {
const { projectRoot, watch, tsConfig, root, outputPath } = normalizedOptions;
const { sourceRoot, projectRoot, watch, tsConfig, root, outputPath } =
normalizedOptions;
const inputDir =
// If `--strip-leading-paths` SWC option is used, we need to transpile from `src` directory.
!normalizedOptions.swcCliOptions.stripLeadingPaths
? projectRoot
: sourceRoot
? sourceRoot
: existsSync(join(root, projectRoot, 'src'))
? join(projectRoot, 'src')
: projectRoot;

const typeCheckOptions: TypeCheckOptions = {
mode: 'emitDeclarationOnly',
tsConfigPath: tsConfig,
outDir: outputPath,
workspaceRoot: root,
rootDir: projectRoot,
rootDir: inputDir,
};

if (watch) {
Expand All @@ -51,7 +82,7 @@ export async function compileSwc(
removeSync(normalizedOptions.outputPath);
}

const swcCmdLog = execSync(getSwcCmd(normalizedOptions.swcCliOptions), {
const swcCmdLog = execSync(getSwcCmd(normalizedOptions), {
encoding: 'utf8',
cwd: normalizedOptions.swcCliOptions.swcCwd,
});
Expand Down Expand Up @@ -104,10 +135,9 @@ export async function* compileSwcWatch(
let stderrOnData: () => void;
let watcherOnExit: () => void;

const swcWatcher = exec(
getSwcCmd(normalizedOptions.swcCliOptions, true),
{ cwd: normalizedOptions.swcCliOptions.swcCwd }
);
const swcWatcher = exec(getSwcCmd(normalizedOptions, true), {
cwd: normalizedOptions.swcCliOptions.swcCwd,
});

processOnExit = () => {
swcWatcher.kill();
Expand Down
2 changes: 1 addition & 1 deletion packages/js/src/utils/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const nxVersion = require('../../package.json').version;

export const esbuildVersion = '^0.19.2';
export const prettierVersion = '^2.6.2';
export const swcCliVersion = '~0.1.62';
export const swcCliVersion = '~0.3.12';
export const swcCoreVersion = '~1.3.85';
export const swcHelpersVersion = '~0.5.2';
export const swcNodeVersion = '~1.8.0';
Expand Down