diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3c50d2a36..6d8c76015f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,8 @@ jobs: - name: Set SHAs uses: nrwl/nx-set-shas@v4 + with: + main-branch-name: 'master' - name: Start CI Run run: npx nx-cloud@next start-ci-run --distribute-on="./.nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e" @@ -147,7 +149,9 @@ jobs: - name: Set SHAs uses: nrwl/nx-set-shas@v4 - + with: + main-branch-name: 'master' + - name: Run E2E Tests for macOS run: | HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD); diff --git a/docs/generated/packages/react-native/generators/component.json b/docs/generated/packages/react-native/generators/component.json index 1e51f213cc..a0d4c7e7d4 100644 --- a/docs/generated/packages/react-native/generators/component.json +++ b/docs/generated/packages/react-native/generators/component.json @@ -59,6 +59,12 @@ "alias": "C", "description": "Use class components instead of functional component.", "default": false + }, + "skipFormat": { + "description": "Skip formatting files.", + "type": "boolean", + "default": false, + "x-priority": "internal" } }, "required": ["path"], diff --git a/packages/expo/src/generators/component/component.ts b/packages/expo/src/generators/component/component.ts index b2a0d0fe5f..114af09d1a 100644 --- a/packages/expo/src/generators/component/component.ts +++ b/packages/expo/src/generators/component/component.ts @@ -53,7 +53,9 @@ function addExportsToBarrel(host: Tree, options: NormalizedSchema) { if (options.export && !isApp) { const indexFilePath = joinPathFragments( - options.projectSourceRoot, + ...(options.projectSourceRoot + ? [options.projectSourceRoot] + : [options.projectRoot, 'src']), options.fileExtensionType === 'js' ? 'index.js' : 'index.ts' ); diff --git a/packages/expo/src/generators/component/lib/normalize-options.ts b/packages/expo/src/generators/component/lib/normalize-options.ts index 082d5fc37f..9096860226 100644 --- a/packages/expo/src/generators/component/lib/normalize-options.ts +++ b/packages/expo/src/generators/component/lib/normalize-options.ts @@ -15,6 +15,7 @@ export interface NormalizedSchema extends Omit { className: string; filePath: string; projectName: string; + projectRoot: string; } export async function normalizeOptions( @@ -63,5 +64,6 @@ export async function normalizeOptions( filePath, projectSourceRoot, projectName, + projectRoot: root, }; } diff --git a/packages/expo/src/generators/library/files/lib/package.json.template b/packages/expo/src/generators/library/files/lib/package.json.template deleted file mode 100644 index 659561c71b..0000000000 --- a/packages/expo/src/generators/library/files/lib/package.json.template +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "<%= projectName %>", - "version": "0.0.1", - "main": "<%= appMain %>" -} diff --git a/packages/expo/src/generators/library/lib/normalize-options.ts b/packages/expo/src/generators/library/lib/normalize-options.ts index fbdfd1892b..d60d1e50e5 100644 --- a/packages/expo/src/generators/library/lib/normalize-options.ts +++ b/packages/expo/src/generators/library/lib/normalize-options.ts @@ -14,7 +14,6 @@ export interface NormalizedSchema extends Schema { projectRoot: string; routePath: string; parsedTags: string[]; - appMain: string; isUsingTsSolutionConfig: boolean; } @@ -43,7 +42,6 @@ export async function normalizeOptions( const parsedTags = options.tags ? options.tags.split(',').map((s) => s.trim()) : []; - const appMain = options.js ? 'src/index.js' : 'src/index.ts'; const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host); const normalized: NormalizedSchema = { @@ -52,12 +50,11 @@ export async function normalizeOptions( routePath: `/${projectNames.projectSimpleName}`, name: projectName, projectName: isUsingTsSolutionConfig - ? getImportPath(host, projectName) + ? importPath ?? getImportPath(host, projectName) : projectName, projectRoot, parsedTags, importPath, - appMain, isUsingTsSolutionConfig, }; diff --git a/packages/expo/src/generators/library/library.spec.ts b/packages/expo/src/generators/library/library.spec.ts index 35314e1d9e..582a86102b 100644 --- a/packages/expo/src/generators/library/library.spec.ts +++ b/packages/expo/src/generators/library/library.spec.ts @@ -10,7 +10,7 @@ import { } from '@nx/devkit'; import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import { Linter } from '@nx/eslint'; - +import { hasPlugin as hasRollupPlugin } from '@nx/rollup/src/utils/has-plugin'; import { expoLibraryGenerator } from './library'; import { Schema } from './schema'; @@ -333,40 +333,27 @@ describe('lib', () => { }); describe('--buildable', () => { - it('should have a builder defined', async () => { + it('should add a rollup.config.cjs', async () => { await expoLibraryGenerator(appTree, { ...defaultSchema, buildable: true, }); - const projects = getProjects(appTree); - - expect(projects.get('my-lib').targets.build).toBeDefined(); + expect(appTree.exists('my-lib/rollup.config.cjs')).toBeTruthy(); + expect(hasRollupPlugin(appTree)).toBeTruthy(); }); }); describe('--publishable', () => { - it('should add build architect', async () => { + it('should add a rollup.config.cjs', async () => { await expoLibraryGenerator(appTree, { ...defaultSchema, publishable: true, importPath: '@proj/my-lib', }); - const projects = getProjects(appTree); - - expect(projects.get('my-lib').targets.build).toMatchObject({ - executor: '@nx/rollup:rollup', - outputs: ['{options.outputPath}'], - options: { - external: ['react/jsx-runtime', 'react-native', 'react', 'react-dom'], - entryFile: 'my-lib/src/index.ts', - outputPath: 'dist/my-lib', - project: 'my-lib/package.json', - tsConfig: 'my-lib/tsconfig.lib.json', - rollupConfig: '@nx/react/plugins/bundle-rollup', - }, - }); + expect(appTree.exists('my-lib/rollup.config.cjs')).toBeTruthy(); + expect(hasRollupPlugin(appTree)).toBeTruthy(); }); it('should fail if no importPath is provided with publishable', async () => { @@ -516,6 +503,11 @@ describe('lib', () => { }, "main": "./src/index.ts", "name": "@proj/my-lib", + "nx": {}, + "peerDependencies": { + "react": "~18.3.1", + "react-native": "0.76.3", + }, "types": "./src/index.ts", "version": "0.0.1", } @@ -528,6 +520,8 @@ describe('lib', () => { "main", "types", "exports", + "nx", + "peerDependencies", ] `); expect(readJson(appTree, 'my-lib/tsconfig.json')).toMatchInlineSnapshot(` @@ -636,53 +630,20 @@ describe('lib', () => { { "exports": { ".": { - "default": "./dist/index.esm.js", - "import": "./dist/index.esm.js", + "default": "./src/index.ts", + "import": "./src/index.ts", "types": "./dist/index.esm.d.ts", }, "./package.json": "./package.json", }, - "main": "./dist/index.esm.js", + "main": "./src/index.ts", "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}", - ], - }, - }, - }, + "nx": {}, "peerDependencies": { "react": "~18.3.1", "react-native": "0.76.3", }, - "type": "module", "types": "./dist/index.esm.d.ts", "version": "0.0.1", } diff --git a/packages/expo/src/generators/library/library.ts b/packages/expo/src/generators/library/library.ts index 1b49232acd..0516ef70d0 100644 --- a/packages/expo/src/generators/library/library.ts +++ b/packages/expo/src/generators/library/library.ts @@ -1,6 +1,5 @@ import { addProjectConfiguration, - ensurePackage, formatFiles, generateFiles, GeneratorCallback, @@ -13,7 +12,6 @@ import { toJS, Tree, updateJson, - updateProjectConfiguration, writeJson, } from '@nx/devkit'; @@ -25,22 +23,22 @@ import { import init from '../init/init'; import { addLinting } from '../../utils/add-linting'; import { addJest } from '../../utils/add-jest'; -import { - nxVersion, - reactNativeVersion, - reactVersion, -} from '../../utils/versions'; import { NormalizedSchema, normalizeOptions } from './lib/normalize-options'; import { Schema } from './schema'; import { ensureDependencies } from '../../utils/ensure-dependencies'; import { initRootBabelConfig } from '../../utils/init-root-babel-config'; -import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils'; import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command'; import { addProjectToTsSolutionWorkspace, updateTsconfigFiles, } from '@nx/js/src/utils/typescript/ts-solution-setup'; import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields'; +import { PackageJson } from 'nx/src/utils/package-json'; +import { addRollupBuildTarget } from '@nx/react/src/generators/library/lib/add-rollup-build-target'; +import { getRelativeCwd } from '@nx/devkit/src/generators/artifact-name-and-directory-utils'; +import { expoComponentGenerator } from '../component/component'; +import { relative } from 'path'; +import { reactNativeVersion, reactVersion } from '../../utils/versions'; export async function expoLibraryGenerator( host: Tree, @@ -109,16 +107,26 @@ export async function expoLibraryGeneratorInternal( ); tasks.push(jestTask); - if (options.publishable || options.buildable) { - updateLibPackageNpmScope(host, options); - } + const relativeCwd = getRelativeCwd(); + const path = joinPathFragments( + options.projectRoot, + 'src/lib', + options.fileName + ); + const componentTask = await expoComponentGenerator(host, { + path: relativeCwd ? relative(relativeCwd, path) : path, + skipTests: options.unitTestRunner === 'none', + export: true, + skipFormat: true, + js: options.js, + }); + tasks.push(() => componentTask); if (!options.skipTsConfig && !options.isUsingTsSolutionConfig) { addTsConfigPath(host, options.importPath, [ joinPathFragments( options.projectRoot, - './src', - 'index.' + (options.js ? 'js' : 'ts') + options.js ? './src/index.js' : './src/index.ts' ), ]); } @@ -168,81 +176,53 @@ async function addProject( }; if (options.isUsingTsSolutionConfig) { - const sourceEntry = !options.buildable - ? options.js - ? './src/index.js' - : './src/index.ts' - : undefined; writeJson(host, joinPathFragments(options.projectRoot, 'package.json'), { name: options.projectName, version: '0.0.1', - main: sourceEntry, - types: sourceEntry, - // 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, + ...determineEntryFields(options), + nx: { + tags: options.parsedTags?.length ? options.parsedTags : undefined, + }, + files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined, + peerDependencies: { + react: reactVersion, + 'react-native': reactNativeVersion, + }, }); } else { addProjectConfiguration(host, options.name, project); } - if (!options.publishable && !options.buildable) { - return () => {}; + if (options.publishable || options.buildable) { + const external = new Set([ + 'react/jsx-runtime', + 'react-native', + 'react', + 'react-dom', + ]); + const rollupTask = await addRollupBuildTarget( + host, + { + ...options, + name: options.projectName, + format: ['cjs', 'esm'], + style: 'none', + js: options.js, + skipFormat: true, + }, + external + ); + updateJson(host, `${options.projectRoot}/package.json`, (json) => { + json.peerDependencies = { + ...json.peerDependencies, + react: reactVersion, + 'react-native': reactNativeVersion, + }; + return json; + }); + return rollupTask; } - - const { configurationGenerator } = ensurePackage( - '@nx/rollup', - nxVersion - ); - const rollupConfigTask = await configurationGenerator(host, { - ...options, - project: options.projectName, - skipFormat: true, - }); - - const external = ['react/jsx-runtime', 'react-native', 'react', 'react-dom']; - - addBuildTargetDefaults(host, '@nx/rollup:rollup'); - - project.targets.build = { - executor: '@nx/rollup:rollup', - outputs: ['{options.outputPath}'], - options: { - outputPath: `dist/${options.projectRoot}`, - tsConfig: `${options.projectRoot}/tsconfig.lib.json`, - project: `${options.projectRoot}/package.json`, - entryFile: maybeJs(options, `${options.projectRoot}/src/index.ts`), - external, - rollupConfig: `@nx/react/plugins/bundle-rollup`, - assets: [ - { - glob: `${options.projectRoot}/README.md`, - input: '.', - output: '.', - }, - ], - }, - }; - - updateProjectConfiguration(host, options.projectName, project); - - return rollupConfigTask; + return () => {}; } function updateTsConfig(tree: Tree, options: NormalizedSchema) { @@ -282,14 +262,6 @@ function createFiles(host: Tree, options: NormalizedSchema) { } ); - if ( - !options.publishable && - !options.buildable && - !options.isUsingTsSolutionConfig - ) { - host.delete(`${options.projectRoot}/package.json`); - } - if (options.js) { toJS(host); } @@ -297,21 +269,23 @@ function createFiles(host: Tree, options: NormalizedSchema) { updateTsConfig(host, options); } -function updateLibPackageNpmScope(host: Tree, options: NormalizedSchema) { - return updateJson(host, `${options.projectRoot}/package.json`, (json) => { - json.name = options.importPath; - json.peerDependencies = { - react: reactVersion, - 'react-native': reactNativeVersion, - }; - return json; - }); -} - -function maybeJs(options: NormalizedSchema, path: string): string { - return options.js && (path.endsWith('.ts') || path.endsWith('.tsx')) - ? path.replace(/\.tsx?$/, '.js') - : path; +function determineEntryFields( + options: NormalizedSchema +): Pick { + return { + main: options.js ? './src/index.js' : './src/index.ts', + types: options.js ? './src/index.js' : './src/index.ts', + exports: { + '.': options.js + ? './src/index.js' + : { + types: './src/index.ts', + import: './src/index.ts', + default: './src/index.ts', + }, + './package.json': './package.json', + }, + }; } export default expoLibraryGenerator; diff --git a/packages/react-native/src/generators/component/component.ts b/packages/react-native/src/generators/component/component.ts index 9667296269..53a746459a 100644 --- a/packages/react-native/src/generators/component/component.ts +++ b/packages/react-native/src/generators/component/component.ts @@ -22,7 +22,9 @@ export async function reactNativeComponentGenerator( addExportsToBarrel(host, options); - await formatFiles(host); + if (!options.skipFormat) { + await formatFiles(host); + } } function createComponentFiles(host: Tree, options: NormalizedSchema) { @@ -59,7 +61,9 @@ function addExportsToBarrel(host: Tree, options: NormalizedSchema) { if (options.export && !isApp) { const indexFilePath = joinPathFragments( - options.projectSourceRoot, + ...(options.projectSourceRoot + ? [options.projectSourceRoot] + : [options.projectRoot, 'src']), options.fileExtensionType === 'js' ? 'index.js' : 'index.ts' ); diff --git a/packages/react-native/src/generators/component/lib/normalize-options.ts b/packages/react-native/src/generators/component/lib/normalize-options.ts index 0185c2d95a..027aed3f82 100644 --- a/packages/react-native/src/generators/component/lib/normalize-options.ts +++ b/packages/react-native/src/generators/component/lib/normalize-options.ts @@ -15,6 +15,7 @@ export interface NormalizedSchema extends Omit { fileExtension: string; fileExtensionType: FileExtensionType; projectName: string; + projectRoot: string; } export async function normalizeOptions( @@ -65,5 +66,6 @@ export async function normalizeOptions( fileExtensionType, projectSourceRoot, projectName, + projectRoot: root, }; } diff --git a/packages/react-native/src/generators/component/schema.d.ts b/packages/react-native/src/generators/component/schema.d.ts index b0b95f7b1d..5f9dec95e8 100644 --- a/packages/react-native/src/generators/component/schema.d.ts +++ b/packages/react-native/src/generators/component/schema.d.ts @@ -7,6 +7,7 @@ export interface Schema { skipTests?: boolean; export?: boolean; classComponent?: boolean; + skipFormat?: boolean; /** * @deprecated Provide the full file path including the file extension in the `path` option. This option will be removed in Nx v21. diff --git a/packages/react-native/src/generators/component/schema.json b/packages/react-native/src/generators/component/schema.json index 486ff3e00b..28b03c26bb 100644 --- a/packages/react-native/src/generators/component/schema.json +++ b/packages/react-native/src/generators/component/schema.json @@ -59,6 +59,12 @@ "alias": "C", "description": "Use class components instead of functional component.", "default": false + }, + "skipFormat": { + "description": "Skip formatting files.", + "type": "boolean", + "default": false, + "x-priority": "internal" } }, "required": ["path"] diff --git a/packages/react-native/src/generators/library/files/lib/package.json.template b/packages/react-native/src/generators/library/files/lib/package.json.template deleted file mode 100644 index fa518765a3..0000000000 --- a/packages/react-native/src/generators/library/files/lib/package.json.template +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "<%= name %>", - "version": "0.0.1" -} diff --git a/packages/react-native/src/generators/library/lib/normalize-options.ts b/packages/react-native/src/generators/library/lib/normalize-options.ts index 3bc82180a9..ae8f110ea0 100644 --- a/packages/react-native/src/generators/library/lib/normalize-options.ts +++ b/packages/react-native/src/generators/library/lib/normalize-options.ts @@ -51,7 +51,7 @@ export async function normalizeOptions( fileName: projectName, routePath: `/${projectNames.projectSimpleName}`, name: isUsingTsSolutionConfig - ? getImportPath(host, projectName) + ? options.importPath ?? getImportPath(host, projectName) : projectName, projectRoot, parsedTags, diff --git a/packages/react-native/src/generators/library/library.spec.ts b/packages/react-native/src/generators/library/library.spec.ts index 1764409e9b..7e60fc1def 100644 --- a/packages/react-native/src/generators/library/library.spec.ts +++ b/packages/react-native/src/generators/library/library.spec.ts @@ -10,6 +10,7 @@ import { import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; import libraryGenerator from './library'; import { Linter } from '@nx/eslint'; +import { hasPlugin as hasRollupPlugin } from '@nx/rollup/src/utils/has-plugin'; import { Schema } from './schema'; describe('lib', () => { @@ -309,40 +310,27 @@ describe('lib', () => { }); describe('--buildable', () => { - it('should have a builder defined', async () => { + it('should add a rollup.config.cjs', async () => { await libraryGenerator(appTree, { ...defaultSchema, buildable: true, }); - const projectConfiguration = readProjectConfiguration(appTree, 'my-lib'); - - expect(projectConfiguration.targets.build).toBeDefined(); + expect(appTree.exists('my-lib/rollup.config.cjs')).toBeTruthy(); + expect(hasRollupPlugin(appTree)).toBeTruthy(); }); }); describe('--publishable', () => { - it('should add build architect', async () => { + it('should add a rollup.config.cjs', async () => { await libraryGenerator(appTree, { ...defaultSchema, publishable: true, importPath: '@proj/my-lib', }); - const projectConfiguration = readProjectConfiguration(appTree, 'my-lib'); - - expect(projectConfiguration.targets.build).toMatchObject({ - executor: '@nx/rollup:rollup', - outputs: ['{options.outputPath}'], - options: { - external: ['react/jsx-runtime', 'react-native', 'react', 'react-dom'], - entryFile: 'my-lib/src/index.ts', - outputPath: 'dist/my-lib', - project: 'my-lib/package.json', - tsConfig: 'my-lib/tsconfig.lib.json', - rollupConfig: '@nx/react/plugins/bundle-rollup', - }, - }); + expect(appTree.exists('my-lib/rollup.config.cjs')).toBeTruthy(); + expect(hasRollupPlugin(appTree)).toBeTruthy(); }); it('should fail if no importPath is provided with publishable', async () => { @@ -492,16 +480,26 @@ describe('lib', () => { ] `); // Make sure keys are in idiomatic order - expect(Object.keys(readJson(appTree, 'my-lib/package.json'))) - .toMatchInlineSnapshot(` - [ - "name", - "version", - "main", - "types", - "exports", - "nx", - ] + 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", + "nx": {}, + "peerDependencies": { + "react": "~18.3.1", + "react-native": "~0.76.3", + }, + "types": "./src/index.ts", + "version": "0.0.1", + } `); expect(readJson(appTree, 'my-lib/tsconfig.json')).toMatchInlineSnapshot(` { diff --git a/packages/react-native/src/generators/library/library.ts b/packages/react-native/src/generators/library/library.ts index d624485060..45bbac96e7 100644 --- a/packages/react-native/src/generators/library/library.ts +++ b/packages/react-native/src/generators/library/library.ts @@ -1,6 +1,5 @@ import { addProjectConfiguration, - ensurePackage, formatFiles, generateFiles, GeneratorCallback, @@ -13,7 +12,6 @@ import { toJS, Tree, updateJson, - updateProjectConfiguration, writeJson, } from '@nx/devkit'; @@ -25,11 +23,7 @@ import { import init from '../init/init'; import { addLinting } from '../../utils/add-linting'; import { addJest } from '../../utils/add-jest'; -import { - nxVersion, - reactNativeVersion, - reactVersion, -} from '../../utils/versions'; +import componentGenerator from '../component/component'; import { NormalizedSchema, normalizeOptions } from './lib/normalize-options'; import { Schema } from './schema'; import { ensureDependencies } from '../../utils/ensure-dependencies'; @@ -38,9 +32,17 @@ import { addProjectToTsSolutionWorkspace, updateTsconfigFiles, } from '@nx/js/src/utils/typescript/ts-solution-setup'; -import { getImportPath } from '@nx/js/src/utils/get-import-path'; -import type { PackageJson } from 'nx/src/utils/package-json'; import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields'; +import { + addReleaseConfigForNonTsSolution, + addReleaseConfigForTsSolution, + releaseTasks, +} from '@nx/js/src/generators/library/utils/add-release-config'; +import { PackageJson } from 'nx/src/utils/package-json'; +import { addRollupBuildTarget } from '@nx/react/src/generators/library/lib/add-rollup-build-target'; +import { getRelativeCwd } from '@nx/devkit/src/generators/artifact-name-and-directory-utils'; +import { relative } from 'path'; +import { reactNativeVersion, reactVersion } from '../../utils/versions'; export async function reactNativeLibraryGenerator( host: Tree, @@ -106,9 +108,20 @@ export async function reactNativeLibraryGeneratorInternal( ); tasks.push(jestTask); - if (options.publishable || options.buildable) { - updateLibPackageNpmScope(host, options); - } + const relativeCwd = getRelativeCwd(); + const path = joinPathFragments( + options.projectRoot, + 'src/lib', + options.fileName + ); + const componentTask = await componentGenerator(host, { + path: relativeCwd ? relative(relativeCwd, path) : path, + skipTests: options.unitTestRunner === 'none', + export: true, + skipFormat: true, + js: options.js, + }); + tasks.push(() => componentTask); if (!options.skipTsConfig && !options.isUsingTsSolutionConfig) { addTsConfigPath(host, options.importPath, [ @@ -167,10 +180,6 @@ async function addProject( targets: {}, }; - const packageJsonPath = joinPathFragments( - options.projectRoot, - 'package.json' - ); if (options.isUsingTsSolutionConfig) { writeJson(host, joinPathFragments(options.projectRoot, 'package.json'), { name: options.name, @@ -179,61 +188,45 @@ async function addProject( nx: { tags: options.parsedTags?.length ? options.parsedTags : undefined, }, + files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined, + peerDependencies: { + react: reactVersion, + 'react-native': reactNativeVersion, + }, }); } else { addProjectConfiguration(host, options.name, project); } - if (!options.publishable && !options.buildable) { - return () => {}; + if (options.publishable || options.buildable) { + const external = new Set([ + 'react/jsx-runtime', + 'react-native', + 'react', + 'react-dom', + ]); + const rollupTask = await addRollupBuildTarget( + host, + { + ...options, + format: ['cjs', 'esm'], + style: 'none', + js: options.js, + skipFormat: true, + }, + external + ); + updateJson(host, `${options.projectRoot}/package.json`, (json) => { + json.peerDependencies = { + ...json.peerDependencies, + react: reactVersion, + 'react-native': reactNativeVersion, + }; + return json; + }); + return rollupTask; } - - const { configurationGenerator } = ensurePackage( - '@nx/rollup', - nxVersion - ); - const rollupConfigTask = await configurationGenerator(host, { - ...options, - project: options.name, - skipFormat: true, - }); - - updateJson(host, packageJsonPath, (json) => { - if (json.type === 'module') { - // The @nx/rollup:configuration generator can set the type to 'module' which would - // potentially break this library. - delete json.type; - } - return json; - }); - - const external = ['react/jsx-runtime', 'react-native', 'react', 'react-dom']; - - project.targets.build = { - executor: '@nx/rollup:rollup', - outputs: ['{options.outputPath}'], - options: { - outputPath: options.isUsingTsSolutionConfig - ? `${options.projectRoot}/dist` - : `dist/${options.projectRoot}`, - tsConfig: `${options.projectRoot}/tsconfig.lib.json`, - project: `${options.projectRoot}/package.json`, - entryFile: maybeJs(options, `${options.projectRoot}/src/index.ts`), - external, - rollupConfig: `@nx/react/plugins/bundle-rollup`, - assets: [ - { - glob: `${options.projectRoot}/README.md`, - input: '.', - output: '.', - }, - ], - }, - }; - - updateProjectConfiguration(host, options.name, project); - - return rollupConfigTask; + return () => {}; } function updateTsConfig(tree: Tree, options: NormalizedSchema) { @@ -276,10 +269,6 @@ function createFiles(host: Tree, options: NormalizedSchema) { } ); - if (!options.publishable && !options.buildable) { - host.delete(`${options.projectRoot}/package.json`); - } - if (options.js) { toJS(host); } @@ -287,30 +276,9 @@ function createFiles(host: Tree, options: NormalizedSchema) { updateTsConfig(host, options); } -function updateLibPackageNpmScope(host: Tree, options: NormalizedSchema) { - return updateJson(host, `${options.projectRoot}/package.json`, (json) => { - json.name = options.importPath; - json.peerDependencies = { - react: reactVersion, - 'react-native': reactNativeVersion, - }; - return json; - }); -} - -function maybeJs(options: NormalizedSchema, path: string): string { - return options.js && (path.endsWith('.ts') || path.endsWith('.tsx')) - ? path.replace(/\.tsx?$/, '.js') - : path; -} - function determineEntryFields( options: NormalizedSchema ): Pick { - if (options.buildable) { - return {}; - } - return { main: options.js ? './src/index.js' : './src/index.ts', types: options.js ? './src/index.js' : './src/index.ts', diff --git a/packages/react/src/generators/library/lib/add-rollup-build-target.ts b/packages/react/src/generators/library/lib/add-rollup-build-target.ts index 2d489f711e..4e2306471e 100644 --- a/packages/react/src/generators/library/lib/add-rollup-build-target.ts +++ b/packages/react/src/generators/library/lib/add-rollup-build-target.ts @@ -21,7 +21,8 @@ import { NormalizedSchema } from '../schema'; export async function addRollupBuildTarget( host: Tree, - options: NormalizedSchema + options: NormalizedSchema & { format?: Array<'esm' | 'cjs'> }, + external: Set = new Set(['react', 'react-dom']) ) { const tasks: GeneratorCallback[] = []; @@ -51,12 +52,10 @@ export async function addRollupBuildTarget( ); } - const external: string[] = ['react', 'react-dom']; - if (options.style === '@emotion/styled') { - external.push('@emotion/react/jsx-runtime'); + external.add('@emotion/react/jsx-runtime'); } else { - external.push('react/jsx-runtime'); + external.add('react/jsx-runtime'); } const nxJson = readNxJson(host); @@ -87,8 +86,8 @@ module.exports = withNx( }', tsConfig: './tsconfig.lib.json', compiler: '${options.compiler ?? 'babel'}', - external: ${JSON.stringify(external)}, - format: ['esm'], + external: ${JSON.stringify(Array.from(external))}, + format: ${JSON.stringify(options.format ?? ['esm'])}, assets:[{ input: '.', output: '.', glob: 'README.md'}], }, { // Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options @@ -117,7 +116,7 @@ module.exports = withNx( tsConfig: `${options.projectRoot}/tsconfig.lib.json`, project: `${options.projectRoot}/package.json`, entryFile: maybeJs(options, `${options.projectRoot}/src/index.ts`), - external, + external: Array.from(external), rollupConfig: `@nx/react/plugins/bundle-rollup`, compiler: options.compiler ?? 'babel', assets: [ diff --git a/packages/react/src/generators/library/library.spec.ts b/packages/react/src/generators/library/library.spec.ts index f8ceea08d9..2db24acd83 100644 --- a/packages/react/src/generators/library/library.spec.ts +++ b/packages/react/src/generators/library/library.spec.ts @@ -551,7 +551,7 @@ describe('lib', () => { tsConfig: './tsconfig.lib.json', compiler: 'babel', external: ["react","react-dom","react/jsx-runtime"], - format: ['esm'], + format: ["esm"], assets:[{ input: '.', output: '.', glob: 'README.md'}], }, { // Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options @@ -1207,7 +1207,7 @@ module.exports = withNx( tsConfig: './tsconfig.lib.json', compiler: 'babel', external: ["react","react-dom","react/jsx-runtime"], - format: ['esm'], + format: ["esm"], assets:[{ input: '.', output: '.', glob: 'README.md'}], }, { // Provide additional rollup configuration here. See: https://rollupjs.org/configuration-options diff --git a/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ b/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ index 6ac2dada8e..309b03caa8 100644 --- a/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ +++ b/packages/storybook/src/generators/configuration/project-files-ts/.storybook/main.ts__tmpl__ @@ -48,10 +48,17 @@ const config: StorybookConfig = { }, resolve: { extensions: [ + '.mjs', '.web.tsx', + '.tsx', '.web.ts', + '.ts', '.web.jsx', + '.jsx', '.web.js', + '.js', + '.css', + '.json', ...(config.resolve?.extensions ?? []), ], alias: { diff --git a/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ b/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ index 5dae77b4dd..0d48090125 100644 --- a/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ +++ b/packages/storybook/src/generators/configuration/project-files/.storybook/main.js__tmpl__ @@ -48,11 +48,18 @@ const config = { }, resolve: { extensions: [ + '.mjs', '.web.tsx', + '.tsx', '.web.ts', + '.ts', '.web.jsx', + '.jsx', '.web.js', - ...(config.resolve.extensions ?? []), + '.js', + '.css', + '.json', + ...(config.resolve?.extensions ?? []), ], alias: { 'react-native': 'react-native-web',