Skip to content

Commit 8b97bfa

Browse files
klemenoslajalan-agius4
authored andcommitted
fix: support the ng-package.json in secondary entry points (#1406)
* fix: support the ng-package.json in secondary entry points Currently secondary entry points are breaking "no-implicit-dependencies" TSLint rule, because the rule is checking for package.json files, which in secondary entry points are anyway just containing "ngPackage" configuration. Adding the support for ng-package.json removes the need for package.json, thus TSLint will look correctly in parent package.json file and act accordingly. fix 1391 * test: add a missing test for the feature-d integration * docs: document the alternative secondary entry point setup
1 parent 88f8cb4 commit 8b97bfa

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

docs/secondary-entrypoints.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ The contents of `my_package/testing/package.json` can be as simple as:
3737
No, that is not a typo. No name is required. No version is required.
3838
It's all handled for you by ng-packagr!
3939
When built, the primary entry point is imported by `import {..} from '@my/library'` and the secondary entry point with `import {..} from '@my/library/testing'`.
40+
41+
### Alternative to `package.json`
42+
43+
Alternatively, you could create `ng-package.json` instead of `package.json`.
44+
This is particularly useful in conjunction with `no-implicit-dependencies` TSLint rule, which will complain if `package.json` does not contain the dependencies used in the secondary entry point, which is misleading since all the dependencies should be mentioned in the primary `package.json`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { FEATURE_A } from '@sample/secondary/feature-a';
2+
import { FEATURE_B } from '@sample/secondary/feature-b';
3+
import { FEATURE_C } from '@sample/secondary/feature-c';
4+
5+
export const FEATURE_D = `Feature D: ${FEATURE_A} ${FEATURE_B} ${FEATURE_C}`;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$schema": "../../../../src/ng-package.schema.json",
3+
"lib": {
4+
"entryFile": "feature-d.ts"
5+
}
6+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { expect } from 'chai';
2+
3+
describe(`@sample/secondary/feature-d`, () => {
4+
let PACKAGE;
5+
6+
before(() => {
7+
PACKAGE = require('../dist/feature-d/package.json');
8+
});
9+
10+
it(`should exist`, () => {
11+
expect(PACKAGE).to.be.ok;
12+
});
13+
14+
it(`should be named '@sample/secondary/feature-d'`, () => {
15+
expect(PACKAGE['name']).to.equal('@sample/secondary/feature-d');
16+
});
17+
18+
it(`should reference "main" bundle (UMD)`, () => {
19+
expect(PACKAGE['main']).to.equal('../bundles/sample-secondary-feature-d.umd.js');
20+
});
21+
22+
it(`should reference "module" bundle (FESM5)`, () => {
23+
expect(PACKAGE['module']).to.equal('../fesm5/sample-secondary-feature-d.js');
24+
});
25+
26+
it(`should reference "typings" files`, () => {
27+
expect(PACKAGE['typings']).to.equal('sample-secondary-feature-d.d.ts');
28+
});
29+
30+
it(`should reference "metadata" file`, () => {
31+
expect(PACKAGE['metadata']).to.equal('sample-secondary-feature-d.metadata.json');
32+
});
33+
});

src/lib/ng-v5/discover-packages.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,22 @@ function formatSchemaValidationErrors(errors: ajv.ErrorObject[]): string {
3232
* Resolves a user's package by testing for 'package.json', 'ng-package.json', or 'ng-package.js'.
3333
*
3434
* @param folderPathOrFilePath A path pointing either to a file or a directory
35+
* @param isSecondary A boolean determining if this is a secondary package
3536
* @return The user's package
3637
*/
37-
async function resolveUserPackage(folderPathOrFilePath: string): Promise<UserPackage | undefined> {
38+
async function resolveUserPackage(folderPathOrFilePath: string, isSecondary = false): Promise<UserPackage | undefined> {
3839
const readConfigFile = async (filePath: string) => (pathExistsSync(filePath) ? import(filePath) : undefined);
3940
const fullPath = path.resolve(folderPathOrFilePath);
4041
const pathStats = await lstat(fullPath);
4142
const basePath = pathStats.isDirectory() ? fullPath : path.dirname(fullPath);
4243
const packageJson = await readConfigFile(path.join(basePath, 'package.json'));
4344

44-
if (!packageJson) {
45+
if (!packageJson && !isSecondary) {
4546
throw new Error(`Cannot discover package sources at ${folderPathOrFilePath} as 'package.json' was not found.`);
4647
}
4748

4849
let ngPackageJson: undefined | object;
49-
if (packageJson['ngPackage']) {
50+
if (packageJson && packageJson['ngPackage']) {
5051
// Read `ngPackage` from `package.json`
5152
ngPackageJson = { ...packageJson['ngPackage'] };
5253
} else if (pathStats.isDirectory()) {
@@ -74,7 +75,7 @@ async function resolveUserPackage(folderPathOrFilePath: string): Promise<UserPac
7475

7576
return {
7677
basePath,
77-
packageJson,
78+
packageJson: packageJson || {},
7879
ngPackageJson,
7980
};
8081
}
@@ -109,9 +110,10 @@ async function findSecondaryPackagesPaths(directoryPath: string, excludeFolder:
109110
'**/.git/**',
110111
`${path.resolve(directoryPath, excludeFolder)}/**`,
111112
`${directoryPath}/package.json`,
113+
`${directoryPath}/ng-package.json`,
112114
];
113115

114-
const filePaths = await globFiles(`${directoryPath}/**/package.json`, {
116+
const filePaths = await globFiles(`${directoryPath}/**/{package,ng-package}.json`, {
115117
ignore,
116118
cwd: directoryPath,
117119
});
@@ -156,7 +158,7 @@ export async function discoverPackages({ project }: { project: string }): Promis
156158
.then(folderPaths =>
157159
Promise.all(
158160
folderPaths.map(folderPath =>
159-
resolveUserPackage(folderPath).catch(() => {
161+
resolveUserPackage(folderPath, true).catch(() => {
160162
log.warn(`Cannot read secondary entry point at ${folderPath}. Skipping.`);
161163

162164
return null;

0 commit comments

Comments
 (0)