From 769974b45a02ca31d338050b340c49e18dfa939a Mon Sep 17 00:00:00 2001
From: Jack Hsu
Date: Wed, 13 Sep 2023 15:05:10 -0400
Subject: [PATCH] feat(vue): init, app, component and lib generators (#19130)
Co-authored-by: Katerina Skroumpelou
---
docs/generated/cli/create-nx-workspace.md | 2 +-
.../nx/documents/create-nx-workspace.md | 2 +-
docs/map.json | 14 +
docs/packages.json | 10 +
docs/shared/packages/vue/vue-plugin.md | 60 ++
e2e/utils/create-project-utils.ts | 1 +
e2e/vue/src/vue.test.ts | 54 ++
.../src/create-nx-workspace.test.ts | 32 +
.../bin/create-nx-workspace.ts | 91 +-
.../src/utils/preset/preset-options.ts | 4 +
.../src/utils/preset/preset.ts | 2 +
.../application/application.spec.ts | 1 +
.../src/generators/application/application.ts | 56 +-
.../src/generators/library/library.spec.ts | 1 +
.../react/src/generators/library/library.ts | 52 +-
.../__snapshots__/configuration.spec.ts.snap | 36 +-
.../configuration/configuration.spec.ts | 1 -
.../generators/configuration/configuration.ts | 27 +-
packages/vite/src/generators/init/init.ts | 2 +-
.../vitest/__snapshots__/vitest.spec.ts.snap | 6 +-
.../src/generators/vitest/vitest-generator.ts | 104 ++-
.../vite/src/generators/vitest/vitest.spec.ts | 1 +
.../vite-config-edit-utils.spec.ts.snap | 181 ++--
packages/vite/src/utils/generator-utils.ts | 132 ++-
.../src/utils/test-files/test-vite-configs.ts | 64 +-
packages/vite/src/utils/test-utils.ts | 6 +-
.../src/utils/vite-config-edit-utils.spec.ts | 50 +-
.../vite/src/utils/vite-config-edit-utils.ts | 124 ++-
packages/vue/.eslintrc.json | 7 +-
packages/vue/generators.json | 30 +-
packages/vue/index.ts | 6 +
packages/vue/package.json | 13 +-
.../__snapshots__/application.spec.ts.snap | 226 +++++
.../application/application.spec.ts | 50 ++
.../src/generators/application/application.ts | 75 ++
.../files/common/index.html.template | 13 +
.../files/common/src/App.vue.template | 53 ++
.../common/src/__tests__/App.spec.ts.template | 12 +
.../src/components/NxWelcome.vue.template | 793 ++++++++++++++++++
.../files/common/src/main.ts.template | 15 +
.../files/common/tsconfig.app.json.template | 8 +
.../routing/src/router/index.ts.template | 23 +
.../routing/src/views/AboutView.vue.template | 16 +
.../routing/src/views/HomeView.vue.template | 9 +
.../stylesheet/src/styles.__style__.template | 42 +
.../src/generators/application/lib/add-e2e.ts | 64 ++
.../generators/application/lib/add-jest.ts | 44 +
.../generators/application/lib/add-vite.ts | 46 +
.../lib/create-application-files.ts | 53 ++
.../application/lib/normalize-options.ts | 56 ++
.../src/generators/application/schema.d.ts | 30 +
.../src/generators/application/schema.json | 140 ++++
.../__snapshots__/component.spec.ts.snap | 72 ++
.../generators/component/component.spec.ts | 207 +++++
.../vue/src/generators/component/component.ts | 161 ++++
.../component/files/__fileName__.vue__tmpl__ | 15 +
.../__tests__/__fileName__.spec.ts__tmpl__ | 13 +
.../vue/src/generators/component/schema.d.ts | 22 +
.../vue/src/generators/component/schema.json | 107 +++
.../init/__snapshots__/init.spec.ts.snap | 21 +
packages/vue/src/generators/init/init.spec.ts | 20 +
packages/vue/src/generators/init/init.ts | 67 ++
packages/vue/src/generators/init/schema.d.ts | 7 +
packages/vue/src/generators/init/schema.json | 37 +
.../__snapshots__/library.spec.ts.snap | 300 +++++++
.../src/generators/library/files/README.md | 7 +
.../library/files/package.json__tmpl__ | 12 +
.../library/files/src/index.ts__tmpl__ | 0
.../library/files/src/vue-shims.d.ts__tmpl__ | 5 +
.../library/files/tsconfig.lib.json__tmpl__ | 34 +
.../library/files/tsconfig.spec.json__tmpl__ | 27 +
.../src/generators/library/lib/add-jest.ts | 41 +
.../src/generators/library/lib/add-vite.ts | 78 ++
.../library/lib/create-library-files.ts | 53 ++
.../library/lib/normalize-options.spec.ts | 53 ++
.../library/lib/normalize-options.ts | 77 ++
.../src/generators/library/library.spec.ts | 409 +++++++++
.../vue/src/generators/library/library.ts | 102 +++
.../vue/src/generators/library/schema.d.ts | 41 +
.../vue/src/generators/library/schema.json | 139 +++
packages/vue/src/utils/add-linting.ts | 149 ++++
packages/vue/src/utils/ast-utils.ts | 35 +
packages/vue/src/utils/create-ts-config.ts | 84 ++
packages/vue/src/utils/lint.ts | 29 +
packages/vue/src/utils/setup-jest.ts | 124 +++
packages/vue/src/utils/test-utils.ts | 29 +
packages/vue/src/utils/versions.ts | 23 +
.../application/application.spec.ts | 11 +-
.../generate-workspace-files.spec.ts.snap | 130 +++
.../src/generators/new/generate-preset.ts | 13 +
.../new/generate-workspace-files.spec.ts | 2 +
.../new/generate-workspace-files.ts | 3 +
.../workspace/src/generators/new/new.spec.ts | 20 +
.../preset/__snapshots__/preset.spec.ts.snap | 20 +
.../src/generators/preset/preset.spec.ts | 24 +
.../workspace/src/generators/preset/preset.ts | 26 +
.../workspace/src/generators/utils/presets.ts | 2 +
tsconfig.base.json | 2 +-
98 files changed, 5388 insertions(+), 405 deletions(-)
create mode 100644 docs/shared/packages/vue/vue-plugin.md
create mode 100644 e2e/vue/src/vue.test.ts
create mode 100644 packages/vue/src/generators/application/__snapshots__/application.spec.ts.snap
create mode 100644 packages/vue/src/generators/application/application.spec.ts
create mode 100644 packages/vue/src/generators/application/application.ts
create mode 100644 packages/vue/src/generators/application/files/common/index.html.template
create mode 100644 packages/vue/src/generators/application/files/common/src/App.vue.template
create mode 100644 packages/vue/src/generators/application/files/common/src/__tests__/App.spec.ts.template
create mode 100644 packages/vue/src/generators/application/files/common/src/components/NxWelcome.vue.template
create mode 100644 packages/vue/src/generators/application/files/common/src/main.ts.template
create mode 100644 packages/vue/src/generators/application/files/common/tsconfig.app.json.template
create mode 100644 packages/vue/src/generators/application/files/routing/src/router/index.ts.template
create mode 100644 packages/vue/src/generators/application/files/routing/src/views/AboutView.vue.template
create mode 100644 packages/vue/src/generators/application/files/routing/src/views/HomeView.vue.template
create mode 100644 packages/vue/src/generators/application/files/stylesheet/src/styles.__style__.template
create mode 100644 packages/vue/src/generators/application/lib/add-e2e.ts
create mode 100644 packages/vue/src/generators/application/lib/add-jest.ts
create mode 100644 packages/vue/src/generators/application/lib/add-vite.ts
create mode 100644 packages/vue/src/generators/application/lib/create-application-files.ts
create mode 100644 packages/vue/src/generators/application/lib/normalize-options.ts
create mode 100644 packages/vue/src/generators/application/schema.d.ts
create mode 100644 packages/vue/src/generators/application/schema.json
create mode 100644 packages/vue/src/generators/component/__snapshots__/component.spec.ts.snap
create mode 100644 packages/vue/src/generators/component/component.spec.ts
create mode 100644 packages/vue/src/generators/component/component.ts
create mode 100644 packages/vue/src/generators/component/files/__fileName__.vue__tmpl__
create mode 100644 packages/vue/src/generators/component/files/__tests__/__fileName__.spec.ts__tmpl__
create mode 100644 packages/vue/src/generators/component/schema.d.ts
create mode 100644 packages/vue/src/generators/component/schema.json
create mode 100644 packages/vue/src/generators/init/__snapshots__/init.spec.ts.snap
create mode 100644 packages/vue/src/generators/init/init.spec.ts
create mode 100755 packages/vue/src/generators/init/init.ts
create mode 100644 packages/vue/src/generators/init/schema.d.ts
create mode 100644 packages/vue/src/generators/init/schema.json
create mode 100644 packages/vue/src/generators/library/__snapshots__/library.spec.ts.snap
create mode 100644 packages/vue/src/generators/library/files/README.md
create mode 100644 packages/vue/src/generators/library/files/package.json__tmpl__
create mode 100644 packages/vue/src/generators/library/files/src/index.ts__tmpl__
create mode 100644 packages/vue/src/generators/library/files/src/vue-shims.d.ts__tmpl__
create mode 100644 packages/vue/src/generators/library/files/tsconfig.lib.json__tmpl__
create mode 100644 packages/vue/src/generators/library/files/tsconfig.spec.json__tmpl__
create mode 100644 packages/vue/src/generators/library/lib/add-jest.ts
create mode 100644 packages/vue/src/generators/library/lib/add-vite.ts
create mode 100644 packages/vue/src/generators/library/lib/create-library-files.ts
create mode 100644 packages/vue/src/generators/library/lib/normalize-options.spec.ts
create mode 100644 packages/vue/src/generators/library/lib/normalize-options.ts
create mode 100644 packages/vue/src/generators/library/library.spec.ts
create mode 100644 packages/vue/src/generators/library/library.ts
create mode 100644 packages/vue/src/generators/library/schema.d.ts
create mode 100644 packages/vue/src/generators/library/schema.json
create mode 100644 packages/vue/src/utils/add-linting.ts
create mode 100644 packages/vue/src/utils/ast-utils.ts
create mode 100644 packages/vue/src/utils/create-ts-config.ts
create mode 100644 packages/vue/src/utils/lint.ts
create mode 100644 packages/vue/src/utils/setup-jest.ts
create mode 100644 packages/vue/src/utils/test-utils.ts
create mode 100644 packages/vue/src/utils/versions.ts
diff --git a/docs/generated/cli/create-nx-workspace.md b/docs/generated/cli/create-nx-workspace.md
index 1d129d85d048c..2d26849dfb966 100644
--- a/docs/generated/cli/create-nx-workspace.md
+++ b/docs/generated/cli/create-nx-workspace.md
@@ -139,7 +139,7 @@ Package manager to use
Type: `string`
-Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
+Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing
diff --git a/docs/generated/packages/nx/documents/create-nx-workspace.md b/docs/generated/packages/nx/documents/create-nx-workspace.md
index 1d129d85d048c..2d26849dfb966 100644
--- a/docs/generated/packages/nx/documents/create-nx-workspace.md
+++ b/docs/generated/packages/nx/documents/create-nx-workspace.md
@@ -139,7 +139,7 @@ Package manager to use
Type: `string`
-Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
+Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing
diff --git a/docs/map.json b/docs/map.json
index 6cea45674c27f..020e2cc47c9c3 100644
--- a/docs/map.json
+++ b/docs/map.json
@@ -2084,6 +2084,20 @@
}
]
},
+ {
+ "name": "vue",
+ "id": "vue",
+ "description": "Vue package.",
+ "itemList": [
+ {
+ "id": "overview",
+ "path": "/packages/vue",
+ "name": "Overview of the Nx Vue Plugin",
+ "description": "The Nx Plugin for Vue contains generators for managing Vue applications and libraries within an Nx workspace. This page also explains how to configure Vue on your Nx workspace.",
+ "file": "shared/packages/vue/vue-plugin"
+ }
+ ]
+ },
{
"name": "webpack",
"id": "webpack",
diff --git a/docs/packages.json b/docs/packages.json
index e48b86656430a..11483d176b7ab 100644
--- a/docs/packages.json
+++ b/docs/packages.json
@@ -361,6 +361,16 @@
"generators": ["init", "configuration", "vitest"]
}
},
+ {
+ "name": "vue",
+ "packageName": "vue",
+ "description": "The Vue plugin for Nx contains executors and generators for managing Vue applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Cypress, and Storybook.\n\n- Generators for applications, libraries, components, hooks, and more.\n\n- Library build support for publishing packages to npm or other registries.\n\n- Utilities for automatic workspace refactoring.",
+ "path": "generated/packages/vite.json",
+ "schemas": {
+ "executors": [],
+ "generators": ["init", "library", "application", "component"]
+ }
+ },
{
"name": "web",
"packageName": "web",
diff --git a/docs/shared/packages/vue/vue-plugin.md b/docs/shared/packages/vue/vue-plugin.md
new file mode 100644
index 0000000000000..909efd6957661
--- /dev/null
+++ b/docs/shared/packages/vue/vue-plugin.md
@@ -0,0 +1,60 @@
+---
+title: Overview of the Nx Vue Plugin
+description: The Nx Plugin for Vue contains generators for managing Vue applications and libraries within an Nx workspace. This page also explains how to configure Vue on your Nx workspace.
+---
+
+The Nx plugin for [Vue](https://vuejs.org/).
+
+## Setting up a new Nx workspace with Vue
+
+You can create a new workspace that uses Vue with one of the following commands:
+
+- Generate a new monorepo with a Vue app set up with Vue
+
+```shell
+npx create-nx-workspace@latest --preset=vue
+```
+
+## Add Vue to an existing workspace
+
+There are a number of ways to use Vue in your existing workspace.
+
+### Install the `@nx/vue` plugin
+
+{% tabs %}
+{% tab label="npm" %}
+
+```shell
+npm install -D @nx/vue
+```
+
+{% /tab %}
+{% tab label="yarn" %}
+
+```shell
+yarn add -D @nx/vue
+```
+
+{% /tab %}
+{% tab label="pnpm" %}
+
+```shell
+pnpm install -D @nx/vue
+```
+
+{% /tab %}
+{% /tabs %}
+
+### Generate a new project using Vue
+
+To generate a Vue application, run the following:
+
+```bash
+nx g @nx/vue:app my-app
+```
+
+To generate a Vue library, run the following:
+
+```bash
+nx g @nx/vue:lib my-lib
+```
diff --git a/e2e/utils/create-project-utils.ts b/e2e/utils/create-project-utils.ts
index 03d77d2c1fe82..69af84352d58f 100644
--- a/e2e/utils/create-project-utils.ts
+++ b/e2e/utils/create-project-utils.ts
@@ -90,6 +90,7 @@ export function newProject({
`@nx/rollup`,
`@nx/react`,
`@nx/storybook`,
+ `@nx/vue`,
`@nx/vite`,
`@nx/web`,
`@nx/webpack`,
diff --git a/e2e/vue/src/vue.test.ts b/e2e/vue/src/vue.test.ts
new file mode 100644
index 0000000000000..43ba294b1114c
--- /dev/null
+++ b/e2e/vue/src/vue.test.ts
@@ -0,0 +1,54 @@
+import {
+ cleanupProject,
+ killPorts,
+ newProject,
+ runCLI,
+ runE2ETests,
+ uniq,
+} from '@nx/e2e/utils';
+
+describe('Vue Plugin', () => {
+ let proj: string;
+
+ beforeAll(() => {
+ proj = newProject({
+ unsetProjectNameAndRootFormat: false,
+ });
+ });
+
+ afterAll(() => cleanupProject());
+
+ it('should serve application in dev mode', async () => {
+ const app = uniq('app');
+
+ runCLI(
+ `generate @nx/vue:app ${app} --unitTestRunner=vitest --e2eTestRunner=playwright`
+ );
+ let result = runCLI(`test ${app}`);
+ expect(result).toContain(`Successfully ran target test for project ${app}`);
+
+ result = runCLI(`build ${app}`);
+ expect(result).toContain(
+ `Successfully ran target build for project ${app}`
+ );
+
+ if (runE2ETests()) {
+ const e2eResults = runCLI(`e2e ${app}-e2e --no-watch`);
+ expect(e2eResults).toContain('Successfully ran target e2e');
+ expect(await killPorts()).toBeTruthy();
+ }
+ }, 200_000);
+
+ it('should build library', async () => {
+ const lib = uniq('lib');
+
+ runCLI(
+ `generate @nx/vue:lib ${lib} --bundler=vite --unitTestRunner=vitest`
+ );
+
+ const result = runCLI(`build ${lib}`);
+ expect(result).toContain(
+ `Successfully ran target build for project ${lib}`
+ );
+ });
+});
diff --git a/e2e/workspace-create/src/create-nx-workspace.test.ts b/e2e/workspace-create/src/create-nx-workspace.test.ts
index dab4f71f77446..d207c87c06e07 100644
--- a/e2e/workspace-create/src/create-nx-workspace.test.ts
+++ b/e2e/workspace-create/src/create-nx-workspace.test.ts
@@ -420,6 +420,38 @@ describe('create-nx-workspace', () => {
}, 90000);
}
});
+
+ it('should create a workspace with a single vue app at the root', () => {
+ const wsName = uniq('vue');
+
+ runCreateWorkspace(wsName, {
+ preset: 'vue-standalone',
+ appName: wsName,
+ style: 'css',
+ packageManager,
+ e2eTestRunner: 'none',
+ });
+
+ checkFilesExist('package.json');
+ checkFilesExist('project.json');
+ checkFilesExist('index.html');
+ checkFilesExist('src/main.ts');
+ checkFilesExist('src/App.vue');
+ expectCodeIsFormatted();
+ });
+
+ it('should be able to create an vue monorepo', () => {
+ const wsName = uniq('vue');
+ const appName = uniq('app');
+ runCreateWorkspace(wsName, {
+ preset: 'vue-monorepo',
+ appName,
+ style: 'css',
+ packageManager,
+ e2eTestRunner: 'none',
+ });
+ expectCodeIsFormatted();
+ });
});
describe('create-nx-workspace parent folder', () => {
diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts
index 025aca3f01206..712a477d7b15e 100644
--- a/packages/create-nx-workspace/bin/create-nx-workspace.ts
+++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts
@@ -62,6 +62,15 @@ interface AngularArguments extends BaseArguments {
e2eTestRunner: 'none' | 'cypress' | 'playwright';
}
+interface VueArguments extends BaseArguments {
+ stack: 'vue';
+ workspaceType: 'standalone' | 'integrated';
+ appName: string;
+ // framework: 'none' | 'nuxt';
+ style: string;
+ e2eTestRunner: 'none' | 'cypress' | 'playwright';
+}
+
interface NodeArguments extends BaseArguments {
stack: 'node';
workspaceType: 'standalone' | 'integrated';
@@ -78,6 +87,7 @@ type Arguments =
| NoneArguments
| ReactArguments
| AngularArguments
+ | VueArguments
| NodeArguments
| UnknownStackArguments;
@@ -347,7 +357,7 @@ async function determineFolder(
async function determineStack(
parsedArgs: yargs.Arguments
-): Promise<'none' | 'react' | 'angular' | 'node' | 'unknown'> {
+): Promise<'none' | 'react' | 'angular' | 'vue' | 'node' | 'unknown'> {
if (parsedArgs.preset) {
switch (parsedArgs.preset) {
case Preset.Angular:
@@ -360,7 +370,9 @@ async function determineStack(
case Preset.NextJs:
case Preset.NextJsStandalone:
return 'react';
-
+ case Preset.VueStandalone:
+ case Preset.VueMonorepo:
+ return 'vue';
case Preset.Nest:
case Preset.NodeStandalone:
case Preset.Express:
@@ -379,7 +391,7 @@ async function determineStack(
}
const { stack } = await enquirer.prompt<{
- stack: 'none' | 'react' | 'angular' | 'node';
+ stack: 'none' | 'react' | 'angular' | 'node' | 'vue';
}>([
{
name: 'stack',
@@ -394,6 +406,10 @@ async function determineStack(
name: `react`,
message: `React: Configures a React application with your framework of choice.`,
},
+ {
+ name: `vue`,
+ message: `Vue: Configures a Vue application with modern tooling.`,
+ },
{
name: `angular`,
message: `Angular: Configures a Angular application with modern tooling.`,
@@ -419,6 +435,8 @@ async function determinePresetOptions(
return determineReactOptions(parsedArgs);
case 'angular':
return determineAngularOptions(parsedArgs);
+ case 'vue':
+ return determineVueOptions(parsedArgs);
case 'node':
return determineNodeOptions(parsedArgs);
default:
@@ -589,6 +607,69 @@ async function determineReactOptions(
return { preset, style, appName, bundler, nextAppDir, e2eTestRunner };
}
+async function determineVueOptions(
+ parsedArgs: yargs.Arguments
+): Promise> {
+ let preset: Preset;
+ let style: undefined | string = undefined;
+ let appName: string;
+ let e2eTestRunner: undefined | 'none' | 'cypress' | 'playwright' = undefined;
+
+ if (parsedArgs.preset) {
+ preset = parsedArgs.preset;
+ } else {
+ const workspaceType = await determineStandaloneOrMonorepo();
+
+ if (workspaceType === 'standalone') {
+ preset = Preset.VueStandalone;
+ } else {
+ preset = Preset.VueMonorepo;
+ }
+ }
+
+ if (preset === Preset.VueStandalone) {
+ appName = parsedArgs.appName ?? parsedArgs.name;
+ } else {
+ appName = await determineAppName(parsedArgs);
+ }
+
+ e2eTestRunner = await determineE2eTestRunner(parsedArgs);
+
+ if (parsedArgs.style) {
+ style = parsedArgs.style;
+ } else {
+ const reply = await enquirer.prompt<{ style: string }>([
+ {
+ name: 'style',
+ message: `Default stylesheet format`,
+ initial: 'css' as any,
+ type: 'autocomplete',
+ choices: [
+ {
+ name: 'css',
+ message: 'CSS',
+ },
+ {
+ name: 'scss',
+ message: 'SASS(.scss) [ http://sass-lang.com ]',
+ },
+ {
+ name: 'less',
+ message: 'LESS [ http://lesscss.org ]',
+ },
+ {
+ name: 'none',
+ message: 'None',
+ },
+ ],
+ },
+ ]);
+ style = reply.style;
+ }
+
+ return { preset, style, appName, e2eTestRunner };
+}
+
async function determineAngularOptions(
parsedArgs: yargs.Arguments
): Promise> {
@@ -847,7 +928,9 @@ async function determineStandaloneOrMonorepo(): Promise<
}
async function determineAppName(
- parsedArgs: yargs.Arguments
+ parsedArgs: yargs.Arguments<
+ ReactArguments | AngularArguments | NodeArguments | VueArguments
+ >
): Promise {
if (parsedArgs.appName) return parsedArgs.appName;
diff --git a/packages/create-nx-workspace/src/utils/preset/preset-options.ts b/packages/create-nx-workspace/src/utils/preset/preset-options.ts
index 3ebfc1fbdfde8..b79c5020db927 100644
--- a/packages/create-nx-workspace/src/utils/preset/preset-options.ts
+++ b/packages/create-nx-workspace/src/utils/preset/preset-options.ts
@@ -19,6 +19,10 @@ export const presetOptions: { name: Preset; message: string }[] = [
name: Preset.AngularMonorepo,
message: 'angular [a monorepo with a single Angular application]',
},
+ {
+ name: Preset.VueMonorepo,
+ message: 'vue [a monorepo with a single Vue application]',
+ },
{
name: Preset.NextJs,
message: 'next.js [a monorepo with a single Next.js application]',
diff --git a/packages/create-nx-workspace/src/utils/preset/preset.ts b/packages/create-nx-workspace/src/utils/preset/preset.ts
index 301b782c4a49b..198e58fb7702d 100644
--- a/packages/create-nx-workspace/src/utils/preset/preset.ts
+++ b/packages/create-nx-workspace/src/utils/preset/preset.ts
@@ -9,6 +9,8 @@ export enum Preset {
AngularStandalone = 'angular-standalone',
ReactMonorepo = 'react-monorepo',
ReactStandalone = 'react-standalone',
+ VueMonorepo = 'vue-monorepo',
+ VueStandalone = 'vue-standalone',
NextJs = 'next',
NextJsStandalone = 'nextjs-standalone',
ReactNative = 'react-native',
diff --git a/packages/react/src/generators/application/application.spec.ts b/packages/react/src/generators/application/application.spec.ts
index cd9a5113ccc3e..2c04b808011aa 100644
--- a/packages/react/src/generators/application/application.spec.ts
+++ b/packages/react/src/generators/application/application.spec.ts
@@ -63,6 +63,7 @@ describe('app', () => {
'vitest/importMeta',
'vite/client',
'node',
+ 'vitest',
]);
});
diff --git a/packages/react/src/generators/application/application.ts b/packages/react/src/generators/application/application.ts
index 9e6fe7d9e525b..de7aa3e5402bb 100644
--- a/packages/react/src/generators/application/application.ts
+++ b/packages/react/src/generators/application/application.ts
@@ -115,9 +115,8 @@ export async function applicationGeneratorInternal(
addProject(host, options);
if (options.bundler === 'vite') {
- const { viteConfigurationGenerator } = ensurePackage<
- typeof import('@nx/vite')
- >('@nx/vite', nxVersion);
+ const { createOrEditViteConfig, viteConfigurationGenerator } =
+ ensurePackage('@nx/vite', nxVersion);
// We recommend users use `import.meta.env.MODE` and other variables in their code to differentiate between production and development.
// See: https://vitejs.dev/guide/env-and-mode.html
if (
@@ -138,6 +137,28 @@ export async function applicationGeneratorInternal(
skipFormat: true,
});
tasks.push(viteTask);
+ createOrEditViteConfig(
+ host,
+ {
+ project: options.projectName,
+ includeLib: false,
+ includeVitest: options.unitTestRunner === 'vitest',
+ inSourceTests: options.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [
+ options.compiler === 'swc'
+ ? `import react from '@vitejs/plugin-react-swc'`
+ : `import react from '@vitejs/plugin-react'`,
+ ],
+ plugins: ['react()'],
+ },
+ false
+ );
} else if (options.bundler === 'webpack') {
const { webpackInitGenerator } = ensurePackage<
typeof import('@nx/webpack')
@@ -167,10 +188,9 @@ export async function applicationGeneratorInternal(
}
if (options.bundler !== 'vite' && options.unitTestRunner === 'vitest') {
- const { vitestGenerator } = ensurePackage(
- '@nx/vite',
- nxVersion
- );
+ const { createOrEditViteConfig, vitestGenerator } = ensurePackage<
+ typeof import('@nx/vite')
+ >('@nx/vite', nxVersion);
const vitestTask = await vitestGenerator(host, {
uiFramework: 'react',
@@ -180,6 +200,28 @@ export async function applicationGeneratorInternal(
skipFormat: true,
});
tasks.push(vitestTask);
+ createOrEditViteConfig(
+ host,
+ {
+ project: options.projectName,
+ includeLib: false,
+ includeVitest: true,
+ inSourceTests: options.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [
+ options.compiler === 'swc'
+ ? `import react from '@vitejs/plugin-react-swc'`
+ : `import react from '@vitejs/plugin-react'`,
+ ],
+ plugins: ['react()'],
+ },
+ true
+ );
}
if (
diff --git a/packages/react/src/generators/library/library.spec.ts b/packages/react/src/generators/library/library.spec.ts
index ebc8bfd12427f..2420d6b64e499 100644
--- a/packages/react/src/generators/library/library.spec.ts
+++ b/packages/react/src/generators/library/library.spec.ts
@@ -80,6 +80,7 @@ describe('lib', () => {
'vitest/importMeta',
'vite/client',
'node',
+ 'vitest',
]);
});
diff --git a/packages/react/src/generators/library/library.ts b/packages/react/src/generators/library/library.ts
index 413291220efa8..969cc4b8d0917 100644
--- a/packages/react/src/generators/library/library.ts
+++ b/packages/react/src/generators/library/library.ts
@@ -69,9 +69,8 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
// Set up build target
if (options.buildable && options.bundler === 'vite') {
- const { viteConfigurationGenerator } = ensurePackage<
- typeof import('@nx/vite')
- >('@nx/vite', nxVersion);
+ const { viteConfigurationGenerator, createOrEditViteConfig } =
+ ensurePackage('@nx/vite', nxVersion);
const viteTask = await viteConfigurationGenerator(host, {
uiFramework: 'react',
project: options.name,
@@ -84,6 +83,28 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
testEnvironment: 'jsdom',
});
tasks.push(viteTask);
+ createOrEditViteConfig(
+ host,
+ {
+ project: options.name,
+ includeLib: true,
+ includeVitest: options.unitTestRunner === 'vitest',
+ inSourceTests: options.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [
+ options.compiler === 'swc'
+ ? `import react from '@vitejs/plugin-react-swc'`
+ : `import react from '@vitejs/plugin-react'`,
+ ],
+ plugins: ['react()'],
+ },
+ false
+ );
} else if (options.buildable && options.bundler === 'rollup') {
const rollupTask = await addRollupBuildTarget(host, options);
tasks.push(rollupTask);
@@ -120,10 +141,9 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
options.unitTestRunner === 'vitest' &&
options.bundler !== 'vite' // tests are already configured if bundler is vite
) {
- const { vitestGenerator } = ensurePackage(
- '@nx/vite',
- nxVersion
- );
+ const { vitestGenerator, createOrEditViteConfig } = ensurePackage<
+ typeof import('@nx/vite')
+ >('@nx/vite', nxVersion);
const vitestTask = await vitestGenerator(host, {
uiFramework: 'react',
project: options.name,
@@ -133,6 +153,24 @@ export async function libraryGeneratorInternal(host: Tree, schema: Schema) {
testEnvironment: 'jsdom',
});
tasks.push(vitestTask);
+ createOrEditViteConfig(
+ host,
+ {
+ project: options.name,
+ includeLib: true,
+ includeVitest: true,
+ inSourceTests: options.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [`import react from '@vitejs/plugin-react'`],
+ plugins: ['react()'],
+ },
+ true
+ );
}
if (options.component) {
diff --git a/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap b/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
index 13b7f088bbde1..6255454a5b971 100644
--- a/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
+++ b/packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap
@@ -1,24 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`@nx/vite:configuration library mode should add config for building library 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
-import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import dts from 'vite-plugin-dts';
import * as path from 'path';
+import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
cacheDir: '../node_modules/.vite/my-lib',
plugins: [
+ react(),
+ nxViteTsPaths(),
dts({
entryRoot: 'src',
tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
skipDiagnostics: true,
}),
- react(),
- nxViteTsPaths(),
],
// Uncomment this if you are using workers.
@@ -48,24 +48,24 @@ export default defineConfig({
`;
exports[`@nx/vite:configuration library mode should set up non buildable library correctly 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
-import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import dts from 'vite-plugin-dts';
import * as path from 'path';
+import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
cacheDir: '../../node_modules/.vite/react-lib-nonb-jest',
plugins: [
+ react(),
+ nxViteTsPaths(),
dts({
entryRoot: 'src',
tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
skipDiagnostics: true,
}),
- react(),
- nxViteTsPaths(),
],
// Uncomment this if you are using workers.
@@ -143,7 +143,7 @@ exports[`@nx/vite:configuration library mode should set up non buildable library
import * as path from 'path';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
-import viteTsConfigPaths from 'vite-tsconfig-paths';
+import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
// Configuration for building your library.
@@ -165,12 +165,8 @@ export default defineConfig({
},
},
plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
+ nxViteTsPaths(),
+ react(),
dts({
entryRoot: 'src',
tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
@@ -180,9 +176,7 @@ export default defineConfig({
test: {
globals: true,
- cache: {
- dir: '../../node_modules/.vitest',
- },
+ cache: { dir: '../../node_modules/.vitest' },
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
@@ -286,7 +280,7 @@ exports[`@nx/vite:configuration transform React app to use Vite by providing cus
`;
exports[`@nx/vite:configuration transform React app to use Vite should create vite.config file at the root of the app 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
@@ -427,7 +421,7 @@ exports[`@nx/vite:configuration transform React app to use Vite should transform
`;
exports[`@nx/vite:configuration transform Web app to use Vite should create vite.config file at the root of the app 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
@@ -555,7 +549,7 @@ exports[`@nx/vite:configuration transform Web app to use Vite should transform w
`;
exports[`@nx/vite:configuration vitest should create a vitest configuration if "includeVitest" is true 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
diff --git a/packages/vite/src/generators/configuration/configuration.spec.ts b/packages/vite/src/generators/configuration/configuration.spec.ts
index 4d423ba05a92a..13920f0601314 100644
--- a/packages/vite/src/generators/configuration/configuration.spec.ts
+++ b/packages/vite/src/generators/configuration/configuration.spec.ts
@@ -350,7 +350,6 @@ describe('@nx/vite:configuration', () => {
const { Confirm } = require('enquirer');
const confirmSpy = jest.spyOn(Confirm.prototype, 'run');
confirmSpy.mockResolvedValue(true);
- expect.assertions(2);
mockReactLibNonBuildableVitestRunnerGenerator(tree);
diff --git a/packages/vite/src/generators/configuration/configuration.ts b/packages/vite/src/generators/configuration/configuration.ts
index bafa4642cae37..f433f5f9dfa75 100644
--- a/packages/vite/src/generators/configuration/configuration.ts
+++ b/packages/vite/src/generators/configuration/configuration.ts
@@ -198,7 +198,32 @@ export async function viteConfigurationGenerator(
});
}
- createOrEditViteConfig(tree, schema, false, projectAlreadyHasViteTargets);
+ if (schema.uiFramework === 'react') {
+ createOrEditViteConfig(
+ tree,
+ {
+ project: schema.project,
+ includeLib: schema.includeLib,
+ includeVitest: schema.includeVitest,
+ inSourceTests: schema.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [
+ schema.compiler === 'swc'
+ ? `import react from '@vitejs/plugin-react-swc'`
+ : `import react from '@vitejs/plugin-react'`,
+ ],
+ plugins: ['react()'],
+ },
+ false
+ );
+ } else {
+ createOrEditViteConfig(tree, schema, false, projectAlreadyHasViteTargets);
+ }
if (schema.includeVitest) {
const vitestTask = await vitestGenerator(tree, {
diff --git a/packages/vite/src/generators/init/init.ts b/packages/vite/src/generators/init/init.ts
index bf2c38b961190..9a52754d89163 100644
--- a/packages/vite/src/generators/init/init.ts
+++ b/packages/vite/src/generators/init/init.ts
@@ -45,7 +45,7 @@ function checkDependenciesInstalled(host: Tree, schema: InitGeneratorSchema) {
devDependencies['happy-dom'] = happyDomVersion;
} else if (schema.testEnvironment === 'edge-runtime') {
devDependencies['@edge-runtime/vm'] = edgeRuntimeVmVersion;
- } else if (schema.testEnvironment !== 'node') {
+ } else if (schema.testEnvironment !== 'node' && schema.testEnvironment) {
logger.info(
`A custom environment was provided: ${schema.testEnvironment}. You need to install it manually.`
);
diff --git a/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap b/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
index 4087eb8e6d90a..247c582f92025 100644
--- a/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
+++ b/packages/vite/src/generators/vitest/__snapshots__/vitest.spec.ts.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`vitest generator insourceTests should add the insourceSource option in the vite config 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
@@ -33,7 +33,7 @@ export default defineConfig({
`;
exports[`vitest generator vite.config should create correct vite.config.ts file for apps 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
@@ -61,7 +61,7 @@ export default defineConfig({
`;
exports[`vitest generator vite.config should create correct vite.config.ts file for non buildable libs 1`] = `
-"///
+"///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
diff --git a/packages/vite/src/generators/vitest/vitest-generator.ts b/packages/vite/src/generators/vitest/vitest-generator.ts
index 92388d8d0aef6..9cfab4d019def 100644
--- a/packages/vite/src/generators/vitest/vitest-generator.ts
+++ b/packages/vite/src/generators/vitest/vitest-generator.ts
@@ -52,15 +52,36 @@ export async function vitestGenerator(
tasks.push(initTask);
if (!schema.skipViteConfig) {
- createOrEditViteConfig(
- tree,
- {
- ...schema,
- includeVitest: true,
- includeLib: projectType === 'library',
- },
- true
- );
+ if (schema.uiFramework === 'react') {
+ createOrEditViteConfig(
+ tree,
+ {
+ project: schema.project,
+ includeLib: projectType === 'library',
+ includeVitest: true,
+ inSourceTests: schema.inSourceTests,
+ rollupOptionsExternal: [
+ `'react'`,
+ `'react-dom'`,
+ `'react/jsx-runtime'`,
+ ],
+ rollupOptionsExternalString: `"'react', 'react-dom', 'react/jsx-runtime'"`,
+ imports: [`import react from '@vitejs/plugin-react'`],
+ plugins: ['react()'],
+ },
+ true
+ );
+ } else {
+ createOrEditViteConfig(
+ tree,
+ {
+ ...schema,
+ includeVitest: true,
+ includeLib: projectType === 'library',
+ },
+ true
+ );
+ }
}
createFiles(tree, schema, root);
@@ -89,26 +110,55 @@ function updateTsConfig(
options: VitestGeneratorSchema,
projectRoot: string
) {
- updateJson(tree, joinPathFragments(projectRoot, 'tsconfig.json'), (json) => {
- if (
- json.references &&
- !json.references.some((r) => r.path === './tsconfig.spec.json')
- ) {
- json.references.push({
- path: './tsconfig.spec.json',
- });
- }
+ if (tree.exists(joinPathFragments(projectRoot, 'tsconfig.spec.json'))) {
+ updateJson(
+ tree,
+ joinPathFragments(projectRoot, 'tsconfig.spec.json'),
+ (json) => {
+ if (!json.compilerOptions?.types?.includes('vitest')) {
+ if (json.compilerOptions?.types) {
+ json.compilerOptions.types.push('vitest');
+ } else {
+ json.compilerOptions ??= {};
+ json.compilerOptions.types = ['vitest'];
+ }
+ }
+ return json;
+ }
+ );
- if (!json.compilerOptions?.types?.includes('vitest')) {
- if (json.compilerOptions?.types) {
- json.compilerOptions.types.push('vitest');
- } else {
- json.compilerOptions ??= {};
- json.compilerOptions.types = ['vitest'];
+ updateJson(
+ tree,
+ joinPathFragments(projectRoot, 'tsconfig.json'),
+ (json) => {
+ if (
+ json.references &&
+ !json.references.some((r) => r.path === './tsconfig.spec.json')
+ ) {
+ json.references.push({
+ path: './tsconfig.spec.json',
+ });
+ }
+ return json;
}
- }
- return json;
- });
+ );
+ } else {
+ updateJson(
+ tree,
+ joinPathFragments(projectRoot, 'tsconfig.json'),
+ (json) => {
+ if (!json.compilerOptions?.types?.includes('vitest')) {
+ if (json.compilerOptions?.types) {
+ json.compilerOptions.types.push('vitest');
+ } else {
+ json.compilerOptions ??= {};
+ json.compilerOptions.types = ['vitest'];
+ }
+ }
+ return json;
+ }
+ );
+ }
if (options.inSourceTests) {
const tsconfigLibPath = joinPathFragments(projectRoot, 'tsconfig.lib.json');
diff --git a/packages/vite/src/generators/vitest/vitest.spec.ts b/packages/vite/src/generators/vitest/vitest.spec.ts
index 8bb3ca9474028..a1ccf54230311 100644
--- a/packages/vite/src/generators/vitest/vitest.spec.ts
+++ b/packages/vite/src/generators/vitest/vitest.spec.ts
@@ -96,6 +96,7 @@ describe('vitest generator', () => {
"vitest/importMeta",
"vite/client",
"node",
+ "vitest",
],
},
"extends": "./tsconfig.json",
diff --git a/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap b/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
index 4972eb3df2939..238797a188409 100644
--- a/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
+++ b/packages/vite/src/utils/__snapshots__/vite-config-edit-utils.spec.ts.snap
@@ -1,19 +1,18 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ensureViteConfigIsCorrect should add build and test options if defineConfig is empty 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
///
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
-
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
- build: {
+ plugins: [react(),
+nxViteTsPaths()],build: {
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
@@ -27,18 +26,7 @@ import { joinPathFragments } from '@nx/devkit';
// External packages that should not be bundled into your library.
external: ["'react', 'react-dom', 'react/jsx-runtime'"]
}
- },plugins: [
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- test: {
+ },test: {
globals: true,
cache: {
dir: '../node_modules/.vitest'
@@ -50,11 +38,10 @@ import { joinPathFragments } from '@nx/devkit';
`;
exports[`ensureViteConfigIsCorrect should add build option but not update test option if test already setup 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
@@ -74,19 +61,9 @@ import { defineConfig } from 'vite';
// External packages that should not be bundled into your library.
external: ["'react', 'react-dom', 'react/jsx-runtime'"]
}
- },plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- ],
+ },plugins: [react(),
+nxViteTsPaths(),
+],
test: {
globals: true,
@@ -102,11 +79,10 @@ import { defineConfig } from 'vite';
`;
exports[`ensureViteConfigIsCorrect should add build options if build options don't exist 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
@@ -126,19 +102,9 @@ import { defineConfig } from 'vite';
// External packages that should not be bundled into your library.
external: ["'react', 'react-dom', 'react/jsx-runtime'"]
}
- },plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- ],
+ },plugins: [react(),
+nxViteTsPaths(),
+],
test: {
globals: true,
@@ -154,11 +120,10 @@ import { defineConfig } from 'vite';
`;
exports[`ensureViteConfigIsCorrect should add build options if defineConfig is not used 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default {
// Configuration for building your library.
@@ -185,19 +150,9 @@ import { defineConfig } from 'vite';
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
},
- plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- ],
+ plugins: [react(),
+nxViteTsPaths(),
+],
};
"
`;
@@ -219,33 +174,22 @@ exports[`ensureViteConfigIsCorrect should add build options if it is using condi
my: 'option',
},
..."\\n // Configuration for building your library.\\n // See: https://vitejs.dev/guide/build.html#library-mode\\n build: {\\n lib: {\\n // Could also be a dictionary or array of multiple entry points.\\n entry: 'src/index.ts',\\n name: 'my-app',\\n fileName: 'index',\\n // Change this to the formats you want to support.\\n // Don't forget to update your package.json as well.\\n formats: ['es', 'cjs']\\n },\\n rollupOptions: {\\n // External packages that should not be bundled into your library.\\n external: [\\"'react', 'react-dom', 'react/jsx-runtime'\\"]\\n }\\n },"
- }
+ }
}
})
"
`;
exports[`ensureViteConfigIsCorrect should add new build options if some build options already exist 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
- plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- ],
+ plugins: [react(),
+nxViteTsPaths(),
+],
test: {
globals: true,
@@ -257,11 +201,11 @@ import { defineConfig } from 'vite';
},
build: {
- ...{
- my: 'option',
- },
- ...{"lib":{"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es","cjs"]},"rollupOptions":{"external":["'react', 'react-dom', 'react/jsx-runtime'"]}}
- }
+ 'my': 'option',
+'lib': {"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es","cjs"]},
+'rollupOptions': {"external":["'react', 'react-dom', 'react/jsx-runtime'"]},
+
+ }
});
"
@@ -271,25 +215,17 @@ exports[`ensureViteConfigIsCorrect should not do anything if cannot understand s
exports[`ensureViteConfigIsCorrect should not do anything if project has everything setup already 1`] = `
"
- ///
- import { defineConfig } from 'vite';
+import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import dts from 'vite-plugin-dts';
import { joinPathFragments } from '@nx/devkit';
export default defineConfig({
- plugins: [
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- react(),
- viteTsConfigPaths({
- root: '../../../',
- }),
- ],
+ plugins: [dts({ entryRoot: 'src', tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'), skipDiagnostics: true }),
+react(),
+nxViteTsPaths(),
+],
// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
@@ -322,40 +258,31 @@ exports[`ensureViteConfigIsCorrect should not do anything if project has everyth
`;
exports[`ensureViteConfigIsCorrect should update both test and build options - keep existing settings 1`] = `
-"import dts from 'vite-plugin-dts';
-import { joinPathFragments } from '@nx/devkit';
+"import dts from 'vite-plugin-dts';import { joinPathFragments } from '@nx/devkit'
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
- import viteTsConfigPaths from 'vite-tsconfig-paths';
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig({
- plugins: [
- ...[
- react(),
- viteTsConfigPaths({
- root: '../../',
- }),
- ],
- dts({
- entryRoot: 'src',
- tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'),
- skipDiagnostics: true,
- }),
- ],
+ plugins: [react(),
+nxViteTsPaths(),
+],
test: {
- ...{
- my: 'option',
- },
- ...{"globals":true,"cache":{"dir":"../node_modules/.vitest"},"environment":"jsdom","include":["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"]}
- },
+ 'my': 'option',
+'globals': true,
+'cache': {"dir":"../node_modules/.vitest"},
+'environment': "jsdom",
+'include': ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
+
+ },
build: {
- ...{
- my: 'option',
- },
- ...{"lib":{"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es","cjs"]},"rollupOptions":{"external":["'react', 'react-dom', 'react/jsx-runtime'"]}}
- }
+ 'my': 'option',
+'lib': {"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es","cjs"]},
+'rollupOptions': {"external":["'react', 'react-dom', 'react/jsx-runtime'"]},
+
+ }
});
"
diff --git a/packages/vite/src/utils/generator-utils.ts b/packages/vite/src/utils/generator-utils.ts
index c89d04e6fff05..cbaf67522a8c8 100644
--- a/packages/vite/src/utils/generator-utils.ts
+++ b/packages/vite/src/utils/generator-utils.ts
@@ -441,14 +441,14 @@ export function moveAndEditIndexHtml(
const indexHtmlContent = tree.read(indexHtmlPath, 'utf8');
if (
!indexHtmlContent.includes(
- ``
+ ``
)
) {
tree.write(
`${projectConfig.root}/index.html`,
indexHtmlContent.replace(
'
-
-
+
+
',
- `
+ `
`
)
);
@@ -461,25 +461,37 @@ export function moveAndEditIndexHtml(
tree.write(
`${projectConfig.root}/index.html`,
`
-
+