diff --git a/docs/generated/api-node/generators/library.md b/docs/generated/api-node/generators/library.md index 7125261ae51e2..963693c1e1341 100644 --- a/docs/generated/api-node/generators/library.md +++ b/docs/generated/api-node/generators/library.md @@ -63,6 +63,16 @@ Type: `boolean` Generate a buildable library. +### compiler + +Default: `tsc` + +Type: `string` + +Possible values: `tsc`, `swc` + +The compiler used by the build and test targets + ### directory Alias(es): dir diff --git a/packages/node/src/generators/library/library.spec.ts b/packages/node/src/generators/library/library.spec.ts index 5e4491d357e57..68d921400e830 100644 --- a/packages/node/src/generators/library/library.spec.ts +++ b/packages/node/src/generators/library/library.spec.ts @@ -1,9 +1,21 @@ -import { getProjects, NxJsonConfiguration, readJson, Tree } from '@nrwl/devkit'; +import { + getProjects, + NxJsonConfiguration, + readJson, + readProjectConfiguration, + Tree, +} from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { Schema } from './schema.d'; import { libraryGenerator } from './library'; +const baseLibraryConfig = { + name: 'myLib', + standaloneConfig: false, + compiler: 'tsc' as const, +}; + describe('lib', () => { let tree: Tree; @@ -13,7 +25,7 @@ describe('lib', () => { describe('not nested', () => { it('should update workspace.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const workspaceJson = readJson(tree, '/workspace.json'); expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib'); expect(workspaceJson.projects['my-lib'].architect.build).toBeUndefined(); @@ -36,10 +48,9 @@ describe('lib', () => { it('adds srcRootForCompilationRoot in workspace.json', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, rootDir: './src', buildable: true, - standaloneConfig: false, }); const workspaceJson = readJson(tree, '/workspace.json'); expect( @@ -50,9 +61,8 @@ describe('lib', () => { it('should update tags', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, tags: 'one,two', - standaloneConfig: false, }); const projects = Object.fromEntries(getProjects(tree)); expect(projects).toMatchObject({ @@ -63,7 +73,7 @@ describe('lib', () => { }); it('should update root tsconfig.base.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const tsconfigJson = readJson(tree, '/tsconfig.base.json'); expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([ 'libs/my-lib/src/index.ts', @@ -71,7 +81,7 @@ describe('lib', () => { }); it('should create a local tsconfig.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json'); expect(tsconfigJson).toMatchInlineSnapshot(` Object { @@ -91,26 +101,26 @@ describe('lib', () => { }); it('should extend the local tsconfig.json with tsconfig.spec.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.spec.json'); expect(tsconfigJson.extends).toEqual('./tsconfig.json'); }); it('should extend the local tsconfig.json with tsconfig.lib.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json'); expect(tsconfigJson.compilerOptions.types).toContain('node'); expect(tsconfigJson.extends).toEqual('./tsconfig.json'); }); it('should exclude test files from tsconfig.lib.json', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json'); expect(tsconfigJson.exclude).toEqual(['**/*.spec.ts', '**/*.test.ts']); }); it('should generate files', async () => { - await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false }); + await libraryGenerator(tree, baseLibraryConfig); expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy(); expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy(); @@ -156,10 +166,9 @@ describe('lib', () => { describe('nested', () => { it('should update tags', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', tags: 'one', - standaloneConfig: false, }); let projects = Object.fromEntries(getProjects(tree)); expect(projects).toMatchObject({ @@ -169,10 +178,10 @@ describe('lib', () => { }); await libraryGenerator(tree, { + ...baseLibraryConfig, name: 'myLib2', directory: 'myDir', tags: 'one,two', - standaloneConfig: false, }); projects = Object.fromEntries(getProjects(tree)); expect(projects).toMatchObject({ @@ -187,9 +196,8 @@ describe('lib', () => { it('should generate files', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', - standaloneConfig: false, }); expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy(); expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy(); @@ -197,9 +205,8 @@ describe('lib', () => { it('should update workspace.json', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', - standaloneConfig: false, }); const workspaceJson = readJson(tree, '/workspace.json'); @@ -217,9 +224,8 @@ describe('lib', () => { it('should update tsconfig.json', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', - standaloneConfig: false, }); const tsconfigJson = readJson(tree, '/tsconfig.base.json'); expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual( @@ -235,10 +241,9 @@ describe('lib', () => { try { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', publishable: true, - standaloneConfig: false, }); } catch (e) { expect(e.message).toContain( @@ -249,9 +254,8 @@ describe('lib', () => { it('should create a local tsconfig.json', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', - standaloneConfig: false, }); const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json'); @@ -268,10 +272,9 @@ describe('lib', () => { it('should generate filenames that do not contain directory with --simpleModuleName', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, directory: 'myDir', simpleModuleName: true, - standaloneConfig: false, }); expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy(); expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy(); @@ -284,12 +287,37 @@ describe('lib', () => { }); }); + describe('--compiler', () => { + it('should specify tsc as compiler', async () => { + await libraryGenerator(tree, { + ...baseLibraryConfig, + compiler: 'tsc', + buildable: true, + }); + + const { build } = readProjectConfiguration(tree, 'my-lib').targets; + + expect(build.executor).toEqual('@nrwl/js:tsc'); + }); + + it('should specify swc as compiler', async () => { + await libraryGenerator(tree, { + ...baseLibraryConfig, + compiler: 'swc', + buildable: true, + }); + + const { build } = readProjectConfiguration(tree, 'my-lib').targets; + + expect(build.executor).toEqual('@nrwl/js:swc'); + }); + }); + describe('--unit-test-runner none', () => { it('should not generate test configuration', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, unitTestRunner: 'none', - standaloneConfig: false, }); expect(tree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy(); expect(tree.exists('libs/my-lib/jest.config.js')).toBeFalsy(); @@ -323,9 +351,8 @@ describe('lib', () => { describe('buildable package', () => { it('should have a builder defined', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, buildable: true, - standaloneConfig: false, }); const workspaceJson = readJson(tree, '/workspace.json'); @@ -334,7 +361,7 @@ describe('lib', () => { expect(workspaceJson.projects['my-lib'].architect.build) .toMatchInlineSnapshot(` Object { - "builder": "@nrwl/node:package", + "builder": "@nrwl/js:tsc", "options": Object { "assets": Array [ "libs/my-lib/*.md", @@ -355,10 +382,9 @@ describe('lib', () => { describe('publishable package', () => { it('should have a builder defined', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, publishable: true, importPath: '@proj/mylib', - standaloneConfig: false, }); const workspaceJson = readJson(tree, '/workspace.json'); @@ -369,10 +395,10 @@ describe('lib', () => { it('should update package.json', async () => { await libraryGenerator(tree, { + ...baseLibraryConfig, name: 'mylib', publishable: true, importPath: '@proj/mylib', - standaloneConfig: false, }); let packageJsonContent = readJson(tree, 'libs/mylib/package.json'); @@ -384,11 +410,10 @@ describe('lib', () => { describe('--importPath', () => { it('should update the package.json & tsconfig with the given import path', async () => { await libraryGenerator(tree, { - name: 'myLib', + ...baseLibraryConfig, publishable: true, directory: 'myDir', importPath: '@myorg/lib', - standaloneConfig: false, }); const packageJson = readJson(tree, 'libs/my-dir/my-lib/package.json'); const tsconfigJson = readJson(tree, '/tsconfig.base.json'); @@ -401,18 +426,18 @@ describe('lib', () => { it('should fail if the same importPath has already been used', async () => { await libraryGenerator(tree, { + ...baseLibraryConfig, name: 'myLib1', publishable: true, importPath: '@myorg/lib', - standaloneConfig: false, }); try { await libraryGenerator(tree, { + ...baseLibraryConfig, name: 'myLib2', publishable: true, importPath: '@myorg/lib', - standaloneConfig: false, }); } catch (e) { expect(e.message).toContain( diff --git a/packages/node/src/generators/library/library.ts b/packages/node/src/generators/library/library.ts index 629d57febd4ea..43f5d37984592 100644 --- a/packages/node/src/generators/library/library.ts +++ b/packages/node/src/generators/library/library.ts @@ -24,6 +24,7 @@ export interface NormalizedSchema extends Schema { projectRoot: string; projectDirectory: string; parsedTags: string[]; + compiler: 'swc' | 'tsc'; } export async function libraryGenerator(tree: Tree, schema: Schema) { @@ -137,7 +138,7 @@ function updateProject(tree: Tree, options: NormalizedSchema) { project.targets = project.targets || {}; project.targets.build = { - executor: '@nrwl/node:package', + executor: `@nrwl/js:${options.compiler}`, outputs: ['{options.outputPath}'], options: { outputPath: `dist/${libsDir}/${options.projectDirectory}`, diff --git a/packages/node/src/generators/library/schema.d.ts b/packages/node/src/generators/library/schema.d.ts index 965d52d86579c..682a1c3a1ebc2 100644 --- a/packages/node/src/generators/library/schema.d.ts +++ b/packages/node/src/generators/library/schema.d.ts @@ -20,4 +20,5 @@ export interface Schema { strict?: boolean; standaloneConfig?: boolean; setParserOptionsProject?: boolean; + compiler: 'tsc' | 'swc'; } diff --git a/packages/node/src/generators/library/schema.json b/packages/node/src/generators/library/schema.json index f9333b9e7f0bb..f17001317f2e1 100644 --- a/packages/node/src/generators/library/schema.json +++ b/packages/node/src/generators/library/schema.json @@ -66,6 +66,12 @@ "default": false, "description": "Generate a buildable library." }, + "compiler": { + "type": "string", + "enum": ["tsc", "swc"], + "default": "tsc", + "description": "The compiler used by the build and test targets" + }, "importPath": { "type": "string", "description": "The library name used to import it, like @myorg/my-awesome-lib. Must be a valid npm name."