Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(nest): use nrwl/js to generate library (#9164)
* chore(js): rename GeneratorSchema to LibraryGeneratorSchema

* fix(js): add publishable to library generator schema

* feat(nest): use nrwl/js for library generator

* fix(js): update documentation about publishable

* chore(nest): fix depcheck for nrwl/js

* chore(nest): update test snapshot

* chore(nest): update nestjs/swagger version in node e2e

* chore(js): rename loadTsPlugins function

* fix(nest): default standaloneConfig for library generator to true

* feat(nest): rename tsPlugins to transformers and add tsPlugins to aliases

* chore(nest): fix e2e test on generate a new nest library

Co-authored-by: Chau Tran <ctran@Chaus-MacBook-Pro.local>
  • Loading branch information
nartc and Chau Tran committed Mar 3, 2022
1 parent bf62996 commit 229f71e
Show file tree
Hide file tree
Showing 24 changed files with 125 additions and 84 deletions.
8 changes: 8 additions & 0 deletions docs/generated/api-js/generators/library.md
Expand Up @@ -115,6 +115,14 @@ Type: `boolean`

Use pascal case file names.

### publishable

Default: `false`

Type: `boolean`

Generate a publishable library.

### setParserOptionsProject

Default: `false`
Expand Down
2 changes: 2 additions & 0 deletions docs/generated/api-nest/generators/library.md
Expand Up @@ -135,6 +135,8 @@ Do not update tsconfig.base.json for development experience.

### standaloneConfig

Default: `true`

Type: `boolean`

Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
Expand Down
6 changes: 4 additions & 2 deletions docs/generated/api-node/executors/webpack.md
Expand Up @@ -159,11 +159,13 @@ Type: `boolean`

Generates a 'stats.json' file which can be analyzed using tools such as: 'webpack-bundle-analyzer' or <https://webpack.github.io/analyse>.

### tsPlugins
### transformers

Alias(es): tsPlugins

Type: `array`

List of TypeScript Compiler Plugins.
List of TypeScript Compiler Transfomers Plugins.

### verbose

Expand Down
16 changes: 7 additions & 9 deletions e2e/node/src/node.test.ts
@@ -1,6 +1,4 @@
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
import { exec, execSync } from 'child_process';
import * as http from 'http';
import {
checkFilesDoNotExist,
checkFilesExist,
Expand All @@ -18,6 +16,8 @@ import {
updateFile,
updateProjectConfig,
} from '@nrwl/e2e/utils';
import { exec, execSync } from 'child_process';
import * as http from 'http';

function getData(port): Promise<any> {
return new Promise((resolve) => {
Expand Down Expand Up @@ -291,8 +291,7 @@ describe('Build Node apps', () => {
const nestapp = uniq('nestapp');
runCLI(`generate @nrwl/nest:app ${nestapp} --linter=eslint`);

// TODO: update to v5 when Nest8 is supported
packageInstall('@nestjs/swagger', undefined, '4.8.2');
packageInstall('@nestjs/swagger', undefined, '~5.0.0');

updateProjectConfig(nestapp, (config) => {
config.targets.build.options.tsPlugins = ['@nestjs/swagger/plugin'];
Expand Down Expand Up @@ -370,9 +369,9 @@ describe('nest libraries', function () {
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
'^.+\\.[tj]s$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/${nestlib}',
};
`
Expand Down Expand Up @@ -424,13 +423,12 @@ describe('nest libraries', function () {
);
}, 200000);

it('should have plugin output if specified in `tsPlugins`', async () => {
it('should have plugin output if specified in `transformers`', async () => {
newProject();
const nestlib = uniq('nestlib');
runCLI(`generate @nrwl/nest:lib ${nestlib} --buildable`);

// TODO: update to v5 when Nest8 is supported
packageInstall('@nestjs/swagger', undefined, '4.8.2');
packageInstall('@nestjs/swagger', undefined, '~5.0.0');

updateProjectConfig(nestlib, (config) => {
config.targets.build.options.transformers = [
Expand Down
23 changes: 11 additions & 12 deletions e2e/utils/index.ts
@@ -1,4 +1,12 @@
import {
joinPathFragments,
parseJson,
ProjectConfiguration,
WorkspaceJsonConfiguration,
} from '@nrwl/devkit';
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { Workspaces } from '@nrwl/tao/src/shared/workspace';
import { angularCliVersion } from '@nrwl/workspace/src/utils/versions';
import { ChildProcess, exec, execSync } from 'child_process';
import {
copySync,
Expand All @@ -14,21 +22,12 @@ import {
} from 'fs-extra';
import * as path from 'path';
import { join } from 'path';
import { dirSync } from 'tmp';
import { coerce } from 'semver';
import { check as portCheck } from 'tcp-port-used';
import {
joinPathFragments,
parseJson,
ProjectConfiguration,
WorkspaceJsonConfiguration,
} from '@nrwl/devkit';
import { dirSync } from 'tmp';
import { promisify } from 'util';
import { Workspaces } from '@nrwl/tao/src/shared/workspace';
import { angularCliVersion } from '@nrwl/workspace/src/utils/versions';
import { coerce } from 'semver';
import isCI = require('is-ci');

import chalk = require('chalk');
import isCI = require('is-ci');
import treeKill = require('tree-kill');

const kill = require('kill-port');
Expand Down
@@ -1,14 +1,14 @@
import { readProjectConfiguration, Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { join } from 'path';
import { GeneratorSchema } from '../../utils/schema';
import { LibraryGeneratorSchema } from '../../utils/schema';
import { libraryGenerator } from '../library/library';
import { convertToSwcGenerator } from './convert-to-swc';

describe('convert to swc', () => {
let tree: Tree;

const defaultLibGenerationOptions: Omit<GeneratorSchema, 'name'> = {
const defaultLibGenerationOptions: Omit<LibraryGeneratorSchema, 'name'> = {
skipTsConfig: false,
unitTestRunner: 'jest',
skipFormat: false,
Expand Down
4 changes: 2 additions & 2 deletions packages/js/src/generators/library/library.spec.ts
Expand Up @@ -6,12 +6,12 @@ import {
updateJson,
} from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { GeneratorSchema } from '../../utils/schema';
import { LibraryGeneratorSchema } from '../../utils/schema';
import libraryGenerator from './library';

describe('lib', () => {
let tree: Tree;
const defaultOptions: Omit<GeneratorSchema, 'name'> = {
const defaultOptions: Omit<LibraryGeneratorSchema, 'name'> = {
skipTsConfig: false,
unitTestRunner: 'jest',
skipFormat: false,
Expand Down
22 changes: 17 additions & 5 deletions packages/js/src/generators/library/library.ts
Expand Up @@ -14,21 +14,24 @@ import {
updateJson,
} from '@nrwl/devkit';
import { join } from 'path';
import { GeneratorSchema } from '../../utils/schema';
import { LibraryGeneratorSchema } from '../../utils/schema';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { jestProjectGenerator } from '@nrwl/jest';
import { addSwcDependencies } from '../../utils/swc/add-swc-dependencies';
import { addSwcConfig } from '../../utils/swc/add-swc-config';

export async function libraryGenerator(tree: Tree, schema: GeneratorSchema) {
export async function libraryGenerator(
tree: Tree,
schema: LibraryGeneratorSchema
) {
const { libsDir } = getWorkspaceLayout(tree);
return projectGenerator(tree, schema, libsDir, join(__dirname, './files'));
}

export async function projectGenerator(
tree: Tree,
schema: GeneratorSchema,
schema: LibraryGeneratorSchema,
destinationDir: string,
filesDir: string
) {
Expand Down Expand Up @@ -60,7 +63,7 @@ export async function projectGenerator(
return runTasksInSerial(...tasks);
}

export interface NormalizedSchema extends GeneratorSchema {
export interface NormalizedSchema extends LibraryGeneratorSchema {
name: string;
fileName: string;
projectRoot: string;
Expand Down Expand Up @@ -221,9 +224,18 @@ async function addJest(

function normalizeOptions(
tree: Tree,
options: GeneratorSchema,
options: LibraryGeneratorSchema,
destinationDir: string
): NormalizedSchema {
if (options.publishable) {
if (!options.importPath) {
throw new Error(
`For publishable libs you have to provide a proper "--importPath" which needs to be a valid npm package name (e.g. my-awesome-lib or @myorg/my-lib)`
);
}
options.buildable = true;
}

if (options.config === 'npm-scripts') {
options.unitTestRunner = 'none';
options.linter = Linter.None;
Expand Down
5 changes: 5 additions & 0 deletions packages/js/src/generators/library/schema.json
Expand Up @@ -77,6 +77,11 @@
"description": "Whether to enable tsconfig strict mode or not.",
"default": true
},
"publishable": {
"type": "boolean",
"default": false,
"description": "Generate a publishable library."
},
"buildable": {
"type": "boolean",
"default": true,
Expand Down
3 changes: 2 additions & 1 deletion packages/js/src/utils/schema.d.ts
Expand Up @@ -8,7 +8,7 @@ import { TransformerEntry } from './typescript/types';

export type Compiler = 'tsc' | 'swc';

export interface GeneratorSchema {
export interface LibraryGeneratorSchema {
name: string;
directory?: string;
skipFormat?: boolean;
Expand All @@ -22,6 +22,7 @@ export interface GeneratorSchema {
js?: boolean;
pascalCaseFiles?: boolean;
strict?: boolean;
publishable?: boolean;
buildable?: boolean;
setParserOptionsProject?: boolean;
config?: 'workspace' | 'project' | 'npm-scripts';
Expand Down
6 changes: 4 additions & 2 deletions packages/js/src/utils/typescript/compile-typescript-files.ts
Expand Up @@ -12,7 +12,7 @@ import type {
} from 'typescript';
import { createAsyncIterable } from '../create-async-iterable/create-async-iteratable';
import { NormalizedExecutorOptions } from '../schema';
import { loadTsPlugins } from './load-ts-plugins';
import { loadTsTransformers } from './load-ts-transformers';

export async function* compileTypeScriptFiles(
normalizedOptions: NormalizedExecutorOptions,
Expand All @@ -24,7 +24,9 @@ export async function* compileTypeScriptFiles(
outfile: normalizedOptions.mainOutputPath,
});

const { compilerPluginHooks } = loadTsPlugins(normalizedOptions.transformers);
const { compilerPluginHooks } = loadTsTransformers(
normalizedOptions.transformers
);

const getCustomTransformers = (program: Program): CustomTransformers => ({
before: compilerPluginHooks.beforeHooks.map(
Expand Down
@@ -1,22 +1,22 @@
import { loadTsPlugins } from './load-ts-plugins';
import { loadTsTransformers } from './load-ts-transformers';

jest.mock('plugin-a');
jest.mock('plugin-b');
const mockRequireResolve = jest.fn((path) => path);

describe('loadTsPlugins', () => {
describe('loadTsTransformers', () => {
it('should return empty hooks if plugins is falsy', () => {
const result = loadTsPlugins(undefined);
const result = loadTsTransformers(undefined);
assertEmptyResult(result);
});

it('should return empty hooks if plugins is []', () => {
const result = loadTsPlugins([]);
const result = loadTsTransformers([]);
assertEmptyResult(result);
});

it('should return correct compiler hooks', () => {
const result = loadTsPlugins(
const result = loadTsTransformers(
['plugin-a', 'plugin-b'],
mockRequireResolve as any
);
Expand All @@ -29,7 +29,7 @@ describe('loadTsPlugins', () => {
});
});

function assertEmptyResult(result: ReturnType<typeof loadTsPlugins>) {
function assertEmptyResult(result: ReturnType<typeof loadTsTransformers>) {
expect(result.hasPlugin).toEqual(false);
expect(result.compilerPluginHooks).toEqual({
beforeHooks: [],
Expand Down
Expand Up @@ -3,11 +3,11 @@ import { join } from 'path';
import {
CompilerPlugin,
CompilerPluginHooks,
TransformerPlugin,
TransformerEntry,
TransformerPlugin,
} from './types';

export function loadTsPlugins(
export function loadTsTransformers(
plugins: TransformerEntry[],
moduleResolver: typeof require.resolve = require.resolve
): {
Expand Down
1 change: 1 addition & 0 deletions packages/nest/package.json
Expand Up @@ -32,6 +32,7 @@
"@nrwl/devkit": "*",
"@nrwl/linter": "*",
"@nrwl/node": "*",
"@nrwl/js": "*",
"@nrwl/jest": "*",
"@nestjs/schematics": "^8.0.0"
}
Expand Down
Expand Up @@ -9,11 +9,10 @@ exports[`lib --testEnvironment should set target jest testEnvironment to jsdom 1
tsconfig: '<rootDir>/tsconfig.spec.json',
}
},
testEnvironment: 'node',
transform: {
'^.+\\\\\\\\.[tj]sx?$': 'ts-jest'
'^.+\\\\\\\\.[tj]s$': 'ts-jest'
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/my-lib'
};
"
Expand All @@ -30,16 +29,19 @@ exports[`lib --testEnvironment should set target jest testEnvironment to node by
},
testEnvironment: 'node',
transform: {
'^.+\\\\\\\\.[tj]sx?$': 'ts-jest'
'^.+\\\\\\\\.[tj]s$': 'ts-jest'
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/my-lib'
};
"
`;

exports[`lib --unit-test-runner none should not generate test configuration 1`] = `
Object {
"compilerOptions": Object {
"module": "CommonJS",
},
"extends": "../../tsconfig.base.json",
"files": Array [],
"include": Array [],
Expand Down Expand Up @@ -67,6 +69,9 @@ Object {

exports[`lib nested should create a local tsconfig.json 1`] = `
Object {
"compilerOptions": Object {
"module": "CommonJS",
},
"extends": "../../../tsconfig.base.json",
"files": Array [],
"include": Array [],
Expand Down Expand Up @@ -96,6 +101,9 @@ export class MyLibModule {}

exports[`lib not nested should create a local tsconfig.json 1`] = `
Object {
"compilerOptions": Object {
"module": "CommonJS",
},
"extends": "../../tsconfig.base.json",
"files": Array [],
"include": Array [],
Expand Down

1 comment on commit 229f71e

@vercel
Copy link

@vercel vercel bot commented on 229f71e Mar 3, 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.