fix(core): Adding react apps/libs to workspaces so they can be referenced. (#29202)
<!-- 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 --> This PR address a few things: 1. When we generate an app or a library using the new TS Solution they are not added to the workspaces/packages option. 2. Currently, when we use `pnpm` to generate a workspace the `pnpm-workspace.yaml` looks like below which is not correct ``` packages: - packages/** ``` ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> 1. Libraries and apps should be referenced correctly out of the box so that they can be symlinked after installation. 2. The intended `pnpm-workspace.yaml` should look similar to: ``` packages: - 'packages/**' - 'demo' ``` ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> --------- Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
This commit is contained in:
parent
4b586a1acc
commit
d05f30fb01
@ -79,7 +79,7 @@ describe('@nx/expo (legacy)', () => {
|
|||||||
|
|
||||||
it('should serve with metro', async () => {
|
it('should serve with metro', async () => {
|
||||||
let process: ChildProcess;
|
let process: ChildProcess;
|
||||||
const port = 8081;
|
const port = 8051;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
process = await runCommandUntil(
|
process = await runCommandUntil(
|
||||||
@ -168,16 +168,17 @@ describe('@nx/expo (legacy)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should start', async () => {
|
it('should start', async () => {
|
||||||
|
const port = 8041;
|
||||||
// run start command
|
// run start command
|
||||||
const startProcess = await runCommandUntil(
|
const startProcess = await runCommandUntil(
|
||||||
`start ${appName} -- --port=8081`,
|
`start ${appName} -- --port=${port}`,
|
||||||
(output) => output.includes(`http://localhost:8081`)
|
(output) => output.includes(`http://localhost:${port}`)
|
||||||
);
|
);
|
||||||
|
|
||||||
// port and process cleanup
|
// port and process cleanup
|
||||||
try {
|
try {
|
||||||
await promisifiedTreeKill(startProcess.pid, 'SIGKILL');
|
await promisifiedTreeKill(startProcess.pid, 'SIGKILL');
|
||||||
await killPorts(8081);
|
await killPorts(port);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
expect(err).toBeFalsy();
|
expect(err).toBeFalsy();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,12 +55,12 @@ describe('@nx/expo', () => {
|
|||||||
|
|
||||||
it('should start the app', async () => {
|
it('should start the app', async () => {
|
||||||
let process: ChildProcess;
|
let process: ChildProcess;
|
||||||
const port = 8081;
|
const port = 8088;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
process = await runCommandUntil(
|
process = await runCommandUntil(
|
||||||
`start ${appName} -- --port=${port}`,
|
`start ${appName} -- --port=${port}`,
|
||||||
(output) => output.includes(`http://localhost:8081`)
|
(output) => output.includes(`http://localhost:8088`)
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@ -74,12 +74,12 @@ describe('@nx/expo', () => {
|
|||||||
|
|
||||||
it('should serve the app', async () => {
|
it('should serve the app', async () => {
|
||||||
let process: ChildProcess;
|
let process: ChildProcess;
|
||||||
const port = 8081;
|
const port = 8071;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
process = await runCommandUntil(
|
process = await runCommandUntil(
|
||||||
`serve ${appName} -- --port=${port}`,
|
`serve ${appName} -- --port=${port}`,
|
||||||
(output) => output.includes(`http://localhost:8081`)
|
(output) => output.includes(`http://localhost:8071`)
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
listFiles,
|
listFiles,
|
||||||
newProject,
|
newProject,
|
||||||
readFile,
|
readFile,
|
||||||
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
runE2ETests,
|
runE2ETests,
|
||||||
@ -20,7 +21,6 @@ import { join } from 'path';
|
|||||||
|
|
||||||
describe('React Applications', () => {
|
describe('React Applications', () => {
|
||||||
let proj: string;
|
let proj: string;
|
||||||
|
|
||||||
describe('Crystal Supported Tests', () => {
|
describe('Crystal Supported Tests', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
proj = newProject({ packages: ['@nx/react'] });
|
proj = newProject({ packages: ['@nx/react'] });
|
||||||
@ -28,7 +28,6 @@ describe('React Applications', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => cleanupProject());
|
afterAll(() => cleanupProject());
|
||||||
|
|
||||||
it('should be able to use Vite to build and test apps', async () => {
|
it('should be able to use Vite to build and test apps', async () => {
|
||||||
const appName = uniq('app');
|
const appName = uniq('app');
|
||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
@ -68,13 +67,13 @@ describe('React Applications', () => {
|
|||||||
const libName = uniq('lib');
|
const libName = uniq('lib');
|
||||||
|
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nx/react:app apps/${appName} --name=${appName} --useTsSolution true --bundler=vite --no-interactive --skipFormat --linter=eslint --unitTestRunner=vitest`
|
`generate @nx/react:app apps/${appName} --name=${appName} --useTsSolution=true --bundler=vite --no-interactive --skipFormat --linter=eslint --unitTestRunner=vitest`
|
||||||
);
|
);
|
||||||
runCLI(
|
runCLI(
|
||||||
`generate @nx/react:lib ${libName} --bundler=none --no-interactive --unit-test-runner=vitest --skipFormat --linter=eslint`
|
`generate @nx/react:lib ${libName} --bundler=none --no-interactive --unit-test-runner=vitest --skipFormat --linter=eslint`
|
||||||
);
|
);
|
||||||
|
|
||||||
const nxJson = JSON.parse(readFile('nx.json'));
|
const nxJson = readJson('nx.json');
|
||||||
|
|
||||||
const jsTypescriptPlugin = nxJson.plugins.find(
|
const jsTypescriptPlugin = nxJson.plugins.find(
|
||||||
(plugin) => plugin.plugin === '@nx/js/typescript'
|
(plugin) => plugin.plugin === '@nx/js/typescript'
|
||||||
|
|||||||
@ -258,6 +258,7 @@ export function runCreateWorkspace(
|
|||||||
const pm = getPackageManagerCommand({ packageManager });
|
const pm = getPackageManagerCommand({ packageManager });
|
||||||
|
|
||||||
let command = `${pm.createWorkspace} ${name} --preset=${preset} --nxCloud=skip --no-interactive`;
|
let command = `${pm.createWorkspace} ${name} --preset=${preset} --nxCloud=skip --no-interactive`;
|
||||||
|
|
||||||
if (appName) {
|
if (appName) {
|
||||||
command += ` --appName=${appName}`;
|
command += ` --appName=${appName}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,10 @@ import {
|
|||||||
Tree,
|
Tree,
|
||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { initGenerator as jsInitGenerator } from '@nx/js';
|
import { initGenerator as jsInitGenerator } from '@nx/js';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
import { addLinting } from '../../utils/add-linting';
|
import { addLinting } from '../../utils/add-linting';
|
||||||
import { addJest } from '../../utils/add-jest';
|
import { addJest } from '../../utils/add-jest';
|
||||||
@ -95,6 +98,12 @@ export async function expoApplicationGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we are using the new TS solution
|
||||||
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||||
|
if (options.useTsSolution) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,10 @@ import { ensureDependencies } from '../../utils/ensure-dependencies';
|
|||||||
import { initRootBabelConfig } from '../../utils/init-root-babel-config';
|
import { initRootBabelConfig } from '../../utils/init-root-babel-config';
|
||||||
import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||||
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
||||||
|
|
||||||
export async function expoLibraryGenerator(
|
export async function expoLibraryGenerator(
|
||||||
@ -130,6 +133,10 @@ export async function expoLibraryGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { FsTree } from 'nx/src/generators/tree';
|
import { FsTree } from 'nx/src/generators/tree';
|
||||||
import { isUsingPackageManagerWorkspaces } from '../package-manager-workspaces';
|
import { isUsingPackageManagerWorkspaces } from '../package-manager-workspaces';
|
||||||
import { basename, join, relative } from 'node:path/posix';
|
import { basename, dirname, join, relative } from 'node:path/posix';
|
||||||
|
|
||||||
export function isUsingTypeScriptPlugin(tree: Tree): boolean {
|
export function isUsingTypeScriptPlugin(tree: Tree): boolean {
|
||||||
const nxJson = readNxJson(tree);
|
const nxJson = readNxJson(tree);
|
||||||
@ -204,3 +204,41 @@ export function updateTsconfigFiles(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addProjectToTsSolutionWorkspace(
|
||||||
|
tree: Tree,
|
||||||
|
projectDir: string
|
||||||
|
) {
|
||||||
|
// If dir is "libs/foo" then use "libs/**" so we don't need so many entries in the workspace file.
|
||||||
|
// If the dir is just "foo" then we have to add it as is.
|
||||||
|
const baseDir = dirname(projectDir);
|
||||||
|
const pattern = baseDir === '.' ? projectDir : `${baseDir}/**`;
|
||||||
|
if (tree.exists('pnpm-workspace.yaml')) {
|
||||||
|
const { load, dump } = require('@zkochan/js-yaml');
|
||||||
|
const workspaceFile = tree.read('pnpm-workspace.yaml', 'utf-8');
|
||||||
|
const yamlData = load(workspaceFile);
|
||||||
|
|
||||||
|
if (!yamlData?.packages) {
|
||||||
|
yamlData.packages = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yamlData.packages.includes(pattern)) {
|
||||||
|
yamlData.packages.push(pattern);
|
||||||
|
tree.write(
|
||||||
|
'pnpm-workspace.yaml',
|
||||||
|
dump(yamlData, { indent: 2, quotingType: '"', forceQuotes: true })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Update package.json
|
||||||
|
const packageJson = readJson(tree, 'package.json');
|
||||||
|
if (!packageJson.workspaces) {
|
||||||
|
packageJson.workspaces = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packageJson.workspaces.includes(pattern)) {
|
||||||
|
packageJson.workspaces.push(pattern);
|
||||||
|
tree.write('package.json', JSON.stringify(packageJson, null, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -30,7 +30,10 @@ import { updateCypressTsConfig } from './lib/update-cypress-tsconfig';
|
|||||||
import { showPossibleWarnings } from './lib/show-possible-warnings';
|
import { showPossibleWarnings } from './lib/show-possible-warnings';
|
||||||
import { tsLibVersion } from '../../utils/versions';
|
import { tsLibVersion } from '../../utils/versions';
|
||||||
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
export async function applicationGenerator(host: Tree, schema: Schema) {
|
export async function applicationGenerator(host: Tree, schema: Schema) {
|
||||||
return await applicationGeneratorInternal(host, {
|
return await applicationGeneratorInternal(host, {
|
||||||
@ -132,6 +135,12 @@ export async function applicationGeneratorInternal(host: Tree, schema: Schema) {
|
|||||||
options.src ? 'src' : '.'
|
options.src ? 'src' : '.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we are using the new TS solution
|
||||||
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||||
|
if (options.useTsSolution) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,10 +4,12 @@ import {
|
|||||||
ensureProjectName,
|
ensureProjectName,
|
||||||
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||||
import { Schema } from '../schema';
|
import { Schema } from '../schema';
|
||||||
|
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
export interface NormalizedSchema extends Schema {
|
export interface NormalizedSchema extends Schema {
|
||||||
importPath: string;
|
importPath: string;
|
||||||
projectRoot: string;
|
projectRoot: string;
|
||||||
|
isUsingTsSolutionConfig: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function normalizeOptions(
|
export async function normalizeOptions(
|
||||||
@ -35,5 +37,6 @@ export async function normalizeOptions(
|
|||||||
...options,
|
...options,
|
||||||
importPath,
|
importPath,
|
||||||
projectRoot,
|
projectRoot,
|
||||||
|
isUsingTsSolutionConfig: isUsingTsSolutionSetup(host),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { normalizeOptions } from './lib/normalize-options';
|
|||||||
import { eslintConfigNextVersion, tsLibVersion } from '../../utils/versions';
|
import { eslintConfigNextVersion, tsLibVersion } from '../../utils/versions';
|
||||||
import {
|
import {
|
||||||
isUsingTsSolutionSetup,
|
isUsingTsSolutionSetup,
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
updateTsconfigFiles,
|
updateTsconfigFiles,
|
||||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
@ -161,6 +162,10 @@ export async function libraryGeneratorInternal(host: Tree, rawOptions: Schema) {
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,10 @@ import { Schema } from './schema';
|
|||||||
import { ensureDependencies } from '../../utils/ensure-dependencies';
|
import { ensureDependencies } from '../../utils/ensure-dependencies';
|
||||||
import { syncDeps } from '../../executors/sync-deps/sync-deps.impl';
|
import { syncDeps } from '../../executors/sync-deps/sync-deps.impl';
|
||||||
import { PackageJson } from 'nx/src/utils/package-json';
|
import { PackageJson } from 'nx/src/utils/package-json';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
export async function reactNativeApplicationGenerator(
|
export async function reactNativeApplicationGenerator(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
@ -143,6 +146,12 @@ export async function reactNativeApplicationGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we are using the new TS solution
|
||||||
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||||
|
if (options.useTsSolution) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.appProjectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,10 @@ import { NormalizedSchema, normalizeOptions } from './lib/normalize-options';
|
|||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
import { ensureDependencies } from '../../utils/ensure-dependencies';
|
import { ensureDependencies } from '../../utils/ensure-dependencies';
|
||||||
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
import { getImportPath } from '@nx/js/src/utils/get-import-path';
|
||||||
|
|
||||||
export async function reactNativeLibraryGenerator(
|
export async function reactNativeLibraryGenerator(
|
||||||
@ -127,6 +130,10 @@ export async function reactNativeLibraryGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|||||||
import { Linter } from '@nx/eslint';
|
import { Linter } from '@nx/eslint';
|
||||||
import { applicationGenerator } from './application';
|
import { applicationGenerator } from './application';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
|
|
||||||
|
const { load } = require('@zkochan/js-yaml');
|
||||||
// need to mock cypress otherwise it'll use the nx installed version from package.json
|
// need to mock cypress otherwise it'll use the nx installed version from package.json
|
||||||
// which is v9 while we are testing for the new v10 version
|
// which is v9 while we are testing for the new v10 version
|
||||||
jest.mock('@nx/cypress/src/utils/cypress-version');
|
jest.mock('@nx/cypress/src/utils/cypress-version');
|
||||||
@ -1277,7 +1279,7 @@ describe('app', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
appTree = createTreeWithEmptyWorkspace();
|
appTree = createTreeWithEmptyWorkspace();
|
||||||
updateJson(appTree, 'package.json', (json) => {
|
updateJson(appTree, 'package.json', (json) => {
|
||||||
json.workspaces = ['packages/*', 'apps/*'];
|
json.workspaces = ['packages/**', 'apps/**'];
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
writeJson(appTree, 'tsconfig.base.json', {
|
writeJson(appTree, 'tsconfig.base.json', {
|
||||||
@ -1453,6 +1455,81 @@ describe('app', () => {
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add project to workspaces when using TS solution (npm, yarn, bun)', async () => {
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'myapp',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'libs/nested1',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'libs/nested2',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
|
const packageJson = readJson(appTree, 'package.json');
|
||||||
|
expect(packageJson.workspaces).toEqual([
|
||||||
|
'packages/**',
|
||||||
|
'apps/**',
|
||||||
|
'myapp',
|
||||||
|
'libs/**',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add project to workspaces when using TS solution (pnpm)', async () => {
|
||||||
|
appTree.write('pnpm-workspace.yaml', `packages:`);
|
||||||
|
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'myapp',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'apps/nested1',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'apps/nested2',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
|
const pnpmContent = appTree.read('pnpm-workspace.yaml', 'utf-8');
|
||||||
|
const pnpmWorkspaceFile = load(pnpmContent);
|
||||||
|
|
||||||
|
expect(pnpmWorkspaceFile.packages).toEqual(['myapp', 'apps/**']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--bundler=rsbuild', () => {
|
describe('--bundler=rsbuild', () => {
|
||||||
|
|||||||
@ -9,7 +9,10 @@ import {
|
|||||||
} from '@nx/devkit';
|
} from '@nx/devkit';
|
||||||
import { initGenerator as jsInitGenerator } from '@nx/js';
|
import { initGenerator as jsInitGenerator } from '@nx/js';
|
||||||
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-command';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
import { extractTsConfigBase } from '../../utils/create-ts-config';
|
import { extractTsConfigBase } from '../../utils/create-ts-config';
|
||||||
import { addStyledModuleDependencies } from '../../rules/add-styled-dependencies';
|
import { addStyledModuleDependencies } from '../../rules/add-styled-dependencies';
|
||||||
import { setupTailwindGenerator } from '../setup-tailwind/setup-tailwind';
|
import { setupTailwindGenerator } from '../setup-tailwind/setup-tailwind';
|
||||||
@ -174,6 +177,12 @@ export async function applicationGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we are using the new TS solution
|
||||||
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(tree, options.appProjectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(tree);
|
await formatFiles(tree);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import {
|
|||||||
import { assertValidStyle } from '../../../utils/assertion';
|
import { assertValidStyle } from '../../../utils/assertion';
|
||||||
import { NormalizedSchema, Schema } from '../schema';
|
import { NormalizedSchema, Schema } from '../schema';
|
||||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
import { promptWhenInteractive } from '@nx/devkit/src/generators/prompt';
|
|
||||||
|
|
||||||
export async function normalizeOptions(
|
export async function normalizeOptions(
|
||||||
host: Tree,
|
host: Tree,
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { nxVersion } from '../../utils/versions';
|
|||||||
import applicationGenerator from '../application/application';
|
import applicationGenerator from '../application/application';
|
||||||
import libraryGenerator from './library';
|
import libraryGenerator from './library';
|
||||||
import { Schema } from './schema';
|
import { Schema } from './schema';
|
||||||
|
const { load } = require('@zkochan/js-yaml');
|
||||||
// need to mock cypress otherwise it'll use the nx installed version from package.json
|
// need to mock cypress otherwise it'll use the nx installed version from package.json
|
||||||
// which is v9 while we are testing for the new v10 version
|
// which is v9 while we are testing for the new v10 version
|
||||||
jest.mock('@nx/cypress/src/utils/cypress-version');
|
jest.mock('@nx/cypress/src/utils/cypress-version');
|
||||||
@ -1215,11 +1216,10 @@ module.exports = withNx(
|
|||||||
await libraryGenerator(tree, {
|
await libraryGenerator(tree, {
|
||||||
...defaultSchema,
|
...defaultSchema,
|
||||||
bundler: 'rollup',
|
bundler: 'rollup',
|
||||||
publishable: true,
|
|
||||||
importPath: '@acme/mylib',
|
|
||||||
unitTestRunner: 'none',
|
|
||||||
directory: 'mylib',
|
directory: 'mylib',
|
||||||
name: 'mylib',
|
name: 'mylib',
|
||||||
|
publishable: true,
|
||||||
|
importPath: '@acme/mylib',
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(readJson(tree, 'mylib/package.json')).toMatchInlineSnapshot(`
|
expect(readJson(tree, 'mylib/package.json')).toMatchInlineSnapshot(`
|
||||||
@ -1249,5 +1249,21 @@ module.exports = withNx(
|
|||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add project to workspaces when using TS solution', async () => {
|
||||||
|
tree.write('pnpm-workspace.yaml', `packages:`);
|
||||||
|
|
||||||
|
await libraryGenerator(tree, {
|
||||||
|
...defaultSchema,
|
||||||
|
bundler: 'rollup',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
directory: 'mylib',
|
||||||
|
name: 'mylib',
|
||||||
|
});
|
||||||
|
const pnpmContent = tree.read('pnpm-workspace.yaml', 'utf-8');
|
||||||
|
const pnpmWorkspaceFile = load(pnpmContent);
|
||||||
|
|
||||||
|
expect(pnpmWorkspaceFile.packages).toEqual(['mylib']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -31,7 +31,10 @@ import { createFiles } from './lib/create-files';
|
|||||||
import { extractTsConfigBase } from '../../utils/create-ts-config';
|
import { extractTsConfigBase } from '../../utils/create-ts-config';
|
||||||
import { installCommonDependencies } from './lib/install-common-dependencies';
|
import { installCommonDependencies } from './lib/install-common-dependencies';
|
||||||
import { setDefaults } from './lib/set-defaults';
|
import { setDefaults } from './lib/set-defaults';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
import { ensureProjectIsExcludedFromPluginRegistrations } from '@nx/js/src/utils/typescript/plugin';
|
import { ensureProjectIsExcludedFromPluginRegistrations } from '@nx/js/src/utils/typescript/plugin';
|
||||||
|
|
||||||
export async function libraryGenerator(host: Tree, schema: Schema) {
|
export async function libraryGenerator(host: Tree, schema: Schema) {
|
||||||
@ -280,6 +283,9 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(host, options.projectRoot);
|
||||||
|
}
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(host);
|
await formatFiles(host);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import {
|
|||||||
} from './lib';
|
} from './lib';
|
||||||
import { NxRemixGeneratorSchema } from './schema';
|
import { NxRemixGeneratorSchema } from './schema';
|
||||||
import {
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
isUsingTsSolutionSetup,
|
isUsingTsSolutionSetup,
|
||||||
updateTsconfigFiles,
|
updateTsconfigFiles,
|
||||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
@ -374,6 +375,12 @@ export default {...nxPreset};
|
|||||||
'.'
|
'.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we are using the new TS solution
|
||||||
|
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||||
|
if (options.useTsSolution) {
|
||||||
|
addProjectToTsSolutionWorkspace(tree, options.projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
tasks.push(() => {
|
tasks.push(() => {
|
||||||
logShowProjectCommand(options.projectName);
|
logShowProjectCommand(options.projectName);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,10 +4,12 @@ import {
|
|||||||
ensureProjectName,
|
ensureProjectName,
|
||||||
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||||
import type { NxRemixGeneratorSchema } from '../schema';
|
import type { NxRemixGeneratorSchema } from '../schema';
|
||||||
|
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
export interface RemixLibraryOptions extends NxRemixGeneratorSchema {
|
export interface RemixLibraryOptions extends NxRemixGeneratorSchema {
|
||||||
projectName: string;
|
projectName: string;
|
||||||
projectRoot: string;
|
projectRoot: string;
|
||||||
|
isUsingTsSolutionConfig: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function normalizeOptions(
|
export async function normalizeOptions(
|
||||||
@ -35,5 +37,6 @@ export async function normalizeOptions(
|
|||||||
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
unitTestRunner: options.unitTestRunner ?? 'vitest',
|
||||||
projectName,
|
projectName,
|
||||||
projectRoot,
|
projectRoot,
|
||||||
|
isUsingTsSolutionConfig: isUsingTsSolutionSetup(tree),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,10 @@ import {
|
|||||||
updateBuildableConfig,
|
updateBuildableConfig,
|
||||||
} from './lib';
|
} from './lib';
|
||||||
import type { NxRemixGeneratorSchema } from './schema';
|
import type { NxRemixGeneratorSchema } from './schema';
|
||||||
import { updateTsconfigFiles } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
import {
|
||||||
|
addProjectToTsSolutionWorkspace,
|
||||||
|
updateTsconfigFiles,
|
||||||
|
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||||
|
|
||||||
export async function remixLibraryGenerator(
|
export async function remixLibraryGenerator(
|
||||||
tree: Tree,
|
tree: Tree,
|
||||||
@ -73,6 +76,10 @@ export async function remixLibraryGeneratorInternal(
|
|||||||
: undefined
|
: undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (options.isUsingTsSolutionConfig) {
|
||||||
|
addProjectToTsSolutionWorkspace(tree, options.projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
if (!options.skipFormat) {
|
if (!options.skipFormat) {
|
||||||
await formatFiles(tree);
|
await formatFiles(tree);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -332,8 +332,8 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
|
|||||||
const packageJson = tree.read('/proj/pnpm-workspace.yaml', 'utf-8');
|
const packageJson = tree.read('/proj/pnpm-workspace.yaml', 'utf-8');
|
||||||
expect(packageJson).toMatchInlineSnapshot(`
|
expect(packageJson).toMatchInlineSnapshot(`
|
||||||
"packages:
|
"packages:
|
||||||
- apps/**
|
- "apps/**"
|
||||||
- packages/**
|
- "packages/**"
|
||||||
"
|
"
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -433,7 +433,7 @@ function setUpWorkspacesInPackageJson(tree: Tree, options: NormalizedSchema) {
|
|||||||
tree.write(
|
tree.write(
|
||||||
join(options.directory, 'pnpm-workspace.yaml'),
|
join(options.directory, 'pnpm-workspace.yaml'),
|
||||||
`packages:
|
`packages:
|
||||||
- ${workspaces.join('\n - ')}
|
${workspaces.map((workspace) => `- "${workspace}"`).join('\n ')}
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user