fix(js): generate pacakge.json for non-buildable nest and expo libs (#29891)
This PR fixes a couple of issues for TS solution setup: 1. Expo library should generate with correct `package.json` file (e.g. `exports` maps either to source or dist). See [spec file](https://github.com/nrwl/nx/pull/29891/files#diff-ae2eb3d10d58786c17aa21f5603043b68043faaebafaec77912f3d69ac0c5295). 2. Nest library should generate `package.json` when non-buildable. See [spec file](https://github.com/nrwl/nx/pull/29891/files#diff-368467bcd2215def98ef14aaff9dcb056a915b0a724d0eb857f3a0badef8b40a). **Notes:** - Also removed an unsupported `standaloneConfig` option from `@nx/nest:lib` generator. This was removed a long time ago in other generators. - Expo lib generator isn't crystalized when using Rollup for build. This is a separate issue and we'll handle it in another task. ## Current Behavior - Non-buildable Expo libs generate without `exports` - Buildable Expo libs fail to generate due to error - Non-buildable Nest libs do not generate `package.json` ## Expected Behavior Expo and Nest libs generate correct `package.json` files depending on whether they are build or non-buildable. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
d62b94f6a7
commit
8bd0bcdd97
@ -118,12 +118,6 @@
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"standaloneConfig": {
|
||||
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"x-deprecated": "Nx only supports standaloneConfig"
|
||||
},
|
||||
"setParserOptionsProject": {
|
||||
"type": "boolean",
|
||||
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "<%= name %>",
|
||||
"name": "<%= projectName %>",
|
||||
"version": "0.0.1",
|
||||
"main": "<%= appMain %>"
|
||||
}
|
||||
|
||||
@ -5,10 +5,12 @@ import {
|
||||
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import { Schema } from '../schema';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
||||
|
||||
export interface NormalizedSchema extends Schema {
|
||||
name: string;
|
||||
fileName: string;
|
||||
projectName: string;
|
||||
projectRoot: string;
|
||||
routePath: string;
|
||||
parsedTags: string[];
|
||||
@ -43,16 +45,20 @@ export async function normalizeOptions(
|
||||
: [];
|
||||
const appMain = options.js ? 'src/index.js' : 'src/index.ts';
|
||||
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host);
|
||||
const normalized: NormalizedSchema = {
|
||||
...options,
|
||||
fileName: projectName,
|
||||
routePath: `/${projectNames.projectSimpleName}`,
|
||||
name: projectName,
|
||||
projectName: isUsingTsSolutionConfig
|
||||
? getImportPath(host, projectName)
|
||||
: projectName,
|
||||
projectRoot,
|
||||
parsedTags,
|
||||
importPath,
|
||||
appMain,
|
||||
isUsingTsSolutionConfig: isUsingTsSolutionSetup(host),
|
||||
isUsingTsSolutionConfig,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
|
||||
@ -504,6 +504,22 @@ describe('lib', () => {
|
||||
]
|
||||
`);
|
||||
// Make sure keys are in idiomatic order
|
||||
expect(readJson(appTree, 'my-lib/package.json')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./src/index.ts",
|
||||
"import": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"name": "@proj/my-lib",
|
||||
"types": "./src/index.ts",
|
||||
"version": "0.0.1",
|
||||
}
|
||||
`);
|
||||
expect(Object.keys(readJson(appTree, 'my-lib/package.json')))
|
||||
.toMatchInlineSnapshot(`
|
||||
[
|
||||
@ -511,7 +527,7 @@ describe('lib', () => {
|
||||
"version",
|
||||
"main",
|
||||
"types",
|
||||
"nx",
|
||||
"exports",
|
||||
]
|
||||
`);
|
||||
expect(readJson(appTree, 'my-lib/tsconfig.json')).toMatchInlineSnapshot(`
|
||||
@ -608,5 +624,69 @@ describe('lib', () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate buildable library', async () => {
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
buildable: true,
|
||||
strict: false,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'my-lib/package.json')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.esm.js",
|
||||
"import": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
},
|
||||
"main": "./dist/index.esm.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"name": "@proj/my-lib",
|
||||
"nx": {
|
||||
"projectType": "library",
|
||||
"sourceRoot": "my-lib/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/rollup:rollup",
|
||||
"options": {
|
||||
"assets": [
|
||||
{
|
||||
"glob": "my-lib/README.md",
|
||||
"input": ".",
|
||||
"output": ".",
|
||||
},
|
||||
],
|
||||
"entryFile": "my-lib/src/index.ts",
|
||||
"external": [
|
||||
"react/jsx-runtime",
|
||||
"react-native",
|
||||
"react",
|
||||
"react-dom",
|
||||
],
|
||||
"outputPath": "dist/my-lib",
|
||||
"project": "my-lib/package.json",
|
||||
"rollupConfig": "@nx/react/plugins/bundle-rollup",
|
||||
"tsConfig": "my-lib/tsconfig.lib.json",
|
||||
},
|
||||
"outputs": [
|
||||
"{options.outputPath}",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "~18.3.1",
|
||||
"react-native": "0.76.3",
|
||||
},
|
||||
"type": "module",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"version": "0.0.1",
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -40,7 +40,6 @@ import {
|
||||
addProjectToTsSolutionWorkspace,
|
||||
updateTsconfigFiles,
|
||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
||||
import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields';
|
||||
|
||||
export async function expoLibraryGenerator(
|
||||
@ -72,6 +71,10 @@ export async function expoLibraryGeneratorInternal(
|
||||
);
|
||||
}
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||
}
|
||||
|
||||
const initTask = await init(host, { ...options, skipFormat: true });
|
||||
tasks.push(initTask);
|
||||
if (!options.skipPackageJson) {
|
||||
@ -88,7 +91,7 @@ export async function expoLibraryGeneratorInternal(
|
||||
|
||||
const lintTask = await addLinting(host, {
|
||||
...options,
|
||||
projectName: options.name,
|
||||
projectName: options.projectName,
|
||||
tsConfigPaths: [
|
||||
joinPathFragments(options.projectRoot, 'tsconfig.lib.json'),
|
||||
],
|
||||
@ -98,7 +101,7 @@ export async function expoLibraryGeneratorInternal(
|
||||
const jestTask = await addJest(
|
||||
host,
|
||||
options.unitTestRunner,
|
||||
options.name,
|
||||
options.projectName,
|
||||
options.projectRoot,
|
||||
options.js,
|
||||
options.skipPackageJson,
|
||||
@ -134,10 +137,6 @@ export async function expoLibraryGeneratorInternal(
|
||||
: undefined
|
||||
);
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||
}
|
||||
|
||||
sortPackageJsonFields(host, options.projectRoot);
|
||||
|
||||
if (!options.skipFormat) {
|
||||
@ -169,23 +168,35 @@ async function addProject(
|
||||
};
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
const packageName = getImportPath(host, options.name);
|
||||
const sourceEntry = !options.buildable
|
||||
? options.js
|
||||
? './src/index.js'
|
||||
: './src/index.ts'
|
||||
: undefined;
|
||||
writeJson(host, joinPathFragments(options.projectRoot, 'package.json'), {
|
||||
name: packageName,
|
||||
name: options.projectName,
|
||||
version: '0.0.1',
|
||||
main: sourceEntry,
|
||||
types: sourceEntry,
|
||||
nx: {
|
||||
name: packageName === options.name ? undefined : options.name,
|
||||
projectType: 'library',
|
||||
sourceRoot: joinPathFragments(options.projectRoot, 'src'),
|
||||
tags: options.parsedTags?.length ? options.parsedTags : undefined,
|
||||
},
|
||||
// For buildable libraries, the entries are configured by the bundler (i.e. Rollup).
|
||||
exports: options.buildable
|
||||
? undefined
|
||||
: {
|
||||
'./package.json': './package.json',
|
||||
'.': options.js
|
||||
? './src/index.js'
|
||||
: {
|
||||
types: './src/index.ts',
|
||||
import: './src/index.ts',
|
||||
default: './src/index.ts',
|
||||
},
|
||||
},
|
||||
|
||||
nx: options.parsedTags?.length
|
||||
? {
|
||||
tags: options.parsedTags,
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
} else {
|
||||
addProjectConfiguration(host, options.name, project);
|
||||
@ -201,7 +212,7 @@ async function addProject(
|
||||
);
|
||||
const rollupConfigTask = await configurationGenerator(host, {
|
||||
...options,
|
||||
project: options.name,
|
||||
project: options.projectName,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -229,7 +240,7 @@ async function addProject(
|
||||
},
|
||||
};
|
||||
|
||||
updateProjectConfiguration(host, options.name, project);
|
||||
updateProjectConfiguration(host, options.projectName, project);
|
||||
|
||||
return rollupConfigTask;
|
||||
}
|
||||
@ -271,7 +282,11 @@ function createFiles(host: Tree, options: NormalizedSchema) {
|
||||
}
|
||||
);
|
||||
|
||||
if (!options.publishable && !options.buildable) {
|
||||
if (
|
||||
!options.publishable &&
|
||||
!options.buildable &&
|
||||
!options.isUsingTsSolutionConfig
|
||||
) {
|
||||
host.delete(`${options.projectRoot}/package.json`);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,11 @@ export function deleteFiles(tree: Tree, options: NormalizedOptions): void {
|
||||
);
|
||||
}
|
||||
|
||||
if (!options.buildable && !options.publishable) {
|
||||
if (
|
||||
!options.buildable &&
|
||||
!options.publishable &&
|
||||
!options.isUsingTsSolutionsConfig
|
||||
) {
|
||||
tree.delete(joinPathFragments(options.projectRoot, 'package.json'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ export async function normalizeOptions(
|
||||
? options.tags.split(',').map((s) => s.trim())
|
||||
: [];
|
||||
|
||||
const isUsingTsSolutionsConfig = isUsingTsSolutionSetup(tree);
|
||||
const normalized: NormalizedOptions = {
|
||||
...options,
|
||||
strict: options.strict ?? true,
|
||||
@ -49,7 +50,7 @@ export async function normalizeOptions(
|
||||
linter: options.linter ?? Linter.EsLint,
|
||||
parsedTags,
|
||||
prefix: getNpmScope(tree), // we could also allow customizing this
|
||||
projectName: isUsingTsSolutionSetup(tree)
|
||||
projectName: isUsingTsSolutionsConfig
|
||||
? getImportPath(tree, projectName)
|
||||
: projectName,
|
||||
projectRoot,
|
||||
@ -58,13 +59,14 @@ export async function normalizeOptions(
|
||||
target: options.target ?? 'es6',
|
||||
testEnvironment: options.testEnvironment ?? 'node',
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
isUsingTsSolutionsConfig,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function toJsLibraryGeneratorOptions(
|
||||
options: LibraryGeneratorOptions
|
||||
options: NormalizedOptions
|
||||
): JsLibraryGeneratorSchema {
|
||||
return {
|
||||
name: options.name,
|
||||
@ -80,8 +82,8 @@ export function toJsLibraryGeneratorOptions(
|
||||
tags: options.tags,
|
||||
testEnvironment: options.testEnvironment,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
config: options.standaloneConfig ? 'project' : 'workspace',
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
addPlugin: options.addPlugin,
|
||||
useProjectJson: !options.isUsingTsSolutionsConfig,
|
||||
};
|
||||
}
|
||||
|
||||
@ -379,6 +379,41 @@ describe('lib', () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(readJson(tree, 'mylib/package.json')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"dependencies": {},
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./src/index.ts",
|
||||
"import": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"name": "@proj/mylib",
|
||||
"nx": {
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "mylib/jest.config.ts",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/test-output/jest/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"types": "./src/index.ts",
|
||||
"version": "0.0.1",
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'mylib/tsconfig.json')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
|
||||
@ -28,11 +28,11 @@ export interface LibraryGeneratorOptions {
|
||||
| 'es2021';
|
||||
testEnvironment?: 'jsdom' | 'node';
|
||||
unitTestRunner?: UnitTestRunner;
|
||||
standaloneConfig?: boolean;
|
||||
setParserOptionsProject?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
simpleName?: boolean;
|
||||
addPlugin?: boolean;
|
||||
isUsingTsSolutionsConfig?: boolean;
|
||||
}
|
||||
|
||||
export interface NormalizedOptions extends LibraryGeneratorOptions {
|
||||
|
||||
@ -118,12 +118,6 @@
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"standaloneConfig": {
|
||||
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"x-deprecated": "Nx only supports standaloneConfig"
|
||||
},
|
||||
"setParserOptionsProject": {
|
||||
"type": "boolean",
|
||||
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user