nx/packages/js/src/migrations/update-15-8-0/rename-swcrc-config.ts

120 lines
3.9 KiB
TypeScript

import {
formatFiles,
getProjects,
joinPathFragments,
Tree,
updateProjectConfiguration,
} from '@nx/devkit';
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
import { SwcExecutorOptions } from '../../utils/schema';
import { tsquery } from '@phenomnomnominal/tsquery';
import type { TemplateSpan } from 'typescript';
export default async function (tree: Tree) {
let changesMade = false;
const projects = getProjects(tree);
forEachExecutorOptions(
tree,
'@nrwl/js:swc',
(_, projectName, target, configurationName) => {
const projectConfiguration = projects.get(projectName);
const executorOptions: SwcExecutorOptions = configurationName
? projectConfiguration.targets[target].configurations[configurationName]
: projectConfiguration.targets[target].options;
// if the project uses a custom path to swcrc file
// and only if it's the default name
if (
executorOptions.swcrc &&
executorOptions.swcrc.includes('.lib.swcrc')
) {
const newSwcrc = executorOptions.swcrc.replace('.lib.swcrc', '.swcrc');
// rename the swcrc file first
tree.rename(executorOptions.swcrc, newSwcrc);
// then update the executor options
executorOptions.swcrc = newSwcrc;
changesMade = true;
}
const libSwcrcPath =
joinPathFragments(projectConfiguration.root, '.lib.swcrc') ||
joinPathFragments(projectConfiguration.sourceRoot, '.lib.swcrc');
const isLibSwcrcExist = tree.exists(libSwcrcPath);
if (isLibSwcrcExist) {
tree.rename(libSwcrcPath, libSwcrcPath.replace('.lib.swcrc', '.swcrc'));
changesMade = true;
}
updateProjectConfiguration(tree, projectName, projectConfiguration);
}
);
forEachExecutorOptions(
tree,
'@nrwl/jest:jest',
(_, projectName, target, configurationName) => {
const projectConfiguration = projects.get(projectName);
const executorOptions = configurationName
? projectConfiguration.targets[target].configurations[configurationName]
: projectConfiguration.targets[target].options;
const isJestConfigExist =
executorOptions.jestConfig && tree.exists(executorOptions.jestConfig);
if (isJestConfigExist) {
const jestConfig = tree.read(executorOptions.jestConfig, 'utf-8');
const jsonParseNodes = tsquery.query(
jestConfig,
':matches(CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]))'
);
if (jsonParseNodes.length) {
// if we already assign false to swcrc, skip
if (jestConfig.includes('.swcrc = false')) {
return;
}
let updatedJestConfig = tsquery.replace(
jestConfig,
'CallExpression:has(Identifier[name="JSON"]):has(Identifier[name="parse"]) TemplateSpan',
(templateSpan: TemplateSpan) => {
if (templateSpan.literal.text === '/.lib.swcrc') {
return templateSpan
.getFullText()
.replace('.lib.swcrc', '.swcrc');
}
return '';
}
);
updatedJestConfig = tsquery.replace(
updatedJestConfig,
':matches(ExportAssignment, BinaryExpression:has(Identifier[name="module"]):has(Identifier[name="exports"]))',
(node) => {
return `
// disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves.
// If we do not disable this, SWC Core will read .swcrc and won't transform our test files due to "exclude"
if (swcJestConfig.swcrc === undefined) {
swcJestConfig.swcrc = false;
}
${node.getFullText()}
`;
}
);
tree.write(executorOptions.jestConfig, updatedJestConfig);
changesMade = true;
}
}
}
);
if (changesMade) {
await formatFiles(tree);
}
}