@nx/web 20.3.1 → 20.4.0-beta.0

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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2017-2024 Narwhal Technologies Inc.
3
+ Copyright (c) 2017-2025 Narwhal Technologies Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/web",
3
- "version": "20.3.1",
3
+ "version": "20.4.0-beta.0",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Web Components contains generators for managing Web Component applications and libraries within an Nx workspace. It provides:\n\n\n- Integration with libraries such as Jest, Playwright, Cypress, and Storybook.\n\n- Scaffolding for creating buildable libraries that can be published to npm.\n\n- Utilities for automatic workspace refactoring.",
6
6
  "repository": {
@@ -35,8 +35,8 @@
35
35
  "http-server": "^14.1.0",
36
36
  "picocolors": "^1.1.0",
37
37
  "tslib": "^2.3.0",
38
- "@nx/devkit": "20.3.1",
39
- "@nx/js": "20.3.1"
38
+ "@nx/devkit": "20.4.0-beta.0",
39
+ "@nx/js": "20.4.0-beta.0"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"
@@ -74,7 +74,14 @@
74
74
  "description": "Path where the build artifacts are located. If not provided then it will be infered from the buildTarget executor options as outputPath"
75
75
  },
76
76
  "cors": {
77
- "type": "boolean",
77
+ "oneOf": [
78
+ {
79
+ "type": "boolean"
80
+ },
81
+ {
82
+ "type": "string"
83
+ }
84
+ ],
78
85
  "description": "Enable CORS",
79
86
  "default": true
80
87
  },
@@ -16,14 +16,16 @@ const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-projec
16
16
  const static_serve_configuration_1 = require("../static-serve/static-serve-configuration");
17
17
  const find_plugin_for_config_file_1 = require("@nx/devkit/src/utils/find-plugin-for-config-file");
18
18
  const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
19
+ const get_import_path_1 = require("@nx/js/src/utils/get-import-path");
19
20
  function createApplicationFiles(tree, options) {
21
+ const rootTsConfigPath = (0, js_1.getRelativePathToRootTsConfig)(tree, options.appProjectRoot);
20
22
  if (options.bundler === 'vite') {
21
23
  (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, './files/app-vite'), options.appProjectRoot, {
22
24
  ...options,
23
25
  ...(0, devkit_1.names)(options.name),
24
26
  tmpl: '',
25
27
  offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
26
- rootTsConfigPath: (0, js_1.getRelativePathToRootTsConfig)(tree, options.appProjectRoot),
28
+ rootTsConfigPath,
27
29
  });
28
30
  }
29
31
  else {
@@ -32,7 +34,7 @@ function createApplicationFiles(tree, options) {
32
34
  ...(0, devkit_1.names)(options.name),
33
35
  tmpl: '',
34
36
  offsetFromRoot: (0, devkit_1.offsetFromRoot)(options.appProjectRoot),
35
- rootTsConfigPath: (0, js_1.getRelativePathToRootTsConfig)(tree, options.appProjectRoot),
37
+ rootTsConfigPath,
36
38
  webpackPluginOptions: (0, has_webpack_plugin_1.hasWebpackPlugin)(tree)
37
39
  ? {
38
40
  compiler: options.compiler,
@@ -53,15 +55,29 @@ function createApplicationFiles(tree, options) {
53
55
  tree.delete((0, path_1.join)(options.appProjectRoot, './src/app/app.element.spec.ts'));
54
56
  }
55
57
  }
56
- (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'), (json) => {
57
- return {
58
- ...json,
59
- compilerOptions: {
60
- ...(json.compilerOptions || {}),
61
- strict: options.strict,
62
- },
63
- };
64
- });
58
+ if (options.isUsingTsSolutionConfig) {
59
+ (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'), () => ({
60
+ extends: rootTsConfigPath,
61
+ files: [],
62
+ include: [],
63
+ references: [
64
+ {
65
+ path: './tsconfig.app.json',
66
+ },
67
+ ],
68
+ }));
69
+ }
70
+ else {
71
+ (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'tsconfig.json'), (json) => {
72
+ return {
73
+ ...json,
74
+ compilerOptions: {
75
+ ...(json.compilerOptions || {}),
76
+ strict: options.strict,
77
+ },
78
+ };
79
+ });
80
+ }
65
81
  }
