@nx/vite 24.0.0-beta.2 → 24.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/executors.d.ts +0 -3
  2. package/dist/executors.js +0 -7
  3. package/dist/plugins/nx-copy-assets.plugin.d.ts +4 -5
  4. package/dist/plugins/nx-copy-assets.plugin.js +5 -49
  5. package/dist/plugins/nx-ready-signal.plugin.d.ts +8 -0
  6. package/dist/plugins/nx-ready-signal.plugin.js +41 -0
  7. package/dist/plugins/nx-tsconfig-paths.plugin.d.ts +5 -7
  8. package/dist/plugins/nx-tsconfig-paths.plugin.js +6 -247
  9. package/dist/ready-check.d.ts +1 -0
  10. package/dist/ready-check.js +9 -0
  11. package/dist/src/generators/configuration/configuration.js +2 -39
  12. package/dist/src/generators/configuration/lib/convert-non-vite.js +1 -0
  13. package/dist/src/generators/configuration/schema.d.ts +0 -1
  14. package/dist/src/generators/convert-to-inferred/lib/build-post-target-transformer.d.ts +0 -1
  15. package/dist/src/generators/convert-to-inferred/lib/build-post-target-transformer.js +3 -66
  16. package/dist/src/generators/init/init.js +20 -32
  17. package/dist/src/generators/init/schema.d.ts +0 -1
  18. package/dist/src/generators/init/schema.json +1 -1
  19. package/dist/src/generators/setup-paths-plugin/schema.d.ts +0 -1
  20. package/dist/src/generators/setup-paths-plugin/schema.json +2 -2
  21. package/dist/src/generators/setup-paths-plugin/setup-paths-plugin.js +16 -91
  22. package/dist/src/migrations/update-23-0-0/ai-instructions-for-vitest-3.md +5 -5
  23. package/dist/src/migrations/update-23-0-0/ai-instructions-for-vitest-4.md +6 -6
  24. package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +12 -0
  25. package/dist/src/migrations/update-24-0-0/migrate-config-helpers.md +86 -0
  26. package/dist/src/migrations/update-24-0-0/migrate-nx-vite-ts-paths.d.ts +2 -0
  27. package/dist/src/migrations/update-24-0-0/migrate-nx-vite-ts-paths.js +154 -0
  28. package/dist/src/migrations/update-24-0-0/register-typescript-plugin-for-typecheck.d.ts +4 -0
  29. package/dist/src/migrations/update-24-0-0/register-typescript-plugin-for-typecheck.js +11 -0
  30. package/dist/src/migrations/update-24-0-0/register-typescript-plugin-for-typecheck.md +37 -0
  31. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
  32. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +46 -0
  33. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +71 -0
  34. package/dist/src/plugins/plugin.d.ts +9 -5
  35. package/dist/src/plugins/plugin.js +56 -49
  36. package/dist/src/utils/deprecation.d.ts +2 -9
  37. package/dist/src/utils/deprecation.js +5 -35
  38. package/dist/src/utils/dev-server-ready-check.d.ts +27 -0
  39. package/dist/src/utils/dev-server-ready-check.js +174 -0
  40. package/dist/src/utils/e2e-web-server-info-utils.d.ts +2 -2
  41. package/dist/src/utils/e2e-web-server-info-utils.js +4 -4
  42. package/dist/src/utils/executor-utils.d.ts +0 -10
  43. package/dist/src/utils/executor-utils.js +0 -51
  44. package/dist/src/utils/generator-utils.d.ts +1 -10
  45. package/dist/src/utils/generator-utils.js +62 -114
  46. package/dist/src/utils/options-utils.d.ts +0 -16
  47. package/dist/src/utils/options-utils.js +0 -73
  48. package/dist/src/utils/versions.d.ts +2 -0
  49. package/dist/src/utils/versions.js +3 -1
  50. package/dist/src/utils/vite-config-edit-utils.d.ts +9 -1
  51. package/dist/src/utils/vite-config-edit-utils.js +143 -1
  52. package/executors.json +2 -34
  53. package/generators.json +1 -1
  54. package/migrations.json +19 -0
  55. package/package.json +22 -7
  56. package/dist/src/executors/build/build.impl.d.ts +0 -11
  57. package/dist/src/executors/build/build.impl.js +0 -205
  58. package/dist/src/executors/build/compat.d.ts +0 -2
  59. package/dist/src/executors/build/compat.js +0 -6
  60. package/dist/src/executors/build/schema.json +0 -82
  61. package/dist/src/executors/dev-server/compat.d.ts +0 -2
  62. package/dist/src/executors/dev-server/compat.js +0 -6
  63. package/dist/src/executors/dev-server/dev-server.impl.d.ts +0 -7
  64. package/dist/src/executors/dev-server/dev-server.impl.js +0 -137
  65. package/dist/src/executors/dev-server/schema.json +0 -40
  66. package/dist/src/executors/preview-server/compat.d.ts +0 -2
  67. package/dist/src/executors/preview-server/compat.js +0 -6
  68. package/dist/src/executors/preview-server/preview-server.impl.d.ts +0 -7
  69. package/dist/src/executors/preview-server/preview-server.impl.js +0 -184
  70. package/dist/src/executors/preview-server/schema.json +0 -44
  71. package/dist/src/utils/nx-tsconfig-paths-find-file.d.ts +0 -2
  72. package/dist/src/utils/nx-tsconfig-paths-find-file.js +0 -22
  73. package/dist/src/utils/nx-tsconfig-paths-load-file.d.ts +0 -12
  74. package/dist/src/utils/nx-tsconfig-paths-load-file.js +0 -71
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = migrateNxViteTsPaths;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const vite_config_edit_utils_1 = require("../../utils/vite-config-edit-utils");
6
+ const version_utils_1 = require("../../utils/version-utils");
7
+ const CONFIG_FILE = /(?:^|\/)(?:vite|vitest)\.config\.[cm]?[jt]s$/;
8
+ const PLUGIN_SPECIFIER = '@nx/vite/plugins/nx-tsconfig-paths.plugin';
9
+ // Generated configs carry a commented-out worker example that calls the plugin.
10
+ const WORKER_EXAMPLE = /^([ \t]*\/\/)\s*plugins: \(\) => \[ nxViteTsPaths\(\) \],[ \t]*$/m;
11
+ async function migrateNxViteTsPaths(tree) {
12
+ // `resolve.tsconfigPaths` landed in Vite 8. On anything older the option is
13
+ // ignored, so swapping the plugin for it would silently drop alias
14
+ // resolution; the prompt picks those workspaces up instead.
15
+ const installedMajor = (0, version_utils_1.getInstalledViteMajorVersion)(tree);
16
+ if (!installedMajor || installedMajor < 8) {
17
+ return;
18
+ }
19
+ let changed = false;
20
+ (0, devkit_1.visitNotIgnoredFiles)(tree, '.', (filePath) => {
21
+ if (!CONFIG_FILE.test(filePath))
22
+ return;
23
+ const original = tree.read(filePath, 'utf-8');
24
+ if (!original?.includes('nxViteTsPaths'))
25
+ return;
26
+ const withResolution = (0, vite_config_edit_utils_1.addTsconfigPathsResolution)(original);
27
+ if (!(0, vite_config_edit_utils_1.hasTsconfigPathsResolution)(withResolution))
28
+ return;
29
+ let updated = removePluginUsage(withResolution);
30
+ if (updated === withResolution)
31
+ return;
32
+ updated = updated.replace(WORKER_EXAMPLE, '$1 plugins: [],');
33
+ tree.write(filePath, updated);
34
+ changed = true;
35
+ });
36
+ if (changed) {
37
+ await (0, devkit_1.formatFiles)(tree);
38
+ }
39
+ }
40
+ /**
41
+ * Drops every `nxViteTsPaths()` call and its import. Bails on the whole file if
42
+ * any call sits somewhere other than directly inside an array, since removing
43
+ * one from an arbitrary expression leaves a syntax hole. The shipped prompt
44
+ * handles what this leaves behind.
45
+ */
46
+ function removePluginUsage(content) {
47
+ const { tsquery } = require('@phenomnomnominal/tsquery');
48
+ const tsModule = require('typescript');
49
+ const file = tsquery.ast(content);
50
+ const importsPlugin = file.statements.some((statement) => {
51
+ if (tsModule.isImportDeclaration(statement) &&
52
+ tsModule.isStringLiteral(statement.moduleSpecifier) &&
53
+ statement.moduleSpecifier.text === PLUGIN_SPECIFIER) {
54
+ const bindings = statement.importClause?.namedBindings;
55
+ return (bindings &&
56
+ tsModule.isNamedImports(bindings) &&
57
+ bindings.elements.some((element) => !element.propertyName && element.name.text === 'nxViteTsPaths'));
58
+ }
59
+ if (!tsModule.isVariableStatement(statement))
60
+ return false;
61
+ return statement.declarationList.declarations.some(({ name, initializer }) => tsModule.isObjectBindingPattern(name) &&
62
+ name.elements.some((element) => !element.propertyName &&
63
+ element.name.getText() === 'nxViteTsPaths') &&
64
+ initializer &&
65
+ tsModule.isCallExpression(initializer) &&
66
+ initializer.expression.getText() === 'require' &&
67
+ initializer.arguments.length === 1 &&
68
+ tsModule.isStringLiteral(initializer.arguments[0]) &&
69
+ initializer.arguments[0].text === PLUGIN_SPECIFIER);
70
+ });
71
+ if (!importsPlugin)
72
+ return content;
73
+ const calls = tsquery.query(file, 'CallExpression:has(Identifier[name="nxViteTsPaths"])').filter((call) => call.expression.getText() === 'nxViteTsPaths');
74
+ if (!calls.length)
75
+ return content;
76
+ const arrays = new Map();
77
+ for (const call of calls) {
78
+ const parent = call.parent;
79
+ if (!parent || !tsModule.isArrayLiteralExpression(parent))
80
+ return content;
81
+ const siblings = arrays.get(parent) ?? [];
82
+ siblings.push(call);
83
+ arrays.set(parent, siblings);
84
+ }
85
+ const changes = [];
86
+ // Reprinting the array from its surviving elements keeps separators valid no
87
+ // matter how many entries are dropped; formatting is restored afterwards.
88
+ for (const [array, removed] of arrays) {
89
+ const survivors = array.elements.filter((element) => !removed.includes(element));
90
+ changes.push({
91
+ type: devkit_1.ChangeType.Delete,
92
+ start: array.getStart(),
93
+ length: array.getEnd() - array.getStart(),
94
+ });
95
+ changes.push({
96
+ type: devkit_1.ChangeType.Insert,
97
+ index: array.getStart(),
98
+ text: `[${survivors.map((element) => element.getText()).join(', ')}]`,
99
+ });
100
+ }
101
+ // A reference outside the removed calls still needs the (inert) stub import.
102
+ const survivingReference = tsquery.query(file, 'Identifier[name="nxViteTsPaths"]').some((id) => !calls.some((call) => call.expression === id) &&
103
+ !tsModule.isImportSpecifier(id.parent) &&
104
+ !tsModule.isBindingElement(id.parent));
105
+ if (survivingReference)
106
+ return (0, devkit_1.applyChangesToString)(content, changes);
107
+ for (const node of findSolePluginImports(tsModule, tsquery, file)) {
108
+ changes.push({
109
+ type: devkit_1.ChangeType.Delete,
110
+ start: node.getStart(),
111
+ length: trailingNewlineEnd(content, node.getEnd()) - node.getStart(),
112
+ });
113
+ }
114
+ return (0, devkit_1.applyChangesToString)(content, changes);
115
+ }
116
+ /**
117
+ * Import and require statements that bring in nothing but the plugin. Anything
118
+ * sharing the statement stays put; an unused binding is harmless next to a
119
+ * broken one.
120
+ */
121
+ function findSolePluginImports(tsModule, tsquery, file) {
122
+ const imports = tsquery.query(file, `ImportDeclaration:has(StringLiteral[value="${PLUGIN_SPECIFIER}"])`);
123
+ const requires = tsquery.query(file, `VariableStatement:has(StringLiteral[value="${PLUGIN_SPECIFIER}"])`);
124
+ const sole = [];
125
+ for (const node of imports) {
126
+ const bindings = node.importClause?.namedBindings;
127
+ if (!node.importClause?.name &&
128
+ bindings &&
129
+ tsModule.isNamedImports(bindings) &&
130
+ bindings.elements.length === 1) {
131
+ sole.push(node);
132
+ }
133
+ }
134
+ for (const node of requires) {
135
+ const declarations = node.declarationList.declarations;
136
+ if (declarations.length !== 1)
137
+ continue;
138
+ const name = declarations[0].name;
139
+ if (tsModule.isObjectBindingPattern(name) &&
140
+ name.elements.length === 1 &&
141
+ name.elements[0].name.getText() === 'nxViteTsPaths') {
142
+ sole.push(node);
143
+ }
144
+ }
145
+ return sole;
146
+ }
147
+ function trailingNewlineEnd(content, end) {
148
+ while (content[end] === ' ' ||
149
+ content[end] === '\t' ||
150
+ content[end] === ';') {
151
+ end++;
152
+ }
153
+ return content[end] === '\n' ? end + 1 : end;
154
+ }
@@ -0,0 +1,4 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function update(tree: Tree): Promise<{
3
+ skipAgentic: boolean;
4
+ }>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = update;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const internal_1 = require("@nx/js/internal");
6
+ async function update(tree) {
7
+ if (!(0, internal_1.registerTypescriptPluginForTypecheck)(tree, '@nx/vite/plugin')) {
8
+ return { skipAgentic: true };
9
+ }
10
+ await (0, devkit_1.formatFiles)(tree);
11
+ }
@@ -0,0 +1,37 @@
1
+ #### Register `@nx/js/typescript` for typecheck targets
2
+
3
+ `@nx/vite/plugin` no longer infers a `typecheck` target, except for Vue projects, which keep their `vue-tsc` target. `@nx/js/typescript` provides the `typecheck` target instead, in all workspaces. This migration registers `@nx/js/typescript` with only its typecheck target when the workspace uses `@nx/vite/plugin` and doesn't register `@nx/js/typescript` yet, so your projects keep a `typecheck` target.
4
+
5
+ The new registration reuses the plugin's `typecheckTargetName` and, when it's `tsgo`, its `compiler`. Registrations with `typecheckTargetName: false` are skipped. `@nx/js/typescript` is registered before `@nx/vite/plugin`, so the Vue projects' `vue-tsc` target wins. Keep that order.
6
+
7
+ #### Sample code changes
8
+
9
+ ##### Before
10
+
11
+ ```json title="nx.json"
12
+ {
13
+ "plugins": [
14
+ {
15
+ "plugin": "@nx/vite/plugin",
16
+ "options": { "typecheckTargetName": "typecheck" }
17
+ }
18
+ ]
19
+ }
20
+ ```
21
+
22
+ ##### After
23
+
24
+ ```json title="nx.json"
25
+ {
26
+ "plugins": [
27
+ {
28
+ "plugin": "@nx/js/typescript",
29
+ "options": { "typecheck": { "targetName": "typecheck" } }
30
+ },
31
+ {
32
+ "plugin": "@nx/vite/plugin",
33
+ "options": { "typecheckTargetName": "typecheck" }
34
+ }
35
+ ]
36
+ }
37
+ ```
@@ -0,0 +1,6 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function update(tree: Tree): Promise<{
3
+ nextSteps?: string[];
4
+ agentContext?: string[];
5
+ skipAgentic?: boolean;
6
+ }>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = update;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const internal_1 = require("@nx/devkit/internal");
6
+ const viteExecutors = [
7
+ '@nx/vite:build',
8
+ '@nx/vite:dev-server',
9
+ '@nx/vite:preview-server',
10
+ '@nrwl/vite:build',
11
+ '@nrwl/vite:dev-server',
12
+ '@nrwl/vite:preview-server',
13
+ ];
14
+ // Earlier @nx/vite migrations rewrite test targets to @nx/vitest:test, but on
15
+ // pnpm @nx/vitest is only transitive, so its own migration may never run.
16
+ const vitestExecutors = ['@nx/vitest:test', '@nx/vite:test', '@nrwl/vite:test'];
17
+ function update(tree) {
18
+ return (0, internal_1.migrateRemovedExecutors)(tree, [...viteExecutors, ...vitestExecutors], async (tree, options) => {
19
+ const executors = [...(0, devkit_1.getProjects)(tree).values()].flatMap((project) => Object.values(project.targets ?? {}).map((target) => target.executor));
20
+ if (executors.some((executor) => viteExecutors.includes(executor))) {
21
+ const { convertToInferred } = require('../../generators/convert-to-inferred/convert-to-inferred');
22
+ // The callback only prints the options the converter could not carry
23
+ // over; migrateRemovedExecutors discards it.
24
+ await skipUnmigrated(async () => {
25
+ const flushLogs = await convertToInferred(tree, options);
26
+ flushLogs();
27
+ });
28
+ }
29
+ if (executors.includes('@nx/vitest:test')) {
30
+ const { convertVitestToInferred } = require('@nx/vitest/internal');
31
+ await skipUnmigrated(() => convertVitestToInferred(tree, options));
32
+ }
33
+ });
34
+ }
35
+ // A converter that skips every target must not stop the other one; the
36
+ // leftover re-scan in migrateRemovedExecutors still names what it left.
37
+ async function skipUnmigrated(convert) {
38
+ try {
39
+ await convert();
40
+ }
41
+ catch (error) {
42
+ if (!(error instanceof internal_1.NoTargetsToMigrateError)) {
43
+ throw error;
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,71 @@
1
+ #### Convert `@nx/vite` and `@nx/vitest:test` targets to inferred tasks
2
+
3
+ Nx 24 removes the `@nx/vite:build`, `@nx/vite:dev-server` and `@nx/vite:preview-server` executors and their `@nrwl` aliases. The migration registers `@nx/vite/plugin` in `nx.json` and converts the targets that use those executors to inferred tasks. It moves build options into `vite.config.*`. It also converts `@nx/vitest:test` targets with the `@nx/vitest` converter, because `@nx/vitest` can be installed only as a transitive dependency and its own migration may not run. A target with nothing left to override is removed from project configuration. When several projects share the same remaining options, those options move to a `targetDefaults` entry scoped to the plugin. `targetDefaults` entries keyed by a removed executor are removed once no target uses that executor.
4
+
5
+ The migration lists the targets the converter cannot convert safely. In agentic runs, an AI prompt finishes them and validates the project graph.
6
+
7
+ #### Sample code changes
8
+
9
+ The `serve` and `preview` targets have no options that differ from the inferred targets, so they are removed.
10
+
11
+ ##### Before
12
+
13
+ ```json title="myapp/project.json"
14
+ {
15
+ "name": "myapp",
16
+ "targets": {
17
+ "build": {
18
+ "executor": "@nx/vite:build",
19
+ "outputs": ["{workspaceRoot}/dist/myapp"],
20
+ "options": {
21
+ "configFile": "myapp/vite.config.ts"
22
+ }
23
+ },
24
+ "serve": {
25
+ "executor": "@nx/vite:dev-server",
26
+ "options": {
27
+ "buildTarget": "myapp:build"
28
+ }
29
+ },
30
+ "preview": {
31
+ "executor": "@nx/vite:preview-server",
32
+ "options": {
33
+ "buildTarget": "myapp:build"
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ##### After
41
+
42
+ ```json title="myapp/project.json"
43
+ {
44
+ "name": "myapp",
45
+ "targets": {
46
+ "build": {
47
+ "options": {
48
+ "config": "./vite.config.ts"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ```json title="nx.json"
56
+ {
57
+ "plugins": [
58
+ {
59
+ "plugin": "@nx/vite/plugin",
60
+ "options": {
61
+ "buildTargetName": "build",
62
+ "devTargetName": "dev",
63
+ "previewTargetName": "preview",
64
+ "serveStaticTargetName": "serve-static",
65
+ "serveTargetName": "serve",
66
+ "typecheckTargetName": "typecheck"
67
+ }
68
+ }
69
+ ]
70
+ }
71
+ ```
@@ -8,12 +8,16 @@ export interface VitePluginOptions {
8
8
  devTargetName?: string;
9
9
  previewTargetName?: string;
10
10
  serveStaticTargetName?: string;
11
- typecheckTargetName?: string;
12
11
  /**
13
- * The compiler to use for type-checking. When unset, defaults to `vue-tsc`
14
- * for Vue projects (detected via the `vite:vue` plugin) and `tsc` otherwise.
15
- * Set to `tsgo` to use the TypeScript Go compiler (`@typescript/native-preview`),
16
- * or `vue-tsc` to force Vue-aware type-checking when auto-detection misses your setup.
12
+ * Name of the `vue-tsc` typecheck target inferred for Vue projects. Other
13
+ * projects get their typecheck target from `@nx/js/typescript`.
14
+ */
15
+ typecheckTargetName?: string | false;
16
+ /**
17
+ * The compiler used to typecheck Vue projects. Defaults to `vue-tsc` when the
18
+ * `vite:vue` plugin is detected. Set `vue-tsc` to force the target when
19
+ * detection misses your setup, or `tsc`/`tsgo` to skip it and rely on
20
+ * `@nx/js/typescript`.
17
21
  */
18
22
  compiler?: 'tsc' | 'tsgo' | 'vue-tsc';
19
23
  watchDepsTargetName?: string;
@@ -108,7 +108,8 @@ async function buildViteTargets(configFilePath, projectRoot, options, tsConfigFi
108
108
  targets[options.buildTargetName] = await buildTarget(options.buildTargetName, namedInputs, buildOutputs, projectRoot, isUsingTsSolutionSetup, pmc);
109
109
  // If running in library mode, then there is nothing to serve.
110
110
  if (!viteBuildConfig.build?.lib || hasServeConfig) {
111
- const devTarget = serveTarget(projectRoot, isUsingTsSolutionSetup, pmc, namedInputs);
111
+ const signals = !!viteBuildConfig.plugins?.some((p) => p.name === 'nx-ready-signal');
112
+ const devTarget = serveTarget(projectRoot, configFilePath, signals, isUsingTsSolutionSetup, pmc, namedInputs);
112
113
  targets[options.serveTargetName] = {
113
114
  ...devTarget,
114
115
  metadata: {
@@ -117,55 +118,44 @@ async function buildViteTargets(configFilePath, projectRoot, options, tsConfigFi
117
118
  },
118
119
  };
119
120
  targets[options.devTargetName] = devTarget;
120
- targets[options.previewTargetName] = previewTarget(projectRoot, options.buildTargetName, pmc, namedInputs);
121
+ targets[options.previewTargetName] = previewTarget(projectRoot, configFilePath, signals, options.buildTargetName, pmc, namedInputs);
121
122
  targets[options.serveStaticTargetName] = serveStaticTarget(options, isUsingTsSolutionSetup, namedInputs);
122
123
  }
123
124
  }
124
- if (tsConfigFiles.length) {
125
- const tsConfigToUse = ['tsconfig.app.json', 'tsconfig.lib.json', 'tsconfig.json'].find((t) => tsConfigFiles.includes(t)) ?? tsConfigFiles[0];
126
- // Check if the project uses Vue plugin
127
- const hasVuePlugin = viteBuildConfig.plugins?.some((p) => p.name === 'vite:vue' || p.name === 'vite:vue2');
128
- // Explicit `compiler` option wins over inference so users can override
129
- // when their setup isn't detected (e.g. custom/non-standard Vue plugin).
130
- const resolvedCompiler = options.compiler ?? (hasVuePlugin ? 'vue-tsc' : 'tsc');
131
- const typeCheckCommand = resolvedCompiler;
132
- const typeCheckExternalDeps = resolvedCompiler === 'tsgo'
133
- ? ['@typescript/native-preview']
134
- : resolvedCompiler === 'vue-tsc'
135
- ? ['vue-tsc', 'typescript']
136
- : ['typescript'];
137
- targets[options.typecheckTargetName] = {
138
- cache: true,
139
- inputs: [
140
- ...('production' in namedInputs
141
- ? ['production', '^production']
142
- : ['default', '^default']),
143
- { externalDependencies: typeCheckExternalDeps },
144
- ],
145
- command: isUsingTsSolutionSetup
146
- ? `${typeCheckCommand} --build --emitDeclarationOnly`
147
- : `${typeCheckCommand} --noEmit -p ${tsConfigToUse}`,
148
- options: { cwd: (0, devkit_1.joinPathFragments)(projectRoot) },
149
- metadata: {
150
- description: `Runs type-checking for the project.`,
151
- technologies: hasVuePlugin ? ['typescript', 'vue'] : ['typescript'],
152
- help: {
153
- command: isUsingTsSolutionSetup
154
- ? `${pmc.exec} ${typeCheckCommand} --build --help`
155
- : `${pmc.exec} ${typeCheckCommand} -p ${tsConfigToUse} --help`,
156
- example: isUsingTsSolutionSetup
157
- ? { args: ['--force'] }
158
- : { options: { noEmit: true } },
159
- },
160
- },
161
- };
162
- if (isUsingTsSolutionSetup) {
163
- targets[options.typecheckTargetName].dependsOn = [
164
- `^${options.typecheckTargetName}`,
165
- ];
166
- targets[options.typecheckTargetName].syncGenerators = [
167
- '@nx/js:typescript-sync',
168
- ];
125
+ const hasVuePlugin = viteBuildConfig.plugins?.some((p) => p.name === 'vite:vue' || p.name === 'vite:vue2');
126
+ // @nx/js/typescript provides tsc typecheck targets but can't run vue-tsc.
127
+ const usesVueTsc = (options.compiler ?? (hasVuePlugin ? 'vue-tsc' : 'tsc')) === 'vue-tsc';
128
+ if (usesVueTsc &&
129
+ options.typecheckTargetName !== false &&
130
+ tsConfigFiles.length) {
131
+ const technologies = hasVuePlugin ? ['typescript', 'vue'] : ['typescript'];
132
+ const tsConfig = (0, internal_2.selectTypecheckTsConfig)(tsConfigFiles);
133
+ if (!isUsingTsSolutionSetup) {
134
+ if (tsConfig) {
135
+ targets[options.typecheckTargetName] = (0, internal_2.createTypecheckTarget)({
136
+ mode: 'noEmit',
137
+ projectRoot: (0, devkit_1.joinPathFragments)(projectRoot),
138
+ pmc,
139
+ tsConfig,
140
+ compiler: 'vue-tsc',
141
+ namedInputs,
142
+ technologies,
143
+ });
144
+ }
145
+ }
146
+ else if (tsConfigFiles.includes('tsconfig.json')) {
147
+ targets[options.typecheckTargetName] = (0, internal_2.createTypecheckTarget)({
148
+ mode: 'build',
149
+ projectRoot: (0, devkit_1.joinPathFragments)(projectRoot),
150
+ pmc,
151
+ compiler: 'vue-tsc',
152
+ targetName: options.typecheckTargetName,
153
+ buildTargetName: targets[options.buildTargetName]
154
+ ? options.buildTargetName
155
+ : undefined,
156
+ namedInputs,
157
+ technologies,
158
+ });
169
159
  }
170
160
  }
171
161
  (0, internal_2.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc);
@@ -212,7 +202,7 @@ function buildInputs(namedInputs) {
212
202
  },
213
203
  ];
214
204
  }
215
- function serveTarget(projectRoot, isUsingTsSolutionSetup, pmc, namedInputs) {
205
+ function serveTarget(projectRoot, configFilePath, signals, isUsingTsSolutionSetup, pmc, namedInputs) {
216
206
  const targetConfig = {
217
207
  continuous: true,
218
208
  inputs: buildInputs(namedInputs),
@@ -220,6 +210,7 @@ function serveTarget(projectRoot, isUsingTsSolutionSetup, pmc, namedInputs) {
220
210
  options: {
221
211
  cwd: (0, devkit_1.joinPathFragments)(projectRoot),
222
212
  },
213
+ readyWhen: getServerReadyWhen(configFilePath, 'serve', signals),
223
214
  metadata: {
224
215
  technologies: ['vite'],
225
216
  description: `Starts Vite dev server`,
@@ -238,7 +229,7 @@ function serveTarget(projectRoot, isUsingTsSolutionSetup, pmc, namedInputs) {
238
229
  }
239
230
  return targetConfig;
240
231
  }
241
- function previewTarget(projectRoot, buildTargetName, pmc, namedInputs) {
232
+ function previewTarget(projectRoot, configFilePath, signals, buildTargetName, pmc, namedInputs) {
242
233
  const targetConfig = {
243
234
  continuous: true,
244
235
  inputs: buildInputs(namedInputs),
@@ -247,6 +238,7 @@ function previewTarget(projectRoot, buildTargetName, pmc, namedInputs) {
247
238
  options: {
248
239
  cwd: (0, devkit_1.joinPathFragments)(projectRoot),
249
240
  },
241
+ readyWhen: getServerReadyWhen(configFilePath, 'preview', signals),
250
242
  metadata: {
251
243
  technologies: ['vite'],
252
244
  description: `Locally preview Vite production build`,
@@ -271,12 +263,27 @@ function serveStaticTarget(options, isUsingTsSolutionSetup, namedInputs) {
271
263
  buildTarget: `${options.buildTargetName}`,
272
264
  spa: true,
273
265
  },
266
+ readyWhen: { port: '{options.port}', host: '{options.host ?? localhost}' },
274
267
  };
275
268
  if (isUsingTsSolutionSetup) {
276
269
  targetConfig.syncGenerators = ['@nx/js:typescript-sync'];
277
270
  }
278
271
  return targetConfig;
279
272
  }
273
+ // A config that loads nxReadySignal() reports when the server listens.
274
+ // Otherwise the check resolves the config when the task runs, with the task's
275
+ // env and options, and waits for the server's port.
276
+ function getServerReadyWhen(configFilePath, command, signals) {
277
+ return signals
278
+ ? { signal: true }
279
+ : {
280
+ // Unquoted: the plugin's glob fixes the file name. Quote it if it ever
281
+ // becomes user-chosen, since the shell expands $, backticks and %.
282
+ command: `node -e "require('@nx/vite/ready-check').waitForDevServer(process.argv[1], '${command}')" ${(0, node_path_1.basename)(configFilePath)}`,
283
+ // Each attempt resolves the config
284
+ interval: 1000,
285
+ };
286
+ }
280
287
  function getOutputs(viteBuildConfig, projectRoot, workspaceRoot) {
281
288
  // TODO(jack): Remove this cast when @nx/vite switches to moduleResolution:
282
289
  // "nodenext". Vite 8's rolldown types are ESM-only (.d.mts) and not
@@ -1,11 +1,4 @@
1
- export declare const VITE_BUILD_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/vite:build` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
2
- export declare const VITE_DEV_SERVER_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/vite:dev-server` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
3
- export declare const VITE_PREVIEW_SERVER_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/vite:preview-server` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
4
- export declare function warnViteBuildExecutorDeprecation(): void;
5
- export declare function warnViteDevServerExecutorDeprecation(): void;
6
- export declare function warnVitePreviewServerExecutorDeprecation(): void;
7
- export declare function warnViteExecutorGenerating(): void;
8
- export declare const NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = "The `nxViteTsPaths` plugin from `@nx/vite/plugins/nx-tsconfig-paths.plugin` is deprecated and will be removed in Nx v24. Replace it with `tsconfigPaths()` from the `vite-tsconfig-paths` package. See https://nx.dev/docs/technologies/build-tools/vite/guides/configure-vite for details.";
9
- export declare const NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = "The `nxCopyAssetsPlugin` plugin from `@nx/vite/plugins/nx-copy-assets.plugin` is deprecated and will be removed in Nx v24. Use Vite's native `publicDir` option or the `vite-plugin-static-copy` package instead. See https://nx.dev/docs/technologies/build-tools/vite/guides/configure-vite for details.";
1
+ export declare const NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = "The `nxViteTsPaths` plugin from `@nx/vite/plugins/nx-tsconfig-paths.plugin` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. Use native `resolve.tsconfigPaths` when supported by the installed Vite version, or a compatible `vite-tsconfig-paths` plugin. Follow the config-helper migration instructions generated by `nx migrate`.";
2
+ export declare const NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = "The `nxCopyAssetsPlugin` plugin from `@nx/vite/plugins/nx-copy-assets.plugin` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. Preserve asset paths and watch behavior using native `publicDir`, a compatible `vite-plugin-static-copy`, or local configuration. Follow the config-helper migration instructions generated by `nx migrate`.";
10
3
  export declare function warnNxViteTsPathsDeprecation(): void;
11
4
  export declare function warnNxCopyAssetsPluginDeprecation(): void;
@@ -1,43 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = exports.NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = exports.VITE_PREVIEW_SERVER_EXECUTOR_DEPRECATION_MESSAGE = exports.VITE_DEV_SERVER_EXECUTOR_DEPRECATION_MESSAGE = exports.VITE_BUILD_EXECUTOR_DEPRECATION_MESSAGE = void 0;
4
- exports.warnViteBuildExecutorDeprecation = warnViteBuildExecutorDeprecation;
5
- exports.warnViteDevServerExecutorDeprecation = warnViteDevServerExecutorDeprecation;
6
- exports.warnVitePreviewServerExecutorDeprecation = warnVitePreviewServerExecutorDeprecation;
7
- exports.warnViteExecutorGenerating = warnViteExecutorGenerating;
3
+ exports.NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = exports.NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = void 0;
8
4
  exports.warnNxViteTsPathsDeprecation = warnNxViteTsPathsDeprecation;
9
5
  exports.warnNxCopyAssetsPluginDeprecation = warnNxCopyAssetsPluginDeprecation;
10
6
  const devkit_1 = require("@nx/devkit");
11
- // TODO(v24): Remove the @nx/vite:build, @nx/vite:dev-server, and
12
- // @nx/vite:preview-server executors. The inferred plugin (@nx/vite/plugin)
13
- // and the convert-to-inferred generator stay supported. (`@nx/vite:test`
14
- // is being deprecated in a separate change for the test-runner batch.)
15
- exports.VITE_BUILD_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/vite:build` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
16
- exports.VITE_DEV_SERVER_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/vite:dev-server` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
17
- exports.VITE_PREVIEW_SERVER_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/vite:preview-server` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` to migrate to the `@nx/vite/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
18
- function warnViteBuildExecutorDeprecation() {
19
- devkit_1.logger.warn(exports.VITE_BUILD_EXECUTOR_DEPRECATION_MESSAGE);
20
- }
21
- function warnViteDevServerExecutorDeprecation() {
22
- devkit_1.logger.warn(exports.VITE_DEV_SERVER_EXECUTOR_DEPRECATION_MESSAGE);
23
- }
24
- function warnVitePreviewServerExecutorDeprecation() {
25
- devkit_1.logger.warn(exports.VITE_PREVIEW_SERVER_EXECUTOR_DEPRECATION_MESSAGE);
26
- }
27
- // Fired when the @nx/vite:configuration generator is about to generate
28
- // targets that use the deprecated executors — i.e. when @nx/vite/plugin
29
- // isn't registered in nx.json. Surfaces the deprecation at generation time
30
- // rather than only when the user later runs the generated targets.
31
- function warnViteExecutorGenerating() {
32
- devkit_1.logger.warn('Generating targets that use the deprecated `@nx/vite:build`, `@nx/vite:dev-server`, and `@nx/vite:preview-server` executors. These executors will be removed in Nx v24. Run `nx g @nx/vite:convert-to-inferred` next to migrate these targets to the `@nx/vite/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
33
- }
34
- // TODO(v24): Remove `nxViteTsPaths` and `nxCopyAssetsPlugin` helpers.
35
- // The inferred `@nx/vite/plugin` already ensures projects extend the base
36
- // tsconfig, so the community `vite-tsconfig-paths` package handles path
37
- // resolution end-to-end. Asset copying is covered by Vite's native
38
- // `publicDir` option or the `vite-plugin-static-copy` package.
39
- exports.NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = 'The `nxViteTsPaths` plugin from `@nx/vite/plugins/nx-tsconfig-paths.plugin` is deprecated and will be removed in Nx v24. Replace it with `tsconfigPaths()` from the `vite-tsconfig-paths` package. See https://nx.dev/docs/technologies/build-tools/vite/guides/configure-vite for details.';
40
- exports.NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = "The `nxCopyAssetsPlugin` plugin from `@nx/vite/plugins/nx-copy-assets.plugin` is deprecated and will be removed in Nx v24. Use Vite's native `publicDir` option or the `vite-plugin-static-copy` package instead. See https://nx.dev/docs/technologies/build-tools/vite/guides/configure-vite for details.";
7
+ // Helper behavior was removed in v24; exports remain only as inert stubs.
8
+ // Keep their imports loadable while existing Vite configs are migrated.
9
+ exports.NX_VITE_TS_PATHS_DEPRECATION_MESSAGE = 'The `nxViteTsPaths` plugin from `@nx/vite/plugins/nx-tsconfig-paths.plugin` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. Use native `resolve.tsconfigPaths` when supported by the installed Vite version, or a compatible `vite-tsconfig-paths` plugin. Follow the config-helper migration instructions generated by `nx migrate`.';
10
+ exports.NX_COPY_ASSETS_PLUGIN_DEPRECATION_MESSAGE = 'The `nxCopyAssetsPlugin` plugin from `@nx/vite/plugins/nx-copy-assets.plugin` was removed in Nx v24. The remaining export is an inert compatibility stub and does not configure builds. Preserve asset paths and watch behavior using native `publicDir`, a compatible `vite-plugin-static-copy`, or local configuration. Follow the config-helper migration instructions generated by `nx migrate`.';
41
11
  let nxViteTsPathsWarned = false;
42
12
  let nxCopyAssetsPluginWarned = false;
43
13
  // Warn-once per process so users don't see the message repeated on every
@@ -0,0 +1,27 @@
1
+ export interface ViteFlags {
2
+ port?: string;
3
+ host?: string | boolean;
4
+ mode?: string;
5
+ config?: string;
6
+ root?: string;
7
+ }
8
+ /**
9
+ * The flags `vite` and `vite preview` get from the target's options, in the
10
+ * order run-commands passes them: named options, `args`, then overrides.
11
+ */
12
+ export declare function parseViteFlags(options: Record<string, unknown>, command: 'serve' | 'preview'): ViteFlags;
13
+ export type ServerAddress = {
14
+ port: number;
15
+ host?: string;
16
+ };
17
+ export declare function getViteServerAddress(server: {
18
+ port?: unknown;
19
+ host?: unknown;
20
+ } | undefined, flags: ViteFlags, command: 'serve' | 'preview'): ServerAddress | null;
21
+ /**
22
+ * The readyWhen of the inferred serve and preview targets when the config
23
+ * doesn't load the signal plugin. Runs in the env and with the options of the
24
+ * task, resolves the config the way `vite` does, and waits for the server's
25
+ * port.
26
+ */
27
+ export declare function waitForViteServer(configPath: string, command: 'serve' | 'preview'): Promise<void>;