@nx/react 18.0.0-beta.0 → 18.0.0-beta.2

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 (57) hide show
  1. package/generators.json +1 -1
  2. package/migrations.json +6 -0
  3. package/package.json +6 -7
  4. package/plugins/component-testing/index.js +33 -10
  5. package/plugins/nx-react-webpack-plugin/lib/apply-react-config.js +0 -6
  6. package/src/generators/application/application.js +9 -0
  7. package/src/generators/application/files/nx-welcome/src/app/nx-welcome.tsx +19 -0
  8. package/src/generators/application/lib/add-e2e.js +1 -0
  9. package/src/generators/application/lib/add-project.js +1 -1
  10. package/src/generators/application/lib/normalize-options.js +1 -0
  11. package/src/generators/application/schema.d.ts +2 -0
  12. package/src/generators/application/schema.json +3 -3
  13. package/src/generators/component/schema.d.ts +4 -4
  14. package/src/generators/component/schema.json +7 -7
  15. package/src/generators/component-cypress-spec/schema.json +1 -1
  16. package/src/generators/component-story/schema.json +1 -1
  17. package/src/generators/component-test/schema.json +1 -1
  18. package/src/generators/cypress-component-configuration/cypress-component-configuration.d.ts +2 -1
  19. package/src/generators/cypress-component-configuration/cypress-component-configuration.js +14 -4
  20. package/src/generators/cypress-component-configuration/lib/add-files.js +1 -6
  21. package/src/generators/cypress-component-configuration/schema.d.ts +1 -0
  22. package/src/generators/federate-module/schema.json +1 -1
  23. package/src/generators/hook/schema.d.ts +4 -4
  24. package/src/generators/hook/schema.json +5 -5
  25. package/src/generators/host/files/module-federation-ts/webpack.config.prod.ts__tmpl__ +2 -1
  26. package/src/generators/host/files/module-federation-ts/webpack.config.ts__tmpl__ +2 -2
  27. package/src/generators/host/host.js +4 -0
  28. package/src/generators/host/schema.d.ts +3 -1
  29. package/src/generators/host/schema.json +3 -3
  30. package/src/generators/init/schema.json +1 -1
  31. package/src/generators/library/lib/add-linting.js +1 -0
  32. package/src/generators/library/lib/normalize-options.js +2 -1
  33. package/src/generators/library/library.js +7 -0
  34. package/src/generators/library/schema.d.ts +1 -0
  35. package/src/generators/library/schema.json +3 -3
  36. package/src/generators/redux/schema.d.ts +1 -1
  37. package/src/generators/redux/schema.json +2 -2
  38. package/src/generators/remote/remote.js +4 -0
  39. package/src/generators/remote/schema.d.ts +1 -1
  40. package/src/generators/remote/schema.json +3 -3
  41. package/src/generators/setup-ssr/schema.json +1 -1
  42. package/src/generators/setup-ssr/setup-ssr.js +16 -4
  43. package/src/generators/setup-tailwind/schema.json +1 -1
  44. package/src/generators/stories/schema.json +1 -1
  45. package/src/generators/stories/stories.js +15 -3
  46. package/src/generators/storybook-configuration/configuration.d.ts +1 -0
  47. package/src/generators/storybook-configuration/configuration.js +15 -5
  48. package/src/generators/storybook-configuration/schema.d.ts +1 -0
  49. package/src/generators/storybook-configuration/schema.json +4 -4
  50. package/src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults.d.ts +2 -0
  51. package/src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults.js +26 -0
  52. package/src/module-federation/with-module-federation-ssr.js +3 -0
  53. package/src/module-federation/with-module-federation.js +3 -0
  54. package/src/utils/add-mf-env-to-inputs.d.ts +2 -0
  55. package/src/utils/add-mf-env-to-inputs.js +24 -0
  56. package/src/utils/ct-utils.d.ts +6 -1
  57. package/src/utils/ct-utils.js +30 -9
