fix(js): avoid nested paths in workspaces because they can lead to future issues (#29553)
For the new TS setup, we currently use nested glob patterns: `apps/**`, `libs/**`, and `packages/**`. Nested paths can result into too many projects being matched. For example, if `libs/mylib/src/__fixtures__/package.json` is there for testing, it will be matched as a project and likely result in an error. Other tools like turborepo also caution against this: https://turbo.build/repo/docs/crafting-your-repository/structuring-a-repository#declaring-directories-for-packages If users want to, they could change to nested `**` paths, but we should not use it by default. Note: For CNW, we only use `apps/*` by default since that is where the project lives. When users do `nx g lib packages/foo` then `packages/*` will be added automatically. <!-- 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 --> Use nested `**` paths. ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> Don't use nested `**` paths. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
e99cf07ffd
commit
fb318005f2
@ -33,13 +33,13 @@ describe('Node Applications', () => {
|
|||||||
'pnpm-workspace.yaml',
|
'pnpm-workspace.yaml',
|
||||||
`
|
`
|
||||||
packages:
|
packages:
|
||||||
- 'apps/**'
|
- 'apps/*'
|
||||||
- 'packages/**'
|
- 'packages/*'
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
updateJson('package.json', (json) => {
|
updateJson('package.json', (json) => {
|
||||||
json.workspaces = ['apps/**', 'packages/**'];
|
json.workspaces = ['apps/*', 'packages/*'];
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,13 +23,13 @@ describe('Vue Plugin', () => {
|
|||||||
'pnpm-workspace.yaml',
|
'pnpm-workspace.yaml',
|
||||||
`
|
`
|
||||||
packages:
|
packages:
|
||||||
- 'apps/**'
|
- 'apps/*'
|
||||||
- 'packages/**'
|
- 'packages/*'
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
updateJson('package.json', (json) => {
|
updateJson('package.json', (json) => {
|
||||||
json.workspaces = ['apps/**', 'packages/**'];
|
json.workspaces = ['apps/*', 'packages/*'];
|
||||||
return json;
|
return json;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,8 +115,8 @@ function getWorkspaceGlobsFromPreset(preset: string): string[] {
|
|||||||
case Preset.RemixMonorepo:
|
case Preset.RemixMonorepo:
|
||||||
case Preset.VueMonorepo:
|
case Preset.VueMonorepo:
|
||||||
case Preset.WebComponents:
|
case Preset.WebComponents:
|
||||||
return ['apps/**', 'libs/**', 'packages/**'];
|
return ['apps/*'];
|
||||||
default:
|
default:
|
||||||
return ['libs/**', 'packages/**'];
|
return ['packages/*'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -198,10 +198,11 @@ export function addProjectToTsSolutionWorkspace(
|
|||||||
tree: Tree,
|
tree: Tree,
|
||||||
projectDir: string
|
projectDir: string
|
||||||
) {
|
) {
|
||||||
// If dir is "libs/foo" then use "libs/**" so we don't need so many entries in the workspace file.
|
// If dir is "libs/foo" then use "libs/*" so we don't need so many entries in the workspace file.
|
||||||
|
// If dir is nested like "libs/shared/foo" then we add "libs/shared/*".
|
||||||
// If the dir is just "foo" then we have to add it as is.
|
// If the dir is just "foo" then we have to add it as is.
|
||||||
const baseDir = dirname(projectDir);
|
const baseDir = dirname(projectDir);
|
||||||
const pattern = baseDir === '.' ? projectDir : `${baseDir}/**`;
|
const pattern = baseDir === '.' ? projectDir : `${baseDir}/*`;
|
||||||
if (tree.exists('pnpm-workspace.yaml')) {
|
if (tree.exists('pnpm-workspace.yaml')) {
|
||||||
const { load, dump } = require('@zkochan/js-yaml');
|
const { load, dump } = require('@zkochan/js-yaml');
|
||||||
const workspaceFile = tree.read('pnpm-workspace.yaml', 'utf-8');
|
const workspaceFile = tree.read('pnpm-workspace.yaml', 'utf-8');
|
||||||
|
|||||||
@ -1279,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', {
|
||||||
@ -1482,10 +1482,10 @@ describe('app', () => {
|
|||||||
|
|
||||||
const packageJson = readJson(appTree, 'package.json');
|
const packageJson = readJson(appTree, 'package.json');
|
||||||
expect(packageJson.workspaces).toEqual([
|
expect(packageJson.workspaces).toEqual([
|
||||||
'packages/**',
|
'packages/*',
|
||||||
'apps/**',
|
'apps/*',
|
||||||
'myapp',
|
'myapp',
|
||||||
'libs/**',
|
'libs/*',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1519,11 +1519,24 @@ describe('app', () => {
|
|||||||
unitTestRunner: 'none',
|
unitTestRunner: 'none',
|
||||||
e2eTestRunner: 'none',
|
e2eTestRunner: 'none',
|
||||||
});
|
});
|
||||||
|
await applicationGenerator(appTree, {
|
||||||
|
directory: 'packages/shared/util',
|
||||||
|
addPlugin: true,
|
||||||
|
linter: Linter.EsLint,
|
||||||
|
style: 'none',
|
||||||
|
bundler: 'vite',
|
||||||
|
unitTestRunner: 'none',
|
||||||
|
e2eTestRunner: 'none',
|
||||||
|
});
|
||||||
|
|
||||||
const pnpmContent = appTree.read('pnpm-workspace.yaml', 'utf-8');
|
const pnpmContent = appTree.read('pnpm-workspace.yaml', 'utf-8');
|
||||||
const pnpmWorkspaceFile = load(pnpmContent);
|
const pnpmWorkspaceFile = load(pnpmContent);
|
||||||
|
|
||||||
expect(pnpmWorkspaceFile.packages).toEqual(['myapp', 'apps/**']);
|
expect(pnpmWorkspaceFile.packages).toEqual([
|
||||||
|
'myapp',
|
||||||
|
'apps/*',
|
||||||
|
'packages/shared/*',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -230,7 +230,7 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
|
|||||||
"scripts": {},
|
"scripts": {},
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/**",
|
"packages/*",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
@ -294,7 +294,7 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
|
|||||||
defaultBase: 'main',
|
defaultBase: 'main',
|
||||||
packageManager: 'npm',
|
packageManager: 'npm',
|
||||||
isCustomPreset: false,
|
isCustomPreset: false,
|
||||||
workspaceGlobs: ['apps/**', 'packages/**'],
|
workspaceGlobs: ['apps/*', 'packages/*'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const packageJson = readJson(tree, '/proj/package.json');
|
const packageJson = readJson(tree, '/proj/package.json');
|
||||||
@ -310,8 +310,8 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
|
|||||||
"scripts": {},
|
"scripts": {},
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/**",
|
"apps/*",
|
||||||
"packages/**",
|
"packages/*",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
@ -326,14 +326,14 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
|
|||||||
defaultBase: 'main',
|
defaultBase: 'main',
|
||||||
packageManager: 'pnpm',
|
packageManager: 'pnpm',
|
||||||
isCustomPreset: false,
|
isCustomPreset: false,
|
||||||
workspaceGlobs: ['apps/**', 'packages/**'],
|
workspaceGlobs: ['apps/*', 'packages/*'],
|
||||||
});
|
});
|
||||||
|
|
||||||
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/*"
|
||||||
"
|
"
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -428,7 +428,7 @@ function setUpWorkspacesInPackageJson(tree: Tree, options: NormalizedSchema) {
|
|||||||
options.preset === Preset.Express) &&
|
options.preset === Preset.Express) &&
|
||||||
options.workspaces)
|
options.workspaces)
|
||||||
) {
|
) {
|
||||||
const workspaces = options.workspaceGlobs ?? ['packages/**'];
|
const workspaces = options.workspaceGlobs ?? ['packages/*'];
|
||||||
if (options.packageManager === 'pnpm') {
|
if (options.packageManager === 'pnpm') {
|
||||||
tree.write(
|
tree.write(
|
||||||
join(options.directory, 'pnpm-workspace.yaml'),
|
join(options.directory, 'pnpm-workspace.yaml'),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user