diff --git a/docs/generated/packages/node.json b/docs/generated/packages/node.json index b0b3126583..71e6fb4796 100644 --- a/docs/generated/packages/node.json +++ b/docs/generated/packages/node.json @@ -138,136 +138,6 @@ "implementation": "/packages/node/src/generators/application/application.ts", "hidden": false, "path": "/packages/node/src/generators/application/schema.json" - }, - { - "name": "library", - "factory": "./src/generators/library/library", - "schema": { - "$schema": "http://json-schema.org/schema", - "cli": "nx", - "$id": "NxNodeLibrary", - "title": "Create a Node Library for Nx", - "description": "Create a Node Library for an Nx workspace.", - "type": "object", - "examples": [ - { - "command": "nx g lib mylib --directory=myapp", - "description": "Generate `libs/myapp/mylib`" - } - ], - "properties": { - "name": { - "type": "string", - "description": "Library name", - "$default": { "$source": "argv", "index": 0 }, - "x-prompt": "What name would you like to use for the library?" - }, - "directory": { - "type": "string", - "description": "A directory where the lib is placed", - "alias": "dir" - }, - "simpleModuleName": { - "description": "Keep the module name simple (when using `--directory`).", - "type": "boolean", - "default": false - }, - "linter": { - "description": "The tool to use for running lint checks.", - "type": "string", - "enum": ["eslint"], - "default": "eslint" - }, - "unitTestRunner": { - "type": "string", - "enum": ["jest", "none"], - "description": "Test runner to use for unit tests.", - "default": "jest" - }, - "tags": { - "type": "string", - "description": "Add tags to the library (used for linting).", - "alias": "t" - }, - "skipFormat": { - "description": "Skip formatting files.", - "type": "boolean", - "default": false - }, - "skipTsConfig": { - "type": "boolean", - "default": false, - "description": "Do not update `tsconfig.base.json` for development experience." - }, - "publishable": { - "type": "boolean", - "description": "Create a publishable library." - }, - "buildable": { - "type": "boolean", - "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." - }, - "rootDir": { - "type": "string", - "description": "Sets the `rootDir` for TypeScript compilation. When not defined, it uses the project's root property, or `srcRootForCompilationRoot` if it is defined." - }, - "testEnvironment": { - "type": "string", - "enum": ["jsdom", "node"], - "description": "The test environment to use if `unitTestRunner` is set to `jest`.", - "default": "jsdom" - }, - "babelJest": { - "type": "boolean", - "description": "Use `babel` instead of `ts-jest`.", - "default": false - }, - "pascalCaseFiles": { - "type": "boolean", - "description": "Use pascal case file names.", - "alias": "P", - "default": false - }, - "js": { - "type": "boolean", - "description": "Generate JavaScript files rather than TypeScript files.", - "default": false - }, - "strict": { - "type": "boolean", - "description": "Whether to enable tsconfig strict mode or not.", - "default": false - }, - "standaloneConfig": { - "description": "Split the project configuration into `/project.json` rather than including it inside `workspace.json`.", - "type": "boolean" - }, - "setParserOptionsProject": { - "type": "boolean", - "description": "Whether or not to configure the ESLint `parserOptions.project`. We do not do this by default for lint performance reasons.", - "default": false - } - }, - "required": ["name"], - "presets": [] - }, - "aliases": ["lib"], - "x-type": "library", - "description": "Create a node library.", - "implementation": "/packages/node/src/generators/library/library.ts", - "hidden": false, - "path": "/packages/node/src/generators/library/schema.json" } ], "executors": [ diff --git a/docs/packages.json b/docs/packages.json index 05953b238e..15b125c0e8 100644 --- a/docs/packages.json +++ b/docs/packages.json @@ -248,7 +248,7 @@ "path": "generated/packages/node.json", "schemas": { "executors": ["webpack", "node"], - "generators": ["init", "application", "library"] + "generators": ["init", "application"] } }, { diff --git a/nx-dev/nx-dev-e2e/src/integration/packages.spec.ts b/nx-dev/nx-dev-e2e/src/integration/packages.spec.ts index 2a2735dec2..7f6d5b6adf 100644 --- a/nx-dev/nx-dev-e2e/src/integration/packages.spec.ts +++ b/nx-dev/nx-dev-e2e/src/integration/packages.spec.ts @@ -296,7 +296,6 @@ describe('nx-dev: Packages Section', () => { title: '@nrwl/node:application', path: '/packages/node/generators/application', }, - { title: '@nrwl/node:library', path: '/packages/node/generators/library' }, { title: '@nrwl/node:webpack', path: '/packages/node/executors/webpack' }, { title: '@nrwl/node:node', path: '/packages/node/executors/node' }, { title: 'nx', path: '/packages/nx' }, diff --git a/packages/node/generators.json b/packages/node/generators.json index 77bc307983..6ff3796c18 100644 --- a/packages/node/generators.json +++ b/packages/node/generators.json @@ -1,7 +1,7 @@ { "name": "nx/node", "version": "0.1", - "extends": ["@nrwl/workspace"], + "extends": ["@nrwl/js"], "generators": { "init": { "factory": "./src/generators/init/init", @@ -16,13 +16,6 @@ "aliases": ["app"], "x-type": "application", "description": "Create a node application." - }, - "library": { - "factory": "./src/generators/library/library", - "schema": "./src/generators/library/schema.json", - "aliases": ["lib"], - "x-type": "library", - "description": "Create a node library." } }, "schematics": { @@ -39,13 +32,6 @@ "aliases": ["app"], "x-type": "application", "description": "Create a node application." - }, - "library": { - "factory": "./src/generators/library/library#librarySchematic", - "schema": "./src/generators/library/schema.json", - "aliases": ["lib"], - "x-type": "library", - "description": "Create a node library." } } } diff --git a/packages/node/index.ts b/packages/node/index.ts index 642dd5b126..17f0a02049 100644 --- a/packages/node/index.ts +++ b/packages/node/index.ts @@ -1,3 +1,8 @@ +import { libraryGenerator } from '@nrwl/js'; + +// backwards compat +// TODO(jack): Remove in Nx 16 +export { libraryGenerator }; + export { applicationGenerator } from './src/generators/application/application'; -export { libraryGenerator } from './src/generators/library/library'; export { initGenerator } from './src/generators/init/init'; diff --git a/packages/node/src/generators/library/files/lib/package.json__tmpl__ b/packages/node/src/generators/library/files/lib/package.json__tmpl__ deleted file mode 100644 index e3a3ad83c4..0000000000 --- a/packages/node/src/generators/library/files/lib/package.json__tmpl__ +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "<%= importPath %>", - "version": "0.0.1" -} diff --git a/packages/node/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ b/packages/node/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ deleted file mode 100644 index 35b0948b95..0000000000 --- a/packages/node/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ +++ /dev/null @@ -1,7 +0,0 @@ -import { <%= propertyName %> } from './<%= fileName %>'; - -describe('<%= propertyName %>', () => { - it('should work', () => { - expect(<%= propertyName %>()).toEqual('<%= name %>'); - }) -}) \ No newline at end of file diff --git a/packages/node/src/generators/library/files/lib/src/lib/__fileName__.ts__tmpl__ b/packages/node/src/generators/library/files/lib/src/lib/__fileName__.ts__tmpl__ deleted file mode 100644 index 87f0f45f16..0000000000 --- a/packages/node/src/generators/library/files/lib/src/lib/__fileName__.ts__tmpl__ +++ /dev/null @@ -1,3 +0,0 @@ -export function <%= propertyName %>(): string { - return '<%= name %>'; -} \ No newline at end of file diff --git a/packages/node/src/generators/library/files/lib/tsconfig.lib.json b/packages/node/src/generators/library/files/lib/tsconfig.lib.json deleted file mode 100644 index fc6648159e..0000000000 --- a/packages/node/src/generators/library/files/lib/tsconfig.lib.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "outDir": "<%= offsetFromRoot %>dist/out-tsc", - "declaration": true, - "types": ["node"] - }, - "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"], - "include": ["**/*.ts"] -} diff --git a/packages/node/src/generators/library/library.spec.ts b/packages/node/src/generators/library/library.spec.ts deleted file mode 100644 index d986f20539..0000000000 --- a/packages/node/src/generators/library/library.spec.ts +++ /dev/null @@ -1,582 +0,0 @@ -import { - getProjects, - NxJsonConfiguration, - readJson, - readProjectConfiguration, - Tree, -} from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } 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; - - beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); - }); - - describe('not nested', () => { - it('should update workspace.json', async () => { - 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(); - expect(workspaceJson.projects['my-lib'].architect.lint).toEqual({ - builder: '@nrwl/linter:eslint', - outputs: ['{options.outputFile}'], - options: { - lintFilePatterns: ['libs/my-lib/**/*.ts'], - }, - }); - expect(workspaceJson.projects['my-lib'].architect.test).toEqual({ - builder: '@nrwl/jest:jest', - outputs: ['{workspaceRoot}/coverage/{projectRoot}'], - options: { - jestConfig: 'libs/my-lib/jest.config.ts', - passWithNoTests: true, - }, - }); - }); - - it('adds srcRootForCompilationRoot in workspace.json', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - rootDir: './src', - buildable: true, - }); - const workspaceJson = readJson(tree, '/workspace.json'); - expect( - workspaceJson.projects['my-lib'].architect.build.options - .srcRootForCompilationRoot - ).toEqual('./src'); - }); - - it('should update tags', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - tags: 'one,two', - }); - const projects = Object.fromEntries(getProjects(tree)); - expect(projects).toMatchObject({ - 'my-lib': { - tags: ['one', 'two'], - }, - }); - }); - - it('should update root tsconfig.base.json', async () => { - 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', - ]); - }); - - it('should create a local tsconfig.json', async () => { - await libraryGenerator(tree, baseLibraryConfig); - const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json'); - expect(tsconfigJson).toMatchInlineSnapshot(` - Object { - "extends": "../../tsconfig.base.json", - "files": Array [], - "include": Array [], - "references": Array [ - Object { - "path": "./tsconfig.lib.json", - }, - Object { - "path": "./tsconfig.spec.json", - }, - ], - } - `); - }); - - it('should extend the local tsconfig.json with tsconfig.spec.json', async () => { - 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, 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, baseLibraryConfig); - const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json'); - expect(tsconfigJson.exclude).toEqual([ - 'jest.config.ts', - '**/*.spec.ts', - '**/*.test.ts', - ]); - }); - - it('should generate files', async () => { - await libraryGenerator(tree, baseLibraryConfig); - expect(tree.exists(`libs/my-lib/jest.config.ts`)).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy(); - - const eslintrc = readJson(tree, 'libs/my-lib/.eslintrc.json'); - expect(eslintrc).toMatchInlineSnapshot(` - Object { - "extends": Array [ - "../../.eslintrc.json", - ], - "ignorePatterns": Array [ - "!**/*", - ], - "overrides": Array [ - Object { - "files": Array [ - "*.ts", - "*.tsx", - "*.js", - "*.jsx", - ], - "rules": Object {}, - }, - Object { - "files": Array [ - "*.ts", - "*.tsx", - ], - "rules": Object {}, - }, - Object { - "files": Array [ - "*.js", - "*.jsx", - ], - "rules": Object {}, - }, - ], - } - `); - }); - }); - - describe('nested', () => { - it('should update tags', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - tags: 'one', - }); - let projects = Object.fromEntries(getProjects(tree)); - expect(projects).toMatchObject({ - 'my-dir-my-lib': { - tags: ['one'], - }, - }); - - await libraryGenerator(tree, { - ...baseLibraryConfig, - name: 'myLib2', - directory: 'myDir', - tags: 'one,two', - }); - projects = Object.fromEntries(getProjects(tree)); - expect(projects).toMatchObject({ - 'my-dir-my-lib': { - tags: ['one'], - }, - 'my-dir-my-lib2': { - tags: ['one', 'two'], - }, - }); - }); - - it('should generate files', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - }); - expect(tree.exists(`libs/my-dir/my-lib/jest.config.ts`)).toBeTruthy(); - expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy(); - }); - - it('should update workspace.json', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - }); - const workspaceJson = readJson(tree, '/workspace.json'); - - expect(workspaceJson.projects['my-dir-my-lib'].root).toEqual( - 'libs/my-dir/my-lib' - ); - expect(workspaceJson.projects['my-dir-my-lib'].architect.lint).toEqual({ - builder: '@nrwl/linter:eslint', - outputs: ['{options.outputFile}'], - options: { - lintFilePatterns: ['libs/my-dir/my-lib/**/*.ts'], - }, - }); - }); - - it('should update tsconfig.json', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - }); - const tsconfigJson = readJson(tree, '/tsconfig.base.json'); - expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual( - ['libs/my-dir/my-lib/src/index.ts'] - ); - expect( - tsconfigJson.compilerOptions.paths['my-dir-my-lib/*'] - ).toBeUndefined(); - }); - - it('should throw an exception when not passing importPath when using --publishable', async () => { - expect.assertions(1); - - try { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - publishable: true, - }); - } catch (e) { - expect(e.message).toContain( - '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)' - ); - } - }); - - it('should create a local tsconfig.json', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - }); - - const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json'); - expect(tsconfigJson.extends).toEqual('../../../tsconfig.base.json'); - expect(tsconfigJson.references).toEqual([ - { - path: './tsconfig.lib.json', - }, - { - path: './tsconfig.spec.json', - }, - ]); - }); - - it('should generate filenames that do not contain directory with --simpleModuleName', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - directory: 'myDir', - simpleModuleName: true, - }); - expect(tree.exists(`libs/my-dir/my-lib/jest.config.ts`)).toBeTruthy(); - expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy(); - expect(tree.exists('libs/my-dir/my-lib/src/lib/my-lib.ts')).toBeTruthy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/my-lib.spec.ts') - ).toBeTruthy(); - expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy(); - expect(tree.exists(`libs/my-dir/my-lib/.eslintrc.json`)).toBeTruthy(); - }); - }); - - 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, { - ...baseLibraryConfig, - unitTestRunner: 'none', - }); - expect(tree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy(); - expect(tree.exists('libs/my-lib/jest.config.ts')).toBeFalsy(); - expect(tree.exists('libs/my-lib/lib/my-lib.spec.ts')).toBeFalsy(); - const workspaceJson = readJson(tree, 'workspace.json'); - expect(workspaceJson.projects['my-lib'].architect.test).toBeUndefined(); - const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json'); - expect(tsconfigJson.extends).toEqual('../../tsconfig.base.json'); - expect(tsconfigJson.references).toEqual([ - { - path: './tsconfig.lib.json', - }, - ]); - expect(workspaceJson.projects['my-lib'].architect.lint) - .toMatchInlineSnapshot(` - Object { - "builder": "@nrwl/linter:eslint", - "options": Object { - "lintFilePatterns": Array [ - "libs/my-lib/**/*.ts", - ], - }, - "outputs": Array [ - "{options.outputFile}", - ], - } - `); - }); - }); - - describe('buildable package', () => { - it('should have a builder defined', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - buildable: true, - }); - const workspaceJson = readJson(tree, '/workspace.json'); - - expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib'); - - expect(workspaceJson.projects['my-lib'].architect.build) - .toMatchInlineSnapshot(` - Object { - "builder": "@nrwl/js:tsc", - "options": Object { - "assets": Array [ - "libs/my-lib/*.md", - ], - "main": "libs/my-lib/src/index.ts", - "outputPath": "dist/libs/my-lib", - "packageJson": "libs/my-lib/package.json", - "tsConfig": "libs/my-lib/tsconfig.lib.json", - }, - "outputs": Array [ - "{options.outputPath}", - ], - } - `); - }); - }); - - describe('publishable package', () => { - it('should have a builder defined', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - publishable: true, - importPath: '@proj/mylib', - }); - const workspaceJson = readJson(tree, '/workspace.json'); - - expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib'); - - expect(workspaceJson.projects['my-lib'].architect.build).toBeDefined(); - }); - - it('should update package.json', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - name: 'mylib', - publishable: true, - importPath: '@proj/mylib', - }); - - let packageJsonContent = readJson(tree, 'libs/mylib/package.json'); - - expect(packageJsonContent.name).toEqual('@proj/mylib'); - }); - }); - - describe('--importPath', () => { - it('should update the package.json & tsconfig with the given import path', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - publishable: true, - directory: 'myDir', - importPath: '@myorg/lib', - }); - const packageJson = readJson(tree, 'libs/my-dir/my-lib/package.json'); - const tsconfigJson = readJson(tree, '/tsconfig.base.json'); - - expect(packageJson.name).toBe('@myorg/lib'); - expect( - tsconfigJson.compilerOptions.paths[packageJson.name] - ).toBeDefined(); - }); - - it('should fail if the same importPath has already been used', async () => { - await libraryGenerator(tree, { - ...baseLibraryConfig, - name: 'myLib1', - publishable: true, - importPath: '@myorg/lib', - }); - - try { - await libraryGenerator(tree, { - ...baseLibraryConfig, - name: 'myLib2', - publishable: true, - importPath: '@myorg/lib', - }); - } catch (e) { - expect(e.message).toContain( - 'You already have a library using the import path' - ); - } - - expect.assertions(1); - }); - }); - - describe(`--babelJest`, () => { - it('should use babel for jest', async () => { - await libraryGenerator(tree, { - name: 'myLib', - babelJest: true, - } as Schema); - - expect(tree.read(`libs/my-lib/jest.config.ts`, 'utf-8')) - .toMatchInlineSnapshot(` - "/* eslint-disable */ - export default { - displayName: 'my-lib', - preset: '../../jest.preset.js', - testEnvironment: 'node', - transform: { - '^.+\\\\\\\\.[tj]sx?$': 'babel-jest' - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/libs/my-lib' - }; - " - `); - }); - }); - describe('--js flag', () => { - it('should generate js files instead of ts files', async () => { - await libraryGenerator(tree, { - name: 'myLib', - js: true, - } as Schema); - - expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/index.js')).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/lib/my-lib.js')).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/lib/my-lib.spec.js')).toBeTruthy(); - - expect( - readJson(tree, 'libs/my-lib/tsconfig.json').compilerOptions - ).toEqual({ - allowJs: true, - }); - expect(readJson(tree, 'libs/my-lib/tsconfig.lib.json').include).toEqual([ - '**/*.ts', - '**/*.js', - ]); - expect(readJson(tree, 'libs/my-lib/tsconfig.lib.json').exclude).toEqual([ - 'jest.config.ts', - '**/*.spec.ts', - '**/*.test.ts', - '**/*.spec.js', - '**/*.test.js', - ]); - }); - - it('should update root tsconfig.json with a js file path', async () => { - await libraryGenerator(tree, { name: 'myLib', js: true } as Schema); - const tsconfigJson = readJson(tree, '/tsconfig.base.json'); - expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([ - 'libs/my-lib/src/index.js', - ]); - }); - - it('should update architect builder when --buildable', async () => { - await libraryGenerator(tree, { - name: 'myLib', - buildable: true, - js: true, - } as Schema); - const workspaceJson = readJson(tree, '/workspace.json'); - - expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib'); - - expect( - workspaceJson.projects['my-lib'].architect.build.options.main - ).toEqual('libs/my-lib/src/index.js'); - }); - - it('should generate js files for nested libs as well', async () => { - await libraryGenerator(tree, { - name: 'myLib', - directory: 'myDir', - js: true, - } as Schema); - expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy(); - expect(tree.exists('libs/my-dir/my-lib/src/index.js')).toBeTruthy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.js') - ).toBeTruthy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.spec.js') - ).toBeTruthy(); - }); - }); - - describe('--pascalCaseFiles', () => { - it('should generate files with upper case names', async () => { - await libraryGenerator(tree, { - name: 'myLib', - pascalCaseFiles: true, - } as Schema); - expect(tree.exists('libs/my-lib/src/lib/MyLib.ts')).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/lib/MyLib.spec.ts')).toBeTruthy(); - expect(tree.exists('libs/my-lib/src/lib/my-lib.spec.ts')).toBeFalsy(); - expect(tree.exists('libs/my-lib/src/lib/my-lib.ts')).toBeFalsy(); - }); - - it('should generate files with upper case names for nested libs as well', async () => { - await libraryGenerator(tree, { - name: 'myLib', - directory: 'myDir', - pascalCaseFiles: true, - } as Schema); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/MyDirMyLib.ts') - ).toBeTruthy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/MyDirMyLib.spec.ts') - ).toBeTruthy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.ts') - ).toBeFalsy(); - expect( - tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.spec.ts') - ).toBeFalsy(); - }); - }); -}); diff --git a/packages/node/src/generators/library/library.ts b/packages/node/src/generators/library/library.ts deleted file mode 100644 index 5e987ea36b..0000000000 --- a/packages/node/src/generators/library/library.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { - convertNxGenerator, - formatFiles, - generateFiles, - getWorkspaceLayout, - joinPathFragments, - names, - offsetFromRoot, - readProjectConfiguration, - toJS, - Tree, - updateProjectConfiguration, - updateTsConfigsToJs, -} from '@nrwl/devkit'; -import { getImportPath } from 'nx/src/utils/path'; -import { Schema } from './schema'; -import { libraryGenerator as workspaceLibraryGenerator } from '@nrwl/workspace/generators'; -import { join } from 'path'; - -export interface NormalizedSchema extends Schema { - name: string; - prefix: string; - fileName: string; - projectRoot: string; - projectDirectory: string; - parsedTags: string[]; - compiler: 'swc' | 'tsc'; -} - -export async function libraryGenerator(tree: Tree, schema: Schema) { - const options = normalizeOptions(tree, schema); - - if (options.publishable === true && !schema.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)` - ); - } - - const libraryInstall = await workspaceLibraryGenerator(tree, { - ...schema, - importPath: options.importPath, - testEnvironment: 'node', - skipFormat: true, - setParserOptionsProject: options.setParserOptionsProject, - }); - createFiles(tree, options); - - if (options.js) { - updateTsConfigsToJs(tree, options); - } - updateProject(tree, options); - - if (!schema.skipFormat) { - await formatFiles(tree); - } - - return libraryInstall; -} - -export default libraryGenerator; -export const librarySchematic = convertNxGenerator(libraryGenerator); - -function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema { - const { npmScope, libsDir } = getWorkspaceLayout(tree); - const name = names(options.name).fileName; - const projectDirectory = options.directory - ? `${names(options.directory).fileName}/${name}` - : name; - - const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-'); - const fileName = getCaseAwareFileName({ - fileName: options.simpleModuleName ? name : projectName, - pascalCaseFiles: options.pascalCaseFiles, - }); - const projectRoot = joinPathFragments(libsDir, projectDirectory); - - const parsedTags = options.tags - ? options.tags.split(',').map((s) => s.trim()) - : []; - - const importPath = - options.importPath || getImportPath(npmScope, projectDirectory); - - return { - ...options, - prefix: npmScope, // we could also allow customizing this - fileName, - name: projectName, - projectRoot, - projectDirectory, - parsedTags, - importPath, - }; -} - -function getCaseAwareFileName(options: { - pascalCaseFiles: boolean; - fileName: string; -}) { - const normalized = names(options.fileName); - - return options.pascalCaseFiles ? normalized.className : normalized.fileName; -} - -function createFiles(tree: Tree, options: NormalizedSchema) { - const { className, name, propertyName } = names(options.fileName); - - generateFiles(tree, join(__dirname, './files/lib'), options.projectRoot, { - ...options, - className, - name, - propertyName, - tmpl: '', - offsetFromRoot: offsetFromRoot(options.projectRoot), - }); - - if (options.unitTestRunner === 'none') { - tree.delete( - join(options.projectRoot, `./src/lib/${options.fileName}.spec.ts`) - ); - } - if (!options.publishable && !options.buildable) { - tree.delete(join(options.projectRoot, 'package.json')); - } - if (options.js) { - toJS(tree); - } -} - -function updateProject(tree: Tree, options: NormalizedSchema) { - if (!options.publishable && !options.buildable) { - return; - } - - const project = readProjectConfiguration(tree, options.name); - const { libsDir } = getWorkspaceLayout(tree); - - project.targets = project.targets || {}; - project.targets.build = { - executor: `@nrwl/js:${options.compiler}`, - outputs: ['{options.outputPath}'], - options: { - outputPath: `dist/${libsDir}/${options.projectDirectory}`, - tsConfig: `${options.projectRoot}/tsconfig.lib.json`, - packageJson: `${options.projectRoot}/package.json`, - main: `${options.projectRoot}/src/index` + (options.js ? '.js' : '.ts'), - assets: [`${options.projectRoot}/*.md`], - }, - }; - - if (options.rootDir) { - project.targets.build.options.srcRootForCompilationRoot = options.rootDir; - } - - updateProjectConfiguration(tree, options.name, project); -} diff --git a/packages/node/src/generators/library/schema.d.ts b/packages/node/src/generators/library/schema.d.ts deleted file mode 100644 index 682a1c3a1e..0000000000 --- a/packages/node/src/generators/library/schema.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Linter } from '@nrwl/linter'; - -export interface Schema { - name: string; - directory?: string; - simpleModuleName?: boolean; - skipTsConfig?: boolean; - skipFormat?: boolean; - tags?: string; - unitTestRunner?: 'jest' | 'none'; - linter?: Linter; - buildable?: boolean; - publishable?: boolean; - importPath?: string; - testEnvironment?: 'jsdom' | 'node'; - rootDir?: string; - babelJest?: boolean; - js?: boolean; - pascalCaseFiles?: boolean; - 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 deleted file mode 100644 index d0100170fa..0000000000 --- a/packages/node/src/generators/library/schema.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "cli": "nx", - "$id": "NxNodeLibrary", - "title": "Create a Node Library for Nx", - "description": "Create a Node Library for an Nx workspace.", - "type": "object", - "examples": [ - { - "command": "nx g lib mylib --directory=myapp", - "description": "Generate `libs/myapp/mylib`" - } - ], - "properties": { - "name": { - "type": "string", - "description": "Library name", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "What name would you like to use for the library?" - }, - "directory": { - "type": "string", - "description": "A directory where the lib is placed", - "alias": "dir" - }, - "simpleModuleName": { - "description": "Keep the module name simple (when using `--directory`).", - "type": "boolean", - "default": false - }, - "linter": { - "description": "The tool to use for running lint checks.", - "type": "string", - "enum": ["eslint"], - "default": "eslint" - }, - "unitTestRunner": { - "type": "string", - "enum": ["jest", "none"], - "description": "Test runner to use for unit tests.", - "default": "jest" - }, - "tags": { - "type": "string", - "description": "Add tags to the library (used for linting).", - "alias": "t" - }, - "skipFormat": { - "description": "Skip formatting files.", - "type": "boolean", - "default": false - }, - "skipTsConfig": { - "type": "boolean", - "default": false, - "description": "Do not update `tsconfig.base.json` for development experience." - }, - "publishable": { - "type": "boolean", - "description": "Create a publishable library." - }, - "buildable": { - "type": "boolean", - "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." - }, - "rootDir": { - "type": "string", - "description": "Sets the `rootDir` for TypeScript compilation. When not defined, it uses the project's root property, or `srcRootForCompilationRoot` if it is defined." - }, - "testEnvironment": { - "type": "string", - "enum": ["jsdom", "node"], - "description": "The test environment to use if `unitTestRunner` is set to `jest`.", - "default": "jsdom" - }, - "babelJest": { - "type": "boolean", - "description": "Use `babel` instead of `ts-jest`.", - "default": false - }, - "pascalCaseFiles": { - "type": "boolean", - "description": "Use pascal case file names.", - "alias": "P", - "default": false - }, - "js": { - "type": "boolean", - "description": "Generate JavaScript files rather than TypeScript files.", - "default": false - }, - "strict": { - "type": "boolean", - "description": "Whether to enable tsconfig strict mode or not.", - "default": false - }, - "standaloneConfig": { - "description": "Split the project configuration into `/project.json` rather than including it inside `workspace.json`.", - "type": "boolean" - }, - "setParserOptionsProject": { - "type": "boolean", - "description": "Whether or not to configure the ESLint `parserOptions.project`. We do not do this by default for lint performance reasons.", - "default": false - } - }, - "required": ["name"] -}