fix(vite): ignore vite temp files in eslint config (#29909)
## Current Behavior Vite config temp files can sometimes cause errors to be thrown by ESLint. ## Expected Behavior Vite config temp files should be ignored by ESLint. ## Related Issue(s) Fixes #
This commit is contained in:
parent
9e204f973c
commit
eb0505b1ad
@ -5530,6 +5530,16 @@
|
|||||||
"path": "/nx-api/vite/migrations/update-20-5-0-update-resolve-conditions",
|
"path": "/nx-api/vite/migrations/update-20-5-0-update-resolve-conditions",
|
||||||
"type": "migration"
|
"type": "migration"
|
||||||
},
|
},
|
||||||
|
"/nx-api/vite/migrations/eslint-ignore-vite-temp-files": {
|
||||||
|
"description": "Add vite config temporary files to the ESLint configuration ignore patterns if ESLint is used.",
|
||||||
|
"file": "generated/packages/vite/migrations/eslint-ignore-vite-temp-files.json",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "eslint-ignore-vite-temp-files",
|
||||||
|
"version": "20.5.0-beta.3",
|
||||||
|
"originalFilePath": "/packages/vite",
|
||||||
|
"path": "/nx-api/vite/migrations/eslint-ignore-vite-temp-files",
|
||||||
|
"type": "migration"
|
||||||
|
},
|
||||||
"/nx-api/vite/migrations/20.5.0-package-updates": {
|
"/nx-api/vite/migrations/20.5.0-package-updates": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"file": "generated/packages/vite/migrations/20.5.0-package-updates.json",
|
"file": "generated/packages/vite/migrations/20.5.0-package-updates.json",
|
||||||
|
|||||||
@ -5496,6 +5496,16 @@
|
|||||||
"path": "vite/migrations/update-20-5-0-update-resolve-conditions",
|
"path": "vite/migrations/update-20-5-0-update-resolve-conditions",
|
||||||
"type": "migration"
|
"type": "migration"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "Add vite config temporary files to the ESLint configuration ignore patterns if ESLint is used.",
|
||||||
|
"file": "generated/packages/vite/migrations/eslint-ignore-vite-temp-files.json",
|
||||||
|
"hidden": false,
|
||||||
|
"name": "eslint-ignore-vite-temp-files",
|
||||||
|
"version": "20.5.0-beta.3",
|
||||||
|
"originalFilePath": "/packages/vite",
|
||||||
|
"path": "vite/migrations/eslint-ignore-vite-temp-files",
|
||||||
|
"type": "migration"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "",
|
"description": "",
|
||||||
"file": "generated/packages/vite/migrations/20.5.0-package-updates.json",
|
"file": "generated/packages/vite/migrations/20.5.0-package-updates.json",
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "eslint-ignore-vite-temp-files",
|
||||||
|
"version": "20.5.0-beta.3",
|
||||||
|
"description": "Add vite config temporary files to the ESLint configuration ignore patterns if ESLint is used.",
|
||||||
|
"implementation": "/packages/vite/src/migrations/update-20-5-0/eslint-ignore-vite-temp-files.ts",
|
||||||
|
"aliases": [],
|
||||||
|
"hidden": false,
|
||||||
|
"path": "/packages/vite",
|
||||||
|
"schema": null,
|
||||||
|
"type": "migration",
|
||||||
|
"examplesFile": "#### Sample Code Changes\n\nAdd `vite.config.*.timestamp*` and `vitest.config.*.timestamp*` to the root `eslint.config.mjs` file (using **ESLint Flat Config**).\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```js {% fileName=\"eslint.config.mjs\" %}\nexport default [\n {\n ignores: ['dist'],\n },\n];\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```js {% highlightLines=[3] fileName=\"eslint.config.mjs\" %}\nexport default [\n {\n ignores: ['dist', 'vite.config.*.timestamp*', 'vitest.config.*.timestamp*'],\n },\n];\n```\n\n{% /tab %}\n\n{% /tabs %}\n\nAdd `vite.config.*.timestamp*` and `vitest.config.*.timestamp*` to the project's `.eslintrc.json` file (using **eslintrc** format config).\n\n{% tabs %}\n{% tab label=\"Before\" %}\n\n```json {% fileName=\"apps/app1/eslintrc.json\" %}\n{\n \"ignorePatterns\": [\"!**/*\"]\n}\n```\n\n{% /tab %}\n{% tab label=\"After\" %}\n\n```json {% highlightLines=[4,5] fileName=\"apps/app1/eslintrc.json\" %}\n{\n \"ignorePatterns\": [\n \"!**/*\",\n \"vite.config.*.timestamp*\",\n \"vitest.config.*.timestamp*\"\n ]\n}\n```\n\n{% /tab %}\n\n{% /tabs %}\n"
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import {
|
|||||||
} from '../../utils/config-file';
|
} from '../../utils/config-file';
|
||||||
import {
|
import {
|
||||||
addExtendsToLintConfig,
|
addExtendsToLintConfig,
|
||||||
|
addIgnoresToLintConfig,
|
||||||
findEslintFile,
|
findEslintFile,
|
||||||
lintConfigHasOverride,
|
lintConfigHasOverride,
|
||||||
replaceOverridesInLintConfig,
|
replaceOverridesInLintConfig,
|
||||||
@ -526,4 +527,197 @@ module.exports = [
|
|||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('addIgnoresToLintConfig', () => {
|
||||||
|
it('should add a new block with ignores to esm flat config when there is none', () => {
|
||||||
|
tree.write('eslint.config.mjs', 'export default [];');
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update existing block with ignores in esm flat config', () => {
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.mjs',
|
||||||
|
`export default [
|
||||||
|
{
|
||||||
|
ignores: ["dist"],
|
||||||
|
}
|
||||||
|
];
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
"ignores": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not duplicate existing patterns in a block with ignores in esm flat config', () => {
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.mjs',
|
||||||
|
`export default [
|
||||||
|
{
|
||||||
|
ignores: ["dist"],
|
||||||
|
}
|
||||||
|
];
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*', 'dist']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
"ignores": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add a new block with ignores to cjs flat config when there is none', () => {
|
||||||
|
tree.write('eslint.config.cjs', 'module.exports = [];');
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.cjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"module.exports = [,
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}];"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update existing block with ignores in cjs flat config', () => {
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.cjs',
|
||||||
|
`module.exports = [
|
||||||
|
{
|
||||||
|
ignores: ["dist"],
|
||||||
|
}
|
||||||
|
];
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.cjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"module.exports = [
|
||||||
|
{
|
||||||
|
"ignores": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not duplicate existing patterns in a block with ignores in cjs flat config', () => {
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.cjs',
|
||||||
|
`module.exports = [
|
||||||
|
{
|
||||||
|
ignores: ["dist"],
|
||||||
|
}
|
||||||
|
];
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*', 'dist']);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.cjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"module.exports = [
|
||||||
|
{
|
||||||
|
"ignores": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add ignore patterns to eslintrc config when there is none', () => {
|
||||||
|
tree.write('.eslintrc.json', '{}');
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"**/some-dir/**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update existing ignore patterns in eslintrc config', () => {
|
||||||
|
tree.write(
|
||||||
|
'.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["dist"]
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*']);
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not duplicate existing ignore patterns in eslintrc config', () => {
|
||||||
|
tree.write(
|
||||||
|
'.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["dist"]
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, '', ['**/some-dir/**/*', 'dist']);
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"dist",
|
||||||
|
"**/some-dir/**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
baseEsLintConfigFile,
|
baseEsLintConfigFile,
|
||||||
ESLINT_CONFIG_FILENAMES,
|
ESLINT_CONFIG_FILENAMES,
|
||||||
BASE_ESLINT_CONFIG_FILENAMES,
|
BASE_ESLINT_CONFIG_FILENAMES,
|
||||||
|
ESLINT_FLAT_CONFIG_FILENAMES,
|
||||||
} from '../../utils/config-file';
|
} from '../../utils/config-file';
|
||||||
import {
|
import {
|
||||||
eslintFlatConfigFilenames,
|
eslintFlatConfigFilenames,
|
||||||
@ -29,12 +30,14 @@ import {
|
|||||||
addBlockToFlatConfigExport,
|
addBlockToFlatConfigExport,
|
||||||
addFlatCompatToFlatConfig,
|
addFlatCompatToFlatConfig,
|
||||||
addImportToFlatConfig,
|
addImportToFlatConfig,
|
||||||
|
addPatternsToFlatConfigIgnoresBlock,
|
||||||
addPluginsToExportsBlock,
|
addPluginsToExportsBlock,
|
||||||
generateAst,
|
generateAst,
|
||||||
generateFlatOverride,
|
generateFlatOverride,
|
||||||
generateFlatPredefinedConfig,
|
generateFlatPredefinedConfig,
|
||||||
generatePluginExtendsElement,
|
generatePluginExtendsElement,
|
||||||
generatePluginExtendsElementWithCompatFixup,
|
generatePluginExtendsElementWithCompatFixup,
|
||||||
|
hasFlatConfigIgnoresBlock,
|
||||||
hasOverride,
|
hasOverride,
|
||||||
overrideNeedsCompat,
|
overrideNeedsCompat,
|
||||||
removeOverridesFromLintConfig,
|
removeOverridesFromLintConfig,
|
||||||
@ -609,15 +612,25 @@ export function addIgnoresToLintConfig(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fileName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = tree.read(fileName, 'utf8');
|
||||||
|
if (hasFlatConfigIgnoresBlock(content)) {
|
||||||
|
content = addPatternsToFlatConfigIgnoresBlock(content, ignorePatterns);
|
||||||
|
tree.write(fileName, content);
|
||||||
|
} else {
|
||||||
const block = generateAst<ts.ObjectLiteralExpression>({
|
const block = generateAst<ts.ObjectLiteralExpression>({
|
||||||
ignores: ignorePatterns.map((path) => mapFilePath(path)),
|
ignores: ignorePatterns.map((path) => mapFilePath(path)),
|
||||||
});
|
});
|
||||||
tree.write(
|
tree.write(fileName, addBlockToFlatConfigExport(content, block));
|
||||||
fileName,
|
}
|
||||||
addBlockToFlatConfigExport(tree.read(fileName, 'utf8'), block)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const fileName = joinPathFragments(root, '.eslintrc.json');
|
const fileName = joinPathFragments(root, '.eslintrc.json');
|
||||||
|
if (!tree.exists(fileName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateJson(tree, fileName, (json) => {
|
updateJson(tree, fileName, (json) => {
|
||||||
const ignoreSet = new Set([
|
const ignoreSet = new Set([
|
||||||
...(json.ignorePatterns ?? []),
|
...(json.ignorePatterns ?? []),
|
||||||
|
|||||||
@ -75,6 +75,84 @@ function findModuleExports(source: ts.SourceFile): ts.NodeArray<ts.Node> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addPatternsToFlatConfigIgnoresBlock(
|
||||||
|
content: string,
|
||||||
|
ignorePatterns: string[]
|
||||||
|
): string {
|
||||||
|
const source = ts.createSourceFile(
|
||||||
|
'',
|
||||||
|
content,
|
||||||
|
ts.ScriptTarget.Latest,
|
||||||
|
true,
|
||||||
|
ts.ScriptKind.JS
|
||||||
|
);
|
||||||
|
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
||||||
|
const exportsArray =
|
||||||
|
format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
||||||
|
if (!exportsArray) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
const changes: StringChange[] = [];
|
||||||
|
for (const node of exportsArray) {
|
||||||
|
if (!isFlatConfigIgnoresBlock(node)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = node.properties.pos + 1; // keep leading line break
|
||||||
|
const data = parseTextToJson(node.getFullText());
|
||||||
|
changes.push({
|
||||||
|
type: ChangeType.Delete,
|
||||||
|
start,
|
||||||
|
length: node.properties.end - start,
|
||||||
|
});
|
||||||
|
data.ignores = Array.from(
|
||||||
|
new Set([...(data.ignores ?? []), ...ignorePatterns])
|
||||||
|
);
|
||||||
|
changes.push({
|
||||||
|
type: ChangeType.Insert,
|
||||||
|
index: start,
|
||||||
|
text:
|
||||||
|
' ' +
|
||||||
|
JSON.stringify(data, null, 2)
|
||||||
|
.slice(2, -2) // Remove curly braces and start/end line breaks
|
||||||
|
.replaceAll(/\n/g, '\n '), // Maintain indentation
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return applyChangesToString(content, changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasFlatConfigIgnoresBlock(content: string): boolean {
|
||||||
|
const source = ts.createSourceFile(
|
||||||
|
'',
|
||||||
|
content,
|
||||||
|
ts.ScriptTarget.Latest,
|
||||||
|
true,
|
||||||
|
ts.ScriptKind.JS
|
||||||
|
);
|
||||||
|
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
||||||
|
const exportsArray =
|
||||||
|
format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
||||||
|
if (!exportsArray) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportsArray.some(isFlatConfigIgnoresBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFlatConfigIgnoresBlock(
|
||||||
|
node: ts.Node
|
||||||
|
): node is ts.ObjectLiteralExpression {
|
||||||
|
return (
|
||||||
|
ts.isObjectLiteralExpression(node) &&
|
||||||
|
node.properties.length === 1 &&
|
||||||
|
(node.properties[0].name.getText() === 'ignores' ||
|
||||||
|
node.properties[0].name.getText() === '"ignores"') &&
|
||||||
|
ts.isPropertyAssignment(node.properties[0]) &&
|
||||||
|
ts.isArrayLiteralExpression(node.properties[0].initializer)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function isOverride(node: ts.Node): boolean {
|
function isOverride(node: ts.Node): boolean {
|
||||||
return (
|
return (
|
||||||
(ts.isObjectLiteralExpression(node) &&
|
(ts.isObjectLiteralExpression(node) &&
|
||||||
|
|||||||
@ -22,7 +22,14 @@ exports[`app generated files content - as-provided - my-app general application
|
|||||||
exports[`app generated files content - as-provided - my-app general application should configure eslint correctly (eslintrc) 1`] = `
|
exports[`app generated files content - as-provided - my-app general application should configure eslint correctly (eslintrc) 1`] = `
|
||||||
"{
|
"{
|
||||||
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
|
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
|
||||||
"ignorePatterns": ["!**/*", ".nuxt/**", ".output/**", "node_modules"],
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
".nuxt/**",
|
||||||
|
".output/**",
|
||||||
|
"node_modules",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
||||||
@ -416,7 +423,14 @@ exports[`app generated files content - as-provided - myApp general application s
|
|||||||
exports[`app generated files content - as-provided - myApp general application should configure eslint correctly (eslintrc) 1`] = `
|
exports[`app generated files content - as-provided - myApp general application should configure eslint correctly (eslintrc) 1`] = `
|
||||||
"{
|
"{
|
||||||
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
|
"extends": ["@nuxt/eslint-config", "../.eslintrc.json"],
|
||||||
"ignorePatterns": ["!**/*", ".nuxt/**", ".output/**", "node_modules"],
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
".nuxt/**",
|
||||||
|
".output/**",
|
||||||
|
"node_modules",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
||||||
|
|||||||
@ -122,6 +122,9 @@ export async function applicationGeneratorInternal(
|
|||||||
tasks.push(twTask);
|
tasks.push(twTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lintTask = await addLinting(tree, options);
|
||||||
|
tasks.push(lintTask);
|
||||||
|
|
||||||
if (options.bundler === 'vite') {
|
if (options.bundler === 'vite') {
|
||||||
await setupViteConfiguration(tree, options, tasks);
|
await setupViteConfiguration(tree, options, tasks);
|
||||||
} else if (options.bundler === 'rsbuild') {
|
} else if (options.bundler === 'rsbuild') {
|
||||||
@ -144,9 +147,6 @@ export async function applicationGeneratorInternal(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lintTask = await addLinting(tree, options);
|
|
||||||
tasks.push(lintTask);
|
|
||||||
|
|
||||||
const e2eTask = await addE2e(tree, options);
|
const e2eTask = await addE2e(tree, options);
|
||||||
tasks.push(e2eTask);
|
tasks.push(e2eTask);
|
||||||
|
|
||||||
|
|||||||
@ -659,7 +659,13 @@ export default defineConfig({
|
|||||||
exports[`Remix Application Standalone Project Repo should create the application correctly 5`] = `
|
exports[`Remix Application Standalone Project Repo should create the application correctly 5`] = `
|
||||||
"{
|
"{
|
||||||
"root": true,
|
"root": true,
|
||||||
"ignorePatterns": ["!**/*", "build", "public/build"],
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"build",
|
||||||
|
"public/build",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
"plugins": ["@nx"],
|
"plugins": ["@nx"],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -47,6 +47,66 @@ describe('Remix Application', () => {
|
|||||||
expect(tree.read('.eslintrc.json', 'utf-8')).toMatchSnapshot();
|
expect(tree.read('.eslintrc.json', 'utf-8')).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files', async () => {
|
||||||
|
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||||
|
|
||||||
|
await applicationGenerator(tree, {
|
||||||
|
name: 'test',
|
||||||
|
directory: '.',
|
||||||
|
addPlugin: true,
|
||||||
|
skipFormat: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(tree.read('.gitignore', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"null
|
||||||
|
.cache
|
||||||
|
build
|
||||||
|
public/build
|
||||||
|
.env
|
||||||
|
|
||||||
|
vite.config.*.timestamp*
|
||||||
|
vitest.config.*.timestamp*"
|
||||||
|
`);
|
||||||
|
expect(tree.read('.eslintrc.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"root": true,
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"build",
|
||||||
|
"public/build",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@nx"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.ts",
|
||||||
|
"*.tsx"
|
||||||
|
],
|
||||||
|
"extends": [
|
||||||
|
"plugin:@nx/typescript"
|
||||||
|
],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.js",
|
||||||
|
"*.jsx"
|
||||||
|
],
|
||||||
|
"extends": [
|
||||||
|
"plugin:@nx/javascript"
|
||||||
|
],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
describe('--unitTestRunner', () => {
|
describe('--unitTestRunner', () => {
|
||||||
it('should generate the correct files for testing using vitest', async () => {
|
it('should generate the correct files for testing using vitest', async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
@ -177,6 +237,62 @@ describe('Remix Application', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files', async () => {
|
||||||
|
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
||||||
|
|
||||||
|
await applicationGenerator(tree, {
|
||||||
|
directory: 'test',
|
||||||
|
addPlugin: true,
|
||||||
|
skipFormat: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(tree.read('.gitignore', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"vite.config.*.timestamp*
|
||||||
|
vitest.config.*.timestamp*"
|
||||||
|
`);
|
||||||
|
expect(tree.read(`${appDir}/.eslintrc.json`, 'utf-8'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"extends": [
|
||||||
|
"../.eslintrc.json"
|
||||||
|
],
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"build",
|
||||||
|
"public/build",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.ts",
|
||||||
|
"*.tsx",
|
||||||
|
"*.js",
|
||||||
|
"*.jsx"
|
||||||
|
],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.ts",
|
||||||
|
"*.tsx"
|
||||||
|
],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.js",
|
||||||
|
"*.jsx"
|
||||||
|
],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
describe('--directory', () => {
|
describe('--directory', () => {
|
||||||
it('should create the application correctly', async () => {
|
it('should create the application correctly', async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
|
|||||||
@ -37,7 +37,7 @@ import initGenerator from '../init/init';
|
|||||||
import { updateDependencies } from '../utils/update-dependencies';
|
import { updateDependencies } from '../utils/update-dependencies';
|
||||||
import {
|
import {
|
||||||
addE2E,
|
addE2E,
|
||||||
addViteTempFilesToGitIgnore,
|
ignoreViteTempFiles,
|
||||||
normalizeOptions,
|
normalizeOptions,
|
||||||
updateUnitTestConfig,
|
updateUnitTestConfig,
|
||||||
} from './lib';
|
} from './lib';
|
||||||
@ -312,7 +312,7 @@ export default {...nxPreset};
|
|||||||
|
|
||||||
tasks.push(await addE2E(tree, options));
|
tasks.push(await addE2E(tree, options));
|
||||||
|
|
||||||
addViteTempFilesToGitIgnore(tree);
|
await ignoreViteTempFiles(tree, options.projectRoot);
|
||||||
|
|
||||||
updateTsconfigFiles(
|
updateTsconfigFiles(
|
||||||
tree,
|
tree,
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
import { stripIndents, Tree } from '@nx/devkit';
|
|
||||||
|
|
||||||
export function addViteTempFilesToGitIgnore(tree: Tree) {
|
|
||||||
let newGitIgnoreContents = `vite.config.*.timestamp*`;
|
|
||||||
if (tree.exists('.gitignore')) {
|
|
||||||
const gitIgnoreContents = tree.read('.gitignore', 'utf-8');
|
|
||||||
if (!gitIgnoreContents.includes(newGitIgnoreContents)) {
|
|
||||||
newGitIgnoreContents = stripIndents`${gitIgnoreContents}
|
|
||||||
${newGitIgnoreContents}`;
|
|
||||||
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
import { ensurePackage, readJson, stripIndents, type Tree } from '@nx/devkit';
|
||||||
|
import { getPackageVersion } from '../../../utils/versions';
|
||||||
|
|
||||||
|
export async function ignoreViteTempFiles(
|
||||||
|
tree: Tree,
|
||||||
|
projectRoot?: string | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
addViteTempFilesToGitIgnore(tree);
|
||||||
|
await ignoreViteTempFilesInEslintConfig(tree, projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addViteTempFilesToGitIgnore(tree: Tree): void {
|
||||||
|
let gitIgnoreContents = tree.exists('.gitignore')
|
||||||
|
? tree.read('.gitignore', 'utf-8')
|
||||||
|
: '';
|
||||||
|
|
||||||
|
if (!/^vite\.config\.\*\.timestamp\*$/m.test(gitIgnoreContents)) {
|
||||||
|
gitIgnoreContents = stripIndents`${gitIgnoreContents}
|
||||||
|
vite.config.*.timestamp*`;
|
||||||
|
}
|
||||||
|
if (!/^vitest\.config\.\*\.timestamp\*$/m.test(gitIgnoreContents)) {
|
||||||
|
gitIgnoreContents = stripIndents`${gitIgnoreContents}
|
||||||
|
vitest.config.*.timestamp*`;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree.write('.gitignore', gitIgnoreContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ignoreViteTempFilesInEslintConfig(
|
||||||
|
tree: Tree,
|
||||||
|
projectRoot: string | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
if (!isEslintInstalled(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensurePackage('@nx/eslint', getPackageVersion(tree, 'nx'));
|
||||||
|
const { addIgnoresToLintConfig, isEslintConfigSupported } = await import(
|
||||||
|
'@nx/eslint/src/generators/utils/eslint-file'
|
||||||
|
);
|
||||||
|
if (!isEslintConfigSupported(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { useFlatConfig } = await import('@nx/eslint/src/utils/flat-config');
|
||||||
|
const isUsingFlatConfig = useFlatConfig(tree);
|
||||||
|
if (!projectRoot && !isUsingFlatConfig) {
|
||||||
|
// root eslintrc files ignore all files and the root eslintrc files add
|
||||||
|
// back all the project files, so we only add the ignores to the project
|
||||||
|
// eslintrc files
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for flat config, we update the root config file
|
||||||
|
const directory = isUsingFlatConfig ? '' : projectRoot ?? '';
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, directory, [
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isEslintInstalled(tree: Tree): boolean {
|
||||||
|
try {
|
||||||
|
require('eslint');
|
||||||
|
return true;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
// it might not be installed yet, but it might be in the tree pending install
|
||||||
|
const { devDependencies, dependencies } = tree.exists('package.json')
|
||||||
|
? readJson(tree, 'package.json')
|
||||||
|
: {};
|
||||||
|
|
||||||
|
return !!devDependencies?.['eslint'] || !!dependencies?.['eslint'];
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
export * from './normalize-options';
|
export * from './normalize-options';
|
||||||
export * from './update-unit-test-config';
|
export * from './update-unit-test-config';
|
||||||
export * from './add-e2e';
|
export * from './add-e2e';
|
||||||
export * from './add-vite-temp-files-to-gitignore';
|
export * from './ignore-vite-temp-files';
|
||||||
|
|||||||
@ -29,7 +29,15 @@
|
|||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"buildTargets": ["build-base"],
|
"buildTargets": ["build-base"],
|
||||||
"ignoredDependencies": ["nx", "typescript", "vite"]
|
"ignoredDependencies": [
|
||||||
|
"nx",
|
||||||
|
"typescript",
|
||||||
|
"vite",
|
||||||
|
// we only check if the package is installed
|
||||||
|
"eslint",
|
||||||
|
// we ensure it is installed and only use it when eslint is installed
|
||||||
|
"@nx/eslint"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,11 @@
|
|||||||
"version": "20.5.0-beta.3",
|
"version": "20.5.0-beta.3",
|
||||||
"description": "Update resolve.conditions to include defaults that are no longer provided by Vite.",
|
"description": "Update resolve.conditions to include defaults that are no longer provided by Vite.",
|
||||||
"implementation": "./src/migrations/update-20-5-0/update-resolve-conditions"
|
"implementation": "./src/migrations/update-20-5-0/update-resolve-conditions"
|
||||||
|
},
|
||||||
|
"eslint-ignore-vite-temp-files": {
|
||||||
|
"version": "20.5.0-beta.3",
|
||||||
|
"description": "Add vite config temporary files to the ESLint configuration ignore patterns if ESLint is used.",
|
||||||
|
"implementation": "./src/migrations/update-20-5-0/eslint-ignore-vite-temp-files"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
|
|||||||
@ -81,7 +81,11 @@ export async function viteConfigurationGeneratorInternal(
|
|||||||
tsConfigName: projectRoot === '.' ? 'tsconfig.json' : 'tsconfig.base.json',
|
tsConfigName: projectRoot === '.' ? 'tsconfig.json' : 'tsconfig.base.json',
|
||||||
});
|
});
|
||||||
tasks.push(jsInitTask);
|
tasks.push(jsInitTask);
|
||||||
const initTask = await initGenerator(tree, { ...schema, skipFormat: true });
|
const initTask = await initGenerator(tree, {
|
||||||
|
...schema,
|
||||||
|
projectRoot,
|
||||||
|
skipFormat: true,
|
||||||
|
});
|
||||||
tasks.push(initTask);
|
tasks.push(initTask);
|
||||||
tasks.push(ensureDependencies(tree, schema));
|
tasks.push(ensureDependencies(tree, schema));
|
||||||
|
|
||||||
|
|||||||
@ -132,17 +132,200 @@ describe('@nx/vite:init', () => {
|
|||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files in gitignore', async () => {
|
||||||
|
await initGenerator(tree, {});
|
||||||
|
|
||||||
|
expect(tree.read('.gitignore', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"vite.config.*.timestamp*
|
||||||
|
vitest.config.*.timestamp*"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
it(`should not add multiple instances of the same vite temp file glob to gitignore`, async () => {
|
it(`should not add multiple instances of the same vite temp file glob to gitignore`, async () => {
|
||||||
// ARRANGE
|
// ARRANGE
|
||||||
tree.write('.gitignore', 'vite.config.*.timestamp*');
|
tree.write(
|
||||||
|
'.gitignore',
|
||||||
|
`vitest.config.*.timestamp*
|
||||||
|
vite.config.*.timestamp*`
|
||||||
|
);
|
||||||
|
|
||||||
// ACT
|
// ACT
|
||||||
await initGenerator(tree, {});
|
await initGenerator(tree, {});
|
||||||
|
|
||||||
// ASSERT
|
// ASSERT
|
||||||
expect(tree.read('.gitignore', 'utf-8')).toMatchInlineSnapshot(`
|
expect(tree.read('.gitignore', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
"vite.config.*.timestamp*
|
"vitest.config.*.timestamp*
|
||||||
vitest.config.*.timestamp*"
|
vite.config.*.timestamp*"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files in eslint flat config without a block with ignores', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write('eslint.config.mjs', `export default [];`);
|
||||||
|
|
||||||
|
await initGenerator(tree, {});
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
ignores: ['**/vite.config.*.timestamp*', '**/vitest.config.*.timestamp*'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files in eslint flat config with a block with ignores', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.mjs',
|
||||||
|
`export default [
|
||||||
|
{
|
||||||
|
ignores: ['dist'],
|
||||||
|
},
|
||||||
|
];`
|
||||||
|
);
|
||||||
|
|
||||||
|
await initGenerator(tree, {});
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'dist',
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not duplicate vite temp files in eslint flat config', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write(
|
||||||
|
'eslint.config.mjs',
|
||||||
|
`export default [
|
||||||
|
{
|
||||||
|
ignores: ['**/vitest.config.*.timestamp*', '**/vite.config.*.timestamp*'],
|
||||||
|
},
|
||||||
|
];`
|
||||||
|
);
|
||||||
|
|
||||||
|
await initGenerator(tree, {});
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
ignores: ['**/vitest.config.*.timestamp*', '**/vite.config.*.timestamp*'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files in project eslintrc config without ignorePatterns', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write('.eslintrc.json', JSON.stringify({ ignorePatterns: ['**/*'] }));
|
||||||
|
tree.write('apps/my-app/.eslintrc.json', `{}`);
|
||||||
|
|
||||||
|
await initGenerator(tree, { projectRoot: 'apps/my-app' });
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(readJson(tree, 'apps/my-app/.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore vite temp files in project eslintrc config with ignorePatterns config', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write('.eslintrc.json', JSON.stringify({ ignorePatterns: ['**/*'] }));
|
||||||
|
tree.write(
|
||||||
|
'apps/my-app/.eslintrc.json',
|
||||||
|
JSON.stringify({ ignorePatterns: ['!**/*'] })
|
||||||
|
);
|
||||||
|
|
||||||
|
await initGenerator(tree, { projectRoot: 'apps/my-app' });
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(readJson(tree, 'apps/my-app/.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not duplicate vite temp files in project eslintrc config', async () => {
|
||||||
|
updateJson(tree, 'package.json', (json) => {
|
||||||
|
json.devDependencies = { eslint: '9.0.0' };
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
tree.write('.eslintrc.json', JSON.stringify({ ignorePatterns: ['**/*'] }));
|
||||||
|
tree.write(
|
||||||
|
'apps/my-app/.eslintrc.json',
|
||||||
|
JSON.stringify({
|
||||||
|
ignorePatterns: [
|
||||||
|
'!**/*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await initGenerator(tree, { projectRoot: 'apps/my-app' });
|
||||||
|
|
||||||
|
expect(readJson(tree, '.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"**/*",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(readJson(tree, 'apps/my-app/.eslintrc.json')).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vitest.config.*.timestamp*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
],
|
||||||
|
}
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { setupPathsPlugin } from '../setup-paths-plugin/setup-paths-plugin';
|
|||||||
import { createNodesV2 } from '../../plugins/plugin';
|
import { createNodesV2 } from '../../plugins/plugin';
|
||||||
import { InitGeneratorSchema } from './schema';
|
import { InitGeneratorSchema } from './schema';
|
||||||
import { checkDependenciesInstalled, moveToDevDependencies } from './lib/utils';
|
import { checkDependenciesInstalled, moveToDevDependencies } from './lib/utils';
|
||||||
import { addViteTempFilesToGitIgnore } from '../../utils/add-vite-temp-files-to-gitignore';
|
import { ignoreViteTempFiles } from '../../utils/ignore-vite-temp-files';
|
||||||
|
|
||||||
export function updateNxJsonSettings(tree: Tree) {
|
export function updateNxJsonSettings(tree: Tree) {
|
||||||
const nxJson = readNxJson(tree);
|
const nxJson = readNxJson(tree);
|
||||||
@ -96,7 +96,7 @@ export async function initGeneratorInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateNxJsonSettings(tree);
|
updateNxJsonSettings(tree);
|
||||||
addViteTempFilesToGitIgnore(tree);
|
await ignoreViteTempFiles(tree, schema.projectRoot);
|
||||||
|
|
||||||
if (schema.setupPathsPlugin) {
|
if (schema.setupPathsPlugin) {
|
||||||
await setupPathsPlugin(tree, { skipFormat: true });
|
await setupPathsPlugin(tree, { skipFormat: true });
|
||||||
|
|||||||
@ -7,4 +7,5 @@ export interface InitGeneratorSchema {
|
|||||||
addPlugin?: boolean;
|
addPlugin?: boolean;
|
||||||
vitestOnly?: boolean;
|
vitestOnly?: boolean;
|
||||||
useViteV5?: boolean;
|
useViteV5?: boolean;
|
||||||
|
projectRoot?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,6 +73,7 @@ export async function vitestGeneratorInternal(
|
|||||||
const useVite5 =
|
const useVite5 =
|
||||||
major(coerce(pkgJson.devDependencies['vite']) ?? '6.0.0') === 5;
|
major(coerce(pkgJson.devDependencies['vite']) ?? '6.0.0') === 5;
|
||||||
const initTask = await initGenerator(tree, {
|
const initTask = await initGenerator(tree, {
|
||||||
|
projectRoot: root,
|
||||||
skipFormat: true,
|
skipFormat: true,
|
||||||
addPlugin: schema.addPlugin,
|
addPlugin: schema.addPlugin,
|
||||||
useViteV5: useVite5,
|
useViteV5: useVite5,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Tree } from '@nx/devkit';
|
import { Tree } from '@nx/devkit';
|
||||||
import { addViteTempFilesToGitIgnore as _addViteTempFilesToGitIgnore } from '../../utils/add-vite-temp-files-to-gitignore';
|
import { addViteTempFilesToGitIgnore as _addViteTempFilesToGitIgnore } from '../../utils/ignore-vite-temp-files';
|
||||||
|
|
||||||
export default function addViteTempFilesToGitIgnore(tree: Tree) {
|
export default function addViteTempFilesToGitIgnore(tree: Tree) {
|
||||||
// need to check if .gitignore exists before adding to it
|
// need to check if .gitignore exists before adding to it
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Tree } from '@nx/devkit';
|
import { Tree } from '@nx/devkit';
|
||||||
import { addViteTempFilesToGitIgnore as _addViteTempFilesToGitIgnore } from '../../utils/add-vite-temp-files-to-gitignore';
|
import { addViteTempFilesToGitIgnore as _addViteTempFilesToGitIgnore } from '../../utils/ignore-vite-temp-files';
|
||||||
|
|
||||||
export default function addViteTempFilesToGitIgnore(tree: Tree) {
|
export default function addViteTempFilesToGitIgnore(tree: Tree) {
|
||||||
// need to check if .gitignore exists before adding to it
|
// need to check if .gitignore exists before adding to it
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
#### Sample Code Changes
|
||||||
|
|
||||||
|
Add `vite.config.*.timestamp*` and `vitest.config.*.timestamp*` to the root `eslint.config.mjs` file (using **ESLint Flat Config**).
|
||||||
|
|
||||||
|
{% tabs %}
|
||||||
|
{% tab label="Before" %}
|
||||||
|
|
||||||
|
```js {% fileName="eslint.config.mjs" %}
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ['dist'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
{% /tab %}
|
||||||
|
{% tab label="After" %}
|
||||||
|
|
||||||
|
```js {% highlightLines=[3] fileName="eslint.config.mjs" %}
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
ignores: ['dist', 'vite.config.*.timestamp*', 'vitest.config.*.timestamp*'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
{% /tab %}
|
||||||
|
|
||||||
|
{% /tabs %}
|
||||||
|
|
||||||
|
Add `vite.config.*.timestamp*` and `vitest.config.*.timestamp*` to the project's `.eslintrc.json` file (using **eslintrc** format config).
|
||||||
|
|
||||||
|
{% tabs %}
|
||||||
|
{% tab label="Before" %}
|
||||||
|
|
||||||
|
```json {% fileName="apps/app1/eslintrc.json" %}
|
||||||
|
{
|
||||||
|
"ignorePatterns": ["!**/*"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{% /tab %}
|
||||||
|
{% tab label="After" %}
|
||||||
|
|
||||||
|
```json {% highlightLines=[4,5] fileName="apps/app1/eslintrc.json" %}
|
||||||
|
{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"vite.config.*.timestamp*",
|
||||||
|
"vitest.config.*.timestamp*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{% /tab %}
|
||||||
|
|
||||||
|
{% /tabs %}
|
||||||
@ -0,0 +1,148 @@
|
|||||||
|
import { addProjectConfiguration, type Tree } from '@nx/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||||
|
import { isEslintInstalled } from '../../utils/ignore-vite-temp-files';
|
||||||
|
import migration from './eslint-ignore-vite-temp-files';
|
||||||
|
|
||||||
|
jest.mock('../../utils/ignore-vite-temp-files', () => ({
|
||||||
|
...jest.requireActual('../../utils/ignore-vite-temp-files'),
|
||||||
|
isEslintInstalled: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('eslint-ignore-vite-temp-files migration', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
let isEslintInstalledMock: jest.Mock;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace();
|
||||||
|
isEslintInstalledMock = (isEslintInstalled as jest.Mock).mockReturnValue(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw an error if eslint is not installed', async () => {
|
||||||
|
isEslintInstalledMock.mockReturnValue(false);
|
||||||
|
|
||||||
|
await expect(migration(tree)).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw an error if there are no eslint config files', async () => {
|
||||||
|
await expect(migration(tree)).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should only update the root eslint config when using flat config', async () => {
|
||||||
|
tree.write('eslint.config.mjs', 'export default [];');
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
targets: {},
|
||||||
|
});
|
||||||
|
tree.write('apps/app1/eslint.config.mjs', 'export default [];');
|
||||||
|
|
||||||
|
await migration(tree);
|
||||||
|
|
||||||
|
expect(tree.read('eslint.config.mjs', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"export default [
|
||||||
|
{
|
||||||
|
ignores: ['**/vite.config.*.timestamp*', '**/vitest.config.*.timestamp*'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('apps/app1/eslint.config.mjs', 'utf-8'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
"export default [];
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the project eslint config when using eslintrc config and it is using vite', async () => {
|
||||||
|
tree.write(
|
||||||
|
'.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["**/*"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
addProjectConfiguration(tree, 'app1', {
|
||||||
|
root: 'apps/app1',
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: 'apps/app1/src',
|
||||||
|
targets: {},
|
||||||
|
});
|
||||||
|
tree.write(
|
||||||
|
'apps/app1/.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["!**/*"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
tree.write('apps/app1/vite.config.ts', 'export default {};');
|
||||||
|
addProjectConfiguration(tree, 'app2', {
|
||||||
|
root: 'apps/app2',
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: 'apps/app2/src',
|
||||||
|
targets: {},
|
||||||
|
});
|
||||||
|
tree.write(
|
||||||
|
'apps/app2/.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["!**/*"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
tree.write('apps/app2/vitest.config.ts', 'export default {};');
|
||||||
|
// app not using vite, it should not be updated
|
||||||
|
addProjectConfiguration(tree, 'app3', {
|
||||||
|
root: 'apps/app3',
|
||||||
|
projectType: 'application',
|
||||||
|
sourceRoot: 'apps/app3/src',
|
||||||
|
targets: {},
|
||||||
|
});
|
||||||
|
tree.write(
|
||||||
|
'apps/app3/.eslintrc.json',
|
||||||
|
`{
|
||||||
|
"ignorePatterns": ["!**/*"]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await migration(tree);
|
||||||
|
|
||||||
|
expect(tree.read('.eslintrc.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"ignorePatterns": ["**/*"]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('apps/app1/.eslintrc.json', 'utf-8'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('apps/app2/.eslintrc.json', 'utf-8'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.read('apps/app3/.eslintrc.json', 'utf-8'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"ignorePatterns": ["!**/*"]
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
ensurePackage,
|
||||||
|
formatFiles,
|
||||||
|
getProjects,
|
||||||
|
globAsync,
|
||||||
|
type Tree,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { isEslintInstalled } from '../../utils/ignore-vite-temp-files';
|
||||||
|
import { nxVersion } from '../../utils/versions';
|
||||||
|
|
||||||
|
export default async function (tree: Tree) {
|
||||||
|
if (!isEslintInstalled(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensurePackage('@nx/eslint', nxVersion);
|
||||||
|
const { addIgnoresToLintConfig, isEslintConfigSupported } = await import(
|
||||||
|
'@nx/eslint/src/generators/utils/eslint-file'
|
||||||
|
);
|
||||||
|
if (!isEslintConfigSupported(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { useFlatConfig } = await import('@nx/eslint/src/utils/flat-config');
|
||||||
|
const isUsingFlatConfig = useFlatConfig(tree);
|
||||||
|
|
||||||
|
if (isUsingFlatConfig) {
|
||||||
|
// using flat config, so we update the root eslint config
|
||||||
|
addIgnoresToLintConfig(tree, '', [
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// not using flat config, so we update each project's eslint config
|
||||||
|
const projects = getProjects(tree);
|
||||||
|
|
||||||
|
for (const [, { root: projectRoot }] of projects) {
|
||||||
|
const viteConfigFiles = await globAsync(tree, [
|
||||||
|
`${projectRoot}/**/{vite,vitest}.config.{js,ts,mjs,mts,cjs,cts}`,
|
||||||
|
]);
|
||||||
|
if (!viteConfigFiles.length) {
|
||||||
|
// the project doesn't use vite or vitest, so we skip it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, projectRoot, [
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import { stripIndents, Tree } from '@nx/devkit';
|
|
||||||
|
|
||||||
export function addViteTempFilesToGitIgnore(tree: Tree) {
|
|
||||||
let newGitIgnoreContents = `vite.config.*.timestamp*`;
|
|
||||||
if (tree.exists('.gitignore')) {
|
|
||||||
const gitIgnoreContents = tree.read('.gitignore', 'utf-8');
|
|
||||||
if (!gitIgnoreContents.includes(newGitIgnoreContents)) {
|
|
||||||
newGitIgnoreContents = stripIndents`${gitIgnoreContents}
|
|
||||||
${newGitIgnoreContents}`;
|
|
||||||
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
|
|
||||||
newGitIgnoreContents = `vitest.config.*.timestamp*`;
|
|
||||||
if (tree.exists('.gitignore')) {
|
|
||||||
const gitIgnoreContents = tree.read('.gitignore', 'utf-8');
|
|
||||||
if (!gitIgnoreContents.includes(newGitIgnoreContents)) {
|
|
||||||
newGitIgnoreContents = stripIndents`${gitIgnoreContents}
|
|
||||||
${newGitIgnoreContents}`;
|
|
||||||
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tree.write('.gitignore', newGitIgnoreContents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
75
packages/vite/src/utils/ignore-vite-temp-files.ts
Normal file
75
packages/vite/src/utils/ignore-vite-temp-files.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { ensurePackage, readJson, stripIndents, type Tree } from '@nx/devkit';
|
||||||
|
import { nxVersion } from './versions';
|
||||||
|
|
||||||
|
export async function ignoreViteTempFiles(
|
||||||
|
tree: Tree,
|
||||||
|
projectRoot?: string | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
addViteTempFilesToGitIgnore(tree);
|
||||||
|
await ignoreViteTempFilesInEslintConfig(tree, projectRoot);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addViteTempFilesToGitIgnore(tree: Tree): void {
|
||||||
|
let gitIgnoreContents = tree.exists('.gitignore')
|
||||||
|
? tree.read('.gitignore', 'utf-8')
|
||||||
|
: '';
|
||||||
|
|
||||||
|
if (!/^vite\.config\.\*\.timestamp\*$/m.test(gitIgnoreContents)) {
|
||||||
|
gitIgnoreContents = stripIndents`${gitIgnoreContents}
|
||||||
|
vite.config.*.timestamp*`;
|
||||||
|
}
|
||||||
|
if (!/^vitest\.config\.\*\.timestamp\*$/m.test(gitIgnoreContents)) {
|
||||||
|
gitIgnoreContents = stripIndents`${gitIgnoreContents}
|
||||||
|
vitest.config.*.timestamp*`;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree.write('.gitignore', gitIgnoreContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ignoreViteTempFilesInEslintConfig(
|
||||||
|
tree: Tree,
|
||||||
|
projectRoot: string | undefined
|
||||||
|
): Promise<void> {
|
||||||
|
if (!isEslintInstalled(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensurePackage('@nx/eslint', nxVersion);
|
||||||
|
const { addIgnoresToLintConfig, isEslintConfigSupported } = await import(
|
||||||
|
'@nx/eslint/src/generators/utils/eslint-file'
|
||||||
|
);
|
||||||
|
if (!isEslintConfigSupported(tree)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { useFlatConfig } = await import('@nx/eslint/src/utils/flat-config');
|
||||||
|
const isUsingFlatConfig = useFlatConfig(tree);
|
||||||
|
if (!projectRoot && !isUsingFlatConfig) {
|
||||||
|
// root eslintrc files ignore all files and the root eslintrc files add
|
||||||
|
// back all the project files, so we only add the ignores to the project
|
||||||
|
// eslintrc files
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for flat config, we update the root config file
|
||||||
|
const directory = isUsingFlatConfig ? '' : projectRoot ?? '';
|
||||||
|
|
||||||
|
addIgnoresToLintConfig(tree, directory, [
|
||||||
|
'**/vite.config.*.timestamp*',
|
||||||
|
'**/vitest.config.*.timestamp*',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isEslintInstalled(tree: Tree): boolean {
|
||||||
|
try {
|
||||||
|
require('eslint');
|
||||||
|
return true;
|
||||||
|
} catch {}
|
||||||
|
|
||||||
|
// it might not be installed yet, but it might be in the tree pending install
|
||||||
|
const { devDependencies, dependencies } = tree.exists('package.json')
|
||||||
|
? readJson(tree, 'package.json')
|
||||||
|
: {};
|
||||||
|
|
||||||
|
return !!devDependencies?.['eslint'] || !!dependencies?.['eslint'];
|
||||||
|
}
|
||||||
@ -94,7 +94,11 @@ exports[`application generator should set up project correctly for cypress 3`] =
|
|||||||
"@vue/eslint-config-prettier/skip-formatting",
|
"@vue/eslint-config-prettier/skip-formatting",
|
||||||
"../.eslintrc.json"
|
"../.eslintrc.json"
|
||||||
],
|
],
|
||||||
"ignorePatterns": ["!**/*"],
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
||||||
@ -300,7 +304,11 @@ exports[`application generator should set up project correctly with given option
|
|||||||
"@vue/eslint-config-prettier/skip-formatting",
|
"@vue/eslint-config-prettier/skip-formatting",
|
||||||
"../.eslintrc.json"
|
"../.eslintrc.json"
|
||||||
],
|
],
|
||||||
"ignorePatterns": ["!**/*"],
|
"ignorePatterns": [
|
||||||
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*"
|
||||||
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
|
||||||
|
|||||||
@ -240,6 +240,8 @@ exports[`library should generate files 1`] = `
|
|||||||
],
|
],
|
||||||
"ignorePatterns": [
|
"ignorePatterns": [
|
||||||
"!**/*",
|
"!**/*",
|
||||||
|
"**/vite.config.*.timestamp*",
|
||||||
|
"**/vitest.config.*.timestamp*",
|
||||||
],
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -317,6 +317,25 @@ export async function applicationGeneratorInternal(host: Tree, schema: Schema) {
|
|||||||
|
|
||||||
createApplicationFiles(host, options);
|
createApplicationFiles(host, options);
|
||||||
|
|
||||||
|
if (options.linter === 'eslint') {
|
||||||
|
const { lintProjectGenerator } = ensurePackage<typeof import('@nx/eslint')>(
|
||||||
|
'@nx/eslint',
|
||||||
|
nxVersion
|
||||||
|
);
|
||||||
|
const lintTask = await lintProjectGenerator(host, {
|
||||||
|
linter: options.linter,
|
||||||
|
project: options.projectName,
|
||||||
|
tsConfigPaths: [
|
||||||
|
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
||||||
|
],
|
||||||
|
unitTestRunner: options.unitTestRunner,
|
||||||
|
skipFormat: true,
|
||||||
|
setParserOptionsProject: options.setParserOptionsProject,
|
||||||
|
addPlugin: options.addPlugin,
|
||||||
|
});
|
||||||
|
tasks.push(lintTask);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.bundler === 'vite') {
|
if (options.bundler === 'vite') {
|
||||||
const { viteConfigurationGenerator, createOrEditViteConfig } =
|
const { viteConfigurationGenerator, createOrEditViteConfig } =
|
||||||
ensurePackage<typeof import('@nx/vite')>('@nx/vite', nxVersion);
|
ensurePackage<typeof import('@nx/vite')>('@nx/vite', nxVersion);
|
||||||
@ -387,25 +406,6 @@ export async function applicationGeneratorInternal(host: Tree, schema: Schema) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.linter === 'eslint') {
|
|
||||||
const { lintProjectGenerator } = ensurePackage<typeof import('@nx/eslint')>(
|
|
||||||
'@nx/eslint',
|
|
||||||
nxVersion
|
|
||||||
);
|
|
||||||
const lintTask = await lintProjectGenerator(host, {
|
|
||||||
linter: options.linter,
|
|
||||||
project: options.projectName,
|
|
||||||
tsConfigPaths: [
|
|
||||||
joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
|
|
||||||
],
|
|
||||||
unitTestRunner: options.unitTestRunner,
|
|
||||||
skipFormat: true,
|
|
||||||
setParserOptionsProject: options.setParserOptionsProject,
|
|
||||||
addPlugin: options.addPlugin,
|
|
||||||
});
|
|
||||||
tasks.push(lintTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nxJson = readNxJson(host);
|
const nxJson = readNxJson(host);
|
||||||
let hasPlugin: PluginConfiguration | undefined;
|
let hasPlugin: PluginConfiguration | undefined;
|
||||||
let buildPlugin: string;
|
let buildPlugin: string;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user