From 7deb0c11bb32d5fb8d1b9a121c28ef99eec4c016 Mon Sep 17 00:00:00 2001 From: Jeffrey Bosch Date: Sun, 27 Oct 2024 09:10:32 +0100 Subject: [PATCH 1/4] feat: add secondary entrypoint schematic --- packages/schematics/angular/collection.json | 6 + .../files/README.md.template | 3 + .../files/ng-package.json.template | 6 + .../files/src/__entryFile__.ts.template | 5 + .../angular/secondary-entrypoint/index.ts | 96 ++++++++++ .../secondary-entrypoint/index_spec.ts | 164 ++++++++++++++++++ .../angular/secondary-entrypoint/schema.json | 34 ++++ 7 files changed, 314 insertions(+) create mode 100644 packages/schematics/angular/secondary-entrypoint/files/README.md.template create mode 100644 packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template create mode 100644 packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template create mode 100644 packages/schematics/angular/secondary-entrypoint/index.ts create mode 100644 packages/schematics/angular/secondary-entrypoint/index_spec.ts create mode 100644 packages/schematics/angular/secondary-entrypoint/schema.json diff --git a/packages/schematics/angular/collection.json b/packages/schematics/angular/collection.json index 5f691819544f..fc852bb454e3 100755 --- a/packages/schematics/angular/collection.json +++ b/packages/schematics/angular/collection.json @@ -117,6 +117,12 @@ "schema": "./library/schema.json", "description": "Generate a library project for Angular." }, + "library-secondary-entrypoint": { + "aliases": ["secondary"], + "factory": "./secondary-entrypoint", + "schema": "./secondary-entrypoint/schema.json", + "description": "Generate a secondary-entrypoint in a library project for Angular." + }, "web-worker": { "factory": "./web-worker", "schema": "./web-worker/schema.json", diff --git a/packages/schematics/angular/secondary-entrypoint/files/README.md.template b/packages/schematics/angular/secondary-entrypoint/files/README.md.template new file mode 100644 index 000000000000..f53f6d471f96 --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/files/README.md.template @@ -0,0 +1,3 @@ +# <%= secondaryEntryPoint %> + +Secondary entry point of `<%= mainEntryPoint %>`. It can be used by importing from `<%= secondaryEntryPoint %>`. diff --git a/packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template b/packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template new file mode 100644 index 000000000000..32bf2a8ebc81 --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template @@ -0,0 +1,6 @@ +{ + "$schema": "<%= relativePathToWorkspaceRoot %>/node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "src/<%= entryFile %>.ts" + } +} \ No newline at end of file diff --git a/packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template b/packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template new file mode 100644 index 000000000000..b2b6bd17ce62 --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template @@ -0,0 +1,5 @@ +/* + * Public API Surface of <%= dasherize(name) %> + */ + +export const greeting = 'Hello Angular World!'; \ No newline at end of file diff --git a/packages/schematics/angular/secondary-entrypoint/index.ts b/packages/schematics/angular/secondary-entrypoint/index.ts new file mode 100644 index 000000000000..c6482370843c --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/index.ts @@ -0,0 +1,96 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { + Rule, + SchematicsException, + Tree, + apply, + applyTemplates, + chain, + mergeWith, + move, + strings, + url, +} from '@angular-devkit/schematics'; +import { JSONFile } from '../utility/json-file'; +import { latestVersions } from '../utility/latest-versions'; +import { relativePathToWorkspaceRoot } from '../utility/paths'; +import { buildDefaultPath, getWorkspace } from '../utility/workspace'; +import { ProjectType } from '../utility/workspace-models'; +import { Schema as LibraryOptions } from './schema'; + +function updateTsConfig(packageName: string, ...paths: string[]) { + return (host: Tree) => { + if (!host.exists('tsconfig.json')) { + return host; + } + + const file = new JSONFile(host, 'tsconfig.json'); + const jsonPath = ['compilerOptions', 'paths', packageName]; + const value = file.get(jsonPath); + file.modify(jsonPath, Array.isArray(value) ? [...value, ...paths] : paths); + }; +} + +export default function (options: LibraryOptions): Rule { + return async (host: Tree) => { + return async (host: Tree) => { + const workspace = await getWorkspace(host); + const project = workspace.projects.get(options.project); + + if (!project) { + throw new SchematicsException(`Project "${options.project}" does not exist.`); + } + + if (project?.extensions.projectType !== ProjectType.Library) { + throw new SchematicsException( + `Secondary Entrypoint schematic requires a project type of "library".`, + ); + } + + const path = buildDefaultPath(project); + const libDir = `${path}/${options.name}`; + const pkgPath = `${project.root}/package.json`; + + const pkg = host.readJson(pkgPath) as { name: string } | null; + if (pkg === null) { + throw new SchematicsException('Could not find package.json'); + } + + const mainEntryPoint = pkg.name; + const secondaryEntryPoint = `${mainEntryPoint}/${options.name}`; + + let folderName = mainEntryPoint.startsWith('@') ? mainEntryPoint.slice(1) : mainEntryPoint; + if (/[A-Z]/.test(folderName)) { + folderName = strings.dasherize(folderName); + } + + const distRoot = `dist/${folderName}/${options.name}`; + + const templateSource = apply(url('./files'), [ + applyTemplates({ + ...strings, + ...options, + mainEntryPoint, + secondaryEntryPoint, + relativePathToWorkspaceRoot: relativePathToWorkspaceRoot(libDir), + packageName: options.name, + angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''), + tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''), + }), + move(libDir), + ]); + + return chain([ + mergeWith(templateSource), + updateTsConfig(secondaryEntryPoint, './' + distRoot), + ]); + }; + }; +} diff --git a/packages/schematics/angular/secondary-entrypoint/index_spec.ts b/packages/schematics/angular/secondary-entrypoint/index_spec.ts new file mode 100644 index 000000000000..e4193148a714 --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/index_spec.ts @@ -0,0 +1,164 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { Schema as LibraryOptions } from '../library/schema'; +import { Schema as WorkspaceOptions } from '../workspace/schema'; +import { Schema as GenerateLibrarySchema } from './schema'; +import { parse as parseJson } from 'jsonc-parser'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getJsonFileContent(tree: UnitTestTree, path: string): any { + return parseJson(tree.readContent(path).toString()); +} + +describe('Secondary Entrypoint Schematic', () => { + const schematicRunner = new SchematicTestRunner( + '@schematics/ng_packagr', + require.resolve('../collection.json'), + ); + const defaultOptions: GenerateLibrarySchema = { + name: 'foo-secondary', + project: 'foo', + }; + + const workspaceOptions: WorkspaceOptions = { + name: 'workspace', + newProjectRoot: 'projects', + + version: '6.0.0', + }; + const libaryOptions: LibraryOptions = { + name: 'foo', + entryFile: 'my-index', + standalone: true, + skipPackageJson: false, + skipTsConfig: false, + skipInstall: false, + }; + + let workspaceTree: UnitTestTree; + beforeEach(async () => { + workspaceTree = await schematicRunner.runSchematic('workspace', workspaceOptions); + }); + + it('should create correct files', async () => { + workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions }, + workspaceTree, + ); + const files = tree.files; + + expect(files).toEqual( + jasmine.arrayContaining([ + '/projects/foo/src/lib/foo-secondary/README.md', + '/projects/foo/src/lib/foo-secondary/ng-package.json', + '/projects/foo/src/lib/foo-secondary/src/public-api.ts', + ]), + ); + }); + + it('should set correct main and secondary entrypoints in the README', async () => { + workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions }, + workspaceTree, + ); + const content = tree.readContent('/projects/foo/src/lib/foo-secondary/README.md'); + expect(content).toMatch('# foo/foo-secondary'); + }); + + it('should set a custom entryfile', async () => { + workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions, entryFile: 'my-index' }, + workspaceTree, + ); + const files = tree.files; + expect(files).toEqual( + jasmine.arrayContaining([ + '/projects/foo/src/lib/foo-secondary/README.md', + '/projects/foo/src/lib/foo-secondary/ng-package.json', + '/projects/foo/src/lib/foo-secondary/src/my-index.ts', + ]), + ); + }); + + it('should handle scope packages', async () => { + workspaceTree = await schematicRunner.runSchematic( + 'library', + { ...libaryOptions, name: '@scope/package' }, + workspaceTree, + ); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions, name: 'testing', project: '@scope/package' }, + workspaceTree, + ); + const files = tree.files; + expect(files).toEqual( + jasmine.arrayContaining([ + '/projects/scope/package/src/lib/testing/README.md', + '/projects/scope/package/src/lib/testing/ng-package.json', + '/projects/scope/package/src/lib/testing/src/public-api.ts', + ]), + ); + }); + + it(`should add paths mapping to the tsconfig`, async () => { + workspaceTree = await schematicRunner.runSchematic( + 'library', + { ...libaryOptions, name: '@scope/package' }, + workspaceTree, + ); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions, name: 'testing', project: '@scope/package' }, + workspaceTree, + ); + + const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json'); + expect(tsConfigJson.compilerOptions.paths['@scope/package/testing']).toEqual([ + './dist/scope/package/testing', + ]); + }); + + it(`should append to existing paths mappings`, async () => { + workspaceTree = await schematicRunner.runSchematic( + 'library', + { ...libaryOptions, name: '@scope/package' }, + workspaceTree, + ); + workspaceTree.overwrite( + 'tsconfig.json', + JSON.stringify({ + compilerOptions: { + paths: { + 'unrelated': ['./something/else.ts'], + '@scope/package/testing': ['libs/*'], + }, + }, + }), + ); + const tree = await schematicRunner.runSchematic( + 'secondary', + { ...defaultOptions, name: 'testing', project: '@scope/package' }, + workspaceTree, + ); + + const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json'); + expect(tsConfigJson.compilerOptions.paths['@scope/package/testing']).toEqual([ + 'libs/*', + './dist/scope/package/testing', + ]); + }); +}); diff --git a/packages/schematics/angular/secondary-entrypoint/schema.json b/packages/schematics/angular/secondary-entrypoint/schema.json new file mode 100644 index 000000000000..218e2db38139 --- /dev/null +++ b/packages/schematics/angular/secondary-entrypoint/schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "SchematicsLibrary", + "title": "Secondary Entrypoint Schema", + "type": "object", + "description": "Creates a secondary entrypoint in a library project in a project.", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the library.", + "pattern": "^(?:@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*/)?[a-zA-Z0-9-~][a-zA-Z0-9-._~]*$", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "What name would you like to use for the secondary entrypoint?" + }, + "project": { + "type": "string", + "description": "The name of the project.", + "$default": { + "$source": "projectName" + } + }, + "entryFile": { + "type": "string", + "format": "path", + "description": "The path at which to create the library's secondary public API file, relative to the workspace root.", + "default": "public-api" + } + }, + "required": ["name", "project"] +} From fa0daa33fc774a67c8c828f6bd0d42fe487a1c79 Mon Sep 17 00:00:00 2001 From: Jeffrey Bosch Date: Mon, 13 Jan 2025 20:44:48 +0100 Subject: [PATCH 2/4] refactor(@schematics/angular): improve feedback --- .../angular/cli/lib/config/workspace-schema.json | 3 +++ packages/schematics/angular/collection.json | 10 +++++----- .../files/README.md.template | 0 .../files/ng-package.json.template | 0 .../files/src/__entryFile__.ts.template | 0 .../index.ts | 7 ++----- .../index_spec.ts | 0 .../schema.json | 15 +++++++++------ .../e2e/tests/build/library-with-demo-app.ts | 3 ++- 9 files changed, 21 insertions(+), 17 deletions(-) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/files/README.md.template (100%) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/files/ng-package.json.template (100%) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/files/src/__entryFile__.ts.template (100%) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/index.ts (87%) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/index_spec.ts (100%) rename packages/schematics/angular/{secondary-entrypoint => library-entrypoint}/schema.json (68%) diff --git a/packages/angular/cli/lib/config/workspace-schema.json b/packages/angular/cli/lib/config/workspace-schema.json index 5fe427d4f415..d2427532c050 100644 --- a/packages/angular/cli/lib/config/workspace-schema.json +++ b/packages/angular/cli/lib/config/workspace-schema.json @@ -162,6 +162,9 @@ "@schematics/angular:library": { "$ref": "../../../../schematics/angular/library/schema.json" }, + "@schematics/angular:library-entrypoint": { + "$ref": "../../../../schematics/angular/library-entrypoint/schema.json" + }, "@schematics/angular:pipe": { "$ref": "../../../../schematics/angular/pipe/schema.json" }, diff --git a/packages/schematics/angular/collection.json b/packages/schematics/angular/collection.json index fc852bb454e3..5f66adbd771f 100755 --- a/packages/schematics/angular/collection.json +++ b/packages/schematics/angular/collection.json @@ -117,11 +117,11 @@ "schema": "./library/schema.json", "description": "Generate a library project for Angular." }, - "library-secondary-entrypoint": { - "aliases": ["secondary"], - "factory": "./secondary-entrypoint", - "schema": "./secondary-entrypoint/schema.json", - "description": "Generate a secondary-entrypoint in a library project for Angular." + "library-entrypoint": { + "aliases": ["lib-entry"], + "factory": "./library-entrypoint", + "schema": "./library-entrypoint/schema.json", + "description": "Generate an library-entrypoint in an Angular library project." }, "web-worker": { "factory": "./web-worker", diff --git a/packages/schematics/angular/secondary-entrypoint/files/README.md.template b/packages/schematics/angular/library-entrypoint/files/README.md.template similarity index 100% rename from packages/schematics/angular/secondary-entrypoint/files/README.md.template rename to packages/schematics/angular/library-entrypoint/files/README.md.template diff --git a/packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template b/packages/schematics/angular/library-entrypoint/files/ng-package.json.template similarity index 100% rename from packages/schematics/angular/secondary-entrypoint/files/ng-package.json.template rename to packages/schematics/angular/library-entrypoint/files/ng-package.json.template diff --git a/packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template b/packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template similarity index 100% rename from packages/schematics/angular/secondary-entrypoint/files/src/__entryFile__.ts.template rename to packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template diff --git a/packages/schematics/angular/secondary-entrypoint/index.ts b/packages/schematics/angular/library-entrypoint/index.ts similarity index 87% rename from packages/schematics/angular/secondary-entrypoint/index.ts rename to packages/schematics/angular/library-entrypoint/index.ts index c6482370843c..0ec038d14c81 100644 --- a/packages/schematics/angular/secondary-entrypoint/index.ts +++ b/packages/schematics/angular/library-entrypoint/index.ts @@ -19,7 +19,6 @@ import { url, } from '@angular-devkit/schematics'; import { JSONFile } from '../utility/json-file'; -import { latestVersions } from '../utility/latest-versions'; import { relativePathToWorkspaceRoot } from '../utility/paths'; import { buildDefaultPath, getWorkspace } from '../utility/workspace'; import { ProjectType } from '../utility/workspace-models'; @@ -34,7 +33,7 @@ function updateTsConfig(packageName: string, ...paths: string[]) { const file = new JSONFile(host, 'tsconfig.json'); const jsonPath = ['compilerOptions', 'paths', packageName]; const value = file.get(jsonPath); - file.modify(jsonPath, Array.isArray(value) ? [...value, ...paths] : paths); + file.modify(jsonPath, Array.isArray(value) ? [...paths, ...value] : paths); }; } @@ -50,7 +49,7 @@ export default function (options: LibraryOptions): Rule { if (project?.extensions.projectType !== ProjectType.Library) { throw new SchematicsException( - `Secondary Entrypoint schematic requires a project type of "library".`, + `Library entrypoint schematic requires a project type of "library".`, ); } @@ -81,8 +80,6 @@ export default function (options: LibraryOptions): Rule { secondaryEntryPoint, relativePathToWorkspaceRoot: relativePathToWorkspaceRoot(libDir), packageName: options.name, - angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''), - tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''), }), move(libDir), ]); diff --git a/packages/schematics/angular/secondary-entrypoint/index_spec.ts b/packages/schematics/angular/library-entrypoint/index_spec.ts similarity index 100% rename from packages/schematics/angular/secondary-entrypoint/index_spec.ts rename to packages/schematics/angular/library-entrypoint/index_spec.ts diff --git a/packages/schematics/angular/secondary-entrypoint/schema.json b/packages/schematics/angular/library-entrypoint/schema.json similarity index 68% rename from packages/schematics/angular/secondary-entrypoint/schema.json rename to packages/schematics/angular/library-entrypoint/schema.json index 218e2db38139..e850df623ab7 100644 --- a/packages/schematics/angular/secondary-entrypoint/schema.json +++ b/packages/schematics/angular/library-entrypoint/schema.json @@ -1,20 +1,20 @@ { "$schema": "http://json-schema.org/draft-07/schema", "$id": "SchematicsLibrary", - "title": "Secondary Entrypoint Schema", + "title": "Library Entrypoint Schema", "type": "object", - "description": "Creates a secondary entrypoint in a library project in a project.", + "description": "Generate an library entrypoint in an Angular library project.", "additionalProperties": false, "properties": { "name": { "type": "string", "description": "The name of the library.", - "pattern": "^(?:@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*/)?[a-zA-Z0-9-~][a-zA-Z0-9-._~]*$", + "pattern": "^[a-zA-Z0-9-._~]+/?[a-zA-Z0-9-._~]+$", "$default": { "$source": "argv", "index": 0 }, - "x-prompt": "What name would you like to use for the secondary entrypoint?" + "x-prompt": "What name would you like to use for the entrypoint?" }, "project": { "type": "string", @@ -30,5 +30,8 @@ "default": "public-api" } }, - "required": ["name", "project"] -} + "required": [ + "name", + "project" + ] +} \ No newline at end of file diff --git a/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts b/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts index 8e8d14ceb54f..ae7bbdeac78c 100644 --- a/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts +++ b/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts @@ -12,7 +12,8 @@ import { updateJsonFile } from '../../utils/project'; export default async function () { await ng('generate', 'library', 'mylib'); - await createLibraryEntryPoint('secondary'); + await ng('generate', 'lib-entry', 'secondary'); + // await createLibraryEntryPoint('secondary'); await createLibraryEntryPoint('another'); // Scenario #1 where we use wildcard path mappings for secondary entry-points. From 57230d0ed84eebe3010fe52233a261d0d39a1945 Mon Sep 17 00:00:00 2001 From: Jeffrey Bosch Date: Sun, 2 Feb 2025 09:22:30 +0100 Subject: [PATCH 3/4] refactor: make small changes and excluded tests --- packages/schematics/angular/collection.json | 2 +- .../files/README.md.template | 2 +- .../files/src/__entryFile__.ts.template | 5 --- .../angular/library-entrypoint/index.ts | 4 ++- .../angular/library-entrypoint/index_spec.ts | 36 ++++--------------- .../angular/library-entrypoint/schema.json | 17 +++------ .../e2e/tests/build/library-with-demo-app.ts | 17 +-------- 7 files changed, 17 insertions(+), 66 deletions(-) delete mode 100644 packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template diff --git a/packages/schematics/angular/collection.json b/packages/schematics/angular/collection.json index 5f66adbd771f..1eb4c9f1ae9b 100755 --- a/packages/schematics/angular/collection.json +++ b/packages/schematics/angular/collection.json @@ -121,7 +121,7 @@ "aliases": ["lib-entry"], "factory": "./library-entrypoint", "schema": "./library-entrypoint/schema.json", - "description": "Generate an library-entrypoint in an Angular library project." + "description": "Generate a library-entrypoint in an Angular library project." }, "web-worker": { "factory": "./web-worker", diff --git a/packages/schematics/angular/library-entrypoint/files/README.md.template b/packages/schematics/angular/library-entrypoint/files/README.md.template index f53f6d471f96..1a1522b50d45 100644 --- a/packages/schematics/angular/library-entrypoint/files/README.md.template +++ b/packages/schematics/angular/library-entrypoint/files/README.md.template @@ -1,3 +1,3 @@ # <%= secondaryEntryPoint %> -Secondary entry point of `<%= mainEntryPoint %>`. It can be used by importing from `<%= secondaryEntryPoint %>`. +Secondary entry point of `<%= mainEntryPoint %>`. It can be used by importing from `<%= secondaryEntryPoint %>` \ No newline at end of file diff --git a/packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template b/packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template deleted file mode 100644 index b2b6bd17ce62..000000000000 --- a/packages/schematics/angular/library-entrypoint/files/src/__entryFile__.ts.template +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Public API Surface of <%= dasherize(name) %> - */ - -export const greeting = 'Hello Angular World!'; \ No newline at end of file diff --git a/packages/schematics/angular/library-entrypoint/index.ts b/packages/schematics/angular/library-entrypoint/index.ts index 0ec038d14c81..6d73ed12dd8d 100644 --- a/packages/schematics/angular/library-entrypoint/index.ts +++ b/packages/schematics/angular/library-entrypoint/index.ts @@ -59,7 +59,7 @@ export default function (options: LibraryOptions): Rule { const pkg = host.readJson(pkgPath) as { name: string } | null; if (pkg === null) { - throw new SchematicsException('Could not find package.json'); + throw new SchematicsException(`Could not find ${pkgPath}`); } const mainEntryPoint = pkg.name; @@ -80,6 +80,8 @@ export default function (options: LibraryOptions): Rule { secondaryEntryPoint, relativePathToWorkspaceRoot: relativePathToWorkspaceRoot(libDir), packageName: options.name, + //TODO: fix this + entryFile: 'index.ts', }), move(libDir), ]); diff --git a/packages/schematics/angular/library-entrypoint/index_spec.ts b/packages/schematics/angular/library-entrypoint/index_spec.ts index e4193148a714..ff725b8318e0 100644 --- a/packages/schematics/angular/library-entrypoint/index_spec.ts +++ b/packages/schematics/angular/library-entrypoint/index_spec.ts @@ -7,10 +7,10 @@ */ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { parse as parseJson } from 'jsonc-parser'; import { Schema as LibraryOptions } from '../library/schema'; import { Schema as WorkspaceOptions } from '../workspace/schema'; import { Schema as GenerateLibrarySchema } from './schema'; -import { parse as parseJson } from 'jsonc-parser'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function getJsonFileContent(tree: UnitTestTree, path: string): any { @@ -35,7 +35,6 @@ describe('Secondary Entrypoint Schematic', () => { }; const libaryOptions: LibraryOptions = { name: 'foo', - entryFile: 'my-index', standalone: true, skipPackageJson: false, skipTsConfig: false, @@ -45,12 +44,12 @@ describe('Secondary Entrypoint Schematic', () => { let workspaceTree: UnitTestTree; beforeEach(async () => { workspaceTree = await schematicRunner.runSchematic('workspace', workspaceOptions); + workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); }); it('should create correct files', async () => { - workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); const tree = await schematicRunner.runSchematic( - 'secondary', + 'library-entrypoint', { ...defaultOptions }, workspaceTree, ); @@ -60,15 +59,13 @@ describe('Secondary Entrypoint Schematic', () => { jasmine.arrayContaining([ '/projects/foo/src/lib/foo-secondary/README.md', '/projects/foo/src/lib/foo-secondary/ng-package.json', - '/projects/foo/src/lib/foo-secondary/src/public-api.ts', ]), ); }); it('should set correct main and secondary entrypoints in the README', async () => { - workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); const tree = await schematicRunner.runSchematic( - 'secondary', + 'library-entrypoint', { ...defaultOptions }, workspaceTree, ); @@ -76,23 +73,6 @@ describe('Secondary Entrypoint Schematic', () => { expect(content).toMatch('# foo/foo-secondary'); }); - it('should set a custom entryfile', async () => { - workspaceTree = await schematicRunner.runSchematic('library', libaryOptions, workspaceTree); - const tree = await schematicRunner.runSchematic( - 'secondary', - { ...defaultOptions, entryFile: 'my-index' }, - workspaceTree, - ); - const files = tree.files; - expect(files).toEqual( - jasmine.arrayContaining([ - '/projects/foo/src/lib/foo-secondary/README.md', - '/projects/foo/src/lib/foo-secondary/ng-package.json', - '/projects/foo/src/lib/foo-secondary/src/my-index.ts', - ]), - ); - }); - it('should handle scope packages', async () => { workspaceTree = await schematicRunner.runSchematic( 'library', @@ -100,7 +80,7 @@ describe('Secondary Entrypoint Schematic', () => { workspaceTree, ); const tree = await schematicRunner.runSchematic( - 'secondary', + 'library-entrypoint', { ...defaultOptions, name: 'testing', project: '@scope/package' }, workspaceTree, ); @@ -109,7 +89,6 @@ describe('Secondary Entrypoint Schematic', () => { jasmine.arrayContaining([ '/projects/scope/package/src/lib/testing/README.md', '/projects/scope/package/src/lib/testing/ng-package.json', - '/projects/scope/package/src/lib/testing/src/public-api.ts', ]), ); }); @@ -121,7 +100,7 @@ describe('Secondary Entrypoint Schematic', () => { workspaceTree, ); const tree = await schematicRunner.runSchematic( - 'secondary', + 'library-entrypoint', { ...defaultOptions, name: 'testing', project: '@scope/package' }, workspaceTree, ); @@ -150,14 +129,13 @@ describe('Secondary Entrypoint Schematic', () => { }), ); const tree = await schematicRunner.runSchematic( - 'secondary', + 'library-entrypoint', { ...defaultOptions, name: 'testing', project: '@scope/package' }, workspaceTree, ); const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json'); expect(tsConfigJson.compilerOptions.paths['@scope/package/testing']).toEqual([ - 'libs/*', './dist/scope/package/testing', ]); }); diff --git a/packages/schematics/angular/library-entrypoint/schema.json b/packages/schematics/angular/library-entrypoint/schema.json index e850df623ab7..d7e98fa61e05 100644 --- a/packages/schematics/angular/library-entrypoint/schema.json +++ b/packages/schematics/angular/library-entrypoint/schema.json @@ -3,12 +3,12 @@ "$id": "SchematicsLibrary", "title": "Library Entrypoint Schema", "type": "object", - "description": "Generate an library entrypoint in an Angular library project.", + "description": "Generate a library entrypoint in an Angular library project.", "additionalProperties": false, "properties": { "name": { "type": "string", - "description": "The name of the library.", + "description": "The name of the entrypoint to create.", "pattern": "^[a-zA-Z0-9-._~]+/?[a-zA-Z0-9-._~]+$", "$default": { "$source": "argv", @@ -22,16 +22,7 @@ "$default": { "$source": "projectName" } - }, - "entryFile": { - "type": "string", - "format": "path", - "description": "The path at which to create the library's secondary public API file, relative to the workspace root.", - "default": "public-api" } }, - "required": [ - "name", - "project" - ] -} \ No newline at end of file + "required": ["name", "project"] +} diff --git a/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts b/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts index ae7bbdeac78c..45d8e3ea4966 100644 --- a/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts +++ b/tests/legacy-cli/e2e/tests/build/library-with-demo-app.ts @@ -13,8 +13,7 @@ import { updateJsonFile } from '../../utils/project'; export default async function () { await ng('generate', 'library', 'mylib'); await ng('generate', 'lib-entry', 'secondary'); - // await createLibraryEntryPoint('secondary'); - await createLibraryEntryPoint('another'); + await ng('generate', 'lib-entry', 'another'); // Scenario #1 where we use wildcard path mappings for secondary entry-points. await updateJsonFile('tsconfig.json', (json) => { @@ -48,17 +47,3 @@ export default async function () { await ng('build'); } - -async function createLibraryEntryPoint(name: string): Promise { - await createDir(`projects/mylib/${name}`); - await writeFile(`projects/mylib/${name}/index.ts`, `export const foo = 'foo';`); - - await writeFile( - `projects/mylib/${name}/ng-package.json`, - JSON.stringify({ - lib: { - entryFile: 'index.ts', - }, - }), - ); -} From ccd52af1a26bdf6fa096c698dc51a43d999456a9 Mon Sep 17 00:00:00 2001 From: Jeffrey Bosch Date: Sun, 2 Feb 2025 09:32:15 +0100 Subject: [PATCH 4/4] test: update tests around tsmapping --- packages/schematics/angular/library-entrypoint/index_spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/library-entrypoint/index_spec.ts b/packages/schematics/angular/library-entrypoint/index_spec.ts index ff725b8318e0..c06baff53a26 100644 --- a/packages/schematics/angular/library-entrypoint/index_spec.ts +++ b/packages/schematics/angular/library-entrypoint/index_spec.ts @@ -133,10 +133,10 @@ describe('Secondary Entrypoint Schematic', () => { { ...defaultOptions, name: 'testing', project: '@scope/package' }, workspaceTree, ); - const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json'); expect(tsConfigJson.compilerOptions.paths['@scope/package/testing']).toEqual([ './dist/scope/package/testing', + 'libs/*', ]); }); });