Skip to content

Commit bb363d6

Browse files
leosvelperezFrozenPandaz
authored andcommitted
fix(misc): ensure exports are generated for several lib generators in ts solution setup (#29588)
- Update React Native, React, Remix and Vue library generators to produce `exports` in the `package.json` for the TS solution setup - Fix an issue in `@nx/rollup/with-nx` where an unhandled `undefined` plugin was causing an error to be thrown - Fix output path of the build task for React Native libraries in the TS solution setup <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # (cherry picked from commit 9dbebbe)
1 parent 8d7505b commit bb363d6

File tree

12 files changed

+146
-45
lines changed

12 files changed

+146
-45
lines changed

e2e/nx/src/affected-graph.test.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ describe('Nx Affected and Graph Tests', () => {
3131
const mylib = uniq('mylib');
3232
const mylib2 = uniq('mylib2');
3333
const mypublishablelib = uniq('mypublishablelib');
34-
runCLI(`generate @nx/web:app apps/${myapp}`);
35-
runCLI(`generate @nx/web:app apps/${myapp2}`);
34+
runCLI(`generate @nx/web:app apps/${myapp} --unitTestRunner=vitest`);
35+
runCLI(`generate @nx/web:app apps/${myapp2} --unitTestRunner=vitest`);
3636
runCLI(`generate @nx/js:lib libs/${mylib}`);
3737
runCLI(`generate @nx/js:lib libs/${mylib2}`);
3838
runCLI(
@@ -193,8 +193,12 @@ describe('Nx Affected and Graph Tests', () => {
193193
});
194194

195195
function generateAll() {
196-
runCLI(`generate @nx/web:app apps/${myapp}`);
197-
runCLI(`generate @nx/web:app apps/${myapp2}`);
196+
runCLI(
197+
`generate @nx/web:app apps/${myapp} --bundler=webpack --unitTestRunner=vitest`
198+
);
199+
runCLI(
200+
`generate @nx/web:app apps/${myapp2} --bundler=webpack --unitTestRunner=vitest`
201+
);
198202
runCLI(`generate @nx/js:lib libs/${mylib}`);
199203
runCommand(`git add . && git commit -am "add all"`);
200204
}
@@ -536,8 +540,12 @@ describe('show projects --affected', () => {
536540
const mylib2 = uniq('mylib2');
537541
const mypublishablelib = uniq('mypublishablelib');
538542

539-
runCLI(`generate @nx/web:app ${myapp} --directory=apps/${myapp}`);
540-
runCLI(`generate @nx/web:app ${myapp2} --directory=apps/${myapp2}`);
543+
runCLI(
544+
`generate @nx/web:app ${myapp} --directory=apps/${myapp} --unitTestRunner=vitest`
545+
);
546+
runCLI(
547+
`generate @nx/web:app ${myapp2} --directory=apps/${myapp2} --unitTestRunner=vitest`
548+
);
541549
runCLI(`generate @nx/js:lib ${mylib} --directory=libs/${mylib}`);
542550
runCLI(`generate @nx/js:lib ${mylib2} --directory=libs/${mylib2}`);
543551
runCLI(

e2e/nx/src/misc.test.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ describe('Nx Commands', () => {
6868

6969
it('should show detailed project info', () => {
7070
const app = uniq('myapp');
71-
runCLI(`generate @nx/web:app apps/${app}`);
71+
runCLI(
72+
`generate @nx/web:app apps/${app} --bundler=webpack --unitTestRunner=vitest --linter=eslint`
73+
);
7274
const project: ProjectConfiguration = JSON.parse(
73-
runCLI(`show project ${app}`)
75+
runCLI(`show project ${app} --json`)
7476
);
7577
expect(project.targets.build).toBeDefined();
7678
expect(project.targets.lint).toBeDefined();

e2e/nx/src/run.test.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -695,8 +695,12 @@ describe('Nx Running Tests', () => {
695695
it('should run multiple targets', () => {
696696
const myapp1 = uniq('myapp');
697697
const myapp2 = uniq('myapp');
698-
runCLI(`generate @nx/web:app ${myapp1} --directory=apps/${myapp1}`);
699-
runCLI(`generate @nx/web:app ${myapp2} --directory=apps/${myapp2}`);
698+
runCLI(
699+
`generate @nx/web:app ${myapp1} --directory=apps/${myapp1} --unitTestRunner=vitest`
700+
);
701+
runCLI(
702+
`generate @nx/web:app ${myapp2} --directory=apps/${myapp2} --unitTestRunner=vitest`
703+
);
700704

701705
let outputs = runCLI(
702706
// Options with lists can be specified using multiple args or with a delimiter (comma or space).

packages/nx/src/utils/package-json.ts

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export interface PackageJson {
5555
require?: string;
5656
import?: string;
5757
development?: string;
58+
default?: string;
5859
}
5960
>;
6061
dependencies?: Record<string, string>;

packages/react-native/src/generators/library/library.ts

+42-9
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
updateTsconfigFiles,
4040
} from '@nx/js/src/utils/typescript/ts-solution-setup';
4141
import { getImportPath } from '@nx/js/src/utils/get-import-path';
42+
import type { PackageJson } from 'nx/src/utils/package-json';
4243

4344
export async function reactNativeLibraryGenerator(
4445
host: Tree,
@@ -162,17 +163,15 @@ async function addProject(
162163
targets: {},
163164
};
164165

166+
const packageJsonPath = joinPathFragments(
167+
options.projectRoot,
168+
'package.json'
169+
);
165170
if (options.isUsingTsSolutionConfig) {
166-
const sourceEntry = !options.buildable
167-
? options.js
168-
? './src/index.js'
169-
: './src/index.ts'
170-
: undefined;
171-
writeJson(host, joinPathFragments(options.projectRoot, 'package.json'), {
171+
writeJson(host, packageJsonPath, {
172172
name: getImportPath(host, options.name),
173173
version: '0.0.1',
174-
main: sourceEntry,
175-
types: sourceEntry,
174+
...determineEntryFields(options),
176175
nx: {
177176
name: options.name,
178177
sourceRoot: joinPathFragments(options.projectRoot, 'src'),
@@ -198,13 +197,24 @@ async function addProject(
198197
skipFormat: true,
199198
});
200199

200+
updateJson(host, packageJsonPath, (json) => {
201+
if (json.type === 'module') {
202+
// The @nx/rollup:configuration generator can set the type to 'module' which would
203+
// potentially break this library.
204+
delete json.type;
205+
}
206+
return json;
207+
});
208+
201209
const external = ['react/jsx-runtime', 'react-native', 'react', 'react-dom'];
202210

203211
project.targets.build = {
204212
executor: '@nx/rollup:rollup',
205213
outputs: ['{options.outputPath}'],
206214
options: {
207-
outputPath: `dist/${options.projectRoot}`,
215+
outputPath: options.isUsingTsSolutionConfig
216+
? `${options.projectRoot}/dist`
217+
: `dist/${options.projectRoot}`,
208218
tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
209219
project: `${options.projectRoot}/package.json`,
210220
entryFile: maybeJs(options, `${options.projectRoot}/src/index.ts`),
@@ -293,4 +303,27 @@ function maybeJs(options: NormalizedSchema, path: string): string {
293303
: path;
294304
}
295305

306+
function determineEntryFields(
307+
options: NormalizedSchema
308+
): Pick<PackageJson, 'main' | 'types' | 'exports'> {
309+
if (options.buildable) {
310+
return {};
311+
}
312+
313+
return {
314+
main: options.js ? './src/index.js' : './src/index.ts',
315+
types: options.js ? './src/index.js' : './src/index.ts',
316+
exports: {
317+
'.': options.js
318+
? './src/index.js'
319+
: {
320+
types: './src/index.ts',
321+
import: './src/index.ts',
322+
default: './src/index.ts',
323+
},
324+
'./package.json': './package.json',
325+
},
326+
};
327+
}
328+
296329
export default reactNativeLibraryGenerator;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { PackageJson } from 'nx/src/utils/package-json';
2+
import type { NormalizedSchema } from '../schema';
3+
4+
export function determineEntryFields(
5+
options: NormalizedSchema
6+
): Pick<PackageJson, 'main' | 'types' | 'exports'> {
7+
if (options.bundler !== 'none') {
8+
return {};
9+
}
10+
11+
return {
12+
main: options.js ? './src/index.js' : './src/index.ts',
13+
types: options.js ? './src/index.js' : './src/index.ts',
14+
exports: {
15+
'.': options.js
16+
? './src/index.js'
17+
: {
18+
types: './src/index.ts',
19+
import: './src/index.ts',
20+
default: './src/index.ts',
21+
},
22+
'./package.json': './package.json',
23+
},
24+
};
25+
}

packages/react/src/generators/library/library.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,14 @@ module.exports = withNx(
11441144

11451145
expect(readJson(tree, 'mylib/package.json')).toMatchInlineSnapshot(`
11461146
{
1147+
"exports": {
1148+
".": {
1149+
"default": "./src/index.ts",
1150+
"import": "./src/index.ts",
1151+
"types": "./src/index.ts",
1152+
},
1153+
"./package.json": "./package.json",
1154+
},
11471155
"main": "./src/index.ts",
11481156
"name": "@proj/mylib",
11491157
"nx": {
@@ -1157,6 +1165,10 @@ module.exports = withNx(
11571165
`);
11581166
expect(readJson(tree, 'myjslib/package.json')).toMatchInlineSnapshot(`
11591167
{
1168+
"exports": {
1169+
".": "./src/index.js",
1170+
"./package.json": "./package.json",
1171+
},
11601172
"main": "./src/index.js",
11611173
"name": "@proj/myjslib",
11621174
"nx": {

packages/react/src/generators/library/library.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
addProjectToTsSolutionWorkspace,
3636
updateTsconfigFiles,
3737
} from '@nx/js/src/utils/typescript/ts-solution-setup';
38+
import { determineEntryFields } from './lib/determine-entry-fields';
3839

3940
export async function libraryGenerator(host: Tree, schema: Schema) {
4041
return await libraryGeneratorInternal(host, {
@@ -69,17 +70,10 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
6970
tasks.push(initTask);
7071

7172
if (options.isUsingTsSolutionConfig) {
72-
const sourceEntry =
73-
options.bundler === 'none'
74-
? options.js
75-
? './src/index.js'
76-
: './src/index.ts'
77-
: undefined;
7873
writeJson(host, `${options.projectRoot}/package.json`, {
7974
name: options.importPath,
8075
version: '0.0.1',
81-
main: sourceEntry,
82-
types: sourceEntry,
76+
...determineEntryFields(options),
8377
nx: {
8478
name: options.importPath === options.name ? undefined : options.name,
8579
projectType: 'library',

packages/remix/src/generators/library/library.impl.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ describe('Remix Library Generator', () => {
167167
expect(readJson(tree, 'packages/foo/package.json'))
168168
.toMatchInlineSnapshot(`
169169
{
170+
"exports": {
171+
".": {
172+
"default": "./src/index.ts",
173+
"import": "./src/index.ts",
174+
"types": "./src/index.ts",
175+
},
176+
"./package.json": "./package.json",
177+
},
170178
"main": "./src/index.ts",
171179
"name": "@proj/foo",
172180
"nx": {

packages/rollup/src/plugins/with-nx/with-nx.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ export function withNx(
265265
commonjs(),
266266
analyze(),
267267
options.generatePackageJson && generatePackageJson(options, packageJson),
268-
];
268+
].filter(Boolean);
269269
if (Array.isArray(rollupConfig.plugins)) {
270270
finalConfig.plugins.push(...rollupConfig.plugins);
271271
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { PackageJson } from 'nx/src/utils/package-json';
2+
import type { NormalizedSchema } from '../schema';
3+
4+
export function determineEntryFields(
5+
options: NormalizedSchema
6+
): Pick<PackageJson, 'module' | 'types' | 'exports'> {
7+
if (options.bundler === 'none') {
8+
return {
9+
module: options.js ? './src/index.js' : './src/index.ts',
10+
types: options.js ? './src/index.js' : './src/index.ts',
11+
exports: {
12+
'.': options.js
13+
? './src/index.js'
14+
: {
15+
types: './src/index.ts',
16+
import: './src/index.ts',
17+
default: './src/index.ts',
18+
},
19+
'./package.json': './package.json',
20+
},
21+
};
22+
}
23+
24+
return {
25+
module: './dist/index.mjs',
26+
types: './dist/index.d.ts',
27+
};
28+
}

packages/vue/src/generators/library/library.ts

+3-17
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ import {
44
GeneratorCallback,
55
installPackagesTask,
66
joinPathFragments,
7-
readNxJson,
87
runTasksInSerial,
98
toJS,
109
Tree,
1110
updateJson,
12-
updateNxJson,
1311
writeJson,
1412
} from '@nx/devkit';
1513
import { addTsConfigPath, initGenerator as jsInitGenerator } from '@nx/js';
@@ -30,6 +28,7 @@ import {
3028
addProjectToTsSolutionWorkspace,
3129
updateTsconfigFiles,
3230
} from '@nx/js/src/utils/typescript/ts-solution-setup';
31+
import { determineEntryFields } from './lib/determine-entry-fields';
3332

3433
export function libraryGenerator(tree: Tree, schema: Schema) {
3534
return libraryGeneratorInternal(tree, { addPlugin: false, ...schema });
@@ -48,28 +47,15 @@ export async function libraryGeneratorInternal(tree: Tree, schema: Schema) {
4847
}
4948

5049
if (options.isUsingTsSolutionConfig) {
51-
const moduleFile =
52-
options.bundler === 'none'
53-
? options.js
54-
? './src/index.js'
55-
: './src/index.ts'
56-
: './dist/index.mjs';
57-
const typesFile =
58-
options.bundler === 'none'
59-
? options.js
60-
? './src/index.js'
61-
: './src/index.ts'
62-
: './dist/index.d.ts';
6350
writeJson(tree, joinPathFragments(options.projectRoot, 'package.json'), {
6451
name: getImportPath(tree, options.name),
6552
version: '0.0.1',
6653
private: true,
67-
module: moduleFile,
68-
types: typesFile,
54+
...determineEntryFields(options),
6955
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
7056
nx: {
7157
name: options.name,
72-
projectType: 'application',
58+
projectType: 'library',
7359
sourceRoot: `${options.projectRoot}/src`,
7460
tags: options.parsedTags?.length ? options.parsedTags : undefined,
7561
},

0 commit comments

Comments
 (0)