Skip to content

Commit

Permalink
fix(vue): application generator should use normalized app name #26605 (
Browse files Browse the repository at this point in the history
…#26729)

<!-- 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 -->
The `vue` app generator is not using the normalized name produced by
`projectRootAndFormat` util when creating the application.
This leads to errors in some cases.

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Use the `projectName` produced by the value to create the project
correctly.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #26605
  • Loading branch information
Coly010 authored Jun 27, 2024
1 parent 544eff0 commit 5843068
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,168 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`application generator should set up project correctly with PascalCase name 1`] = `
"{
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nx"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
}
},
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nx/typescript"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nx/javascript"],
"rules": {}
}
]
}
"
`;

exports[`application generator should set up project correctly with PascalCase name 2`] = `
"/// <reference types='vitest' />
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
root: __dirname,
cacheDir: '../node_modules/.vite/TestApp',
server: {
port: 4200,
host: 'localhost',
},
preview: {
port: 4300,
host: 'localhost',
},
plugins: [vue(), nxViteTsPaths()],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
build: {
outDir: '../dist/TestApp',
emptyOutDir: true,
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
},
test: {
watch: false,
globals: true,
cache: {
dir: '../node_modules/.vitest/TestApp',
},
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
reporters: ['default'],
coverage: {
reportsDirectory: '../coverage/TestApp',
provider: 'v8',
},
},
});
"
`;

exports[`application generator should set up project correctly with PascalCase name 3`] = `
"{
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/eslint-config-typescript",
"@vue/eslint-config-prettier/skip-formatting",
"../.eslintrc.json"
],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx", "*.vue"],
"rules": {
"vue/multi-word-component-names": "off"
}
}
]
}
"
`;

exports[`application generator should set up project correctly with PascalCase name 4`] = `
"import { describe, it, expect } from 'vitest';
import { mount } from '@vue/test-utils';
import App from './App.vue';
describe('App', () => {
it('renders properly', async () => {
const wrapper = mount(App, {});
expect(wrapper.text()).toContain('Welcome TestApp 👋');
});
});
"
`;

exports[`application generator should set up project correctly with PascalCase name 5`] = `
[
".eslintignore",
".eslintrc.json",
".prettierignore",
".prettierrc",
".vscode/extensions.json",
"nx.json",
"package.json",
"TestApp-e2e/.eslintrc.json",
"TestApp-e2e/playwright.config.ts",
"TestApp-e2e/project.json",
"TestApp-e2e/src/example.spec.ts",
"TestApp-e2e/tsconfig.json",
"TestApp/.eslintrc.json",
"TestApp/index.html",
"TestApp/project.json",
"TestApp/src/app/App.spec.ts",
"TestApp/src/app/App.vue",
"TestApp/src/app/NxWelcome.vue",
"TestApp/src/main.ts",
"TestApp/src/styles.css",
"TestApp/tsconfig.app.json",
"TestApp/tsconfig.json",
"TestApp/tsconfig.spec.json",
"TestApp/vite.config.ts",
"tsconfig.base.json",
"vitest.workspace.ts",
]
`;

exports[`application generator should set up project correctly with given options 1`] = `
"{
"root": true,
Expand Down
14 changes: 14 additions & 0 deletions packages/vue/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ describe('application generator', () => {
expect(listFiles(tree)).toMatchSnapshot();
});

it('should set up project correctly with PascalCase name', async () => {
await applicationGenerator(tree, {
...options,
name: 'TestApp',
unitTestRunner: 'vitest',
projectNameAndRootFormat: 'as-provided',
});
expect(tree.read('.eslintrc.json', 'utf-8')).toMatchSnapshot();
expect(tree.read('TestApp/vite.config.ts', 'utf-8')).toMatchSnapshot();
expect(tree.read('TestApp/.eslintrc.json', 'utf-8')).toMatchSnapshot();
expect(tree.read('TestApp/src/app/App.spec.ts', 'utf-8')).toMatchSnapshot();
expect(listFiles(tree)).toMatchSnapshot();
});

it('should not use stylesheet if --style=none', async () => {
await applicationGenerator(tree, { ...options, style: 'none' });

Expand Down
2 changes: 1 addition & 1 deletion packages/vue/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export async function applicationGeneratorInternal(

const tasks: GeneratorCallback[] = [];

addProjectConfiguration(tree, options.name, {
addProjectConfiguration(tree, options.projectName, {
root: options.appProjectRoot,
projectType: 'application',
sourceRoot: `${options.appProjectRoot}/src`,
Expand Down
8 changes: 4 additions & 4 deletions packages/vue/src/generators/application/lib/add-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function addVite(
// Set up build target (and test target if using vitest)
const viteTask = await viteConfigurationGenerator(tree, {
uiFramework: 'none',
project: options.name,
project: options.projectName,
newProject: true,
inSourceTests: options.inSourceTests,
includeVitest: options.unitTestRunner === 'vitest',
Expand All @@ -27,7 +27,7 @@ export async function addVite(
createOrEditViteConfig(
tree,
{
project: options.name,
project: options.projectName,
includeLib: false,
includeVitest: options.unitTestRunner === 'vitest',
inSourceTests: options.inSourceTests,
Expand All @@ -39,10 +39,10 @@ export async function addVite(

// Update build to skip type checking since tsc won't work on .vue files.
// Need to use vue-tsc instead.
const projectConfig = readProjectConfiguration(tree, options.name);
const projectConfig = readProjectConfiguration(tree, options.projectName);
if (projectConfig.targets?.build?.options) {
projectConfig.targets.build.options.skipTypeCheck = true;
updateProjectConfiguration(tree, options.name, projectConfig);
updateProjectConfiguration(tree, options.projectName, projectConfig);
}

return viteTask;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import { Tree, extractLayoutDirectory, names } from '@nx/devkit';
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
import { NormalizedSchema, Schema } from '../schema';

export function normalizeDirectory(options: Schema) {
options.directory = options.directory?.replace(/\\{1,2}/g, '/');
const { projectDirectory } = extractLayoutDirectory(options.directory);
return projectDirectory
? `${names(projectDirectory).fileName}/${names(options.name).fileName}`
: names(options.name).fileName;
}

export async function normalizeOptions(
host: Tree,
options: Schema,
Expand Down Expand Up @@ -39,7 +31,6 @@ export async function normalizeOptions(

const normalized = {
...options,
name: names(options.name).fileName,
projectName: appProjectName,
appProjectRoot,
e2eProjectName,
Expand Down

0 comments on commit 5843068

Please sign in to comment.