From c0855107588a4f7dd84637eef1a4f7bdb39b40d2 Mon Sep 17 00:00:00 2001 From: Sam Pullman Date: Sat, 11 May 2024 23:40:56 +0800 Subject: [PATCH 1/4] chore: update packages --- CHANGELOG.md | 6 +++ package.json | 40 ++++++++++---------- packages/vue3-vite/package.json | 6 +-- packages/vue3-vite/src/util/defaults.ts | 50 ++++++++++++------------- 4 files changed, 54 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 779231f..8fc739a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ TODO -- automate changelog generation +### v0.28.0 - 250511 + +- Update packages +- Update to Nx 18.3.4 +- Make Cypress optional peer dependency + ### v0.27.0 - 240117 - Update packages diff --git a/package.json b/package.json index 711caea..5b84cb7 100644 --- a/package.json +++ b/package.json @@ -29,35 +29,35 @@ "private": true, "devDependencies": { "@cypress/vite-dev-server": "^5.0.7", - "@nx/devkit": "17.2.8", - "@nx/eslint-plugin": "17.2.8", - "@nx/jest": "17.2.8", - "@nx/js": "17.2.8", - "@nx/eslint": "17.2.8", - "@nx/workspace": "17.2.8", - "@types/jest": "29.5.11", - "@types/node": "20.11.4", - "@typescript-eslint/eslint-plugin": "6.19.0", - "@typescript-eslint/parser": "6.19.0", - "@vitejs/plugin-vue": "5.0.3", + "@nx/devkit": "18.3.4", + "@nx/eslint-plugin": "18.3.4", + "@nx/jest": "18.3.4", + "@nx/js": "18.3.4", + "@nx/eslint": "18.3.4", + "@nx/workspace": "18.3.4", + "@types/jest": "29.5.12", + "@types/node": "20.12.11", + "@typescript-eslint/eslint-plugin": "7.8.0", + "@typescript-eslint/parser": "7.8.0", + "@vitejs/plugin-vue": "5.0.4", "conventional-github-releaser": "^3.1.5", - "cypress": "^13.6.2", - "dotenv": "16.3.1", - "eslint": "8.56.0", + "cypress": "^13.9.0", + "dotenv": "16.4.5", + "eslint": "9.2.0", "eslint-config-prettier": "9.1.0", "fs-extra": "^11.2.0", "husky": "^8.0.3", "jest": "29.7.0", - "nx": "17.2.8", + "nx": "18.3.4", "picocolors": "^1.0.0", - "prettier": "^3.2.2", + "prettier": "^3.2.5", "readline": "^1.3.0", - "rollup": "^4.9.5", - "ts-jest": "^29.1.1", + "rollup": "^4.17.2", + "ts-jest": "^29.1.2", "ts-node": "~10.9.2", "tslib": "^2.6.2", - "typescript": "~5.3.3", - "vite": "^5.0.11", + "typescript": "~5.4.5", + "vite": "^5.2.11", "vitepress": "^0.22.4" } } \ No newline at end of file diff --git a/packages/vue3-vite/package.json b/packages/vue3-vite/package.json index ec717b4..e56edc9 100644 --- a/packages/vue3-vite/package.json +++ b/packages/vue3-vite/package.json @@ -6,9 +6,9 @@ "executors": "./executors.json", "peerDependencies": { "vite": "^2.9.15 || ^3.2.4 || ^4.3.9 || ^5.0.11", - "@vitejs/plugin-vue": "^5.0.3", - "@nx/devkit": "^17.2.8", - "cypress": "^13.6.2", + "@vitejs/plugin-vue": "^5.0.4", + "@nx/devkit": "^18.3.4", + "cypress": "^13.9.0", "@cypress/vite-dev-server": "^5.0.7" }, "repository": { diff --git a/packages/vue3-vite/src/util/defaults.ts b/packages/vue3-vite/src/util/defaults.ts index bbedf60..8567bad 100644 --- a/packages/vue3-vite/src/util/defaults.ts +++ b/packages/vue3-vite/src/util/defaults.ts @@ -3,44 +3,44 @@ export const VSCodeExtensionsFilePath = '.vscode/extensions.json'; export const recommendedExtensions = ['vue.volar', 'cpylua.language-postcss']; // dependency versions -export const vueVersion = '^3.4.14'; -export const vueI18nVersion = '^9.9.0'; -export const vueRouterVersion = '^4.2.5'; +export const vueVersion = '^3.4.27'; +export const vueI18nVersion = '^9.13.1'; +export const vueRouterVersion = '^4.3.2'; // devDependency versions -export const viteVersion = '^5.0.11'; -export const eslintVersion = '^8.56.0'; -export const vuePluginVersion = '^5.0.3'; +export const viteVersion = '^5.2.11'; +export const eslintVersion = '^9.2.0'; +export const vuePluginVersion = '^5.0.4'; export const babelJestVersion = '^29.7.0'; export const jestGlobalsVersion = '^29.7.0'; export const vue3JestVersion = '^29.2.6'; -export const babelPresetEnvVersion = '^7.23.8'; -export const postcssVersion = '^8.4.33'; +export const babelPresetEnvVersion = '^7.24.5'; +export const postcssVersion = '^8.4.38'; export const postcssBasicsVersion = '^0.7.3'; -export const stylelintVersion = '^16.1.0'; +export const stylelintVersion = '^16.5.0'; export const stylelintConfigVersion = '^36.0.0'; export const tslibVersion = '^2.6.2'; export const tsConfigVersion = '^7.0.0'; -export const nrwlJestVersion = '^17.2.8'; -export const typescriptVersion = '~5.3.3'; +export const nrwlJestVersion = '^18.3.4'; +export const typescriptVersion = '~5.4.5'; export const CypressDevDependencies = { - cypress: '^13.6.2', + cypress: '^13.9.0', '@cypress/vue': '^6.0.0', '@cypress/vite-dev-server': '^5.0.7', - '@cypress/code-coverage': '^3.12.18', - 'eslint-plugin-cypress': '^2.15.1', + '@cypress/code-coverage': '^3.12.39', + 'eslint-plugin-cypress': '^3.2.0', '@nx/cypress': '*', }; export const VueDevDependencies = { - '@vue/test-utils': '^2.4.3', + '@vue/test-utils': '^2.4.6', }; export const VitestDevDependencies = { - '@nx/vite': '^17.2.8', - 'happy-dom': '^13.1.4', - vitest: '^1.2.0', + '@nx/vite': '^18.3.4', + 'happy-dom': '^14.10.1', + vitest: '^1.6.0', }; export const JestDevDependencies = { @@ -53,23 +53,23 @@ export const JestDevDependencies = { export const LintDevDependencies = { '@intlify/eslint-plugin-vue-i18n': '^2.0.0', - '@vue/eslint-config-typescript': '^12.0.0', + '@vue/eslint-config-typescript': '^13.0.0', eslint: eslintVersion, 'eslint-config-prettier': '^9.1.0', 'eslint-plugin-import': '^2.29.1', - 'eslint-plugin-vue': '^9.20.1', + 'eslint-plugin-vue': '^9.26.0', stylelint: stylelintVersion, 'stylelint-config-standard': stylelintConfigVersion, - '@typescript-eslint/eslint-plugin': '6.19.0', - '@typescript-eslint/parser': '6.19.0', - 'vue-eslint-parser': '^9.4.0', + '@typescript-eslint/eslint-plugin': '7.8.0', + '@typescript-eslint/parser': '7.8.0', + 'vue-eslint-parser': '^9.4.2', }; export const ProjectDependencies = { vue: vueVersion, 'vue-i18n': vueI18nVersion, 'vue-router': vueRouterVersion, - 'date-fns': '^2.30.0', + 'date-fns': '^3.6.0', }; export const ProjectDevDependencies = { @@ -78,7 +78,7 @@ export const ProjectDevDependencies = { 'class-transformer': '^0.5.1', postcss: postcssVersion, '@vitejs/plugin-vue': vuePluginVersion, - '@babel/plugin-transform-modules-commonjs': '^7.23.3', + '@babel/plugin-transform-modules-commonjs': '^7.24.1', '@babel/preset-env': babelPresetEnvVersion, '@babel/core': '^7.23.7', '@samatech/postcss-basics': postcssBasicsVersion, From 9094923ed119ed3e53c88d1bfb088599f35d993d Mon Sep 17 00:00:00 2001 From: Sam Pullman Date: Sat, 11 May 2024 23:42:12 +0800 Subject: [PATCH 2/4] fix: mark cypress peer dependency as optional --- package.json | 2 +- packages/vue3-vite/package.json | 8 ++++++++ packages/vue3-vite/src/util/defaults.ts | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5b84cb7..acdb4d8 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "conventional-github-releaser": "^3.1.5", "cypress": "^13.9.0", "dotenv": "16.4.5", - "eslint": "9.2.0", + "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", "fs-extra": "^11.2.0", "husky": "^8.0.3", diff --git a/packages/vue3-vite/package.json b/packages/vue3-vite/package.json index e56edc9..211bd9e 100644 --- a/packages/vue3-vite/package.json +++ b/packages/vue3-vite/package.json @@ -11,6 +11,14 @@ "cypress": "^13.9.0", "@cypress/vite-dev-server": "^5.0.7" }, + "peerDependenciesMeta": { + "cypress": { + "optional": true + }, + "@cypress/vite-dev-server": { + "optional": true + } + }, "repository": { "type": "git", "url": "git+https://github.com/samatechtw/nx-vue3-vite.git" diff --git a/packages/vue3-vite/src/util/defaults.ts b/packages/vue3-vite/src/util/defaults.ts index 8567bad..8a1e4e9 100644 --- a/packages/vue3-vite/src/util/defaults.ts +++ b/packages/vue3-vite/src/util/defaults.ts @@ -9,7 +9,7 @@ export const vueRouterVersion = '^4.3.2'; // devDependency versions export const viteVersion = '^5.2.11'; -export const eslintVersion = '^9.2.0'; +export const eslintVersion = '^8.57.0'; export const vuePluginVersion = '^5.0.4'; export const babelJestVersion = '^29.7.0'; export const jestGlobalsVersion = '^29.7.0'; From 25bec4ea7aa2090855952d11a0709234323d6600 Mon Sep 17 00:00:00 2001 From: Sam Pullman Date: Sun, 12 May 2024 15:04:01 +0800 Subject: [PATCH 3/4] fix: adjustments for e2e tests --- .vscode/settings.json | 5 +- e2e/vue3-vite-e2e/tests/library.spec.ts | 256 ++++++++++++---------- e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts | 4 +- package.json | 2 +- packages/vue3-vite/package.json | 2 +- 5 files changed, 143 insertions(+), 126 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9bf4d12..c64daf9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true + "editor.formatOnSave": true, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/e2e/vue3-vite-e2e/tests/library.spec.ts b/e2e/vue3-vite-e2e/tests/library.spec.ts index 90d0257..e5c6f16 100644 --- a/e2e/vue3-vite-e2e/tests/library.spec.ts +++ b/e2e/vue3-vite-e2e/tests/library.spec.ts @@ -16,106 +16,108 @@ jest.setTimeout(60000); describe('library e2e', () => { let proj: string; - beforeAll(() => { - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); - }); - afterAll(() => { cleanup(proj); }); - it('should create library and build', async () => { - // Create library - const library = uniq('library'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + describe('basic library check', () => { + beforeAll(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); - // Check files exist - checkFilesExist(proj, [ - `libs/${library}/postcss.config.js`, - `libs/${library}/project.json`, - `libs/${library}/vite.config.ts`, - `libs/${library}/src/index.ts`, - `libs/${library}/src/lib/MyWidget.vue`, - `libs/${library}/src/lib/MyWidget.spec.ts`, - ]); - - // Build library - const result = await runNxCommandAsync(proj, `build ${library}`); - expect(result.stdout).toContain('Build complete'); - }); + it('should create library and build', async () => { + // Create library + const library = uniq('library'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + + // Check files exist + checkFilesExist(proj, [ + `libs/${library}/postcss.config.js`, + `libs/${library}/project.json`, + `libs/${library}/vite.config.ts`, + `libs/${library}/src/index.ts`, + `libs/${library}/src/lib/MyWidget.vue`, + `libs/${library}/src/lib/MyWidget.spec.ts`, + ]); + + // Build library + const result = await runNxCommandAsync(proj, `build ${library}`); + expect(result.stdout).toContain('Build complete'); + }); - it('should make a copy of `package.json` to `dist` if it exists', async () => { - // Create library - const library = uniq('library'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + it('should make a copy of `package.json` to `dist` if it exists', async () => { + // Create library + const library = uniq('library'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - // Create `package.json` - const stringifiedPackageJson = JSON.stringify({ - name: library, - version: '0.0.1', - }); - updateFile( - 'package.json', - stringifiedPackageJson, - `${proj}/libs/${library}`, - ); - checkFilesExist(proj, [`libs/${library}/package.json`]); + // Create `package.json` + const stringifiedPackageJson = JSON.stringify({ + name: library, + version: '0.0.1', + }); + updateFile( + 'package.json', + stringifiedPackageJson, + `${proj}/libs/${library}`, + ); + checkFilesExist(proj, [`libs/${library}/package.json`]); - // Build library - const result = await runNxCommandAsync(proj, `build ${library}`); - expect(result.stdout).toContain('Build complete'); + // Build library + const result = await runNxCommandAsync(proj, `build ${library}`); + expect(result.stdout).toContain('Build complete'); - // Verify `package.json` is copied - const copiedPackageJson = readJson( - proj, - `dist/libs/${library}/package.json`, - ); - expect(JSON.stringify(copiedPackageJson)).toEqual(stringifiedPackageJson); - }); + // Verify `package.json` is copied + const copiedPackageJson = readJson( + proj, + `dist/libs/${library}/package.json`, + ); + expect(JSON.stringify(copiedPackageJson)).toEqual(stringifiedPackageJson); + }); - it('should not make a copy of `package.json` to `dist` if it does not exist', async () => { - // Create library - const library = uniq('library'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + it('should not make a copy of `package.json` to `dist` if it does not exist', async () => { + // Create library + const library = uniq('library'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - // Build library - const result = await runNxCommandAsync(proj, `build ${library}`); - expect(result.stdout).toContain('Build complete'); + // Build library + const result = await runNxCommandAsync(proj, `build ${library}`); + expect(result.stdout).toContain('Build complete'); - // Verify `package.json` does not exist in library folder - const packageJsonInLibrary = `${proj}/libs/${library}/package.json`; - expect(exists(packageJsonInLibrary)).toEqual(false); + // Verify `package.json` does not exist in library folder + const packageJsonInLibrary = `${proj}/libs/${library}/package.json`; + expect(exists(packageJsonInLibrary)).toEqual(false); - // Verify `package.json` does not exist in `dist` folder - const packageJsonInDist = `${proj}/dist/libs/${library}/package.json`; - expect(exists(packageJsonInDist)).toEqual(false); - }); + // Verify `package.json` does not exist in `dist` folder + const packageJsonInDist = `${proj}/dist/libs/${library}/package.json`; + expect(exists(packageJsonInDist)).toEqual(false); + }); - it('should pass lint check', async () => { - // Create library - const library = uniq('library'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + it('should pass lint check', async () => { + // Create library + const library = uniq('library'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - // Lint - const lintResult = await runNxCommandAsync(proj, `lint ${library}`); - expect(lintResult.stdout).toContain('All files pass linting.'); - }); + // Lint + const lintResult = await runNxCommandAsync(proj, `lint ${library}`); + expect(lintResult.stdout).toContain('All files pass linting.'); + }); - it('should add path to `tsconfig.base.json`', async () => { - // Create library - const library = uniq('some/random/library'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + it('should add path to `tsconfig.base.json`', async () => { + // Create library + const library = uniq('some/random/library'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - // Evaluate key and path - const { npmScope } = readJson(proj, 'nx.json'); - const key = `@${npmScope}/${library}`; - const path = `libs/${library}/src/index.ts`; + // Evaluate key and path + const { npmScope } = readJson(proj, 'nx.json'); + const key = `@${npmScope}/${library}`; + const path = `libs/${library}/src/index.ts`; - // Check if path is added to `tsConfigBaseJson.compilerOptions.paths` correctly - const tsConfigBaseJson = readJson(proj, 'tsconfig.base.json'); - const { paths } = tsConfigBaseJson.compilerOptions; - expect(paths[key]).toEqual([path]); + // Check if path is added to `tsConfigBaseJson.compilerOptions.paths` correctly + const tsConfigBaseJson = readJson(proj, 'tsconfig.base.json'); + const { paths } = tsConfigBaseJson.compilerOptions; + expect(paths[key]).toEqual([path]); + }); }); it('should not overwrite `dependencies` in `package.json`', async () => { @@ -125,7 +127,7 @@ describe('library e2e', () => { // Install Vue 2 const packageName = 'vue'; - const oldVersion = '^2.7.14'; + const oldVersion = '^2.7.16'; await runCommandAsync( proj, `npm install ${packageName}@${oldVersion} --save`, @@ -151,7 +153,7 @@ describe('library e2e', () => { // Install Vite 3 const packageName = 'vite'; - const oldVersion = '^3.2.7'; + const oldVersion = '^3.2.10'; await runCommandAsync( proj, `npm install ${packageName}@${oldVersion} --save-dev`, @@ -171,8 +173,13 @@ describe('library e2e', () => { }); describe('--test', () => { - describe('lints', () => { - it('lints and uses Vitest as testing framework by default', async () => { + describe('vitest', () => { + beforeAll(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + + it.only('lints and uses Vitest as testing framework by default', async () => { // Reset project to verify correct dependencies are installed proj = uniq('vue3-vite'); ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); @@ -207,6 +214,28 @@ describe('library e2e', () => { expect(lintResult.stdout).toContain('All files pass linting.'); }); + it('runs tests with Vitest when `test` equals to "vitest"', async () => { + // Create library + const library = uniq('lib-test'); + await runNxCommandAsync( + proj, + `generate nx-vue3-vite:library ${library} --test vitest`, + ); + + // Run test + const testResult = await runNxCommandAsync(proj, `test ${library}`); + expect(testResult.stdout).toContain( + `Successfully ran target test for project ${library}`, + ); + }); + }); + + describe('lints jest', () => { + beforeAll(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + it('lints and uses Jest as testing framework when `test` equals to "jest"', async () => { // Reset project to verify correct dependencies are installed proj = uniq('vue3-vite'); @@ -241,23 +270,6 @@ describe('library e2e', () => { const lintResult = await runNxCommandAsync(proj, `lint ${library}`); expect(lintResult.stdout).toContain('All files pass linting.'); }); - }); - - describe('runs tests', () => { - it('runs tests with Vitest when `test` equals to "vitest"', async () => { - // Create library - const library = uniq('lib-test'); - await runNxCommandAsync( - proj, - `generate nx-vue3-vite:library ${library} --test vitest`, - ); - - // Run test - const testResult = await runNxCommandAsync(proj, `test ${library}`); - expect(testResult.stdout).toContain( - `Successfully ran target test for project ${library}`, - ); - }); it('runs tests with Jest when `test` equals to "jest"', async () => { // Create library @@ -273,26 +285,28 @@ describe('library e2e', () => { `Successfully ran target test for project ${library}`, ); }); - }); - - it('should fail when `test` is not a valid value', async () => { - // Create app - const library = uniq('lib-test'); - const wrongValue = 'hello'; - const createAppCommand = `generate nx-vue3-vite:library ${library} --test ${wrongValue}`; - // Expect it to throw an error - await expect(runNxCommandAsync(proj, createAppCommand)).rejects.toThrow(); - - // Silence error to verify error message, because the error message thrown - // by `runNxCommandAsync` looks like `Command failed: {command}`, which is - // not detailed enough. - const result = await runNxCommandAsync(proj, createAppCommand, { - silenceError: true, + it('should fail when `test` is not a valid value', async () => { + // Create app + const library = uniq('lib-test'); + const wrongValue = 'hello'; + const createAppCommand = `generate nx-vue3-vite:library ${library} --test ${wrongValue}`; + + // Expect it to throw an error + await expect( + runNxCommandAsync(proj, createAppCommand), + ).rejects.toThrow(); + + // Silence error to verify error message, because the error message thrown + // by `runNxCommandAsync` looks like `Command failed: {command}`, which is + // not detailed enough. + const result = await runNxCommandAsync(proj, createAppCommand, { + silenceError: true, + }); + expect(result.stdout).toContain( + `Property 'test' does not match the schema. '${wrongValue}' should be one of vitest,jest.`, + ); }); - expect(result.stdout).toContain( - `Property 'test' does not match the schema. '${wrongValue}' should be one of vitest,jest.`, - ); }); }); }); diff --git a/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts b/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts index 0a2be29..6bbd03b 100644 --- a/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts +++ b/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts @@ -101,7 +101,7 @@ describe('vue3-vite e2e', () => { it('should not overwrite `dependencies` in `package.json`', async () => { // Install Vue 2 const packageName = 'vue'; - const oldVersion = '^2.7.14'; + const oldVersion = '^2.7.16'; await runCommandAsync( proj, `npm install ${packageName}@${oldVersion} --force --save`, @@ -123,7 +123,7 @@ describe('vue3-vite e2e', () => { it('should not overwrite `devDependencies` in `package.json`', async () => { // Install Vite 3 const packageName = 'vite'; - const oldVersion = '^3.2.7'; + const oldVersion = '^3.2.10'; await runCommandAsync( proj, `npm install ${packageName}@${oldVersion} --force --save-dev`, diff --git a/package.json b/package.json index acdb4d8..99f9b92 100644 --- a/package.json +++ b/package.json @@ -60,4 +60,4 @@ "vite": "^5.2.11", "vitepress": "^0.22.4" } -} \ No newline at end of file +} diff --git a/packages/vue3-vite/package.json b/packages/vue3-vite/package.json index 211bd9e..f908ee4 100644 --- a/packages/vue3-vite/package.json +++ b/packages/vue3-vite/package.json @@ -29,4 +29,4 @@ "vite", "generator" ] -} \ No newline at end of file +} From 9909e48de9c4b5e6261fa54181095056cfbfce7b Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 12 May 2024 12:47:51 +0000 Subject: [PATCH 4/4] fix: adjustments for nx 18 and update e2e --- CHANGELOG.md | 2 + e2e/vue3-vite-e2e/tests/library.spec.ts | 142 ++--- .../tests/utils/async-commands.ts | 6 +- e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts | 530 ++++++++++-------- package.json | 60 +- .../src/generators/cypress/generator.ts | 7 +- .../src/generators/docs/generator.ts | 7 +- .../library/files/postcss.config.js.template | 3 - .../library/files/postcss.config.mjs.template | 3 + .../src/generators/library/generator.ts | 6 +- .../files/postcss.config.js.template | 7 - .../files/postcss.config.mjs.template | 5 + .../src/generators/vue3-vite/generator.ts | 15 +- packages/vue3-vite/src/util/defaults.ts | 2 +- .../src/util/generate-test-target.ts | 5 +- packages/vue3-vite/src/util/utils.ts | 11 + tsconfig.base.json | 3 +- 17 files changed, 455 insertions(+), 359 deletions(-) delete mode 100644 packages/vue3-vite/src/generators/library/files/postcss.config.js.template create mode 100644 packages/vue3-vite/src/generators/library/files/postcss.config.mjs.template delete mode 100644 packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.js.template create mode 100644 packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.mjs.template diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fc739a..dd40db5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ TODO -- automate changelog generation - Update packages - Update to Nx 18.3.4 - Make Cypress optional peer dependency +- BREAKING - may need to add project path to vitest executors in project.json. For example, `"config": "apps/myproject/vite.config.ts"` +- BREAKING - postcss config may need to be renamed from `postcss.config.js` to `postcss.config.mjs` ### v0.27.0 - 240117 diff --git a/e2e/vue3-vite-e2e/tests/library.spec.ts b/e2e/vue3-vite-e2e/tests/library.spec.ts index e5c6f16..893c4d7 100644 --- a/e2e/vue3-vite-e2e/tests/library.spec.ts +++ b/e2e/vue3-vite-e2e/tests/library.spec.ts @@ -1,3 +1,4 @@ +import { getPackageManagerCommand } from '@nx/devkit'; import { checkFilesExist, cleanup, @@ -16,16 +17,16 @@ jest.setTimeout(60000); describe('library e2e', () => { let proj: string; - afterAll(() => { - cleanup(proj); - }); - describe('basic library check', () => { beforeAll(() => { proj = uniq('vue3-vite'); ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); }); + afterAll(() => { + cleanup(proj); + }); + it('should create library and build', async () => { // Create library const library = uniq('library'); @@ -33,7 +34,7 @@ describe('library e2e', () => { // Check files exist checkFilesExist(proj, [ - `libs/${library}/postcss.config.js`, + `libs/${library}/postcss.config.mjs`, `libs/${library}/project.json`, `libs/${library}/vite.config.ts`, `libs/${library}/src/index.ts`, @@ -100,7 +101,7 @@ describe('library e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${library}`); - expect(lintResult.stdout).toContain('All files pass linting.'); + expect(lintResult.stdout).toContain('All files pass linting'); }); it('should add path to `tsconfig.base.json`', async () => { @@ -120,56 +121,67 @@ describe('library e2e', () => { }); }); - it('should not overwrite `dependencies` in `package.json`', async () => { - // Reset project to verify correct dependencies are installed - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); - - // Install Vue 2 - const packageName = 'vue'; - const oldVersion = '^2.7.16'; - await runCommandAsync( - proj, - `npm install ${packageName}@${oldVersion} --save`, - ); - - // Verify `dependencies` after install - let packageJson = readJson(proj, 'package.json'); - expect(packageJson.dependencies[packageName]).toEqual(oldVersion); - - // Create library - const library = uniq('library-dep'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - - // Verify `dependencies` after running the generator - packageJson = readJson(proj, 'package.json'); - expect(packageJson.dependencies[packageName]).toEqual(oldVersion); - }); + describe('update configuration', () => { + beforeEach(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + + afterEach(() => { + cleanup(proj); + }); + + it('should not overwrite `dependencies` in `package.json`', async () => { + const pmc = getPackageManagerCommand(); + + // Install Vue 2 + const packageName = 'vue'; + const oldVersion = '^2.7.16'; + await runCommandAsync( + proj, + `${pmc.install} ${packageName}@${oldVersion} --save`, + ); + + // Verify `dependencies` after install + let packageJson = readJson(proj, 'package.json'); + expect(packageJson.dependencies[packageName]).toEqual(oldVersion); + + // Create library + const library = uniq('library-dep'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + + // Verify `dependencies` after running the generator + packageJson = readJson(proj, 'package.json'); + expect(packageJson.dependencies[packageName]).toEqual(oldVersion); + }); - it('should not overwrite `devDependencies` in `package.json`', async () => { - // Reset project to verify correct dependencies are installed - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); - - // Install Vite 3 - const packageName = 'vite'; - const oldVersion = '^3.2.10'; - await runCommandAsync( - proj, - `npm install ${packageName}@${oldVersion} --save-dev`, - ); - - // Verify `dependencies` after install - let packageJson = readJson(proj, 'package.json'); - expect(packageJson.devDependencies[packageName]).toEqual(oldVersion); - - // Create library - const library = uniq('library-dev-dep'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); - - // Verify `devDepndencies` after running the generator - packageJson = readJson(proj, 'package.json'); - expect(packageJson.devDependencies[packageName]).toEqual(oldVersion); + it('should not overwrite `devDependencies` in `package.json`', async () => { + const pmc = getPackageManagerCommand(); + + // Install Vite 3 + const packageName = 'vite'; + const oldVersion = '5.2.5'; + await runCommandAsync( + proj, + `${pmc.install} -D ${packageName}@${oldVersion}`, + ); + + // Verify `dependencies` after install + let packageJson = readJson(proj, 'package.json'); + expect(packageJson.devDependencies[packageName]).toEqual( + `^${oldVersion}`, + ); + + // Create library + const library = uniq('library-dev-dep'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:library ${library}`); + + // Verify `devDepndencies` after running the generator + packageJson = readJson(proj, 'package.json'); + expect(packageJson.devDependencies[packageName]).toEqual( + `^${oldVersion}`, + ); + }); }); describe('--test', () => { @@ -179,11 +191,11 @@ describe('library e2e', () => { ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); }); - it.only('lints and uses Vitest as testing framework by default', async () => { - // Reset project to verify correct dependencies are installed - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + afterAll(() => { + cleanup(proj); + }); + it('lints and uses Vitest as testing framework by default', async () => { // Create library const library = uniq('lib-test'); await runNxCommandAsync( @@ -211,7 +223,7 @@ describe('library e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${library}`); - expect(lintResult.stdout).toContain('All files pass linting.'); + expect(lintResult.stdout).toContain('All files pass linting'); }); it('runs tests with Vitest when `test` equals to "vitest"', async () => { @@ -236,11 +248,11 @@ describe('library e2e', () => { ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); }); - it('lints and uses Jest as testing framework when `test` equals to "jest"', async () => { - // Reset project to verify correct dependencies are installed - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + afterAll(() => { + cleanup(proj); + }); + it('lints and uses Jest as testing framework when `test` equals to "jest"', async () => { // Create library const library = uniq('lib-test'); await runNxCommandAsync( @@ -268,7 +280,7 @@ describe('library e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${library}`); - expect(lintResult.stdout).toContain('All files pass linting.'); + expect(lintResult.stdout).toContain('All files pass linting'); }); it('runs tests with Jest when `test` equals to "jest"', async () => { diff --git a/e2e/vue3-vite-e2e/tests/utils/async-commands.ts b/e2e/vue3-vite-e2e/tests/utils/async-commands.ts index 7dba4c2..db9abf3 100644 --- a/e2e/vue3-vite-e2e/tests/utils/async-commands.ts +++ b/e2e/vue3-vite-e2e/tests/utils/async-commands.ts @@ -44,5 +44,9 @@ export function runNxCommandAsync( }, ): Promise<{ stdout: string; stderr: string }> { const pmc = getPackageManagerCommand(); - return runCommandAsync(projectPath, `${pmc.exec} nx ${command}`, opts); + return runCommandAsync( + projectPath, + `NX_DAEMON=false ${pmc.exec} nx ${command}`, + opts, + ); } diff --git a/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts b/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts index 6bbd03b..ec07c4a 100644 --- a/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts +++ b/e2e/vue3-vite-e2e/tests/vue3-vite.spec.ts @@ -1,3 +1,4 @@ +import { getPackageManagerCommand } from '@nx/devkit'; import { checkFilesExist, cleanup, @@ -16,209 +17,262 @@ jest.setTimeout(90000); describe('vue3-vite e2e', () => { let proj: string; - beforeAll(() => { - proj = uniq('vue3-vite'); - ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); - }); + describe('basic app checks', () => { + beforeAll(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); - afterAll(() => { - cleanup(proj); - }); + afterAll(() => { + cleanup(proj); + }); - it('should create and build vue3-vite app', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - - // Check files exist - checkFilesExist(proj, [ - `apps/${app}/index.html`, - `apps/${app}/postcss.config.js`, - `apps/${app}/project.json`, - `apps/${app}/src/app/main.ts`, - `apps/${app}/tsconfig.json`, - `apps/${app}/vite.config.ts`, - `nx.json`, - `package.json`, - `tsconfig.base.json`, - ]); - - // Build app - const result = await runNxCommandAsync(proj, `build ${app}`); - expect(result.stdout).toContain('Build complete'); - }); + it('should create and build vue3-vite app', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - it('should make a copy of `package.json` to `dist` if it exists', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); + // Check files exist + checkFilesExist(proj, [ + `apps/${app}/index.html`, + `apps/${app}/postcss.config.mjs`, + `apps/${app}/project.json`, + `apps/${app}/src/app/main.ts`, + `apps/${app}/tsconfig.json`, + `apps/${app}/vite.config.ts`, + `nx.json`, + `package.json`, + `tsconfig.base.json`, + ]); - // Create `package.json` - const stringifiedPackageJson = JSON.stringify({ - name: app, - version: '0.0.1', + // Build app + const result = await runNxCommandAsync(proj, `build ${app}`); + expect(result.stdout).toContain('Build complete'); }); - updateFile('package.json', stringifiedPackageJson, `${proj}/apps/${app}`); - checkFilesExist(proj, [`apps/${app}/package.json`]); - // Build app - const result = await runNxCommandAsync(proj, `build ${app}`); - expect(result.stdout).toContain('Build complete'); + it('should make a copy of `package.json` to `dist` if it exists', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - // Verify `package.json` is copied - const copiedPackageJson = readJson(proj, `dist/apps/${app}/package.json`); - expect(JSON.stringify(copiedPackageJson)).toEqual(stringifiedPackageJson); - }); + // Create `package.json` + const stringifiedPackageJson = JSON.stringify({ + name: app, + version: '0.0.1', + }); + updateFile('package.json', stringifiedPackageJson, `${proj}/apps/${app}`); + checkFilesExist(proj, [`apps/${app}/package.json`]); - it('should not make a copy of `package.json` to `dist` if it does not exist', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); + // Build app + const result = await runNxCommandAsync(proj, `build ${app}`); + expect(result.stdout).toContain('Build complete'); - // Build app - const result = await runNxCommandAsync(proj, `build ${app}`); - expect(result.stdout).toContain('Build complete'); + // Verify `package.json` is copied + const copiedPackageJson = readJson(proj, `dist/apps/${app}/package.json`); + expect(JSON.stringify(copiedPackageJson)).toEqual(stringifiedPackageJson); + }); - // Verify `package.json` does not exist in app folder - const packageJsonInApp = `${proj}/apps/${app}/package.json`; - expect(exists(packageJsonInApp)).toEqual(false); + it('should not make a copy of `package.json` to `dist` if it does not exist', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - // Verify `package.json` does not exist in `dist` folder - const packageJsonInDist = `${proj}/dist/apps/${app}/package.json`; - expect(exists(packageJsonInDist)).toEqual(false); - }); + // Build app + const result = await runNxCommandAsync(proj, `build ${app}`); + expect(result.stdout).toContain('Build complete'); - it('should pass lint check', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); + // Verify `package.json` does not exist in app folder + const packageJsonInApp = `${proj}/apps/${app}/package.json`; + expect(exists(packageJsonInApp)).toEqual(false); - // Lint - const lintResult = await runNxCommandAsync(proj, `lint ${app}`); - expect(lintResult.stdout).toContain('All files pass linting.'); - }); + // Verify `package.json` does not exist in `dist` folder + const packageJsonInDist = `${proj}/dist/apps/${app}/package.json`; + expect(exists(packageJsonInDist)).toEqual(false); + }); - it('should not overwrite `dependencies` in `package.json`', async () => { - // Install Vue 2 - const packageName = 'vue'; - const oldVersion = '^2.7.16'; - await runCommandAsync( - proj, - `npm install ${packageName}@${oldVersion} --force --save`, - ); - - // Verify `dependencies` after install - let packageJson = readJson(proj, 'package.json'); - expect(packageJson.dependencies[packageName]).toEqual(oldVersion); - - // Create app - const app = uniq('vue3-vite-dep'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - - // Verify `dependencies` after running the generator - packageJson = readJson(proj, 'package.json'); - expect(packageJson.dependencies[packageName]).toEqual(oldVersion); - }); + it('should pass lint check', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - it('should not overwrite `devDependencies` in `package.json`', async () => { - // Install Vite 3 - const packageName = 'vite'; - const oldVersion = '^3.2.10'; - await runCommandAsync( - proj, - `npm install ${packageName}@${oldVersion} --force --save-dev`, - ); - - // Verify `dependencies` after install - let packageJson = readJson(proj, 'package.json'); - expect(packageJson.devDependencies[packageName]).toEqual(oldVersion); - - // Create app - const app = uniq('vue3-vite-dev-dep'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - - // Verify `devDepndencies` after running the generator - packageJson = readJson(proj, 'package.json'); - expect(packageJson.devDependencies[packageName]).toEqual(oldVersion); - }); + // Lint + const lintResult = await runNxCommandAsync(proj, `lint ${app}`); + expect(lintResult.stdout).toContain('All files pass linting'); + }); - describe('--directory', () => { - it('should create app in the specified directory and add tags to nx.json', async () => { - const plugin = uniq('vue3-vite'); - await runNxCommandAsync( - proj, - `generate nx-vue3-vite:app ${plugin} --directory subdir/${plugin} --tags e2etag,e2ePackage`, - ); + describe('--directory', () => { + it('should create app in the specified directory and add tags to nx.json', async () => { + const plugin = uniq('vue3-vite'); + await runNxCommandAsync( + proj, + `generate nx-vue3-vite:app ${plugin} --directory subdir/${plugin} --tags e2etag,e2ePackage`, + ); - expect(() => - checkFilesExist(proj, [`apps/subdir/${plugin}/vite.config.ts`]), - ).not.toThrow(); - const projectJson = readJson(proj, `apps/subdir/${plugin}/project.json`); - expect(projectJson.tags).toEqual(['e2etag', 'e2ePackage']); + expect(() => + checkFilesExist(proj, [`apps/subdir/${plugin}/vite.config.ts`]), + ).not.toThrow(); + const projectJson = readJson( + proj, + `apps/subdir/${plugin}/project.json`, + ); + expect(projectJson.tags).toEqual(['e2etag', 'e2ePackage']); + }); }); - }); - describe('--alias', () => { - it('should use global path alias by default', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); + describe('--alias', () => { + it('should use global path alias by default', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - // Read paths - const tsConfigJson = readJson(proj, `apps/${app}/tsconfig.json`); - const { baseUrl, paths } = tsConfigJson.compilerOptions; + // Read paths + const tsConfigJson = readJson(proj, `apps/${app}/tsconfig.json`); + const { baseUrl, paths } = tsConfigJson.compilerOptions; - // Verify `tsConfigJson.compilerOptions.paths` - expect(baseUrl).toBeUndefined(); - expect(paths).toBeUndefined(); + // Verify `tsConfigJson.compilerOptions.paths` + expect(baseUrl).toBeUndefined(); + expect(paths).toBeUndefined(); - // Verify `vite.config.ts` - const viteConfig = readFile(proj, `apps/${app}/vite.config.ts`); - expect(viteConfig).toMatch( - /import\s{.*tsconfigBaseAliases.*}\sfrom\s'nx-vue3-vite'/, - ); - expect(viteConfig).toContain('...tsconfigBaseAliases(__dirname),'); + // Verify `vite.config.ts` + const viteConfig = readFile(proj, `apps/${app}/vite.config.ts`); + expect(viteConfig).toMatch( + /import\s{.*tsconfigBaseAliases.*}\sfrom\s'nx-vue3-vite'/, + ); + expect(viteConfig).toContain('...tsconfigBaseAliases(__dirname),'); + }); + + it('should use local path alias when `alias` equals to "local"', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync( + proj, + `generate nx-vue3-vite:app ${app} --alias local`, + ); + + // Read paths + const tsConfigJson = readJson(proj, `apps/${app}/tsconfig.json`); + const { paths } = tsConfigJson.compilerOptions; + + // Verify `tsConfigJson.compilerOptions.paths` + expect(Object.keys(paths)).toHaveLength(3); + expect(paths).toMatchObject({ + '@assets/*': ['./src/assets/*'], + '@app/*': ['./src/app/*'], + '@public/*': ['./src/public/*'], + }); + + // Verify `vite.config.ts` + const viteConfig = readFile(proj, `apps/${app}/vite.config.ts`); + expect(viteConfig).not.toContain('tsconfigBaseAliases'); + expect(viteConfig).toContain( + "'@assets/': `${path.resolve(__dirname, './src/assets')}/`", + ); + expect(viteConfig).toContain( + "'@app/': `${path.resolve(__dirname, './src/app')}/`", + ); + expect(viteConfig).toContain( + "'@public/': `${path.resolve(__dirname, './src/public')}/", + ); + }); + + it('should fail when `alias` is not a valid value', async () => { + // Create app + const app = uniq('vue3-vite'); + const wrongValue = 'hello'; + const createAppCommand = `generate nx-vue3-vite:app ${app} --alias ${wrongValue}`; + + // Expect it to throw an error + await expect( + runNxCommandAsync(proj, createAppCommand), + ).rejects.toThrow(); + + // Silence error to verify error message, because the error message thrown + // by `runNxCommandAsync` looks like `Command failed: {command}`, which is + // not detailed enough. + const result = await runNxCommandAsync(proj, createAppCommand, { + silenceError: true, + }); + expect(result.stdout).toContain( + `Property 'alias' does not match the schema. '${wrongValue}' should be one of local,global.`, + ); + }); }); + }); - it('should use local path alias when `alias` equals to "local"', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync( + describe('update configuration', () => { + beforeEach(() => { + proj = uniq('vue3-vite'); + ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + + afterEach(() => { + cleanup(proj); + }); + + it('should not overwrite `dependencies` in `package.json`', async () => { + const pmc = getPackageManagerCommand(); + + // Install Vue 2 + const packageName = 'vue'; + const oldVersion = '^2.7.16'; + await runCommandAsync( proj, - `generate nx-vue3-vite:app ${app} --alias local`, + `${pmc.install} ${packageName}@${oldVersion} --force --save`, ); - // Read paths - const tsConfigJson = readJson(proj, `apps/${app}/tsconfig.json`); - const { paths } = tsConfigJson.compilerOptions; + // Verify `dependencies` after install + let packageJson = readJson(proj, 'package.json'); + expect(packageJson.dependencies[packageName]).toEqual(oldVersion); - // Verify `tsConfigJson.compilerOptions.paths` - expect(Object.keys(paths)).toHaveLength(3); - expect(paths).toMatchObject({ - '@assets/*': ['./src/assets/*'], - '@app/*': ['./src/app/*'], - '@public/*': ['./src/public/*'], - }); + // Create app + const app = uniq('vue3-vite-dep'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); - // Verify `vite.config.ts` - const viteConfig = readFile(proj, `apps/${app}/vite.config.ts`); - expect(viteConfig).not.toContain('tsconfigBaseAliases'); - expect(viteConfig).toContain( - "'@assets/': `${path.resolve(__dirname, './src/assets')}/`", + // Verify `dependencies` after running the generator + packageJson = readJson(proj, 'package.json'); + expect(packageJson.dependencies[packageName]).toEqual(oldVersion); + }); + + it('should not overwrite `devDependencies` in `package.json`', async () => { + const pmc = getPackageManagerCommand(); + + // Install Vite 3 + const packageName = 'vite'; + const oldVersion = '5.2.5'; + await runCommandAsync( + proj, + `${pmc.install} -D ${packageName}@${oldVersion} --force`, ); - expect(viteConfig).toContain( - "'@app/': `${path.resolve(__dirname, './src/app')}/`", + + // Verify `dependencies` after install + let packageJson = readJson(proj, 'package.json'); + expect(packageJson.devDependencies[packageName]).toEqual( + `^${oldVersion}`, ); - expect(viteConfig).toContain( - "'@public/': `${path.resolve(__dirname, './src/public')}/", + + // Create app + const app = uniq('vue3-vite-dev-dep'); + await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); + + // Verify `devDependencies` after running the generator + packageJson = readJson(proj, 'package.json'); + expect(packageJson.devDependencies[packageName]).toEqual( + `^${oldVersion}`, ); }); + }); - it('lints and builds with global paths when `alias` is "global"', async () => { - // Reset project to avoid issues with previous project state + describe('alias global', () => { + beforeAll(() => { proj = uniq('vue3-vite'); ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + afterAll(() => { + cleanup(proj); + }); + + it('lints and builds with global paths when `alias` is "global"', async () => { // Create app const app = uniq('vue3-vite'); await runNxCommandAsync( @@ -243,41 +297,26 @@ describe('vue3-vite e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${app}`); - expect(lintResult.stdout).toContain('All files pass linting.'); + expect(lintResult.stdout).toContain('All files pass linting'); // Build app const result = await runNxCommandAsync(proj, `build ${app}`); expect(result.stdout).toContain('Build complete'); }); - - it('should fail when `alias` is not a valid value', async () => { - // Create app - const app = uniq('vue3-vite'); - const wrongValue = 'hello'; - const createAppCommand = `generate nx-vue3-vite:app ${app} --alias ${wrongValue}`; - - // Expect it to throw an error - await expect(runNxCommandAsync(proj, createAppCommand)).rejects.toThrow(); - - // Silence error to verify error message, because the error message thrown - // by `runNxCommandAsync` looks like `Command failed: {command}`, which is - // not detailed enough. - const result = await runNxCommandAsync(proj, createAppCommand, { - silenceError: true, - }); - expect(result.stdout).toContain( - `Property 'alias' does not match the schema. '${wrongValue}' should be one of local,global.`, - ); - }); }); describe('--test', () => { - describe('lints', () => { - it('lints and uses Vitest as testing framework by default', async () => { - // Reset project to verify correct dependencies are installed + describe('vitest', () => { + beforeAll(() => { proj = uniq('vue3-vite'); ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + afterAll(() => { + cleanup(proj); + }); + + it('lints and uses Vitest as testing framework by default', async () => { // Create app const app = uniq('vue3-vite'); await runNxCommandAsync(proj, `generate nx-vue3-vite:app ${app}`); @@ -302,14 +341,49 @@ describe('vue3-vite e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${app}`); - expect(lintResult.stdout).toContain('All files pass linting.'); + expect(lintResult.stdout).toContain('All files pass linting'); }); - it('lints and uses Jest as testing framework when `test` equals to "jest"', async () => { - // Reset project to verify correct dependencies are installed + it('runs tests with Vitest when `test` equals to "vitest"', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync( + proj, + `generate nx-vue3-vite:app ${app} --test vitest`, + ); + + // Runs tests + const testResult = await runNxCommandAsync(proj, `test ${app}`); + expect(testResult.stdout).toContain( + `Successfully ran target test for project ${app}`, + ); + }); + + it('builds with Vitest when `test` equals to "vitest"', async () => { + // Create app + const app = uniq('vue3-vite'); + await runNxCommandAsync( + proj, + `generate nx-vue3-vite:app ${app} --test vitest`, + ); + + // Build app + const result = await runNxCommandAsync(proj, `build ${app}`); + expect(result.stdout).toContain('Build complete'); + }); + }); + + describe('jest', () => { + beforeAll(() => { proj = uniq('vue3-vite'); ensureNxProject('nx-vue3-vite', 'dist/packages/vue3-vite', proj); + }); + + afterAll(() => { + cleanup(proj); + }); + it('lints and uses Jest as testing framework when `test` equals to "jest"', async () => { // Create app const app = uniq('vue3-vite'); await runNxCommandAsync( @@ -337,24 +411,7 @@ describe('vue3-vite e2e', () => { // Lint const lintResult = await runNxCommandAsync(proj, `lint ${app}`); - expect(lintResult.stdout).toContain('All files pass linting.'); - }); - }); - - describe('runs tests', () => { - it('runs tests with Vitest when `test` equals to "vitest"', async () => { - // Create app - const app = uniq('vue3-vite'); - await runNxCommandAsync( - proj, - `generate nx-vue3-vite:app ${app} --test vitest`, - ); - - // Runs tests - const testResult = await runNxCommandAsync(proj, `test ${app}`); - expect(testResult.stdout).toContain( - `Successfully ran target test for project ${app}`, - ); + expect(lintResult.stdout).toContain('All files pass linting'); }); it('runs tests with Jest when `test` equals to "jest"', async () => { @@ -371,15 +428,13 @@ describe('vue3-vite e2e', () => { `Successfully ran target test for project ${app}`, ); }); - }); - describe('builds', () => { - it('builds with Vitest when `test` equals to "vitest"', async () => { + it('builds with Jest when `test` equals to "jest"', async () => { // Create app const app = uniq('vue3-vite'); await runNxCommandAsync( proj, - `generate nx-vue3-vite:app ${app} --test vitest`, + `generate nx-vue3-vite:app ${app} --test jest`, ); // Build app @@ -387,38 +442,27 @@ describe('vue3-vite e2e', () => { expect(result.stdout).toContain('Build complete'); }); - it('builds with Jest when `test` equals to "jest"', async () => { + it('should fail when `test` is not a valid value', async () => { // Create app const app = uniq('vue3-vite'); - await runNxCommandAsync( - proj, - `generate nx-vue3-vite:app ${app} --test jest`, + const wrongValue = 'hello'; + const createAppCommand = `generate nx-vue3-vite:app ${app} --test ${wrongValue}`; + + // Expect it to throw an error + await expect( + runNxCommandAsync(proj, createAppCommand), + ).rejects.toThrow(); + + // Silence error to verify error message, because the error message thrown + // by `runNxCommandAsync` looks like `Command failed: {command}`, which is + // not detailed enough. + const result = await runNxCommandAsync(proj, createAppCommand, { + silenceError: true, + }); + expect(result.stdout).toContain( + `Property 'test' does not match the schema. '${wrongValue}' should be one of vitest,jest.`, ); - - // Build app - const result = await runNxCommandAsync(proj, `build ${app}`); - expect(result.stdout).toContain('Build complete'); - }); - }); - - it('should fail when `test` is not a valid value', async () => { - // Create app - const app = uniq('vue3-vite'); - const wrongValue = 'hello'; - const createAppCommand = `generate nx-vue3-vite:app ${app} --test ${wrongValue}`; - - // Expect it to throw an error - await expect(runNxCommandAsync(proj, createAppCommand)).rejects.toThrow(); - - // Silence error to verify error message, because the error message thrown - // by `runNxCommandAsync` looks like `Command failed: {command}`, which is - // not detailed enough. - const result = await runNxCommandAsync(proj, createAppCommand, { - silenceError: true, }); - expect(result.stdout).toContain( - `Property 'test' does not match the schema. '${wrongValue}' should be one of vitest,jest.`, - ); }); }); }); diff --git a/package.json b/package.json index 99f9b92..86976ee 100644 --- a/package.json +++ b/package.json @@ -4,60 +4,88 @@ "version": "0.27.0", "license": "MIT", "scripts": { - "nx": "nx", - "build": "nx build vue3-vite", - "test": "nx test vue3-vite", - "lint": "nx workspace-lint && nx lint vue3-vite", - "e2e": "nx e2e vue3-vite-e2e", + "affected": "nx affected", "affected:apps": "nx affected:apps", - "affected:libs": "nx affected:libs", "affected:build": "nx affected:build", + "affected:dep-graph": "nx affected:dep-graph", "affected:e2e": "nx affected:e2e", - "affected:test": "nx affected:test", + "affected:libs": "nx affected:libs", "affected:lint": "nx affected:lint", - "affected:dep-graph": "nx affected:dep-graph", - "affected": "nx affected", + "affected:test": "nx affected:test", + "build": "nx build vue3-vite", + "commit-msg": "node tools/scripts/verifyCommit.js", + "dep-graph": "nx dep-graph", + "e2e": "nx e2e vue3-vite-e2e", "format": "nx format:write", - "format:write": "nx format:write", "format:check": "nx format:check", - "update": "nx migrate latest", - "dep-graph": "nx dep-graph", + "format:write": "nx format:write", "help": "nx help", - "commit-msg": "node tools/scripts/verifyCommit.js", - "prepare": "husky install" + "lint": "nx workspace-lint && nx lint vue3-vite", + "nx": "nx", + "prepare": "husky install", + "test": "nx test vue3-vite", + "update": "nx migrate latest" }, "private": true, "devDependencies": { + "@babel/core": "^7.23.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.1", + "@babel/preset-env": "^7.24.5", + "@cypress/code-coverage": "^3.12.39", "@cypress/vite-dev-server": "^5.0.7", + "@cypress/vue": "^6.0.0", + "@intlify/eslint-plugin-vue-i18n": "^2.0.0", + "@nx/cypress": "*", "@nx/devkit": "18.3.4", + "@nx/eslint": "18.3.4", "@nx/eslint-plugin": "18.3.4", "@nx/jest": "18.3.4", "@nx/js": "18.3.4", - "@nx/eslint": "18.3.4", + "@nx/vite": "^18.3.4", "@nx/workspace": "18.3.4", + "@samatech/postcss-basics": "^0.7.4", "@types/jest": "29.5.12", "@types/node": "20.12.11", "@typescript-eslint/eslint-plugin": "7.8.0", "@typescript-eslint/parser": "7.8.0", "@vitejs/plugin-vue": "5.0.4", + "@vue/eslint-config-typescript": "^13.0.0", + "@vue/test-utils": "^2.4.6", + "class-transformer": "^0.5.1", "conventional-github-releaser": "^3.1.5", "cypress": "^13.9.0", "dotenv": "16.4.5", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", + "eslint-plugin-cypress": "^3.2.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-vue": "^9.26.0", "fs-extra": "^11.2.0", + "happy-dom": "^14.10.1", "husky": "^8.0.3", "jest": "29.7.0", "nx": "18.3.4", "picocolors": "^1.0.0", + "postcss": "^8.4.38", "prettier": "^3.2.5", "readline": "^1.3.0", "rollup": "^4.17.2", + "stylelint": "^16.5.0", + "stylelint-config-standard": "^36.0.0", "ts-jest": "^29.1.2", "ts-node": "~10.9.2", + "tsconfig": "^7.0.0", "tslib": "^2.6.2", "typescript": "~5.4.5", "vite": "^5.2.11", - "vitepress": "^0.22.4" + "vitepress": "^0.22.4", + "vitest": "^1.6.0", + "vue-eslint-parser": "^9.4.2" + }, + "dependencies": { + "date-fns": "^3.6.0", + "vue": "^3.4.27", + "vue-i18n": "^9.13.1", + "vue-router": "^4.3.2" } } diff --git a/packages/vue3-vite/src/generators/cypress/generator.ts b/packages/vue3-vite/src/generators/cypress/generator.ts index ae8429e..79dd3b7 100644 --- a/packages/vue3-vite/src/generators/cypress/generator.ts +++ b/packages/vue3-vite/src/generators/cypress/generator.ts @@ -2,7 +2,6 @@ import { addProjectConfiguration, formatFiles, generateFiles, - getWorkspaceLayout, names, offsetFromRoot, Tree, @@ -12,6 +11,7 @@ import * as path from 'path'; import { CypressGeneratorSchema } from './schema'; import { CypressDevDependencies } from '../../util/defaults'; import { + getAppsDir, parseTags, runTasksInSerial, updateDependencies, @@ -36,10 +36,7 @@ function normalizeOptions( const projectDirectory = options.directory ? names(options.directory).fileName : name; - const projectRoot = joinPathFragments( - getWorkspaceLayout(host).appsDir, - projectDirectory, - ); + const projectRoot = joinPathFragments(getAppsDir(host), projectDirectory); const parsedTags = parseTags(options.tags); return { diff --git a/packages/vue3-vite/src/generators/docs/generator.ts b/packages/vue3-vite/src/generators/docs/generator.ts index 0eedd5b..a1d2f1a 100644 --- a/packages/vue3-vite/src/generators/docs/generator.ts +++ b/packages/vue3-vite/src/generators/docs/generator.ts @@ -2,7 +2,6 @@ import { addProjectConfiguration, formatFiles, generateFiles, - getWorkspaceLayout, names, offsetFromRoot, Tree, @@ -18,6 +17,7 @@ import { recommendedExtensions, } from '../../util/defaults'; import { + getAppsDir, parseTags, runTasksInSerial, updateDependencies, @@ -42,10 +42,7 @@ function normalizeOptions( const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-'); const projectTitle = options.title || projectName; - const projectRoot = joinPathFragments( - getWorkspaceLayout(host).appsDir, - projectDirectory, - ); + const projectRoot = joinPathFragments(getAppsDir(host), projectDirectory); const parsedTags = parseTags(options.tags); return { diff --git a/packages/vue3-vite/src/generators/library/files/postcss.config.js.template b/packages/vue3-vite/src/generators/library/files/postcss.config.js.template deleted file mode 100644 index b82655a..0000000 --- a/packages/vue3-vite/src/generators/library/files/postcss.config.js.template +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - plugins: [] -} \ No newline at end of file diff --git a/packages/vue3-vite/src/generators/library/files/postcss.config.mjs.template b/packages/vue3-vite/src/generators/library/files/postcss.config.mjs.template new file mode 100644 index 0000000..1ffb2ee --- /dev/null +++ b/packages/vue3-vite/src/generators/library/files/postcss.config.mjs.template @@ -0,0 +1,3 @@ +export default { + plugins: [], +} diff --git a/packages/vue3-vite/src/generators/library/generator.ts b/packages/vue3-vite/src/generators/library/generator.ts index 3824bbf..1f54eca 100644 --- a/packages/vue3-vite/src/generators/library/generator.ts +++ b/packages/vue3-vite/src/generators/library/generator.ts @@ -22,6 +22,7 @@ import { } from '../../util/defaults'; import { getCaseAwareFileName, + getLibsDir, parseTags, updateDependencies, } from '../../util/utils'; @@ -46,8 +47,7 @@ function normalizeOptions( ): NormalizedSchema { const { layoutDirectory, projectDirectory: libraryDirectory } = extractLayoutDirectory(options.directory); - const { libsDir: defaultLibsDir } = getWorkspaceLayout(host); - const libsDir = layoutDirectory ?? defaultLibsDir; + const libsDir = layoutDirectory ?? getLibsDir(host); const name = names(options.name).fileName; const fullLibraryDirectory = libraryDirectory @@ -172,7 +172,7 @@ export default async function (host: Tree, options: LibraryGeneratorSchema) { lintFilePatterns: [`${libraryRoot}/**/*.{js,jsx,ts,tsx,vue}`], }, }, - test: generateTestTarget(libraryRoot, testFramework), + test: generateTestTarget(libraryRoot, testFramework, libraryName), }, tags: normalizedOptions.parsedTags, }); diff --git a/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.js.template b/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.js.template deleted file mode 100644 index 07317e0..0000000 --- a/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.js.template +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ - -module.exports = { - plugins: [ - ...require('@samatech/postcss-basics')(), - ], -}; diff --git a/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.mjs.template b/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.mjs.template new file mode 100644 index 0000000..fe007cb --- /dev/null +++ b/packages/vue3-vite/src/generators/vue3-vite/files/postcss.config.mjs.template @@ -0,0 +1,5 @@ +import postcssBasics from '@samatech/postcss-basics' + +export default { + plugins: [...postcssBasics()], +} diff --git a/packages/vue3-vite/src/generators/vue3-vite/generator.ts b/packages/vue3-vite/src/generators/vue3-vite/generator.ts index 2a0a9d8..0093e9f 100644 --- a/packages/vue3-vite/src/generators/vue3-vite/generator.ts +++ b/packages/vue3-vite/src/generators/vue3-vite/generator.ts @@ -2,7 +2,6 @@ import { addProjectConfiguration, formatFiles, generateFiles, - getWorkspaceLayout, names, offsetFromRoot, Tree, @@ -19,7 +18,12 @@ import { JestDevDependencies, VitestDevDependencies, } from '../../util/defaults'; -import { parseTags, updateDependencies, updateScripts } from '../../util/utils'; +import { + getAppsDir, + parseTags, + updateDependencies, + updateScripts, +} from '../../util/utils'; import { PathAlias } from '../../util/path-alias'; import { TestFramework } from '../../util/test-framework'; import { generateTestTarget } from '../../util/generate-test-target'; @@ -44,10 +48,7 @@ function normalizeOptions( : name; const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-'); const projectTitle = options.title || projectName; - const projectRoot = joinPathFragments( - getWorkspaceLayout(host).appsDir, - projectDirectory, - ); + const projectRoot = joinPathFragments(getAppsDir(host), projectDirectory); const parsedTags = parseTags(options.tags); // Default to global paths const useLocalAlias = options.alias === PathAlias.Local; @@ -161,7 +162,7 @@ export default async function (host: Tree, options: Vue3ViteGeneratorSchema) { lintFilePatterns: [`${projectRoot}/**/*.{js,jsx,ts,tsx,vue}`], }, }, - test: generateTestTarget(projectRoot, testFramework), + test: generateTestTarget(projectRoot, testFramework, projectName), }, tags: normalizedOptions.parsedTags, }); diff --git a/packages/vue3-vite/src/util/defaults.ts b/packages/vue3-vite/src/util/defaults.ts index 8a1e4e9..4f99be7 100644 --- a/packages/vue3-vite/src/util/defaults.ts +++ b/packages/vue3-vite/src/util/defaults.ts @@ -16,7 +16,7 @@ export const jestGlobalsVersion = '^29.7.0'; export const vue3JestVersion = '^29.2.6'; export const babelPresetEnvVersion = '^7.24.5'; export const postcssVersion = '^8.4.38'; -export const postcssBasicsVersion = '^0.7.3'; +export const postcssBasicsVersion = '^0.7.4'; export const stylelintVersion = '^16.5.0'; export const stylelintConfigVersion = '^36.0.0'; export const tslibVersion = '^2.6.2'; diff --git a/packages/vue3-vite/src/util/generate-test-target.ts b/packages/vue3-vite/src/util/generate-test-target.ts index 857ea25..cbbdb80 100644 --- a/packages/vue3-vite/src/util/generate-test-target.ts +++ b/packages/vue3-vite/src/util/generate-test-target.ts @@ -3,12 +3,13 @@ import { TestFramework } from './test-framework'; export const generateTestTarget = ( projectRoot: string, testFramework: TestFramework, + projectName: string, ) => { const useVitest = testFramework === TestFramework.Vitest; const executor = useVitest ? '@nx/vite:test' : '@nx/jest:jest'; const config = useVitest ? { - config: 'vite.config.ts', + config: `${projectRoot}/vite.config.ts`, } : { jestConfig: `${projectRoot}/jest.config.ts`, @@ -16,7 +17,7 @@ export const generateTestTarget = ( return { executor, - outputs: ['coverage/libs/e2e/apps'], + outputs: [`{workspaceRoot}/coverage/apps/${projectName}`], options: { ...config, passWithNoTests: true, diff --git a/packages/vue3-vite/src/util/utils.ts b/packages/vue3-vite/src/util/utils.ts index 47acfd8..092be2b 100644 --- a/packages/vue3-vite/src/util/utils.ts +++ b/packages/vue3-vite/src/util/utils.ts @@ -6,6 +6,7 @@ import { GeneratorCallback, updateJson, names, + getWorkspaceLayout, } from '@nx/devkit'; import { jestProjectGenerator } from '@nx/jest'; @@ -99,6 +100,16 @@ export function parseTags(tagsStr: string): string[] { return tagsStr ? tagsStr.split(',').map((s) => s.trim()) : []; } +export function getAppsDir(host: Tree) { + const dir = getWorkspaceLayout(host).appsDir; + return !dir || dir === '.' ? 'apps' : dir; +} + +export function getLibsDir(host: Tree) { + const dir = getWorkspaceLayout(host).libsDir; + return !dir || dir === '.' ? 'libs' : dir; +} + export async function addJest(host: Tree, projectName: string) { const jestTask = await jestProjectGenerator(host, { project: projectName, diff --git a/tsconfig.base.json b/tsconfig.base.json index a6e251e..45a3393 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,7 +17,8 @@ "baseUrl": ".", "paths": { "nx-vue3-vite": ["packages/vue3-vite/src/index.ts"] - } + }, + "resolveJsonModule": true }, "exclude": ["node_modules", "tmp"] }