Skip to content

Commit

Permalink
fix(js): generate js libs with exports in package.json and ensure esm…
Browse files Browse the repository at this point in the history
… output when using rollup bundler
  • Loading branch information
leosvelperez committed Jan 9, 2025
1 parent f98ae78 commit e7a253c
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export function createFiles(
? `${rootOffset}tsconfig.base.json`
: './tsconfig.json',
outDir: isTsSolutionSetup ? `./out-tsc/jest` : `${rootOffset}dist/out-tsc`,
module: !isTsSolutionSetup ? 'commonjs' : undefined,
module:
!isTsSolutionSetup || transformer === 'ts-jest' ? 'commonjs' : undefined,
});

if (options.setupFile === 'none') {
Expand Down
20 changes: 18 additions & 2 deletions packages/js/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1686,11 +1686,19 @@ describe('lib', () => {
"dependencies": {
"tslib": "^2.3.0",
},
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"name": "@proj/my-ts-lib",
"private": true,
"type": "module",
"typings": "./dist/index.d.ts",
"types": "./dist/index.d.ts",
"version": "0.0.1",
}
`);
Expand All @@ -1710,11 +1718,19 @@ describe('lib', () => {
"dependencies": {
"@swc/helpers": "~0.5.11",
},
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"name": "@proj/my-ts-lib",
"private": true,
"type": "module",
"typings": "./dist/index.d.ts",
"types": "./dist/index.d.ts",
"version": "0.0.1",
}
`);
Expand Down
149 changes: 96 additions & 53 deletions packages/js/src/generators/library/library.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
addDependenciesToPackageJson,
installPackagesTask,
addProjectConfiguration,
ensurePackage,
formatFiles,
generateFiles,
GeneratorCallback,
getPackageManagerCommand,
installPackagesTask,
joinPathFragments,
names,
offsetFromRoot,
Expand Down Expand Up @@ -35,6 +35,7 @@ import { type PackageJson } from 'nx/src/utils/package-json';
import { join } from 'path';
import type { CompilerOptions } from 'typescript';
import { normalizeLinterOption } from '../../utils/generator-prompts';
import { getUpdatedPackageJsonContent } from '../../utils/package-json/update-package-json';
import {
getProjectPackageManagerWorkspaceState,
getProjectPackageManagerWorkspaceStateWarningTask,
Expand All @@ -43,6 +44,7 @@ import { addSwcConfig } from '../../utils/swc/add-swc-config';
import { getSwcDependencies } from '../../utils/swc/add-swc-dependencies';
import { getNeededCompilerOptionOverrides } from '../../utils/typescript/configuration';
import { tsConfigBaseOptions } from '../../utils/typescript/create-ts-config';
import { ensureTypescript } from '../../utils/typescript/ensure-typescript';
import { ensureProjectIsIncludedInPluginRegistrations } from '../../utils/typescript/plugin';
import {
addTsConfigPath,
Expand All @@ -68,7 +70,6 @@ import type {
LibraryGeneratorSchema,
NormalizedLibraryGeneratorOptions,
} from './schema';
import { ensureTypescript } from '../../utils/typescript/ensure-typescript';

const defaultOutputDirectory = 'dist';

Expand Down Expand Up @@ -118,7 +119,7 @@ export async function libraryGeneratorInternal(
await configurationGenerator(tree, {
project: options.name,
compiler: 'swc',
format: ['cjs', 'esm'],
format: options.isUsingTsSolutionConfig ? ['esm'] : ['cjs', 'esm'],
});
}

Expand Down Expand Up @@ -206,6 +207,12 @@ export async function libraryGeneratorInternal(
// add project reference to the runtime tsconfig.lib.json file
json.references ??= [];
json.references.push({ path: './tsconfig.lib.json' });

if (options.isUsingTsSolutionConfig && options.bundler === 'rollup') {
json.compilerOptions.module = 'esnext';
json.compilerOptions.moduleResolution = 'bundler';
}

return json;
}
);
Expand Down Expand Up @@ -503,8 +510,7 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
let fileNameImport = options.fileName;
if (
options.bundler === 'vite' ||
(options.isUsingTsSolutionConfig &&
['esbuild', 'swc', 'tsc'].includes(options.bundler))
(options.isUsingTsSolutionConfig && options.bundler !== 'none')
) {
const tsConfig = readTsConfigFromTree(
tree,
Expand Down Expand Up @@ -606,17 +612,35 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
// https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files
json.files = ['dist', '!**/*.tsbuildinfo'];
}
return {

const updatedPackageJson = {
...json,
dependencies: {
...json.dependencies,
...determineDependencies(options),
},
...determineEntryFields(options),
};

if (
options.isUsingTsSolutionConfig &&
!['none', 'rollup', 'vite'].includes(options.bundler)
) {
return getUpdatedPackageJsonContent(updatedPackageJson, {
main: join(options.projectRoot, 'src/index.ts'),
outputPath: joinPathFragments(options.projectRoot, 'dist'),
projectRoot: options.projectRoot,
rootDir: join(options.projectRoot, 'src'),
generateExportsField: true,
packageJsonPath,
format: ['esm'],
});
}

return updatedPackageJson;
});
} else {
const packageJson: PackageJson = {
let packageJson: PackageJson = {
name: options.importPath,
version: '0.0.1',
dependencies: determineDependencies(options),
Expand All @@ -630,6 +654,22 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) {
// https://docs.npmjs.com/cli/v10/configuring-npm/package-json#files
packageJson.files = ['dist', '!**/*.tsbuildinfo'];
}

if (
options.isUsingTsSolutionConfig &&
!['none', 'rollup', 'vite'].includes(options.bundler)
) {
packageJson = getUpdatedPackageJsonContent(packageJson, {
main: join(options.projectRoot, 'src/index.ts'),
outputPath: joinPathFragments(options.projectRoot, 'dist'),
projectRoot: options.projectRoot,
rootDir: join(options.projectRoot, 'src'),
generateExportsField: true,
packageJsonPath,
format: ['esm'],
});
}

writeJson<PackageJson>(tree, packageJsonPath, packageJson);
}

Expand Down Expand Up @@ -1094,56 +1134,59 @@ function determineEntryFields(
): Record<string, EntryField> {
switch (options.bundler) {
case 'tsc':
return {
type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs',
main: options.isUsingTsSolutionConfig
? './dist/index.js'
: './src/index.js',
typings: options.isUsingTsSolutionConfig
? './dist/index.d.ts'
: './src/index.d.ts',
};
case 'swc':
return {
type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs',
main: options.isUsingTsSolutionConfig
? './dist/index.js'
: './src/index.js',
typings: options.isUsingTsSolutionConfig
? './dist/index.d.ts'
: './src/index.d.ts',
};
if (options.isUsingTsSolutionConfig) {
return {
type: 'module',
main: './dist/index.js',
module: './dist/index.js',
types: './dist/index.d.ts',
};
} else {
return {
type: 'commonjs',
main: './src/index.js',
types: './src/index.d.ts',
};
}
case 'rollup':
return {
// Since we're publishing both formats, skip the type field.
// Bundlers or Node will determine the entry point to use.
main: options.isUsingTsSolutionConfig
? './dist/index.cjs'
: './index.cjs',
module: options.isUsingTsSolutionConfig
? './dist/index.js'
: './index.js',
};
if (options.isUsingTsSolutionConfig) {
// the rollup configuration generator already handles this
return {};
} else {
return {
// Since we're publishing both formats, skip the type field.
// Bundlers or Node will determine the entry point to use.
main: './index.cjs',
module: './index.js',
};
}
case 'vite':
return {
type: 'module',
main: options.isUsingTsSolutionConfig
? './dist/index.js'
: './index.js',
typings: options.isUsingTsSolutionConfig
? './dist/index.d.ts'
: './index.d.ts',
};
if (options.isUsingTsSolutionConfig) {
// the vite configuration generator already handle this
return {};
} else {
return {
type: 'module',
main: './index.js',
types: './index.d.ts',
};
}
case 'esbuild':
return {
type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs',
main: options.isUsingTsSolutionConfig
? './dist/index.js'
: './index.cjs',
typings: options.isUsingTsSolutionConfig
? './dist/index.d.ts'
: './index.d.ts',
};
if (options.isUsingTsSolutionConfig) {
return {
type: 'module',
main: './dist/index.js',
module: './dist/index.js',
types: './dist/index.d.ts',
};
} else {
return {
type: 'commonjs',
main: './index.cjs',
types: './index.d.ts',
};
}
default: {
return {
// Safest option is to not set a type field.
Expand Down
2 changes: 1 addition & 1 deletion packages/js/src/generators/setup-build/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export async function setupBuildGenerator(
tsConfig: tsConfigFile,
project: options.project,
compiler: 'tsc',
format: ['cjs', 'esm'],
format: isTsSolutionSetup ? ['esm'] : ['cjs', 'esm'],
addPlugin,
skipFormat: true,
skipValidation: true,
Expand Down
4 changes: 2 additions & 2 deletions packages/js/src/utils/typescript/ts-solution-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
updateJson,
workspaceRoot,
} from '@nx/devkit';
import { basename, dirname, join } from 'node:path/posix';
import { FsTree } from 'nx/src/generators/tree';
import { isUsingPackageManagerWorkspaces } from '../package-manager-workspaces';
import { basename, dirname, join, relative } from 'node:path/posix';

export function isUsingTypeScriptPlugin(tree: Tree): boolean {
const nxJson = readNxJson(tree);
Expand Down Expand Up @@ -62,7 +62,7 @@ function isWorkspaceSetupWithTsSolution(tree: Tree): boolean {
if (
!baseTsconfigJson.compilerOptions ||
!baseTsconfigJson.compilerOptions.composite ||
!baseTsconfigJson.compilerOptions.declaration
baseTsconfigJson.compilerOptions.declaration === false
) {
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/nest/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ describe('lib', () => {
expect(readJson(tree, 'mylib/tsconfig.spec.json')).toMatchInlineSnapshot(`
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node10",
"outDir": "./out-tsc/jest",
"types": [
"jest",
Expand Down
12 changes: 11 additions & 1 deletion packages/node/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,8 @@ describe('lib', () => {
expect(readJson(tree, 'mylib/tsconfig.spec.json')).toMatchInlineSnapshot(`
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node10",
"outDir": "./out-tsc/jest",
"types": [
"jest",
Expand Down Expand Up @@ -648,7 +650,15 @@ describe('lib', () => {
"dependencies": {
"tslib": "^2.3.0",
},
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts",
},
"./package.json": "./package.json",
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"name": "@proj/mylib",
"nx": {
"name": "mylib",
Expand All @@ -672,7 +682,7 @@ describe('lib', () => {
},
"private": true,
"type": "module",
"typings": "./dist/index.d.ts",
"types": "./dist/index.d.ts",
"version": "0.0.1",
}
`);
Expand Down

0 comments on commit e7a253c

Please sign in to comment.