Skip to content

Commit

Permalink
fix(js): adjust how to pass information down to swc cli (#8298)
Browse files Browse the repository at this point in the history
  • Loading branch information
nartc committed Jan 6, 2022
1 parent 67cb8cf commit 22c6ddb
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 39 deletions.
6 changes: 6 additions & 0 deletions docs/angular/api-js/executors/swc.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Type: `boolean`

Whether to skip TypeScript type checking.

### swcExclude

Type: `array`

List of SWC Glob/Regex to be excluded from compilation (https://swc.rs/docs/configuration/compilation#exclude)

### watch

Default: `false`
Expand Down
6 changes: 6 additions & 0 deletions docs/node/api-js/executors/swc.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Type: `boolean`

Whether to skip TypeScript type checking.

### swcExclude

Type: `array`

List of SWC Glob/Regex to be excluded from compilation (https://swc.rs/docs/configuration/compilation#exclude)

### watch

Default: `false`
Expand Down
6 changes: 6 additions & 0 deletions docs/react/api-js/executors/swc.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Type: `boolean`

Whether to skip TypeScript type checking.

### swcExclude

Type: `array`

List of SWC Glob/Regex to be excluded from compilation (https://swc.rs/docs/configuration/compilation#exclude)

### watch

Default: `false`
Expand Down
48 changes: 48 additions & 0 deletions e2e/js/src/js.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,54 @@ describe('js e2e', () => {
// expect(runCommand(`serve ${app} --watch=false`)).toContain(`Running ${lib}`)
// }, 120000);

it('should create/build/test js:swc lib', async () => {
const lib = uniq('lib');
runCLI(`generate @nrwl/js:lib ${lib} --buildable --compiler=swc`);

const libPackageJson = readJson(`libs/${lib}/package.json`);
expect(libPackageJson.scripts).toBeUndefined();
expect((await runCLIAsync(`test ${lib}`)).combinedOutput).toContain(
'Ran all test suites'
);
expect((await runCLIAsync(`test ${lib}`)).combinedOutput).toContain(
'match the cache'
);

expect(runCLI(`build ${lib}`)).toContain(
'Successfully compiled: 2 files with swc'
);
checkFilesExist(
`dist/libs/${lib}/package.json`,
`dist/libs/${lib}/src/index.js`,
`dist/libs/${lib}/src/lib/${lib}.js`
);
});

it('should create/build/test js:swc lib with nested directories', async () => {
const lib = uniq('lib');
runCLI(
`generate @nrwl/js:lib ${lib} --directory=dir --buildable --compiler=swc`
);

const libPackageJson = readJson(`libs/dir/${lib}/package.json`);
expect(libPackageJson.scripts).toBeUndefined();
expect((await runCLIAsync(`test dir-${lib}`)).combinedOutput).toContain(
'Ran all test suites'
);
expect((await runCLIAsync(`test dir-${lib}`)).combinedOutput).toContain(
'match the cache'
);

expect(runCLI(`build dir-${lib}`)).toContain(
'Successfully compiled: 2 files with swc'
);
checkFilesExist(
`dist/libs/dir/${lib}/package.json`,
`dist/libs/dir/${lib}/src/index.js`,
`dist/libs/dir/${lib}/src/lib/dir-${lib}.js`
);
});

describe('convert js:tsc to js:swc', () => {
it('should convert apps', async () => {
const app = uniq('app');
Expand Down
10 changes: 0 additions & 10 deletions packages/js/src/executors/swc/schema.d.ts

This file was deleted.

5 changes: 5 additions & 0 deletions packages/js/src/executors/swc/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
"type": "boolean",
"description": "Whether to skip TypeScript type checking.",
"default": false
},
"swcExclude": {
"type": "array",
"description": "List of SWC Glob/Regex to be excluded from compilation (https://swc.rs/docs/configuration/compilation#exclude)",
"default": ["./src/**/.*.spec.ts$", "./**/.*.js$"]
}
},
"required": ["main", "outputPath", "tsConfig"],
Expand Down
11 changes: 10 additions & 1 deletion packages/js/src/executors/swc/swc.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
copyAssetFiles,
FileInputOutput,
} from '@nrwl/workspace/src/utilities/assets';
import { join, resolve } from 'path';
import { join, relative, resolve } from 'path';
import { eachValueFrom } from 'rxjs-for-await';
import { map } from 'rxjs/operators';
import { checkDependencies } from '../../utils/check-dependencies';
Expand All @@ -13,6 +13,7 @@ import {
NormalizedSwcExecutorOptions,
SwcExecutorOptions,
} from '../../utils/schema';
import { addTempSwcrc } from '../../utils/swc/add-temp-swcrc';
import { compileSwc } from '../../utils/swc/compile-swc';
import { updatePackageJson } from '../../utils/update-package-json';

Expand All @@ -38,6 +39,12 @@ export function normalizeOptions(
outputPath
);

const swcCliOptions = {
projectDir: projectRoot.split('/').pop(),
// TODO: assume consumers put their code in `src`
destPath: `${relative(projectRoot, options.outputPath)}/src`,
};

return {
...options,
swcrcPath: join(projectRoot, '.swcrc'),
Expand All @@ -51,6 +58,7 @@ export function normalizeOptions(
projectRoot,
outputPath,
tsConfig: join(contextRoot, options.tsConfig),
swcCliOptions,
} as NormalizedSwcExecutorOptions;
}

Expand All @@ -65,6 +73,7 @@ export async function* swcExecutor(
sourceRoot,
root
);
normalizedOptions.swcrcPath = addTempSwcrc(normalizedOptions);
const { tmpTsConfig, projectRoot } = checkDependencies(
context,
options.tsConfig
Expand Down
8 changes: 8 additions & 0 deletions packages/js/src/utils/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,20 @@ export interface NormalizedExecutorOptions extends ExecutorOptions {

export interface SwcExecutorOptions extends ExecutorOptions {
skipTypeCheck?: boolean;
swcExclude?: string[];
}

export interface SwcCliOptions {
projectDir: string;
destPath: string;
}

export interface NormalizedSwcExecutorOptions
extends NormalizedExecutorOptions {
swcExclude: string[];
skipTypeCheck: boolean;
swcrcPath: string;
swcCliOptions: SwcCliOptions;
}

export interface ExecutorEvent {
Expand Down
5 changes: 1 addition & 4 deletions packages/js/src/utils/swc/add-swc-config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// TODO(chau): change back to 2015 when https://github.com/swc-project/swc/issues/1108 is solved
// target: 'es2015'
// TODO(chau): "exclude" is required here to exclude spec files as --ignore cli option is not working atm
// Open issue: https://github.com/swc-project/cli/issues/20
import { Tree } from '@nrwl/devkit';
import { join } from 'path';

Expand All @@ -25,8 +23,7 @@ const swcOptionsString = () => `{
"type": "commonjs",
"strict": true,
"noInterop": true
},
"exclude": ["./src/**/.*.spec.ts$", "./**/.*.js$"]
}
}`;

export function addSwcConfig(tree: Tree, projectDir: string) {
Expand Down
35 changes: 35 additions & 0 deletions packages/js/src/utils/swc/add-temp-swcrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { readJsonFile, writeJsonFile } from '@nrwl/devkit';
import { unlinkSync } from 'fs';
import { join } from 'path';
import { NormalizedSwcExecutorOptions } from '../schema';

// TODO(chau): "exclude" is required here to exclude spec files as --ignore cli option is not working atm
// Open issue: https://github.com/swc-project/cli/issues/20
export function addTempSwcrc(options: NormalizedSwcExecutorOptions) {
const tmpPath = join(
options.root,
'tmp',
options.projectRoot,
'.swcrc.generated'
);
const swcrcJson = readJsonFile(join(options.projectRoot, '.swcrc'));

process.on('exit', cleanUpSwcrc(tmpPath));

writeJsonFile(tmpPath, {
...swcrcJson,
exclude: options.swcExclude,
});

return tmpPath;
}

function cleanUpSwcrc(tmpPath: string) {
return () => {
try {
if (tmpPath) {
unlinkSync(tmpPath);
}
} catch (e) {}
};
}
48 changes: 24 additions & 24 deletions packages/js/src/utils/swc/compile-swc.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ExecutorContext, logger } from '@nrwl/devkit';
import { exec, execSync } from 'child_process';
import { EMPTY, Observable, zip } from 'rxjs';
import { concatMap, map, tap } from 'rxjs/operators';
import { normalizeTsCompilationOptions } from '../normalize-ts-compilation-options';
import { concatMap, map } from 'rxjs/operators';
import { NormalizedSwcExecutorOptions } from '../schema';
import { printDiagnostics } from '../typescript/print-diagnostics';
import {
Expand All @@ -16,23 +15,9 @@ export function compileSwc(
normalizedOptions: NormalizedSwcExecutorOptions,
postCompilationCallback: () => Promise<void>
) {
const tsOptions = {
outputPath: normalizedOptions.outputPath,
projectName: context.projectName,
projectRoot: normalizedOptions.projectRoot,
tsConfig: normalizedOptions.tsConfig,
watch: normalizedOptions.watch,
};
const outDir = tsOptions.outputPath.replace(`/${tsOptions.projectRoot}`, '');

const normalizedTsOptions = normalizeTsCompilationOptions(tsOptions);
logger.log(`Compiling with SWC for ${normalizedTsOptions.projectName}...`);
const srcPath = normalizedTsOptions.projectRoot;
const destPath = normalizedTsOptions.outputPath.replace(
`/${normalizedTsOptions.projectName}`,
''
);
let swcCmd = `npx swc ${srcPath} -d ${destPath} --source-maps --config-file=${normalizedOptions.swcrcPath}`;
logger.log(`Compiling with SWC for ${context.projectName}...`);
const srcPath = `../${normalizedOptions.swcCliOptions.projectDir}`;
let swcCmd = `npx swc ${srcPath} -d ${normalizedOptions.swcCliOptions.destPath} --source-maps --no-swcrc --config-file=${normalizedOptions.swcrcPath}`;

const postCompilationOperator = () =>
concatMap(({ success }) => {
Expand All @@ -45,17 +30,23 @@ export function compileSwc(
const compile$ = new Observable<{ success: boolean }>((subscriber) => {
if (normalizedOptions.watch) {
swcCmd += ' --watch';
const watchProcess = createSwcWatchProcess(swcCmd, (success) => {
subscriber.next({ success });
});
const watchProcess = createSwcWatchProcess(
swcCmd,
normalizedOptions.projectRoot,
(success) => {
subscriber.next({ success });
}
);

return () => {
watchProcess.close();
subscriber.complete();
};
}

const swcCmdLog = execSync(swcCmd).toString();
const swcCmdLog = execSync(swcCmd, {
cwd: normalizedOptions.projectRoot,
}).toString();
logger.log(swcCmdLog.replace(/\n/, ''));
subscriber.next({ success: swcCmdLog.includes('Successfully compiled') });

Expand All @@ -68,6 +59,14 @@ export function compileSwc(
return compile$.pipe(postCompilationOperator());
}

const tsOptions = {
outputPath: normalizedOptions.outputPath,
projectName: context.projectName,
projectRoot: normalizedOptions.projectRoot,
tsConfig: normalizedOptions.tsConfig,
watch: normalizedOptions.watch,
};
const outDir = tsOptions.outputPath.replace(`/${tsOptions.projectRoot}`, '');
const typeCheck$ = new Observable<{ success: boolean }>((subscriber) => {
const typeCheckOptions: TypeCheckOptions = {
mode: 'emitDeclarationOnly',
Expand Down Expand Up @@ -136,9 +135,10 @@ export function compileSwc(

function createSwcWatchProcess(
swcCmd: string,
cwd: string,
callback: (success: boolean) => void
) {
const watchProcess = exec(swcCmd);
const watchProcess = exec(swcCmd, { cwd });

watchProcess.stdout.on('data', (data) => {
process.stdout.write(data);
Expand Down

1 comment on commit 22c6ddb

@vercel
Copy link

@vercel vercel bot commented on 22c6ddb Jan 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.