@@ -1,6 +1,6 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
2
  import type { Linter } from '@nx/eslint';
3
- import type { SupportedStyles } from '../../../typings';
3
+ import type { SupportedStyles } from '../../../typings/style';
4
4
 
5
5
  export interface Schema {
6
6
  classComponent?: boolean;
@@ -26,10 +26,12 @@ export interface Schema {
26
26
  minimal?: boolean;
27
27
  typescriptConfiguration?: boolean;
28
28
  dynamic?: boolean;
29
+ addPlugin?: boolean;
29
30
  }
30
31
 
31
32
  export interface NormalizedSchema extends Schema {
32
33
  appProjectRoot: string;
33
34
  e2eProjectName: string;
34
35
  projectName: string;
36
+ addPlugin?: boolean;
35
37
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "GeneratorReactHost",
4
4
  "cli": "nx",
5
5
  "title": "Generate Module Federation Setup for React Host App",
@@ -43,11 +43,11 @@
43
43
  },
44
44
  {
45
45
  "value": "scss",
46
- "label": "SASS(.scss) [ http://sass-lang.com ]"
46
+ "label": "SASS(.scss) [ https://sass-lang.com ]"
47
47
  },
48
48
  {
49
49
  "value": "less",
50
- "label": "LESS [ http://lesscss.org ]"
50
+ "label": "LESS [ https://lesscss.org ]"
51
51
  },
52
52
  {
53
53
  "value": "styled-components",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "NxReactNgInit",
4
4
  "title": "Init React Plugin",
5
5
  "description": "Initialize a React Plugin.",
@@ -18,6 +18,7 @@ async function addLinting(host, options) {
18
18
  skipFormat: true,
19
19
  skipPackageJson: options.skipPackageJson,
20
20
  setParserOptionsProject: options.setParserOptionsProject,
21
+ addPlugin: options.addPlugin,
21
22
  });
22
23
  if ((0, eslint_file_1.isEslintConfigSupported)(host)) {
23
24
  (0, eslint_file_1.addExtendsToLintConfig)(host, options.projectRoot, 'plugin:@nx/react');
@@ -13,6 +13,7 @@ async function normalizeOptions(host, options) {
13
13
  projectNameAndRootFormat: options.projectNameAndRootFormat,
14
14
  callingGenerator: '@nx/react:library',
15
15
  });
16
+ options.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
16
17
  const fileName = options.simpleName
17
18
  ? projectNames.projectSimpleName
18
19
  : projectNames.projectFileName;
@@ -50,7 +51,7 @@ async function normalizeOptions(host, options) {
50
51
  throw new Error(`appProject expected type of "application" but got "${appProjectConfig.projectType}"`);
51
52
  }
52
53
  normalized.appMain =
53
- appProjectConfig.targets.build.options.main ??
54
+ appProjectConfig.targets.build?.options?.main ??
54
55
  findMainEntry(host, appProjectConfig.root);
55
56
  normalized.appSourceRoot = (0, devkit_1.normalizePath)(appProjectConfig.sourceRoot);
56
57
  // TODO(jack): We should use appEntryFile instead of appProject so users can directly set it rather than us inferring it.
@@ -17,8 +17,10 @@ const create_ts_config_1 = require("../../utils/create-ts-config");
17
17
  const install_common_dependencies_1 = require("./lib/install-common-dependencies");
18
18
  const set_defaults_1 = require("./lib/set-defaults");
19
19
  const path_1 = require("path");
20
+ const log_show_project_command_1 = require("@nx/devkit/src/utils/log-show-project-command");
20
21
  async function libraryGenerator(host, schema) {
21
22
  return await libraryGeneratorInternal(host, {
23
+ addPlugin: false,
22
24
  projectNameAndRootFormat: 'derived',
23
25
  ...schema,
24
26
  });
@@ -66,6 +68,7 @@ async function libraryGeneratorInternal(host, schema) {
66
68
  compiler: options.compiler,
67
69
  skipFormat: true,
68
70
  testEnvironment: 'jsdom',
71
+ addPlugin: options.addPlugin,
69
72
  });
70
73
  tasks.push(viteTask);
71
74
  createOrEditViteConfig(host, {
@@ -120,6 +123,7 @@ async function libraryGeneratorInternal(host, schema) {
120
123
  inSourceTests: options.inSourceTests,
121
124
  skipFormat: true,
122
125
  testEnvironment: 'jsdom',
126
+ addPlugin: options.addPlugin,
123
127
  });
124
128
  tasks.push(vitestTask);
125
129
  createOrEditViteConfig(host, {
@@ -179,6 +183,9 @@ async function libraryGeneratorInternal(host, schema) {
179
183
  if (!options.skipFormat) {
180
184
  await (0, devkit_1.formatFiles)(host);
181
185
  }
186
+ tasks.push(() => {
187
+ (0, log_show_project_command_1.logShowProjectCommand)(options.name);
188
+ });
182
189
  return (0, devkit_1.runTasksInSerial)(...tasks);
183
190
  }
184
191
  exports.libraryGeneratorInternal = libraryGeneratorInternal;
@@ -29,6 +29,7 @@ export interface Schema {
29
29
  unitTestRunner?: 'jest' | 'vitest' | 'none';
30
30
  minimal?: boolean;
31
31
  simpleName?: boolean;
32
+ addPlugin?: boolean;
32
33
  }
33
34
 
34
35
  export interface NormalizedSchema extends Schema {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "cli": "nx",
4
4
  "$id": "NxReactLibrary",
5
5
  "title": "Create a React Library",
@@ -50,11 +50,11 @@
50
50
  { "value": "css", "label": "CSS" },
51
51
  {
52
52
  "value": "scss",
53
- "label": "SASS(.scss) [ http://sass-lang.com ]"
53
+ "label": "SASS(.scss) [ https://sass-lang.com ]"
54
54
  },
55
55
  {
56
56
  "value": "less",
57
- "label": "LESS [ http://lesscss.org ]"
57
+ "label": "LESS [ https://lesscss.org ]"
58
58
  },
59
59
  {
60
60
  "value": "styled-components",
@@ -1,7 +1,7 @@
1
1
  export interface Schema {
2
2
  name: string;
3
3
  /**
4
- * @deprecated Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18.
4
+ * @deprecated Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v19.
5
5
  */
6
6
  project?: string;
7
7
  directory?: string;
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "cli": "nx",
4
4
  "$id": "redux",
5
5
  "title": "Create Redux state",
@@ -22,7 +22,7 @@
22
22
  "$default": {
23
23
  "$source": "projectName"
24
24
  },
25
- "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v18."
25
+ "x-deprecated": "Provide the `directory` option instead and use the `as-provided` format. The project will be determined from the directory provided. It will be removed in Nx v19."
26
26
  },
27
27
  "directory": {
28
28
  "type": "string",
@@ -11,6 +11,7 @@ const setup_ssr_1 = require("../setup-ssr/setup-ssr");
11
11
  const setup_ssr_for_remote_1 = require("./lib/setup-ssr-for-remote");
12
12
  const setup_tspath_for_remote_1 = require("./lib/setup-tspath-for-remote");
13
13
  const add_remote_to_dynamic_host_1 = require("./lib/add-remote-to-dynamic-host");
14
+ const add_mf_env_to_inputs_1 = require("../../utils/add-mf-env-to-inputs");
14
15
  function addModuleFederationFiles(host, options) {
15
16
  const templateVariables = {
16
17
  ...(0, devkit_1.names)(options.name),
@@ -46,6 +47,8 @@ async function remoteGeneratorInternal(host, schema) {
46
47
  ...(await (0, normalize_options_1.normalizeOptions)(host, schema, '@nx/react:remote')),
47
48
  typescriptConfiguration: schema.typescriptConfiguration ?? false,
48
49
  dynamic: schema.dynamic ?? false,
50
+ // TODO(colum): remove when MF works with Crystal
51
+ addPlugin: false,
49
52
  };
50
53
  const initAppTask = await (0, application_1.default)(host, {
51
54
  ...options,
@@ -85,6 +88,7 @@ async function remoteGeneratorInternal(host, schema) {
85
88
  const pathToMFManifest = (0, devkit_1.joinPathFragments)(hostConfig.sourceRoot, 'assets/module-federation.manifest.json');
86
89
  (0, add_remote_to_dynamic_host_1.addRemoteToDynamicHost)(host, options.name, options.devServerPort, pathToMFManifest);
87
90
  }
91
+ (0, add_mf_env_to_inputs_1.addMfEnvToTargetDefaultInputs)(host);
88
92
  if (!options.skipFormat) {
89
93
  await (0, devkit_1.formatFiles)(host);
90
94
  }
@@ -1,6 +1,6 @@
1
1
  import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
2
2
  import type { Linter } from '@nx/eslint';
3
- import type { SupportedStyles } from '../../../typings';
3
+ import type { SupportedStyles } from '../../../typings/style';
4
4
  import type { NormalizedSchema as ApplicationNormalizedSchema } from '../application/schema';
5
5
 
6
6
  export interface Schema {
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "GeneratorReactRemote",
4
4
  "cli": "nx",
5
5
  "title": "Generate Module Federation Setup for React Remote App",
@@ -49,11 +49,11 @@
49
49
  },
50
50
  {
51
51
  "value": "scss",
52
- "label": "SASS(.scss) [ http://sass-lang.com ]"
52
+ "label": "SASS(.scss) [ https://sass-lang.com ]"
53
53
  },
54
54
  {
55
55
  "value": "less",
56
- "label": "LESS [ http://lesscss.org ]"
56
+ "label": "LESS [ https://lesscss.org ]"
57
57
  },
58
58
  {
59
59
  "value": "styled-components",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "GeneratorReactSSRSetup",
4
4
  "cli": "nx",
5
5
  "title": "Generate SSR setup for a React app",
@@ -18,7 +18,14 @@ function readEntryFile(host, path) {
18
18
  };
19
19
  }
20
20
  async function setupSsrGenerator(tree, options) {
21
- const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
21
+ let projectGraph;
22
+ try {
23
+ projectGraph = (0, devkit_1.readCachedProjectGraph)();
24
+ }
25
+ catch {
26
+ projectGraph = await (0, devkit_1.createProjectGraphAsync)();
27
+ }
28
+ const projectConfig = projectGraph.nodes[options.project].data;
22
29
  const projectRoot = projectConfig.root;
23
30
  const appImportCandidates = [
24
31
  options.appComponentImportPath ?? 'app/app',
@@ -42,11 +49,15 @@ async function setupSsrGenerator(tree, options) {
42
49
  if (projectConfig.targets.server) {
43
50
  throw new Error(`Project ${options.project} already has a server target.`);
44
51
  }
45
- const originalOutputPath = projectConfig.targets.build?.options?.outputPath;
52
+ const originalOutputPath = projectConfig.targets.build?.options?.outputPath ??
53
+ projectConfig.targets.build?.outputs[0];
46
54
  if (!originalOutputPath) {
47
55
  throw new Error(`Project ${options.project} does not contain a outputPath for the build target.`);
48
56
  }
49
- projectConfig.targets.build.options.outputPath = (0, devkit_1.joinPathFragments)(originalOutputPath, 'browser');
57
+ // TODO(colum): We need to figure out how to handle this for Crystal
58
+ if (projectConfig.targets.build.options?.outputPath) {
59
+ projectConfig.targets.build.options.outputPath = (0, devkit_1.joinPathFragments)(originalOutputPath, 'browser');
60
+ }
50
61
  projectConfig.targets = {
51
62
  ...projectConfig.targets,
52
63
  server: {
@@ -136,7 +147,8 @@ async function setupSsrGenerator(tree, options) {
136
147
  ? `"${options.extraInclude.join('", "')}",`
137
148
  : '',
138
149
  appComponentImport: appComponentInfo.importPath,
139
- browserBuildOutputPath: projectConfig.targets.build.options.outputPath,
150
+ browserBuildOutputPath: projectConfig.targets.build?.options?.outputPath ??
151
+ projectConfig.targets.build?.outputs[0],
140
152
  });
141
153
  // Add <StaticRouter> to server main if needed.
142
154
  // TODO: need to read main.server.tsx not main.tsx.
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "cli": "nx",
4
4
  "$id": "NxReactTailwindSetupGenerator",
5
5
  "title": "Configures Tailwind CSS for an application or a buildable/publishable library.",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "cli": "nx",
4
4
  "$id": "NxReactStorybookStories",
5
5
  "title": "Generate React Storybook stories",
@@ -11,11 +11,10 @@ const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescri
11
11
  const versions_1 = require("../../utils/versions");
12
12
  let tsModule;
13
13
  async function projectRootPath(tree, config) {
14
- const { findStorybookAndBuildTargetsAndCompiler } = await Promise.resolve().then(() => require('@nx/storybook/src/utils/utilities'));
15
14
  let projectDir;
16
15
  if (config.projectType === 'application') {
17
- const { nextBuildTarget } = findStorybookAndBuildTargetsAndCompiler(config.targets);
18
- if (!!nextBuildTarget) {
16
+ const isNextJs = await isNextJsProject(tree, config);
17
+ if (isNextJs) {
19
18
  // Next.js apps
20
19
  projectDir = 'components';
21
20
  }
@@ -115,4 +114,17 @@ async function storiesGenerator(host, schema) {
115
114
  return (0, devkit_1.runTasksInSerial)(...tasks);
116
115
  }
117
116
  exports.storiesGenerator = storiesGenerator;
117
+ async function isNextJsProject(tree, config) {
118
+ const { findStorybookAndBuildTargetsAndCompiler } = await Promise.resolve().then(() => require('@nx/storybook/src/utils/utilities'));
119
+ const { nextBuildTarget } = findStorybookAndBuildTargetsAndCompiler(config.targets);
120
+ if (nextBuildTarget) {
121
+ return true;
122
+ }
123
+ for (const configFile of ['next.config.js', 'next.config.ts']) {
124
+ if (tree.exists((0, path_1.join)(config.root, configFile))) {
125
+ return true;
126
+ }
127
+ }
128
+ return false;
129
+ }
118
130
  exports.default = storiesGenerator;
@@ -1,5 +1,6 @@
1
1
  import { StorybookConfigureSchema } from './schema';
2
2
  import { Tree } from '@nx/devkit';
3
3
  export declare function storybookConfigurationGenerator(host: Tree, schema: StorybookConfigureSchema): Promise<import("@nx/devkit").GeneratorCallback>;
4
+ export declare function storybookConfigurationGeneratorInternal(host: Tree, schema: StorybookConfigureSchema): Promise<import("@nx/devkit").GeneratorCallback>;
4
5
  export default storybookConfigurationGenerator;
5
6
  export declare function findWebpackConfig(tree: Tree, projectRoot: string): string | undefined;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findWebpackConfig = exports.storybookConfigurationGenerator = void 0;
3
+ exports.findWebpackConfig = exports.storybookConfigurationGeneratorInternal = exports.storybookConfigurationGenerator = void 0;
4
4
  const stories_1 = require("../stories/stories");
5
5
  const devkit_1 = require("@nx/devkit");
6
6
  const versions_1 = require("../../utils/versions");
7
7
  async function generateStories(host, schema) {
8
- // TODO(katerina): Nx 18 -> remove Cypress
8
+ // TODO(katerina): Nx 19 -> remove Cypress
9
9
  (0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
10
10
  const { getE2eProjectName } = await Promise.resolve().then(() => require('@nx/cypress/src/utils/project-name'));
11
11
  const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.project);
@@ -20,13 +20,22 @@ async function generateStories(host, schema) {
20
20
  interactionTests: schema.interactionTests ?? true,
21
21
  });
22
22
  }
23
- async function storybookConfigurationGenerator(host, schema) {
23
+ function storybookConfigurationGenerator(host, schema) {
24
+ return storybookConfigurationGeneratorInternal(host, {
25
+ addPlugin: false,
26
+ ...schema,
27
+ });
28
+ }
29
+ exports.storybookConfigurationGenerator = storybookConfigurationGenerator;
30
+ async function storybookConfigurationGeneratorInternal(host, schema) {
31
+ schema.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
24
32
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/storybook', versions_1.nxVersion);
25
33
  let uiFramework = '@storybook/react-vite';
26
34
  const projectConfig = (0, devkit_1.readProjectConfiguration)(host, schema.project);
27
35
  if (findWebpackConfig(host, projectConfig.root) ||
28
36
  projectConfig.targets['build']?.executor === '@nx/rollup:rollup' ||
29
- projectConfig.targets['build']?.executor === '@nrwl/rollup:rollup') {
37
+ projectConfig.targets['build']?.executor === '@nrwl/rollup:rollup' ||
38
+ projectConfig.targets['build']?.executor === '@nx/expo:build') {
30
39
  uiFramework = '@storybook/react-webpack5';
31
40
  }
32
41
  const installTask = await configurationGenerator(host, {
@@ -40,6 +49,7 @@ async function storybookConfigurationGenerator(host, schema) {
40
49
  configureStaticServe: schema.configureStaticServe,
41
50
  uiFramework: uiFramework, // cannot import UiFramework type dynamically
42
51
  skipFormat: true,
52
+ addPlugin: schema.addPlugin,
43
53
  });
44
54
  if (schema.generateStories) {
45
55
  await generateStories(host, schema);
@@ -47,7 +57,7 @@ async function storybookConfigurationGenerator(host, schema) {
47
57
  await (0, devkit_1.formatFiles)(host);
48
58
  return installTask;
49
59
  }
50
- exports.storybookConfigurationGenerator = storybookConfigurationGenerator;
60
+ exports.storybookConfigurationGeneratorInternal = storybookConfigurationGeneratorInternal;
51
61
  exports.default = storybookConfigurationGenerator;
52
62
  function findWebpackConfig(tree, projectRoot) {
53
63
  const allowsExt = ['js', 'mjs', 'ts', 'cjs', 'mts', 'cts'];
@@ -12,4 +12,5 @@ export interface StorybookConfigureSchema {
12
12
  configureCypress?: boolean;
13
13
  generateCypressSpecs?: boolean;
14
14
  cypressDirectory?: string;
15
+ addPlugin?: boolean;
15
16
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "cli": "nx",
4
4
  "$id": "NxReactStorybookConfigure",
5
5
  "title": "React Storybook Configure",
@@ -29,7 +29,7 @@
29
29
  "configureCypress": {
30
30
  "type": "boolean",
31
31
  "description": "Run the cypress-configure generator.",
32
- "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
32
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v19."
33
33
  },
34
34
  "generateStories": {
35
35
  "type": "boolean",
@@ -41,7 +41,7 @@
41
41
  "generateCypressSpecs": {
42
42
  "type": "boolean",
43
43
  "description": "Automatically generate test files in the Cypress E2E app generated by the `cypress-configure` generator.",
44
- "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
44
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v19."
45
45
  },
46
46
  "configureStaticServe": {
47
47
  "type": "boolean",
@@ -53,7 +53,7 @@
53
53
  "cypressDirectory": {
54
54
  "type": "string",
55
55
  "description": "A directory where the Cypress project will be placed. Placed at the root by default.",
56
- "x-deprecated": "Use interactionTests instead. This option will be removed in v18."
56
+ "x-deprecated": "Use interactionTests instead. This option will be removed in v19."
57
57
  },
58
58
  "js": {
59
59
  "type": "boolean",
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const add_mf_env_to_inputs_1 = require("../../utils/add-mf-env-to-inputs");
5
+ async function default_1(tree) {
6
+ if (!hasModuleFederationProject(tree)) {
7
+ return;
8
+ }
9
+ (0, add_mf_env_to_inputs_1.addMfEnvToTargetDefaultInputs)(tree);
10
+ await (0, devkit_1.formatFiles)(tree);
11
+ }
12
+ exports.default = default_1;
13
+ function hasModuleFederationProject(tree) {
14
+ const projects = (0, devkit_1.getProjects)(tree);
15
+ for (const project of projects.values()) {
16
+ const targets = project.targets;
17
+ for (const [_, target] of Object.entries(targets)) {
18
+ if (target.executor === '@nx/webpack:webpack' &&
19
+ (tree.exists((0, devkit_1.joinPathFragments)(project.root, 'module-federation.config.ts')) ||
20
+ tree.exists((0, devkit_1.joinPathFragments)(project.root, 'module-federation.config.js')))) {
21
+ return true;
22
+ }
23
+ }
24
+ }
25
+ return false;
26
+ }
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withModuleFederationForSSR = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  async function withModuleFederationForSSR(options) {
6
+ if (global.NX_GRAPH_CREATION) {
7
+ return (config) => config;
8
+ }
6
9
  const { sharedLibraries, sharedDependencies, mappedRemotes } = await (0, utils_1.getModuleFederationConfig)(options, {
7
10
  isServer: true,
8
11
  });
@@ -9,6 +9,9 @@ const isVarOrWindow = (libType) => libType === 'var' || libType === 'window';
9
9
  * @return {Promise<AsyncNxComposableWebpackPlugin>}
10
10
  */
11
11
  async function withModuleFederation(options) {
12
+ if (global.NX_GRAPH_CREATION) {
13
+ return (config) => config;
14
+ }
12
15
  const { sharedDependencies, sharedLibraries, mappedRemotes } = await (0, utils_1.getModuleFederationConfig)(options);
13
16
  const isGlobal = isVarOrWindow(options.library?.type);
14
17
  return (config, ctx) => {
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export declare function addMfEnvToTargetDefaultInputs(tree: Tree): void;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addMfEnvToTargetDefaultInputs = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ function addMfEnvToTargetDefaultInputs(tree) {
6
+ const nxJson = (0, devkit_1.readNxJson)(tree);
7
+ const webpackExecutor = '@nx/webpack:webpack';
8
+ const mfEnvVar = 'NX_MF_DEV_SERVER_STATIC_REMOTES';
9
+ nxJson.targetDefaults ??= {};
10
+ nxJson.targetDefaults[webpackExecutor] ??= {};
11
+ nxJson.targetDefaults[webpackExecutor].inputs ??= [];
12
+ let mfEnvVarExists = false;
13
+ for (const input of nxJson.targetDefaults[webpackExecutor].inputs) {
14
+ if (typeof input === 'object' && input['env'] === mfEnvVar) {
15
+ mfEnvVarExists = true;
16
+ break;
17
+ }
18
+ }
19
+ if (!mfEnvVarExists) {
20
+ nxJson.targetDefaults[webpackExecutor].inputs.push({ env: mfEnvVar });
21
+ (0, devkit_1.updateNxJson)(tree, nxJson);
22
+ }
23
+ }
24
+ exports.addMfEnvToTargetDefaultInputs = addMfEnvToTargetDefaultInputs;
@@ -1,9 +1,14 @@
1
1
  import { Tree } from '@nx/devkit';
2
2
  import { type FoundTarget } from '@nx/cypress/src/utils/find-target-options';
3
- export declare function addCTTargetWithBuildTarget(tree: Tree, options: {
3
+ export declare function configureCypressCT(tree: Tree, options: {
4
4
  project: string;
5
5
  buildTarget: string;
6
+ bundler: 'vite' | 'webpack';
6
7
  validExecutorNames: Set<string>;
7
8
  }): Promise<FoundTarget>;
8
9
  export declare function getBundlerFromTarget(found: FoundTarget, tree: Tree): Promise<'vite' | 'webpack'>;
10
+ export declare function getActualBundler(tree: Tree, options: {
11
+ buildTarget?: string;
12
+ bundler?: 'vite' | 'webpack';
13
+ }, found: FoundTarget): Promise<"vite" | "webpack">;
9
14
  export declare function isComponent(tree: Tree, filePath: string): boolean;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isComponent = exports.getBundlerFromTarget = exports.addCTTargetWithBuildTarget = void 0;
3
+ exports.isComponent = exports.getActualBundler = exports.getBundlerFromTarget = exports.configureCypressCT = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
6
6
  const ast_utils_1 = require("./ast-utils");
7
7
  let tsModule;
8
8
  const allowedFileExt = new RegExp(/\.[jt]sx?/);
9
9
  const isSpecFile = new RegExp(/(spec|test)\./);
10
- async function addCTTargetWithBuildTarget(tree, options) {
10
+ async function configureCypressCT(tree, options) {
11
11
  let found = { target: options.buildTarget, config: undefined };
12
12
  // Specifically undefined as a workaround for Remix to pass an empty string as the buildTarget
13
13
  if (options.buildTarget === undefined) {
@@ -19,16 +19,29 @@ async function addCTTargetWithBuildTarget(tree, options) {
19
19
  });
20
20
  assertValidConfig(found?.config);
21
21
  }
22
- const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
23
- projectConfig.targets['component-test'].options = {
24
- ...projectConfig.targets['component-test'].options,
25
- devServerTarget: found.target,
26
- skipServe: true,
22
+ const { addDefaultCTConfig, getProjectCypressConfigPath } = await Promise.resolve().then(() => require('@nx/cypress/src/utils/config'));
23
+ const ctConfigOptions = {
24
+ bundler: options.bundler ?? (await getActualBundler(tree, options, found)),
27
25
  };
28
- (0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
26
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
27
+ if (projectConfig.targets?.['component-test']?.executor ===
28
+ '@nx/cypress:cypress') {
29
+ projectConfig.targets['component-test'].options = {
30
+ ...projectConfig.targets['component-test'].options,
31
+ devServerTarget: found.target,
32
+ skipServe: true,
33
+ };
34
+ (0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
35
+ }
36
+ else {
37
+ ctConfigOptions.buildTarget = found.target;
38
+ }
39
+ const cypressConfigFilePath = getProjectCypressConfigPath(tree, projectConfig.root);
40
+ const updatedCyConfig = await addDefaultCTConfig(tree.read(cypressConfigFilePath, 'utf-8'), ctConfigOptions);
41
+ tree.write(cypressConfigFilePath, `import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing';\n${updatedCyConfig}`);
29
42
  return found;
30
43
  }
31
- exports.addCTTargetWithBuildTarget = addCTTargetWithBuildTarget;
44
+ exports.configureCypressCT = configureCypressCT;
32
45
  function assertValidConfig(config) {
33
46
  if (!config) {
34
47
  throw new Error('Unable to find a valid build configuration. Try passing in a target for an app. --build-target=<project>:<target>[:<configuration>]');
@@ -49,6 +62,14 @@ async function getBundlerFromTarget(found, tree) {
49
62
  : 'webpack';
50
63
  }
51
64
  exports.getBundlerFromTarget = getBundlerFromTarget;
65
+ async function getActualBundler(tree, options, found) {
66
+ // Specifically undefined to allow Remix workaround of passing an empty string
67
+ const actualBundler = options.buildTarget !== undefined && options.bundler
68
+ ? options.bundler
69
+ : await getBundlerFromTarget(found, tree);
70
+ return actualBundler;
71
+ }
72
+ exports.getActualBundler = getActualBundler;
52
73
  function isComponent(tree, filePath) {
53
74
  if (!tsModule) {
54
75
  tsModule = (0, ensure_typescript_1.ensureTypescript)();