66
82
  async function setupBundler(tree, options) {
67
83
  const main = (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'src/main.ts');
@@ -117,6 +133,7 @@ async function setupBundler(tree, options) {
117
133
  else if (options.bundler === 'none') {
118
134
  const project = (0, devkit_1.readProjectConfiguration)(tree, options.projectName);
119
135
  (0, target_defaults_utils_1.addBuildTargetDefaults)(tree, `@nx/js:${options.compiler}`);
136
+ project.targets ??= {};
120
137
  project.targets.build = {
121
138
  executor: `@nx/js:${options.compiler}`,
122
139
  outputs: ['{options.outputPath}'],
@@ -133,14 +150,28 @@ async function setupBundler(tree, options) {
133
150
  }
134
151
  }
135
152
  async function addProject(tree, options) {
136
- const targets = {};
137
- (0, devkit_1.addProjectConfiguration)(tree, options.projectName, {
138
- projectType: 'application',
139
- root: options.appProjectRoot,
140
- sourceRoot: (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'src'),
141
- tags: options.parsedTags,
142
- targets,
143
- }, options.standaloneConfig);
153
+ if (options.isUsingTsSolutionConfig) {
154
+ (0, devkit_1.writeJson)(tree, (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'package.json'), {
155
+ name: (0, get_import_path_1.getImportPath)(tree, options.name),
156
+ version: '0.0.1',
157
+ private: true,
158
+ nx: {
159
+ name: options.name,
160
+ projectType: 'application',
161
+ sourceRoot: `${options.appProjectRoot}/src`,
162
+ tags: options.parsedTags?.length ? options.parsedTags : undefined,
163
+ },
164
+ });
165
+ }
166
+ else {
167
+ (0, devkit_1.addProjectConfiguration)(tree, options.projectName, {
168
+ projectType: 'application',
169
+ root: options.appProjectRoot,
170
+ sourceRoot: (0, devkit_1.joinPathFragments)(options.appProjectRoot, 'src'),
171
+ tags: options.parsedTags,
172
+ targets: {},
173
+ });
174
+ }
144
175
  }
145
176
  function setDefaults(tree, options) {
146
177
  const nxJson = (0, devkit_1.readNxJson)(tree);
@@ -161,7 +192,6 @@ async function applicationGenerator(host, schema) {
161
192
  });
162
193
  }
163
194
  async function applicationGeneratorInternal(host, schema) {
164
- (0, ts_solution_setup_1.assertNotUsingTsSolutionSetup)(host, 'web', 'application');
165
195
  const options = await normalizeOptions(host, schema);
166
196
  const tasks = [];
167
197
  const jsInitTask = await (0, js_1.initGenerator)(host, {
@@ -274,14 +304,28 @@ async function applicationGeneratorInternal(host, schema) {
274
304
  }
275
305
  if (options.e2eTestRunner === 'cypress') {
276
306
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/cypress', versions_2.nxVersion);
277
- (0, devkit_1.addProjectConfiguration)(host, options.e2eProjectName, {
278
- root: options.e2eProjectRoot,
279
- sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
280
- projectType: 'application',
281
- targets: {},
282
- tags: [],
283
- implicitDependencies: [options.projectName],
284
- });
307
+ if (options.isUsingTsSolutionConfig) {
308
+ (0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'package.json'), {
309
+ name: options.e2eProjectName,
310
+ version: '0.0.1',
311
+ private: true,
312
+ nx: {
313
+ projectType: 'application',
314
+ sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
315
+ implicitDependencies: [options.projectName],
316
+ },
317
+ });
318
+ }
319
+ else {
320
+ (0, devkit_1.addProjectConfiguration)(host, options.e2eProjectName, {
321
+ root: options.e2eProjectRoot,
322
+ sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
323
+ projectType: 'application',
324
+ targets: {},
325
+ tags: [],
326
+ implicitDependencies: [options.projectName],
327
+ });
328
+ }
285
329
  const cypressTask = await configurationGenerator(host, {
286
330
  ...options,
287
331
  project: options.e2eProjectName,
@@ -317,14 +361,28 @@ async function applicationGeneratorInternal(host, schema) {
317
361
  }
318
362
  else if (options.e2eTestRunner === 'playwright') {
319
363
  const { configurationGenerator: playwrightConfigGenerator } = (0, devkit_1.ensurePackage)('@nx/playwright', versions_2.nxVersion);
320
- (0, devkit_1.addProjectConfiguration)(host, options.e2eProjectName, {
321
- root: options.e2eProjectRoot,
322
- sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
323
- projectType: 'application',
324
- targets: {},
325
- tags: [],
326
- implicitDependencies: [options.projectName],
327
- });
364
+ if (options.isUsingTsSolutionConfig) {
365
+ (0, devkit_1.writeJson)(host, (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'package.json'), {
366
+ name: options.e2eProjectName,
367
+ version: '0.0.1',
368
+ private: true,
369
+ nx: {
370
+ projectType: 'application',
371
+ sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
372
+ implicitDependencies: [options.projectName],
373
+ },
374
+ });
375
+ }
376
+ else {
377
+ (0, devkit_1.addProjectConfiguration)(host, options.e2eProjectName, {
378
+ root: options.e2eProjectRoot,
379
+ sourceRoot: (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'src'),
380
+ projectType: 'application',
381
+ targets: {},
382
+ tags: [],
383
+ implicitDependencies: [options.projectName],
384
+ });
385
+ }
328
386
  const playwrightTask = await playwrightConfigGenerator(host, {
329
387
  project: options.e2eProjectName,
330
388
  skipFormat: true,
@@ -383,7 +441,16 @@ async function applicationGeneratorInternal(host, schema) {
383
441
  }
384
442
  setDefaults(host, options);
385
443
  tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, { tslib: versions_2.tsLibVersion }, { '@types/node': versions_2.typesNodeVersion }));
386
- if (!schema.skipFormat) {
444
+ (0, ts_solution_setup_1.updateTsconfigFiles)(host, options.appProjectRoot, 'tsconfig.app.json', {
445
+ module: 'esnext',
446
+ moduleResolution: 'bundler',
447
+ }, options.linter === 'eslint'
448
+ ? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
449
+ : undefined);
450
+ if (options.isUsingTsSolutionConfig) {
451
+ (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.appProjectRoot);
452
+ }
453
+ if (!options.skipFormat) {
387
454
  await (0, devkit_1.formatFiles)(host);
388
455
  }
389
456
  tasks.push(() => {
@@ -404,6 +471,7 @@ async function normalizeOptions(host, options) {
404
471
  options.addPlugin ??= addPluginDefault;
405
472
  const e2eProjectName = `${appProjectName}-e2e`;
406
473
  const e2eProjectRoot = `${appProjectRoot}-e2e`;
474
+ const isUsingTsSolutionConfig = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(host);
407
475
  const npmScope = (0, get_npm_scope_1.getNpmScope)(host);
408
476
  const parsedTags = options.tags
409
477
  ? options.tags.split(',').map((s) => s.trim())
@@ -424,6 +492,7 @@ async function normalizeOptions(host, options) {
424
492
  e2eProjectRoot,
425
493
  e2eProjectName,
426
494
  parsedTags,
495
+ isUsingTsSolutionConfig,
427
496
  };
428
497
  }
429
498
  exports.default = applicationGenerator;
@@ -13,7 +13,6 @@ export interface Schema {
13
13
  inSourceTests?: boolean;
14
14
  e2eTestRunner?: 'cypress' | 'playwright' | 'none';
15
15
  linter?: Linter | LinterType;
16
- standaloneConfig?: boolean;
17
16
  setParserOptionsProject?: boolean;
18
17
  strict?: boolean;
19
18
  addPlugin?: boolean;
@@ -54,8 +54,8 @@
54
54
  "bundler": {
55
55
  "type": "string",
56
56
  "description": "The bundler to use.",
57
- "enum": ["webpack", "none", "vite"],
58
- "default": "webpack",
57
+ "enum": ["vite", "webpack", "none"],
58
+ "default": "vite",
59
59
  "x-prompt": "Which bundler do you want to use?",
60
60
  "x-priority": "important"
61
61
  },
@@ -63,7 +63,8 @@
63
63
  "description": "The tool to use for running lint checks.",
64
64
  "type": "string",
65
65
  "enum": ["eslint", "none"],
66
- "default": "eslint"
66
+ "default": "none",
67
+ "x-prompt": "Which linter would you like to use?"
67
68
  },
68
69
  "skipFormat": {
69
70
  "description": "Skip formatting files",
@@ -74,8 +75,9 @@
74
75
  "unitTestRunner": {
75
76
  "type": "string",
76
77
  "enum": ["vitest", "jest", "none"],
77
- "default": "vitest",
78
- "description": "Test runner to use for unit tests. Default value is 'jest' when using 'webpack' or 'none' as the bundler and 'vitest' when using 'vite' as the bundler"
78
+ "default": "none",
79
+ "description": "Test runner to use for unit tests. Default value is 'jest' when using 'webpack' or 'none' as the bundler and 'vitest' when using 'vite' as the bundler",
80
+ "x-prompt": "What unit test runner should be used?"
79
81
  },
80
82
  "inSourceTests": {
81
83
  "type": "boolean",
@@ -102,12 +104,6 @@
102
104
  "type": "boolean",
103
105
  "description": "Creates an application with strict mode and strict type checking.",
104
106
  "default": true
105
- },
106
- "standaloneConfig": {
107
- "description": "Split the project configuration into `<projectRoot>/project.json` rather than including it inside workspace.json",
108
- "type": "boolean",
109
- "default": true,
110
- "x-deprecated": "Nx only supports standaloneConfig"
111
107
  }
112
108
  },
113
109
  "required": ["directory"],
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.webInitGenerator = webInitGenerator;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
6
5
  const versions_1 = require("../../utils/versions");
7
6
  function updateDependencies(tree, schema) {
8
7
  const tasks = [];
@@ -11,7 +10,6 @@ function updateDependencies(tree, schema) {
11
10
  return (0, devkit_1.runTasksInSerial)(...tasks);
12
11
  }
13
12
  async function webInitGenerator(tree, schema) {
14
- (0, ts_solution_setup_1.assertNotUsingTsSolutionSetup)(tree, 'web', 'init');
15
13
  let installTask = () => { };
16
14
  if (!schema.skipPackageJson) {
17
15
  installTask = updateDependencies(tree, schema);