Skip to content

Commit

Permalink
fix(misc): improve package.json scripts handling when running "nx ini…
Browse files Browse the repository at this point in the history
…t" and "nx add" (#22168)
  • Loading branch information
leosvelperez committed Mar 6, 2024
1 parent 9194448 commit 876bc94
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 25 deletions.
82 changes: 74 additions & 8 deletions packages/devkit/src/utils/update-package-scripts.spec.ts
Expand Up @@ -235,30 +235,96 @@ describe('updatePackageScripts', () => {
);
});

it('should exclude all package.json scripts when none are excluded', async () => {
tree.write('next.config.js', '');
it('should set "includedScripts" to an empty array when running "nx init"', async () => {
const originalEnvVarValue = process.env.NX_RUNNING_NX_INIT;
process.env.NX_RUNNING_NX_INIT = 'true';

tree.write('vite.config.ts', '');
writeJson(tree, 'package.json', {
name: 'app1',
scripts: {
build: 'next build',
build: 'vite build',
serve: 'vite',
test: 'vitest',
coverage: 'vitest run --coverage',
foo: 'echo "foo"',
},
});

await updatePackageScripts(tree, [
'**/next.config.{js,cjs,mjs}',
'**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}',
() => ({
projects: {
app1: {
targets: {
build: { command: 'next build' },
build: { command: 'vite build' },
serve: { command: 'vite serve' },
test: { command: 'vitest run' },
},
},
},
}),
]);

const { nx } = readJson<PackageJson>(tree, 'package.json');
expect(nx).toStrictEqual({ includedScripts: [] });
const packageJson = readJson<PackageJson>(tree, 'package.json');
expect(packageJson.scripts).toStrictEqual({
build: 'nx build',
serve: 'vite',
test: 'vitest',
coverage: 'nx test --coverage',
foo: 'echo "foo"',
});
expect(packageJson.nx.includedScripts).toStrictEqual([]);

process.env.NX_RUNNING_NX_INIT = originalEnvVarValue;
});

it('should set "includedScripts" to all scripts except the ones matching inferred target names when "includedScripts" is not set', async () => {
tree.write('vite.config.ts', '');
writeJson(tree, 'package.json', {
name: 'app1',
scripts: {
build: 'vite build',
serve: 'vite',
test: 'vitest',
coverage: 'vitest run --coverage',
foo: 'echo "foo"',
},
});

await updatePackageScripts(tree, [
'**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}',
() => ({
projects: {
app1: {
targets: {
build: { command: 'vite build' },
serve: { command: 'vite serve' },
test: { command: 'vitest run' },
},
},
},
}),
]);

const packageJson = readJson<PackageJson>(tree, 'package.json');
expect(packageJson.scripts).toStrictEqual({
build: 'nx build',
serve: 'vite',
test: 'vitest',
coverage: 'nx test --coverage',
foo: 'echo "foo"',
});
// "build": excluded because a script (itself) was replaced with a target "build"
// "serve" not excluded even though it matches the name of an inferred target because no script was replaced with a target "serve"
// "test" excluded even though it was not replaced because another script was replaced with a target "test"
// "coverage" not excluded even though it was replaced because it does not match a target
// "foo" not excluded because it does not match a target
expect(packageJson.nx.includedScripts).toStrictEqual([
'serve',
'coverage',
'foo',
]);
});

it('should exclude replaced package.json scripts from nx if they are initially included', async () => {
Expand Down Expand Up @@ -288,6 +354,6 @@ describe('updatePackageScripts', () => {
]);

const { nx } = readJson<PackageJson>(tree, 'package.json');
expect(nx).toStrictEqual({ includedScripts: ['foo'] });
expect(nx.includedScripts).toStrictEqual(['foo']);
});
});
36 changes: 20 additions & 16 deletions packages/devkit/src/utils/update-package-scripts.ts
Expand Up @@ -60,10 +60,7 @@ async function processProject(
return;
}

// exclude package.json scripts from nx
packageJson.nx ??= {};
packageJson.nx.includedScripts ??= [];

const replacedTargets = new Set<string>();
for (const targetCommand of targetCommands) {
const { command, target, configuration } = targetCommand;
const targetCommandRegex = new RegExp(
Expand All @@ -80,7 +77,7 @@ async function processProject(
? `$1nx ${target} --configuration=${configuration}$3`
: `$1nx ${target}$3`
);
excludeScriptFromPackageJson(packageJson, scriptName);
replacedTargets.add(target);
} else {
/**
* Parse script and command to handle the following:
Expand Down Expand Up @@ -157,6 +154,7 @@ async function processProject(
: `$1nx ${target}$4`
)
);
replacedTargets.add(target);
} else {
// there are different args or the script has extra args, replace with the command leaving the args
packageJson.scripts[scriptName] = packageJson.scripts[
Expand All @@ -170,14 +168,29 @@ async function processProject(
: `$1nx ${target}$3`
)
);
replacedTargets.add(target);
}

excludeScriptFromPackageJson(packageJson, scriptName);
}
}
}
}

packageJson.nx ??= {};
if (process.env.NX_RUNNING_NX_INIT === 'true') {
// running `nx init` so we want to exclude everything by default
packageJson.nx.includedScripts = [];
} else {
/**
* Running `nx add`. In this case we want to:
* - if `includedScripts` is already set: exclude scripts that match inferred targets that were used to replace a script
* - if `includedScripts` is not set: set `includedScripts` with all scripts except the ones that match an inferred target that was used to replace a script
*/
packageJson.nx.includedScripts ??= Object.keys(packageJson.scripts);
packageJson.nx.includedScripts = packageJson.nx.includedScripts.filter(
(s) => !replacedTargets.has(s)
);
}

writeJson(tree, packageJsonPath, packageJson);
}

Expand Down Expand Up @@ -228,15 +241,6 @@ function getInferredTargetCommands(result: CreateNodesResult): TargetCommand[] {
return targetCommands;
}

function excludeScriptFromPackageJson(
packageJson: PackageJson,
scriptName: string
) {
packageJson.nx.includedScripts = packageJson.nx.includedScripts.filter(
(s) => s !== scriptName
);
}

function getProjectRootFromConfigFile(file: string): string {
let projectRoot = dirname(file);
if (basename(projectRoot) === '.storybook') {
Expand Down
3 changes: 2 additions & 1 deletion packages/nx/src/command-line/init/init-v2.ts
Expand Up @@ -31,6 +31,7 @@ export interface InitArgs {
}

export async function initHandler(options: InitArgs): Promise<void> {
process.env.NX_RUNNING_NX_INIT = 'true';
const version =
process.env.NX_VERSION ?? (prerelease(nxVersion) ? 'next' : 'latest');
if (process.env.NX_VERSION) {
Expand Down Expand Up @@ -112,7 +113,7 @@ export async function initHandler(options: InitArgs): Promise<void> {
if (!detectPluginsResponse.updatePackageScripts) {
const rootPackageJsonPath = join(repoRoot, 'package.json');
const json = readJsonFile<PackageJson>(rootPackageJsonPath);
json.nx = {};
json.nx = { includedScripts: [] };
writeJsonFile(rootPackageJsonPath, json);
}

Expand Down

0 comments on commit 876bc94

Please sign in to comment.