feat(misc): set a development conditional export for buildable libraries when using the ts solution setup (#30451)
Update library generators to set a `development` conditional export for buildable libraries' `package.json` files and set the `customConditions` compiler options in `tsconfig.base.json`. This will only be done for workspaces using the TS solution setup. ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes #
This commit is contained in:
parent
533e9ffc25
commit
176c792e34
@ -167,6 +167,9 @@ function updatePackageJson(
|
||||
esbuildOptions,
|
||||
} = mergedTarget.options;
|
||||
|
||||
// the file must exist in the TS solution setup
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
// can't use the declarationRootDir as rootDir because it only affects the typings,
|
||||
// not the runtime entry point
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
@ -186,6 +189,10 @@ function updatePackageJson(
|
||||
outputFileExtensionForEsm: getOutExtension('esm', {
|
||||
userDefinedBuildOptions: esbuildOptions,
|
||||
}),
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes(
|
||||
'development'
|
||||
),
|
||||
});
|
||||
|
||||
if (declarationRootDir !== dirname(main)) {
|
||||
|
||||
@ -467,6 +467,7 @@ describe('lib', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(appTree, 'tsconfig.json', {
|
||||
@ -630,13 +631,14 @@ describe('lib', () => {
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./src/index.ts",
|
||||
"import": "./src/index.ts",
|
||||
"default": "./dist/index.cjs.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"main": "./dist/index.cjs.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"name": "@proj/my-lib",
|
||||
"peerDependencies": {
|
||||
@ -649,6 +651,25 @@ describe('lib', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(appTree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
buildable: true,
|
||||
strict: false,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(appTree, 'my-lib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name', async () => {
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
|
||||
@ -295,6 +295,15 @@ function createFiles(host: Tree, options: NormalizedSchema) {
|
||||
function determineEntryFields(
|
||||
options: NormalizedSchema
|
||||
): Pick<PackageJson, 'main' | 'types' | 'exports'> {
|
||||
if (
|
||||
options.buildable ||
|
||||
options.publishable ||
|
||||
!options.isUsingTsSolutionConfig
|
||||
) {
|
||||
// For buildable libraries, the entries are configured by the bundler (i.e. Rollup).
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
main: options.js ? './src/index.js' : './src/index.ts',
|
||||
types: options.js ? './src/index.js' : './src/index.ts',
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
"noUnusedLocals": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "es2022"
|
||||
"target": "es2022",
|
||||
"customConditions": ["development"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +208,8 @@ describe('js init generator', () => {
|
||||
"noUnusedLocals": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "es2022"
|
||||
"target": "es2022",
|
||||
"customConditions": ["development"]
|
||||
}
|
||||
}
|
||||
"
|
||||
|
||||
@ -1817,6 +1817,7 @@ describe('lib', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -1954,6 +1955,7 @@ describe('lib', () => {
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
},
|
||||
@ -1987,6 +1989,7 @@ describe('lib', () => {
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
},
|
||||
@ -2428,5 +2431,26 @@ describe('lib', () => {
|
||||
expect(readJson(tree, 'my-lib/project.json').name).toBe('my-lib');
|
||||
expect(readJson(tree, 'my-lib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
...defaultOptions,
|
||||
directory: 'my-lib',
|
||||
name: 'my-lib',
|
||||
useProjectJson: true,
|
||||
bundler: 'tsc',
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'my-lib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
names,
|
||||
offsetFromRoot,
|
||||
ProjectConfiguration,
|
||||
readJson,
|
||||
readNxJson,
|
||||
readProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
@ -631,6 +632,9 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
|
||||
options.isUsingTsSolutionConfig &&
|
||||
!['none', 'rollup', 'vite'].includes(options.bundler)
|
||||
) {
|
||||
// the file must exist in the TS solution setup
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
return getUpdatedPackageJsonContent(updatedPackageJson, {
|
||||
main: join(options.projectRoot, 'src/index.ts'),
|
||||
outputPath: joinPathFragments(options.projectRoot, 'dist'),
|
||||
@ -639,6 +643,10 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
|
||||
generateExportsField: true,
|
||||
packageJsonPath,
|
||||
format: ['esm'],
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes(
|
||||
'development'
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@ -664,6 +672,8 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
|
||||
options.isUsingTsSolutionConfig &&
|
||||
!['none', 'rollup', 'vite'].includes(options.bundler)
|
||||
) {
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
main: join(options.projectRoot, 'src/index.ts'),
|
||||
outputPath: joinPathFragments(options.projectRoot, 'dist'),
|
||||
@ -672,6 +682,10 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
|
||||
generateExportsField: true,
|
||||
packageJsonPath,
|
||||
format: ['esm'],
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes(
|
||||
'development'
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -325,6 +325,11 @@ function updatePackageJson(
|
||||
version: '0.0.1',
|
||||
};
|
||||
}
|
||||
|
||||
// the file must exist in the TS solution setup, which is the only case this
|
||||
// function is called
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
main,
|
||||
outputPath,
|
||||
@ -333,6 +338,8 @@ function updatePackageJson(
|
||||
packageJsonPath,
|
||||
rootDir,
|
||||
format,
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes('development'),
|
||||
});
|
||||
writeJson(tree, packageJsonPath, packageJson);
|
||||
}
|
||||
|
||||
@ -2206,6 +2206,111 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not create build target when the entry points point to source files', async () => {
|
||||
// Sibling package.json
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.json': `{}`,
|
||||
'libs/my-lib/tsconfig.lib.json': `{"compilerOptions": {"outDir": "dist"}}`,
|
||||
'libs/my-lib/package.json': JSON.stringify({
|
||||
exports: {
|
||||
'.': {
|
||||
default: './src/index.ts',
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(
|
||||
await invokeCreateNodesOnMatchingFiles(context, {
|
||||
// Reduce noise in build snapshots by disabling default typecheck target
|
||||
typecheck: false,
|
||||
build: true,
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create build target when the entry points point to dist files', async () => {
|
||||
// Sibling package.json
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.json': `{}`,
|
||||
'libs/my-lib/tsconfig.lib.json': `{"compilerOptions": {"outDir": "dist"}}`,
|
||||
'libs/my-lib/package.json': JSON.stringify({
|
||||
exports: {
|
||||
'.': {
|
||||
// should ignore the fact that the development condition points to source
|
||||
development: './src/index.ts',
|
||||
types: './dist/index.d.ts',
|
||||
default: './dist/index.js',
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(
|
||||
await invokeCreateNodesOnMatchingFiles(context, {
|
||||
// Reduce noise in build snapshots by disabling default typecheck target
|
||||
typecheck: false,
|
||||
build: true,
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"cache": true,
|
||||
"command": "tsc --build tsconfig.lib.json",
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Builds the project with \`tsc\`.",
|
||||
"help": {
|
||||
"command": "npx tsc --build --help",
|
||||
"example": {
|
||||
"args": [
|
||||
"--force",
|
||||
],
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "libs/my-lib",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/dist",
|
||||
],
|
||||
"syncGenerators": [
|
||||
"@nx/js:typescript-sync",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a node with a build target when enabled, for a project level tsconfig.lib.json build file by default', async () => {
|
||||
// Sibling package.json
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
|
||||
@ -95,8 +95,8 @@ export function isValidPackageJsonBuildConfig(
|
||||
return isPathSourceFile(value);
|
||||
} else if (typeof value === 'object') {
|
||||
return Object.entries(value).some(([currentKey, subValue]) => {
|
||||
// Skip types field
|
||||
if (currentKey === 'types') {
|
||||
// Skip types and development conditions
|
||||
if (currentKey === 'types' || currentKey === 'development') {
|
||||
return false;
|
||||
}
|
||||
if (typeof subValue === 'string') {
|
||||
|
||||
@ -157,6 +157,7 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
version: '0.0.1',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.js',
|
||||
import: './src/index.js',
|
||||
types: './src/index.d.ts',
|
||||
@ -190,6 +191,7 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
type: 'commonjs',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.cjs',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
@ -228,15 +230,28 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
version: '0.0.1',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.js',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
'./foo': './src/foo.js',
|
||||
'./bar': './src/bar.js',
|
||||
'./foo': {
|
||||
development: './src/foo.ts',
|
||||
default: './src/foo.js',
|
||||
},
|
||||
'./bar': {
|
||||
development: './src/bar.ts',
|
||||
default: './src/bar.js',
|
||||
},
|
||||
'./package.json': './package.json',
|
||||
'./migrations.json': './migrations.json',
|
||||
'./feature': './feature/index.js',
|
||||
'./feature/index': './feature/index.js',
|
||||
'./feature': {
|
||||
development: './feature/index.ts',
|
||||
default: './feature/index.js',
|
||||
},
|
||||
'./feature/index': {
|
||||
development: './feature/index.ts',
|
||||
default: './feature/index.js',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -269,15 +284,32 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
version: '0.0.1',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.js',
|
||||
import: './src/index.js',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
'./foo': './src/foo.js',
|
||||
'./bar': './src/bar.js',
|
||||
'./foo': {
|
||||
development: './src/foo.ts',
|
||||
import: './src/foo.js',
|
||||
default: './src/foo.js',
|
||||
},
|
||||
'./bar': {
|
||||
development: './src/bar.ts',
|
||||
import: './src/bar.js',
|
||||
default: './src/bar.js',
|
||||
},
|
||||
'./package.json': './package.json',
|
||||
'./feature': './feature/index.js',
|
||||
'./feature/index': './feature/index.js',
|
||||
'./feature': {
|
||||
development: './feature/index.ts',
|
||||
import: './feature/index.js',
|
||||
default: './feature/index.js',
|
||||
},
|
||||
'./feature/index': {
|
||||
development: './feature/index.ts',
|
||||
import: './feature/index.js',
|
||||
default: './feature/index.js',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -310,23 +342,28 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
version: '0.0.1',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
import: './src/index.js',
|
||||
default: './src/index.cjs',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
'./foo': {
|
||||
development: './src/foo.ts',
|
||||
import: './src/foo.js',
|
||||
default: './src/foo.cjs',
|
||||
},
|
||||
'./bar': {
|
||||
development: './src/bar.ts',
|
||||
import: './src/bar.js',
|
||||
default: './src/bar.cjs',
|
||||
},
|
||||
'./feature': {
|
||||
development: './feature/index.ts',
|
||||
import: './feature/index.js',
|
||||
default: './feature/index.cjs',
|
||||
},
|
||||
'./feature/index': {
|
||||
development: './feature/index.ts',
|
||||
import: './feature/index.js',
|
||||
default: './feature/index.cjs',
|
||||
},
|
||||
@ -364,6 +401,7 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
version: '0.0.1',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
import: './src/index.js',
|
||||
default: './src/index.cjs',
|
||||
types: './src/index.d.ts',
|
||||
@ -400,6 +438,7 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
type: 'module',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.cjs',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
@ -432,6 +471,7 @@ describe('getUpdatedPackageJsonContent', () => {
|
||||
type: 'commonjs',
|
||||
exports: {
|
||||
'.': {
|
||||
development: './src/index.ts',
|
||||
default: './src/index.js',
|
||||
types: './src/index.d.ts',
|
||||
},
|
||||
|
||||
@ -48,6 +48,7 @@ export interface UpdatePackageJsonOption {
|
||||
buildableProjectDepsInPackageJsonType?: 'dependencies' | 'peerDependencies';
|
||||
generateLockfile?: boolean;
|
||||
packageJsonPath?: string;
|
||||
skipDevelopmentExports?: boolean;
|
||||
}
|
||||
|
||||
export function updatePackageJson(
|
||||
@ -113,7 +114,10 @@ export function updatePackageJson(
|
||||
}
|
||||
|
||||
// update package specific settings
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, options);
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
skipDevelopmentExports: true,
|
||||
...options,
|
||||
});
|
||||
|
||||
// save files
|
||||
writeJsonFile(`${options.outputPath}/package.json`, packageJson);
|
||||
@ -285,6 +289,21 @@ export function getUpdatedPackageJsonContent(
|
||||
packageJson.exports ??=
|
||||
typeof packageJson.exports === 'string' ? {} : { ...packageJson.exports };
|
||||
packageJson.exports['./package.json'] ??= './package.json';
|
||||
|
||||
if (!options.skipDevelopmentExports && (hasCjsFormat || hasEsmFormat)) {
|
||||
packageJson.exports['.'] ??= {};
|
||||
const developmentExports = getDevelopmentExports(options);
|
||||
for (const [exportEntry, filePath] of Object.entries(
|
||||
developmentExports
|
||||
)) {
|
||||
if (!packageJson.exports[exportEntry]) {
|
||||
packageJson.exports[exportEntry] ??= {};
|
||||
packageJson.exports[exportEntry]['development'] ??= filePath;
|
||||
} else if (typeof packageJson.exports[exportEntry] === 'object') {
|
||||
packageJson.exports[exportEntry].development ??= filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.skipTypings) {
|
||||
@ -364,6 +383,47 @@ export function getUpdatedPackageJsonContent(
|
||||
return packageJson;
|
||||
}
|
||||
|
||||
function getDevelopmentExports(
|
||||
options: Pick<
|
||||
UpdatePackageJsonOption,
|
||||
'additionalEntryPoints' | 'main' | 'projectRoot'
|
||||
>
|
||||
) {
|
||||
const mainRelativeDir = getRelativeDirectoryToProjectRoot(
|
||||
options.main,
|
||||
options.projectRoot
|
||||
);
|
||||
const exports: Exports = {
|
||||
'.': mainRelativeDir + basename(options.main),
|
||||
};
|
||||
|
||||
if (options.additionalEntryPoints?.length) {
|
||||
const jsRegex = /\.[jt]sx?$/;
|
||||
|
||||
for (const file of options.additionalEntryPoints) {
|
||||
const { ext: fileExt, name: fileName, base: baseName } = parse(file);
|
||||
if (!jsRegex.test(fileExt)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const relativeDir = getRelativeDirectoryToProjectRoot(
|
||||
file,
|
||||
options.projectRoot
|
||||
);
|
||||
const sourceFilePath = relativeDir + baseName;
|
||||
const entryRelativeDir = relativeDir.replace(/^\.\/src\//, './');
|
||||
const entryFilePath = entryRelativeDir + fileName;
|
||||
if (fileName === 'index') {
|
||||
const barrelEntry = entryRelativeDir.replace(/\/$/, '');
|
||||
exports[barrelEntry] = sourceFilePath;
|
||||
}
|
||||
exports[entryFilePath] = sourceFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
export function getOutputDir(
|
||||
options: Pick<
|
||||
UpdatePackageJsonOption,
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
import type { Tree } from '@nx/devkit';
|
||||
import * as devkit from '@nx/devkit';
|
||||
import { readJson, readProjectConfiguration, writeJson } from '@nx/devkit';
|
||||
import {
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
updateJson,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import { libraryGenerator } from './library';
|
||||
|
||||
@ -357,6 +362,7 @@ describe('lib', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -498,6 +504,90 @@ describe('lib', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.read('mylib/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/mylib",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": [
|
||||
"{projectRoot}/test-output/jest/coverage"
|
||||
],
|
||||
"options": {
|
||||
"jestConfig": "mylib/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/mylib",
|
||||
"tsConfig": "mylib/tsconfig.lib.json",
|
||||
"packageJson": "mylib/package.json",
|
||||
"main": "mylib/src/index.ts",
|
||||
"assets": [
|
||||
"mylib/*.md"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'mylib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
|
||||
@ -133,6 +133,7 @@ describe('next library', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -264,6 +265,109 @@ describe('next library', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: true,
|
||||
skipTsConfig: false,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
component: false,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
});
|
||||
|
||||
expect(tree.read('mylib/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/mylib",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.esm.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"import": "./dist/index.esm.js",
|
||||
"default": "./dist/index.esm.js"
|
||||
}
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
},
|
||||
"build": {
|
||||
"executor": "@nx/rollup:rollup",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/mylib",
|
||||
"tsConfig": "mylib/tsconfig.lib.json",
|
||||
"project": "mylib/package.json",
|
||||
"entryFile": "mylib/src/index.ts",
|
||||
"external": [
|
||||
"react",
|
||||
"react-dom",
|
||||
"react/jsx-runtime"
|
||||
],
|
||||
"rollupConfig": "@nx/react/plugins/bundle-rollup",
|
||||
"compiler": "babel",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "mylib/README.md",
|
||||
"input": ".",
|
||||
"output": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": [
|
||||
"{projectRoot}/test-output/jest/coverage"
|
||||
],
|
||||
"options": {
|
||||
"jestConfig": "mylib/jest.config.ts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceRoot": "mylib/src",
|
||||
"projectType": "library",
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: true,
|
||||
skipTsConfig: false,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
component: false,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'mylib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
|
||||
@ -531,6 +531,7 @@ describe('lib', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -654,6 +655,61 @@ describe('lib', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
expect(tree.read('mylib/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/mylib",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
expect(
|
||||
readJson(tree, 'mylib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set correct options for swc', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
@ -672,6 +728,7 @@ describe('lib', () => {
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
},
|
||||
|
||||
@ -339,6 +339,7 @@ describe('NxPlugin Plugin Generator', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -447,6 +448,7 @@ describe('NxPlugin Plugin Generator', () => {
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
},
|
||||
@ -532,6 +534,25 @@ describe('NxPlugin Plugin Generator', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await pluginGenerator(
|
||||
tree,
|
||||
getSchema({
|
||||
e2eTestRunner: 'jest',
|
||||
skipFormat: true,
|
||||
})
|
||||
);
|
||||
|
||||
expect(
|
||||
readJson(tree, 'my-plugin/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name and "useProjectJson" is "false"', async () => {
|
||||
await pluginGenerator(tree, {
|
||||
directory: 'my-plugin',
|
||||
|
||||
@ -459,6 +459,7 @@ describe('lib', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(appTree, 'tsconfig.json', {
|
||||
@ -599,6 +600,58 @@ describe('lib', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(appTree.read('my-lib/package.json', 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/my-lib",
|
||||
"version": "0.0.1",
|
||||
"main": "./dist/index.cjs.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"import": "./dist/index.esm.js",
|
||||
"default": "./dist/index.cjs.js"
|
||||
}
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "~18.3.1",
|
||||
"react-native": "~0.76.3"
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(appTree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(appTree, 'my-lib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name', async () => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
|
||||
@ -78,15 +78,15 @@ export async function reactNativeLibraryGeneratorInternal(
|
||||
|
||||
createFiles(host, options);
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
await addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||
}
|
||||
|
||||
const addProjectTask = await addProject(host, options);
|
||||
if (addProjectTask) {
|
||||
tasks.push(addProjectTask);
|
||||
}
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
await addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||
}
|
||||
|
||||
const lintTask = await addLinting(host, {
|
||||
...options,
|
||||
projectName: options.name,
|
||||
@ -296,6 +296,15 @@ function createFiles(host: Tree, options: NormalizedSchema) {
|
||||
function determineEntryFields(
|
||||
options: NormalizedSchema
|
||||
): Pick<PackageJson, 'main' | 'types' | 'exports'> {
|
||||
if (
|
||||
options.buildable ||
|
||||
options.publishable ||
|
||||
!options.isUsingTsSolutionConfig
|
||||
) {
|
||||
// For buildable libraries, the entries are configured by the bundler (i.e. Rollup).
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
main: options.js ? './src/index.js' : './src/index.ts',
|
||||
types: options.js ? './src/index.js' : './src/index.ts',
|
||||
|
||||
@ -939,6 +939,7 @@ module.exports = withNx(
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -1246,6 +1247,7 @@ module.exports = withNx(
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.esm.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
},
|
||||
@ -1265,6 +1267,27 @@ module.exports = withNx(
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
...defaultSchema,
|
||||
bundler: 'rollup',
|
||||
directory: 'libs/mylib',
|
||||
publishable: true,
|
||||
importPath: '@acme/mylib',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'libs/mylib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should add project to workspaces when using TS solution', async () => {
|
||||
tree.write('pnpm-workspace.yaml', `packages:`);
|
||||
|
||||
|
||||
@ -149,6 +149,7 @@ describe('Remix Library Generator', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -196,6 +197,59 @@ describe('Remix Library Generator', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'packages/foo',
|
||||
style: 'css',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.read('packages/foo/package.json', 'utf-8'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/foo",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.esm.js",
|
||||
"module": "./dist/index.esm.js",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.esm.d.ts",
|
||||
"import": "./dist/index.esm.js",
|
||||
"default": "./dist/index.esm.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'packages/foo',
|
||||
style: 'css',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
buildable: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'packages/foo/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should generate server entrypoint', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'test',
|
||||
|
||||
@ -181,6 +181,9 @@ function updatePackageJson(
|
||||
({ main, outputPath } = mergedTarget.options);
|
||||
}
|
||||
|
||||
// the file must exist in the TS solution setup
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
main,
|
||||
outputPath,
|
||||
@ -191,6 +194,10 @@ function updatePackageJson(
|
||||
format: options.format ?? ['esm'],
|
||||
outputFileExtensionForCjs: '.cjs.js',
|
||||
outputFileExtensionForEsm: '.esm.js',
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes(
|
||||
'development'
|
||||
),
|
||||
});
|
||||
|
||||
// rollup has a specific declaration file generation not handled by the util above,
|
||||
|
||||
@ -331,7 +331,7 @@ describe('@nx/vite:configuration', () => {
|
||||
});
|
||||
|
||||
describe('TS solution setup', () => {
|
||||
beforeAll(async () => {
|
||||
beforeEach(async () => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
updateJson(tree, '/package.json', (json) => {
|
||||
json.workspaces = ['packages/*', 'apps/*'];
|
||||
@ -341,6 +341,7 @@ describe('@nx/vite:configuration', () => {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -371,6 +372,7 @@ describe('@nx/vite:configuration', () => {
|
||||
"exports": {
|
||||
".": {
|
||||
"default": "./dist/index.js",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
},
|
||||
@ -386,6 +388,31 @@ describe('@nx/vite:configuration', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
addProjectConfiguration(tree, 'my-lib', {
|
||||
root: 'packages/my-lib',
|
||||
});
|
||||
writeJson(tree, 'packages/my-lib/tsconfig.lib.json', {});
|
||||
writeJson(tree, 'packages/my-lib/tsconfig.json', {});
|
||||
|
||||
await viteConfigurationGenerator(tree, {
|
||||
addPlugin: true,
|
||||
uiFramework: 'none',
|
||||
project: 'my-lib',
|
||||
projectType: 'library',
|
||||
newProject: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'packages/my-lib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should create package.json without exports field for apps', async () => {
|
||||
addProjectConfiguration(tree, 'my-app', {
|
||||
root: 'apps/my-app',
|
||||
|
||||
@ -219,6 +219,10 @@ function updatePackageJson(
|
||||
const rootDir = join(project.root, 'src');
|
||||
const outputPath = joinPathFragments(project.root, 'dist');
|
||||
|
||||
// the file must exist in the TS solution setup, which is the only case this
|
||||
// function is called
|
||||
const tsconfigBase = readJson(tree, 'tsconfig.base.json');
|
||||
|
||||
packageJson = getUpdatedPackageJsonContent(packageJson, {
|
||||
main,
|
||||
outputPath,
|
||||
@ -227,6 +231,10 @@ function updatePackageJson(
|
||||
generateExportsField: true,
|
||||
packageJsonPath,
|
||||
format: ['esm'],
|
||||
skipDevelopmentExports:
|
||||
!tsconfigBase.compilerOptions?.customConditions?.includes(
|
||||
'development'
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,11 @@ import type { NormalizedSchema } from '../schema';
|
||||
export function determineEntryFields(
|
||||
options: NormalizedSchema
|
||||
): Pick<PackageJson, 'module' | 'types' | 'exports'> {
|
||||
if (options.bundler === 'none') {
|
||||
if (options.bundler !== 'none' || !options.isUsingTsSolutionConfig) {
|
||||
// for buildable libraries, the entries are configured by the bundler
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
module: options.js ? './src/index.js' : './src/index.ts',
|
||||
types: options.js ? './src/index.js' : './src/index.ts',
|
||||
@ -19,10 +23,4 @@ export function determineEntryFields(
|
||||
'./package.json': './package.json',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
module: './dist/index.mjs',
|
||||
types: './dist/index.d.ts',
|
||||
};
|
||||
}
|
||||
|
||||
@ -521,6 +521,7 @@ module.exports = [
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
declaration: true,
|
||||
customConditions: ['development'],
|
||||
},
|
||||
});
|
||||
writeJson(tree, 'tsconfig.json', {
|
||||
@ -585,6 +586,39 @@ module.exports = [
|
||||
"nx",
|
||||
]
|
||||
`);
|
||||
expect(tree.read('my-lib/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/my-lib",
|
||||
"version": "0.0.1",
|
||||
"module": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.ts",
|
||||
"import": "./src/index.ts",
|
||||
"default": "./src/index.ts"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint"
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/vite:test",
|
||||
"outputs": [
|
||||
"{options.reportsDirectory}"
|
||||
],
|
||||
"options": {
|
||||
"reportsDirectory": "../coverage/my-lib"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
expect(readJson(tree, 'my-lib/tsconfig.json')).toMatchInlineSnapshot(`
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
@ -690,6 +724,60 @@ module.exports = [
|
||||
`);
|
||||
});
|
||||
|
||||
it('should create a correct package.json for buildable libraries', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
...defaultSchema,
|
||||
setParserOptionsProject: true,
|
||||
linter: 'eslint',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
bundler: 'vite',
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.read('my-lib/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
"{
|
||||
"name": "@proj/my-lib",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not set the "development" condition in exports when it does not exist in tsconfig.base.json', async () => {
|
||||
updateJson(tree, 'tsconfig.base.json', (json) => {
|
||||
delete json.compilerOptions.customConditions;
|
||||
return json;
|
||||
});
|
||||
|
||||
await libraryGenerator(tree, {
|
||||
...defaultSchema,
|
||||
setParserOptionsProject: true,
|
||||
linter: 'eslint',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
bundler: 'vite',
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(
|
||||
readJson(tree, 'my-lib/package.json').exports['.']
|
||||
).not.toHaveProperty('development');
|
||||
});
|
||||
|
||||
it('should set "nx.name" in package.json when the user provides a name that is different than the package name', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
...defaultSchema,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user