fix(react-native): change build target to be crystalized (#30151)
<!-- 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 #
This commit is contained in:
parent
a5d20030db
commit
e57df6f6be
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -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);
|
||||
|
||||
@ -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"],
|
||||
|
||||
@ -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'
|
||||
);
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ export interface NormalizedSchema extends Omit<Schema, 'js'> {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
{
|
||||
"name": "<%= projectName %>",
|
||||
"version": "0.0.1",
|
||||
"main": "<%= appMain %>"
|
||||
}
|
||||
@ -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,
|
||||
};
|
||||
|
||||
|
||||
@ -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",
|
||||
}
|
||||
|
||||
@ -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<typeof import('@nx/rollup')>(
|
||||
'@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<PackageJson, 'main' | 'types' | 'exports'> {
|
||||
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;
|
||||
|
||||
@ -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'
|
||||
);
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ export interface NormalizedSchema extends Omit<Schema, 'js'> {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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"]
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "<%= name %>",
|
||||
"version": "0.0.1"
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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(`
|
||||
{
|
||||
|
||||
@ -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<typeof import('@nx/rollup')>(
|
||||
'@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<PackageJson, 'main' | 'types' | 'exports'> {
|
||||
if (options.buildable) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
main: options.js ? './src/index.js' : './src/index.ts',
|
||||
types: options.js ? './src/index.js' : './src/index.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<String> = 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: [
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user