@nx/angular 21.1.2 → 21.2.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 (271) hide show
  1. package/README.md +4 -4
  2. package/fesm2022/nx-angular-mf.mjs +10 -3
  3. package/fesm2022/nx-angular-mf.mjs.map +1 -1
  4. package/fesm2022/nx-angular.mjs.map +1 -1
  5. package/index.d.ts +2 -1
  6. package/mf/index.d.ts +71 -1
  7. package/migrations.json +106 -0
  8. package/ng-package.json +0 -1
  9. package/package.json +28 -16
  10. package/plugins/component-testing.js +8 -3
  11. package/src/builders/dev-server/dev-server.impl.js +4 -7
  12. package/src/builders/dev-server/lib/normalize-options.js +0 -6
  13. package/src/builders/dev-server/lib/validate-options.js +0 -4
  14. package/src/builders/dev-server/schema.d.ts +3 -15
  15. package/src/builders/dev-server/schema.json +3 -9
  16. package/src/builders/webpack-browser/webpack-browser.impl.js +2 -0
  17. package/src/builders/webpack-server/webpack-server.impl.d.ts +3 -1
  18. package/src/builders/webpack-server/webpack-server.impl.js +2 -0
  19. package/src/executors/application/application.impl.d.ts +2 -2
  20. package/src/executors/application/application.impl.js +11 -6
  21. package/src/executors/application/schema.d.ts +1 -1
  22. package/src/executors/application/schema.json +21 -10
  23. package/src/executors/application/utils/normalize-options.js +8 -1
  24. package/src/executors/application/utils/validate-options.js +10 -40
  25. package/src/executors/extract-i18n/extract-i18n.impl.js +6 -14
  26. package/src/executors/extract-i18n/schema.d.ts +1 -6
  27. package/src/executors/extract-i18n/schema.json +5 -0
  28. package/src/executors/extract-i18n/utils/validate-options.d.ts +2 -0
  29. package/src/executors/extract-i18n/utils/validate-options.js +13 -0
  30. package/src/executors/module-federation-dev-server/lib/normalize-options.js +1 -7
  31. package/src/executors/module-federation-dev-server/schema.d.ts +3 -15
  32. package/src/executors/module-federation-dev-server/schema.json +2 -15
  33. package/src/executors/module-federation-ssr-dev-server/module-federation-ssr-dev-server.impl.js +10 -8
  34. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/entry-point.d.ts +6 -3
  35. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/entry-point.js +46 -8
  36. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.di.d.ts +1 -1
  37. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.di.js +3 -3
  38. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.transform.d.ts +2 -2
  39. package/src/executors/ng-packagr-lite/ng-packagr-adjustments/ng-package/entry-point/write-bundles.transform.js +36 -7
  40. package/src/executors/ng-packagr-lite/schema.json +2 -3
  41. package/src/executors/package/package.impl.js +1 -5
  42. package/src/executors/package/schema.d.ts +3 -1
  43. package/src/executors/package/schema.json +2 -3
  44. package/src/executors/utilities/builder-package.d.ts +1 -0
  45. package/src/executors/utilities/builder-package.js +11 -0
  46. package/src/executors/utilities/esbuild-extensions.d.ts +2 -1
  47. package/src/executors/utilities/ng-packagr/package-imports.d.ts +3 -1
  48. package/src/executors/utilities/ng-packagr/package-imports.js +2 -2
  49. package/src/executors/utilities/ng-packagr/pre-v19/stylesheet-processor.d.ts +2 -24
  50. package/src/executors/utilities/ng-packagr/pre-v19/stylesheet-processor.js +40 -107
  51. package/src/executors/utilities/ng-packagr/stylesheet-processor.di.js +4 -8
  52. package/src/executors/utilities/ng-packagr/v19+/stylesheet-processor.d.ts +1 -1
  53. package/src/executors/utilities/ng-packagr/v19+/stylesheet-processor.js +18 -11
  54. package/src/generators/add-linting/add-linting.js +8 -0
  55. package/src/generators/application/application.js +22 -8
  56. package/src/generators/application/files/base/tsconfig.app.json__tpl__ +10 -1
  57. package/src/generators/application/files/base/tsconfig.json__tpl__ +7 -8
  58. package/src/generators/application/files/ng-module/src/app/app__componentFileSuffix__.spec.ts__tpl__ +28 -0
  59. package/src/generators/application/files/ng-module/src/app/{app.component.ts__tpl__ → app__componentFileSuffix__.ts__tpl__} +4 -4
  60. package/src/generators/application/files/ng-module/src/app/app__moduleTypeSeparator__module.ts__tpl__ +17 -0
  61. package/src/generators/application/files/ng-module/src/main.ts__tpl__ +11 -3
  62. package/src/generators/application/files/nx-welcome/claimed/ng-module/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  63. package/src/generators/application/files/nx-welcome/claimed/standalone/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  64. package/src/generators/application/files/nx-welcome/not-configured/ng-module/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  65. package/src/generators/application/files/nx-welcome/not-configured/standalone/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  66. package/src/generators/application/files/nx-welcome/unclaimed/ng-module/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  67. package/src/generators/application/files/nx-welcome/unclaimed/standalone/src/app/{nx-welcome.component.ts__tpl__ → nx-welcome__componentFileSuffix__.ts__tpl__} +1 -1
  68. package/src/generators/application/files/standalone-components/src/app/app.config.ts__tpl__ +6 -2
  69. package/src/generators/application/files/standalone-components/src/app/app__componentFileSuffix__.spec.ts__tpl__ +27 -0
  70. package/src/generators/application/files/standalone-components/src/app/{app.component.ts__tpl__ → app__componentFileSuffix__.ts__tpl__} +6 -6
  71. package/src/generators/application/files/standalone-components/src/main.ts__tpl__ +2 -2
  72. package/src/generators/application/lib/create-files.d.ts +1 -1
  73. package/src/generators/application/lib/create-files.js +18 -19
  74. package/src/generators/application/lib/create-project.d.ts +1 -1
  75. package/src/generators/application/lib/create-project.js +119 -26
  76. package/src/generators/application/lib/enable-strict-type-checking.js +4 -2
  77. package/src/generators/application/lib/index.d.ts +1 -2
  78. package/src/generators/application/lib/index.js +1 -2
  79. package/src/generators/application/lib/set-generator-defaults.js +1 -0
  80. package/src/generators/application/lib/{update-editor-tsconfig.d.ts → update-tsconfig-files.d.ts} +1 -1
  81. package/src/generators/application/lib/update-tsconfig-files.js +93 -0
  82. package/src/generators/application/schema.json +1 -1
  83. package/src/generators/component/component.js +13 -2
  84. package/src/generators/component/files/__fileName__.ts__tpl__ +1 -1
  85. package/src/generators/component/lib/component.js +11 -1
  86. package/src/generators/component/lib/module.d.ts +7 -2
  87. package/src/generators/component/lib/module.js +7 -5
  88. package/src/generators/component/lib/normalize-options.js +7 -3
  89. package/src/generators/component/schema.d.ts +1 -0
  90. package/src/generators/component/schema.json +6 -2
  91. package/src/generators/convert-to-application-executor/convert-to-application-executor.js +37 -24
  92. package/src/generators/convert-to-rspack/convert-to-rspack.d.ts +1 -1
  93. package/src/generators/convert-to-rspack/convert-to-rspack.js +173 -28
  94. package/src/generators/convert-to-rspack/lib/get-custom-webpack-config.js +1 -1
  95. package/src/generators/directive/directive.js +1 -1
  96. package/src/generators/directive/lib/normalize-options.js +7 -2
  97. package/src/generators/directive/schema.d.ts +1 -0
  98. package/src/generators/directive/schema.json +10 -2
  99. package/src/generators/host/host.js +21 -1
  100. package/src/generators/host/schema.d.ts +1 -0
  101. package/src/generators/host/schema.json +7 -1
  102. package/src/generators/init/init.js +1 -1
  103. package/src/generators/library/files/base/tsconfig.json__tpl__ +5 -5
  104. package/src/generators/library/files/ng-module/src/index.ts__tpl__ +1 -1
  105. package/src/generators/library/files/standalone-components/src/lib/lib.routes.ts__tpl__ +2 -2
  106. package/src/generators/library/lib/add-standalone-component.js +1 -0
  107. package/src/generators/library/lib/create-files.js +10 -3
  108. package/src/generators/library/lib/normalize-options.d.ts +3 -3
  109. package/src/generators/library/lib/normalize-options.js +6 -1
  110. package/src/generators/library/lib/normalized-schema.d.ts +2 -0
  111. package/src/generators/library/lib/set-generator-defaults.js +1 -0
  112. package/src/generators/library/lib/update-tsconfig-files.d.ts +3 -0
  113. package/src/generators/library/lib/update-tsconfig-files.js +98 -0
  114. package/src/generators/library/library.js +19 -33
  115. package/src/generators/library-secondary-entry-point/files/src/index.ts__tmpl__ +1 -1
  116. package/src/generators/library-secondary-entry-point/lib/add-files.js +2 -1
  117. package/src/generators/library-secondary-entry-point/lib/normalize-options.d.ts +2 -2
  118. package/src/generators/library-secondary-entry-point/lib/normalize-options.js +3 -0
  119. package/src/generators/library-secondary-entry-point/schema.d.ts +1 -0
  120. package/src/generators/move/lib/update-module-name.js +17 -10
  121. package/src/generators/move/lib/update-secondary-entry-points.js +0 -3
  122. package/src/generators/ng-add/migrators/builders/angular-devkit-karma.migrator.js +1 -1
  123. package/src/generators/ng-add/migrators/projects/app.migrator.js +43 -8
  124. package/src/generators/ngrx/schema.json +3 -3
  125. package/src/generators/ngrx-root-store/lib/normalize-options.js +9 -2
  126. package/src/generators/pipe/lib/normalize-options.js +4 -0
  127. package/src/generators/pipe/pipe.js +1 -1
  128. package/src/generators/pipe/schema.d.ts +1 -0
  129. package/src/generators/pipe/schema.json +11 -2
  130. package/src/generators/remote/files/standalone/src/bootstrap.server.ts__tmpl__ +4 -4
  131. package/src/generators/remote/lib/update-ssr-setup.js +5 -0
  132. package/src/generators/remote/remote.js +23 -0
  133. package/src/generators/remote/schema.d.ts +1 -0
  134. package/src/generators/remote/schema.json +7 -1
  135. package/src/generators/scam/lib/convert-component-to-scam.js +1 -3
  136. package/src/generators/scam/lib/normalize-options.js +11 -3
  137. package/src/generators/scam/schema.d.ts +1 -0
  138. package/src/generators/scam/schema.json +1 -2
  139. package/src/generators/scam-directive/lib/convert-directive-to-scam.js +1 -3
  140. package/src/generators/scam-directive/lib/normalize-options.js +11 -2
  141. package/src/generators/scam-directive/schema.d.ts +2 -0
  142. package/src/generators/scam-directive/schema.json +10 -2
  143. package/src/generators/scam-pipe/lib/convert-pipe-to-scam.js +1 -3
  144. package/src/generators/scam-pipe/lib/normalize-options.js +8 -0
  145. package/src/generators/scam-pipe/schema.d.ts +2 -0
  146. package/src/generators/scam-pipe/schema.json +5 -0
  147. package/src/generators/setup-mf/files/entry-module-files/{entry.module.ts__tmpl__ → __entryModuleFileName__.ts__tmpl__} +4 -4
  148. package/src/generators/setup-mf/files/entry-module-files/entry.routes.ts__tmpl__ +2 -2
  149. package/src/generators/setup-mf/files/entry-module-files/{entry.component.ts__tmpl__ → entry__componentFileSuffix__.ts__tmpl__} +1 -1
  150. package/src/generators/setup-mf/files/host-files/__appFileName__.spec.ts__tmpl__ +43 -0
  151. package/src/generators/setup-mf/files/standalone-entry-component-files/entry.routes.ts__tmpl__ +2 -2
  152. package/src/generators/setup-mf/files/standalone-entry-component-files/{entry.component.ts__tmpl__ → entry__componentFileSuffix__.ts__tmpl__} +3 -3
  153. package/src/generators/setup-mf/files/ts-webpack/module-federation.config.ts__tmpl__ +1 -1
  154. package/src/generators/setup-mf/files/ts-webpack/tsconfig.lint.json__tmpl__ +1 -1
  155. package/src/generators/setup-mf/files/webpack/module-federation.config.js__tmpl__ +1 -1
  156. package/src/generators/setup-mf/lib/add-remote-entry.d.ts +2 -2
  157. package/src/generators/setup-mf/lib/add-remote-entry.js +9 -3
  158. package/src/generators/setup-mf/lib/add-remote-to-host.js +11 -1
  159. package/src/generators/setup-mf/lib/fix-bootstrap.d.ts +2 -2
  160. package/src/generators/setup-mf/lib/fix-bootstrap.js +4 -4
  161. package/src/generators/setup-mf/lib/generate-config.d.ts +2 -2
  162. package/src/generators/setup-mf/lib/generate-config.js +1 -0
  163. package/src/generators/setup-mf/lib/normalize-options.d.ts +1 -1
  164. package/src/generators/setup-mf/lib/normalize-options.js +13 -0
  165. package/src/generators/setup-mf/lib/remove-dead-code-from-remote.d.ts +2 -2
  166. package/src/generators/setup-mf/lib/remove-dead-code-from-remote.js +18 -14
  167. package/src/generators/setup-mf/lib/setup-host-if-dynamic.js +1 -5
  168. package/src/generators/setup-mf/lib/setup-tspath-for-remote.d.ts +2 -2
  169. package/src/generators/setup-mf/lib/setup-tspath-for-remote.js +1 -1
  170. package/src/generators/setup-mf/lib/update-host-app-routes.d.ts +2 -2
  171. package/src/generators/setup-mf/lib/update-host-app-routes.js +12 -9
  172. package/src/generators/setup-mf/lib/update-tsconfig.d.ts +2 -2
  173. package/src/generators/setup-mf/lib/update-tsconfig.js +5 -5
  174. package/src/generators/setup-mf/schema.d.ts +7 -0
  175. package/src/generators/setup-mf/setup-mf.d.ts +2 -2
  176. package/src/generators/setup-mf/setup-mf.js +16 -6
  177. package/src/generators/setup-ssr/files/v20+/application-builder/ngmodule-src/__main__ +1 -0
  178. package/src/generators/setup-ssr/files/v20+/application-builder/ngmodule-src/app/__rootModuleFileName__ +12 -0
  179. package/src/generators/setup-ssr/files/v20+/application-builder/ngmodule-src/app/app.routes.server.ts__tpl__ +8 -0
  180. package/src/generators/setup-ssr/files/v20+/application-builder/server/__serverFileName__ +66 -0
  181. package/src/generators/setup-ssr/files/v20+/application-builder/standalone-src/__main__ +7 -0
  182. package/src/generators/setup-ssr/files/v20+/application-builder/standalone-src/app/app.config.server.ts__tpl__ +12 -0
  183. package/src/generators/setup-ssr/files/v20+/application-builder/standalone-src/app/app.routes.server.ts__tpl__ +8 -0
  184. package/src/generators/setup-ssr/files/v20+/server-builder/ngmodule-src/__main__ +1 -0
  185. package/src/generators/setup-ssr/files/v20+/server-builder/ngmodule-src/app/__rootModuleFileName__ +14 -0
  186. package/src/generators/setup-ssr/files/v20+/server-builder/root/tsconfig.server.json.template +18 -0
  187. package/src/generators/setup-ssr/files/v20+/server-builder/server/__serverFileName__ +69 -0
  188. package/src/generators/setup-ssr/files/v20+/server-builder/standalone-src/__main__ +7 -0
  189. package/src/generators/setup-ssr/files/v20+/server-builder/standalone-src/app/app.config.server.ts.template +11 -0
  190. package/src/generators/setup-ssr/lib/add-dependencies.js +11 -8
  191. package/src/generators/setup-ssr/lib/add-hydration.js +10 -3
  192. package/src/generators/setup-ssr/lib/add-server-file.js +7 -2
  193. package/src/generators/setup-ssr/lib/generate-files.js +17 -4
  194. package/src/generators/setup-ssr/lib/generate-server-ts-config.js +32 -6
  195. package/src/generators/setup-ssr/lib/normalize-options.js +5 -3
  196. package/src/generators/setup-ssr/lib/update-project-config.js +5 -0
  197. package/src/generators/setup-ssr/lib/validate-options.js +2 -2
  198. package/src/generators/setup-ssr/schema.d.ts +1 -0
  199. package/src/generators/setup-ssr/schema.json +1 -1
  200. package/src/generators/utils/add-jest.js +6 -1
  201. package/src/generators/utils/app-components-info.d.ts +9 -0
  202. package/src/generators/utils/app-components-info.js +39 -0
  203. package/src/generators/utils/artifact-types.d.ts +3 -0
  204. package/src/generators/utils/artifact-types.js +33 -0
  205. package/src/generators/utils/assert-mf-utils.d.ts +1 -0
  206. package/src/generators/utils/assert-mf-utils.js +11 -0
  207. package/src/generators/utils/ensure-angular-dependencies.js +6 -3
  208. package/src/generators/utils/export-scam.d.ts +1 -0
  209. package/src/generators/utils/export-scam.js +1 -2
  210. package/src/generators/utils/find-module.js +18 -13
  211. package/src/generators/utils/storybook-ast/component-info.js +40 -24
  212. package/src/generators/utils/storybook-ast/module-info.d.ts +1 -1
  213. package/src/generators/utils/storybook-ast/module-info.js +3 -8
  214. package/src/generators/utils/testing.js +28 -28
  215. package/src/generators/utils/version-utils.js +2 -2
  216. package/src/generators/web-worker/lib/add-snippet.js +3 -3
  217. package/src/migrations/update-21-2-0/migrate-provide-server-rendering-import.d.ts +2 -0
  218. package/src/migrations/update-21-2-0/migrate-provide-server-rendering-import.js +110 -0
  219. package/src/migrations/update-21-2-0/replace-provide-server-routing.d.ts +2 -0
  220. package/src/migrations/update-21-2-0/replace-provide-server-routing.js +103 -0
  221. package/src/migrations/update-21-2-0/set-generator-defaults-for-previous-style-guide.d.ts +2 -0
  222. package/src/migrations/update-21-2-0/set-generator-defaults-for-previous-style-guide.js +47 -0
  223. package/src/migrations/update-21-2-0/update-angular-cli.d.ts +3 -0
  224. package/src/migrations/update-21-2-0/update-angular-cli.js +23 -0
  225. package/src/migrations/update-21-2-0/update-module-resolution.d.ts +2 -0
  226. package/src/migrations/update-21-2-0/update-module-resolution.js +45 -0
  227. package/src/plugins/plugin.js +22 -13
  228. package/src/utils/backward-compatible-versions.d.ts +2 -2
  229. package/src/utils/backward-compatible-versions.js +22 -19
  230. package/src/utils/nx-devkit/ast-utils.js +17 -3
  231. package/src/utils/nx-devkit/testing.js +9 -9
  232. package/src/utils/targets.d.ts +2 -1
  233. package/src/utils/targets.js +6 -0
  234. package/src/utils/versions.d.ts +4 -3
  235. package/src/utils/versions.js +5 -4
  236. package/mf/mf.d.ts +0 -69
  237. package/src/generators/application/files/base-pre18/src/favicon.ico +0 -0
  238. package/src/generators/application/files/ng-module/src/app/app.component.spec.ts__tpl__ +0 -29
  239. package/src/generators/application/files/ng-module/src/app/app.module.ts__tpl__ +0 -17
  240. package/src/generators/application/files/standalone-components/src/app/app.component.__style__ +0 -0
  241. package/src/generators/application/files/standalone-components/src/app/app.component.spec.ts__tpl__ +0 -28
  242. package/src/generators/application/lib/set-app-strict-default.d.ts +0 -2
  243. package/src/generators/application/lib/set-app-strict-default.js +0 -13
  244. package/src/generators/application/lib/update-editor-tsconfig.js +0 -21
  245. package/src/generators/library/lib/enable-strict-type-checking.d.ts +0 -7
  246. package/src/generators/library/lib/enable-strict-type-checking.js +0 -47
  247. package/src/generators/library/lib/update-tsconfig.d.ts +0 -3
  248. package/src/generators/library/lib/update-tsconfig.js +0 -36
  249. package/src/generators/setup-mf/files/host-files/app.component.spec.ts__tmpl__ +0 -47
  250. /package/src/generators/application/files/{base-18+ → base}/public/favicon.ico +0 -0
  251. /package/src/generators/application/files/{base-pre18/src/assets/.gitkeep__tpl__ → ng-module/src/app/app__componentFileSuffix__.__style__} +0 -0
  252. /package/src/generators/application/files/ng-module/src/app/{app.component.html__tpl__ → app__componentFileSuffix__.html__tpl__} +0 -0
  253. /package/src/generators/application/files/{ng-module/src/app/app.component.__style__ → standalone-components/src/app/app__componentFileSuffix__.__style__} +0 -0
  254. /package/src/generators/application/files/standalone-components/src/app/{app.component.html__tpl__ → app__componentFileSuffix__.html__tpl__} +0 -0
  255. /package/src/generators/component/files/{__fileName__.html__tpl__ → __fileName____ngext__.html__tpl__} +0 -0
  256. /package/src/generators/library/files/ng-module/src/lib/{__libFileName__.module.ts__tpl__ → __libFileName____moduleTypeSeparator__module.ts__tpl__} +0 -0
  257. /package/src/generators/library-secondary-entry-point/files/src/lib/{__fileName__.module.ts__tmpl__ → __fileName____moduleTypeSeparator__module.ts__tmpl__} +0 -0
  258. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/ngmodule-src/__main__ +0 -0
  259. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/ngmodule-src/app/__rootModuleFileName__ +0 -0
  260. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/ngmodule-src/app/app.routes.server.ts__tpl__ +0 -0
  261. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/server/__serverFileName__ +0 -0
  262. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/standalone-src/__main__ +0 -0
  263. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/standalone-src/app/app.config.server.ts__tpl__ +0 -0
  264. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder/standalone-src/app/app.routes.server.ts__tpl__ +0 -0
  265. /package/src/generators/setup-ssr/files/{v19+ → v19}/application-builder-common-engine/server/__serverFileName__ +0 -0
  266. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/ngmodule-src/__main__ +0 -0
  267. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/ngmodule-src/app/__rootModuleFileName__ +0 -0
  268. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/root/tsconfig.server.json.template +0 -0
  269. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/server/__serverFileName__ +0 -0
  270. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/standalone-src/__main__ +0 -0
  271. /package/src/generators/setup-ssr/files/{v19+ → v19}/server-builder/standalone-src/app/app.config.server.ts.template +0 -0
@@ -5,11 +5,13 @@ const devkit_1 = require("@nx/devkit");
5
5
  const path_1 = require("path");
6
6
  // Adapted from https://github.com/angular/angular-cli/blob/732aab5fa7e63618c89dfbbb6f78753f706d7014/packages/schematics/angular/utility/find-module.ts#L29
7
7
  // to match the logic from the Angular CLI component schematic.
8
- const moduleExt = '.module.ts';
9
- const routingModuleExt = '-routing.module.ts';
8
+ const MODULE_EXT = '.module.ts';
9
+ const ROUTING_MODULE_EXT = '-routing.module.ts';
10
10
  function findModuleFromOptions(tree, options, projectRoot) {
11
+ const moduleExt = options.moduleExt || MODULE_EXT;
12
+ const routingModuleExt = options.routingModuleExt || ROUTING_MODULE_EXT;
11
13
  if (!options.module) {
12
- return (0, devkit_1.normalizePath)(findModule(tree, options.directory, projectRoot));
14
+ return (0, devkit_1.normalizePath)(findModule(tree, options.directory, projectRoot, moduleExt, routingModuleExt));
13
15
  }
14
16
  else {
15
17
  const modulePath = (0, devkit_1.joinPathFragments)(options.directory, options.module);
@@ -32,7 +34,7 @@ function findModuleFromOptions(tree, options, projectRoot) {
32
34
  `${moduleBaseName}${moduleExt}`,
33
35
  ].map((x) => (0, devkit_1.joinPathFragments)(c, x));
34
36
  for (const sc of candidateFiles) {
35
- if (tree.isFile(sc)) {
37
+ if (tree.isFile(sc) && tree.read(sc, 'utf-8').includes('@NgModule')) {
36
38
  return (0, devkit_1.normalizePath)(sc);
37
39
  }
38
40
  }
@@ -41,7 +43,7 @@ function findModuleFromOptions(tree, options, projectRoot) {
41
43
  `Looked in the following directories:\n ${candidatesDirs.join('\n ')}`);
42
44
  }
43
45
  }
44
- function findModule(tree, generateDir, projectRoot) {
46
+ function findModule(tree, generateDir, projectRoot, moduleExt = MODULE_EXT, routingModuleExt = ROUTING_MODULE_EXT) {
45
47
  let dir = generateDir;
46
48
  const projectRootParent = (0, path_1.dirname)(projectRoot);
47
49
  while (dir !== projectRootParent) {
@@ -5,12 +5,16 @@ const devkit_1 = require("@nx/devkit");
5
5
  const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
6
6
  const selector_1 = require("../../utils/selector");
7
7
  const validations_1 = require("../../utils/validations");
8
+ const version_utils_1 = require("../../utils/version-utils");
8
9
  async function normalizeOptions(tree, options) {
9
- options.type ??= 'component';
10
+ const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
11
+ if (angularMajorVersion < 20) {
12
+ options.type ??= 'component';
13
+ }
10
14
  const { artifactName: name, directory, fileName, filePath, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(tree, {
11
15
  name: options.name,
12
16
  path: options.path,
13
- suffix: options.type ?? 'component',
17
+ suffix: options.type,
14
18
  allowedFileExtensions: ['ts'],
15
19
  fileExtension: 'ts',
16
20
  });
@@ -18,7 +22,7 @@ async function normalizeOptions(tree, options) {
18
22
  throw new Error(`The component name '${name}' cannot contain a slash as it must be a valid JS symbol. Please use a different name.`);
19
23
  }
20
24
  const { className } = (0, devkit_1.names)(name);
21
- const { className: suffixClassName } = (0, devkit_1.names)(options.type);
25
+ const suffixClassName = options.type ? (0, devkit_1.names)(options.type).className : '';
22
26
  const symbolName = `${className}${suffixClassName}`;
23
27
  (0, validations_1.validateClassName)(symbolName);
24
28
  const { prefix, root, sourceRoot } = (0, devkit_1.readProjectConfiguration)(tree, projectName);
@@ -17,6 +17,7 @@ export interface Schema {
17
17
  export?: boolean;
18
18
  exportDefault?: boolean;
19
19
  prefix?: string;
20
+ ngHtml?: boolean;
20
21
  skipFormat?: boolean;
21
22
  }
22
23
 
@@ -95,8 +95,7 @@
95
95
  },
96
96
  "type": {
97
97
  "type": "string",
98
- "description": "Adds a developer-defined type to the filename, in the format `name.type.ts`.",
99
- "default": "component"
98
+ "description": "Append a custom type to the component's filename. It defaults to 'component' for Angular versions below v20. For Angular v20 and above, no type is appended unless specified."
100
99
  },
101
100
  "export": {
102
101
  "type": "boolean",
@@ -109,6 +108,11 @@
109
108
  "default": false,
110
109
  "description": "Use default export for the component instead of a named export."
111
110
  },
111
+ "ngHtml": {
112
+ "type": "boolean",
113
+ "default": false,
114
+ "description": "Generate component template files with an '.ng.html' file extension instead of '.html'."
115
+ },
112
116
  "skipFormat": {
113
117
  "description": "Skip formatting files.",
114
118
  "type": "boolean",
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertToApplicationExecutor = convertToApplicationExecutor;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const posix_1 = require("node:path/posix");
6
- const semver_1 = require("semver");
7
6
  const targets_1 = require("../../utils/targets");
8
7
  const setup_ssr_1 = require("../setup-ssr/setup-ssr");
9
8
  const validations_1 = require("../utils/validations");
@@ -26,17 +25,16 @@ const redundantExecutors = new Set([
26
25
  '@nx/angular:webpack-server',
27
26
  ]);
28
27
  async function convertToApplicationExecutor(tree, options) {
29
- const { version: angularVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
30
28
  let didAnySucceed = false;
31
29
  if (options.project) {
32
30
  (0, validations_1.validateProject)(tree, options.project);
33
- didAnySucceed = await convertProjectTargets(tree, options.project, angularVersion, true);
31
+ didAnySucceed = await convertProjectTargets(tree, options.project, true);
34
32
  }
35
33
  else {
36
34
  const projects = (0, devkit_1.getProjects)(tree);
37
35
  for (const [projectName] of projects) {
38
36
  devkit_1.logger.info(`Converting project "${projectName}"...`);
39
- const success = await convertProjectTargets(tree, projectName, angularVersion);
37
+ const success = await convertProjectTargets(tree, projectName);
40
38
  if (success) {
41
39
  devkit_1.logger.info(`Project "${projectName}" converted successfully.`);
42
40
  }
@@ -52,7 +50,7 @@ async function convertToApplicationExecutor(tree, options) {
52
50
  }
53
51
  return didAnySucceed ? () => (0, devkit_1.installPackagesTask)(tree) : () => { };
54
52
  }
55
- async function convertProjectTargets(tree, projectName, angularVersion, isProvidedProject = false) {
53
+ async function convertProjectTargets(tree, projectName, isProvidedProject = false) {
56
54
  function warnIfProvided(message) {
57
55
  if (isProvidedProject) {
58
56
  devkit_1.logger.warn(message);
@@ -63,7 +61,7 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
63
61
  warnIfProvided(`The provided project "${projectName}" is not an application. Skipping conversion.`);
64
62
  return false;
65
63
  }
66
- const { buildTargetName, serverTargetName } = getTargetsToConvert(project.targets, angularVersion);
64
+ const { buildTargetName, serverTargetName } = getTargetsToConvert(project.targets);
67
65
  if (!buildTargetName) {
68
66
  warnIfProvided(`The provided project "${projectName}" does not have any targets using on of the ` +
69
67
  `'@angular-devkit/build-angular:browser', '@angular-devkit/build-angular:browser-esbuild', ` +
@@ -71,12 +69,20 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
71
69
  return false;
72
70
  }
73
71
  const useNxExecutor = project.targets[buildTargetName].executor.startsWith('@nx/angular:');
74
- const newExecutor = useNxExecutor
75
- ? '@nx/angular:application'
76
- : '@angular-devkit/build-angular:application';
72
+ let newExecutor;
73
+ if (useNxExecutor) {
74
+ newExecutor = '@nx/angular:application';
75
+ }
76
+ else {
77
+ const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
78
+ newExecutor =
79
+ angularMajorVersion >= 20
80
+ ? '@angular/build:application'
81
+ : '@angular-devkit/build-angular:application';
82
+ }
77
83
  const buildTarget = project.targets[buildTargetName];
78
84
  buildTarget.executor = newExecutor;
79
- if ((0, semver_1.gte)(angularVersion, '17.1.0') && buildTarget.outputs) {
85
+ if (buildTarget.outputs) {
80
86
  buildTarget.outputs = buildTarget.outputs.map((output) => output === '{options.outputPath}' ? '{options.outputPath.base}' : output);
81
87
  }
82
88
  for (const [, options] of (0, targets_1.allTargetOptions)(buildTarget)) {
@@ -94,10 +100,7 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
94
100
  options['polyfills'] = [options['polyfills']];
95
101
  }
96
102
  let outputPath = options['outputPath'];
97
- if ((0, semver_1.lt)(angularVersion, '17.1.0')) {
98
- options['outputPath'] = outputPath?.replace(/\/browser\/?$/, '');
99
- }
100
- else if (typeof outputPath === 'string') {
103
+ if (typeof outputPath === 'string') {
101
104
  if (!/\/browser\/?$/.test(outputPath)) {
102
105
  devkit_1.logger.warn(`The output location of the browser build has been updated from "${outputPath}" to ` +
103
106
  `"${(0, posix_1.join)(outputPath, 'browser')}". ` +
@@ -121,9 +124,6 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
121
124
  }
122
125
  }
123
126
  // Delete removed options
124
- if ((0, semver_1.lt)(angularVersion, '17.3.0')) {
125
- delete options['deployUrl'];
126
- }
127
127
  delete options['vendorChunk'];
128
128
  delete options['commonChunk'];
129
129
  delete options['resourcesOutputPath'];
@@ -145,18 +145,34 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
145
145
  }
146
146
  const browserTsConfigJson = (0, devkit_1.readJson)(tree, browserTsConfigPath);
147
147
  const serverTsConfigJson = (0, devkit_1.readJson)(tree, serverTsConfigPath);
148
+ const serverFiles = ['src/main.server.ts', 'src/server.ts'];
149
+ if (tree.exists((0, posix_1.join)(project.root, 'src/app/app.config.server.ts'))) {
150
+ serverFiles.push('src/app/app.config.server.ts');
151
+ }
148
152
  const files = new Set([
149
153
  ...(browserTsConfigJson.files ?? []),
150
154
  ...(serverTsConfigJson.files ?? []),
151
155
  ]);
152
- // Server file will be added later by the setup-ssr generator
156
+ // Server files will be added later if needed by the setup-ssr generator
153
157
  files.delete('server.ts');
154
- browserTsConfigJson.files = Array.from(files);
158
+ files.delete('src/server.ts');
159
+ files.delete('src/main.server.ts');
160
+ if (files.size) {
161
+ browserTsConfigJson.files = Array.from(files);
162
+ }
163
+ else if (browserTsConfigJson.files) {
164
+ delete browserTsConfigJson.files;
165
+ }
155
166
  browserTsConfigJson.compilerOptions ?? {};
156
167
  browserTsConfigJson.compilerOptions.types = Array.from(new Set([
157
168
  ...(browserTsConfigJson.compilerOptions.types ?? []),
158
169
  ...(serverTsConfigJson.compilerOptions?.types ?? []),
159
170
  ]));
171
+ if (browserTsConfigJson.exclude?.length) {
172
+ const normalizeExclude = (exclude) => exclude.startsWith('./') ? exclude.slice(2) : exclude;
173
+ browserTsConfigJson.exclude = browserTsConfigJson.exclude.filter((exclude) => !serverFiles.includes(normalizeExclude(exclude)));
174
+ }
175
+ (0, devkit_1.writeJson)(tree, browserTsConfigPath, browserTsConfigJson);
160
176
  // Delete server tsconfig
161
177
  tree.delete(serverTsConfigPath);
162
178
  }
@@ -189,11 +205,12 @@ async function convertProjectTargets(tree, projectName, angularVersion, isProvid
189
205
  (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
190
206
  return true;
191
207
  }
192
- function getTargetsToConvert(targets, angularVersion) {
208
+ function getTargetsToConvert(targets) {
193
209
  let buildTargetName;
194
210
  let serverTargetName;
195
211
  for (const target of Object.keys(targets)) {
196
212
  if (targets[target].executor === '@nx/angular:application' ||
213
+ targets[target].executor === '@angular/build:application' ||
197
214
  targets[target].executor === '@angular-devkit/build-angular:application') {
198
215
  devkit_1.logger.warn('The project is already using the application builder. Skipping conversion.');
199
216
  return {};
@@ -201,10 +218,6 @@ function getTargetsToConvert(targets, angularVersion) {
201
218
  // build target
202
219
  if (executorsToConvert.has(targets[target].executor)) {
203
220
  for (const [, options] of (0, targets_1.allTargetOptions)(targets[target])) {
204
- if ((0, semver_1.lt)(angularVersion, '17.3.0') && options.deployUrl) {
205
- devkit_1.logger.warn(`The project is using the "deployUrl" option which is not available in the application builder. Skipping conversion.`);
206
- return {};
207
- }
208
221
  if (options.customWebpackConfig) {
209
222
  devkit_1.logger.warn(`The project is using a custom webpack configuration which is not supported by the esbuild-based application executor. Skipping conversion.`);
210
223
  return {};
@@ -1,4 +1,4 @@
1
- import { type Tree, GeneratorCallback } from '@nx/devkit';
1
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
2
  import type { ConvertToRspackSchema } from './schema';
3
3
  export declare function convertToRspack(tree: Tree, schema: ConvertToRspackSchema): Promise<GeneratorCallback>;
4
4
  export default convertToRspack;
@@ -2,15 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertToRspack = convertToRspack;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
6
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
7
+ const enquirer_1 = require("enquirer");
8
+ const path_1 = require("path");
9
+ const posix_1 = require("path/posix");
5
10
  const versions_1 = require("../../utils/versions");
6
11
  const create_config_1 = require("./lib/create-config");
7
12
  const get_custom_webpack_config_1 = require("./lib/get-custom-webpack-config");
8
13
  const update_tsconfig_1 = require("./lib/update-tsconfig");
9
14
  const validate_supported_executor_1 = require("./lib/validate-supported-executor");
10
- const posix_1 = require("path/posix");
11
- const path_1 = require("path");
12
- const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
13
- const enquirer_1 = require("enquirer");
14
15
  const SUPPORTED_EXECUTORS = [
15
16
  '@angular-devkit/build-angular:browser',
16
17
  '@angular-devkit/build-angular:dev-server',
@@ -27,12 +28,7 @@ const RENAMED_OPTIONS = {
27
28
  ngswConfigPath: 'serviceWorker',
28
29
  };
29
30
  const DEFAULT_PORT = 4200;
30
- const REMOVED_OPTIONS = [
31
- 'buildOptimizer',
32
- 'buildTarget',
33
- 'browserTarget',
34
- 'publicHost',
35
- ];
31
+ const REMOVED_OPTIONS = ['buildOptimizer', 'buildTarget', 'browserTarget'];
36
32
  function normalizeFromProjectRoot(tree, path, projectRoot) {
37
33
  if (projectRoot === '.') {
38
34
  if (!path.startsWith('./')) {
@@ -169,10 +165,6 @@ function handleBuildTargetOptions(tree, options, newConfigurationOptions, root)
169
165
  customWebpackConfigPath = options.customWebpackConfig.path;
170
166
  delete options.customWebpackConfig;
171
167
  }
172
- if (options.outputs) {
173
- // handled by the Rspack inference plugin
174
- delete options.outputs;
175
- }
176
168
  for (const [key, value] of Object.entries(options)) {
177
169
  let optionName = key;
178
170
  let optionValue = key in PATH_NORMALIZER ? PATH_NORMALIZER[key](tree, value, root) : value;
@@ -252,8 +244,9 @@ async function convertToRspack(tree, schema) {
252
244
  root: project.root,
253
245
  };
254
246
  const configurationOptions = {};
255
- const buildTargetNames = [];
256
- const serveTargetNames = [];
247
+ let buildTarget;
248
+ let serveTarget;
249
+ const targetsToRemove = [];
257
250
  let customWebpackConfigPath;
258
251
  (0, validate_supported_executor_1.validateSupportedBuildExecutor)(Object.values(project.targets));
259
252
  let projectServePort = DEFAULT_PORT;
@@ -267,14 +260,15 @@ async function convertToRspack(tree, schema) {
267
260
  handleBuildTargetOptions(tree, configuration, configurationOptions[configurationName], project.root);
268
261
  }
269
262
  }
270
- buildTargetNames.push(targetName);
263
+ buildTarget = { name: targetName, config: target };
264
+ targetsToRemove.push(targetName);
271
265
  }
272
266
  else if (target.executor === '@angular-devkit/build-angular:server' ||
273
267
  target.executor === '@nx/angular:webpack-server') {
274
268
  createConfigOptions.ssr ??= {};
275
269
  createConfigOptions.ssr.entry ??= normalizeFromProjectRoot(tree, target.options.main, project.root);
276
270
  createConfigOptions.server = './src/main.server.ts';
277
- buildTargetNames.push(targetName);
271
+ targetsToRemove.push(targetName);
278
272
  }
279
273
  else if (target.executor === '@angular-devkit/build-angular:dev-server' ||
280
274
  target.executor === '@nx/angular:dev-server' ||
@@ -282,7 +276,7 @@ async function convertToRspack(tree, schema) {
282
276
  createConfigOptions.devServer = {};
283
277
  if (target.options) {
284
278
  handleDevServerTargetOptions(tree, target.options, createConfigOptions.devServer, project.root);
285
- if (target.options.port !== DEFAULT_PORT) {
279
+ if (target.options.port && target.options.port !== DEFAULT_PORT) {
286
280
  projectServePort = target.options.port;
287
281
  }
288
282
  }
@@ -293,7 +287,8 @@ async function convertToRspack(tree, schema) {
293
287
  handleDevServerTargetOptions(tree, configuration, configurationOptions[configurationName].devServer, project.root);
294
288
  }
295
289
  }
296
- serveTargetNames.push(targetName);
290
+ serveTarget = { name: targetName, config: target };
291
+ targetsToRemove.push(targetName);
297
292
  }
298
293
  else if (target.executor === '@angular-devkit/build-angular:prerender') {
299
294
  if (target.options) {
@@ -314,11 +309,11 @@ async function convertToRspack(tree, schema) {
314
309
  }
315
310
  }
316
311
  }
317
- buildTargetNames.push(targetName);
312
+ targetsToRemove.push(targetName);
318
313
  }
319
314
  else if (target.executor === '@angular-devkit/build-angular:app-shell') {
320
315
  createConfigOptions.appShell = true;
321
- buildTargetNames.push(targetName);
316
+ targetsToRemove.push(targetName);
322
317
  }
323
318
  }
324
319
  const customWebpackConfigInfo = customWebpackConfigPath
@@ -326,20 +321,169 @@ async function convertToRspack(tree, schema) {
326
321
  : undefined;
327
322
  (0, create_config_1.createConfig)(tree, createConfigOptions, configurationOptions, customWebpackConfigInfo?.normalizedPathToCustomWebpackConfig, customWebpackConfigInfo?.isWebpackConfigFunction);
328
323
  (0, update_tsconfig_1.updateTsconfig)(tree, project.root);
329
- for (const targetName of [...buildTargetNames, ...serveTargetNames]) {
324
+ for (const targetName of targetsToRemove) {
330
325
  delete project.targets[targetName];
331
326
  }
332
- if (projectServePort !== DEFAULT_PORT) {
333
- project.targets.serve ??= {};
334
- project.targets.serve.options ??= {};
335
- project.targets.serve.options.port = projectServePort;
336
- }
337
327
  (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
328
+ // ensure plugin is registered
338
329
  const { rspackInitGenerator } = (0, devkit_1.ensurePackage)('@nx/rspack', versions_1.nxVersion);
339
330
  await rspackInitGenerator(tree, {
340
331
  addPlugin: true,
341
332
  framework: 'angular',
342
333
  });
334
+ // find the inferred target names
335
+ const nxJson = (0, devkit_1.readNxJson)(tree);
336
+ let inferredBuildTargetName = 'build';
337
+ let inferredServeTargetName = 'serve';
338
+ const pluginRegistration = nxJson.plugins.find((p) => typeof p === 'string' ? false : p.plugin === '@nx/rspack/plugin');
339
+ if (pluginRegistration) {
340
+ inferredBuildTargetName =
341
+ pluginRegistration.options.buildTargetName ?? inferredBuildTargetName;
342
+ inferredServeTargetName =
343
+ pluginRegistration.options.serveTargetName ?? inferredServeTargetName;
344
+ }
345
+ if (buildTarget) {
346
+ // these are all replaced by the inferred task
347
+ delete buildTarget.config.options;
348
+ delete buildTarget.config.configurations;
349
+ delete buildTarget.config.defaultConfiguration;
350
+ delete buildTarget.config.executor;
351
+ const shouldOverrideInputs = (inputs) => {
352
+ if (!inputs?.length) {
353
+ return false;
354
+ }
355
+ if (inputs.length === 2) {
356
+ // check whether the existing inputs would match the inferred task
357
+ // inputs with the exception of the @rspack/cli external dependency
358
+ // which webpack tasks wouldn't have
359
+ const namedInputs = (0, get_named_inputs_1.getNamedInputs)(project.root, {
360
+ nxJsonConfiguration: nxJson,
361
+ configFiles: [],
362
+ workspaceRoot: devkit_1.workspaceRoot,
363
+ });
364
+ if ('production' in namedInputs) {
365
+ return !['production', '^production'].every((input) => inputs.includes(input));
366
+ }
367
+ return !['default', '^default'].every((input) => inputs.includes(input));
368
+ }
369
+ return true;
370
+ };
371
+ if (shouldOverrideInputs(buildTarget.config.inputs)) {
372
+ // keep existing inputs and add the @rspack/cli external dependency
373
+ buildTarget.config.inputs = [
374
+ ...buildTarget.config.inputs,
375
+ { externalDependencies: ['@rspack/cli'] },
376
+ ];
377
+ }
378
+ else {
379
+ delete buildTarget.config.inputs;
380
+ }
381
+ if (buildTarget.config.cache) {
382
+ delete buildTarget.config.cache;
383
+ }
384
+ if (buildTarget.config.dependsOn?.length === 1 &&
385
+ buildTarget.config.dependsOn[0] === `^${buildTarget.name}`) {
386
+ delete buildTarget.config.dependsOn;
387
+ }
388
+ else if (buildTarget.config.dependsOn) {
389
+ buildTarget.config.dependsOn = buildTarget.config.dependsOn.map((dep) => dep === `^${buildTarget.name}` ? `^${inferredBuildTargetName}` : dep);
390
+ }
391
+ const newOutputPath = (0, devkit_1.joinPathFragments)(project.root, createConfigOptions.outputPath.base);
392
+ const shouldOverrideOutputs = (outputs) => {
393
+ if (!outputs?.length) {
394
+ // this means the target was wrongly configured, so, we don't override
395
+ // anything and let the inferred outputs be used
396
+ return false;
397
+ }
398
+ if (outputs.length === 1) {
399
+ if (outputs[0] === '{options.outputPath}') {
400
+ // the inferred task output is created after the createConfig
401
+ // outputPath option, so we don't need to keep this
402
+ return false;
403
+ }
404
+ const normalizedOutputPath = outputs[0]
405
+ .replace('{workspaceRoot}/', '')
406
+ .replace('{projectRoot}', project.root)
407
+ .replace('{projectName}', '');
408
+ if (normalizedOutputPath === newOutputPath ||
409
+ normalizedOutputPath.replace(/\/browser\/?$/, '') === newOutputPath) {
410
+ return false;
411
+ }
412
+ }
413
+ return true;
414
+ };
415
+ const normalizeOutput = (path, workspaceRoot, projectRoot) => {
416
+ const fullProjectRoot = (0, path_1.resolve)(workspaceRoot, projectRoot);
417
+ const fullPath = (0, path_1.resolve)(workspaceRoot, path);
418
+ const pathRelativeToProjectRoot = (0, devkit_1.normalizePath)((0, path_1.relative)(fullProjectRoot, fullPath));
419
+ if (pathRelativeToProjectRoot.startsWith('..')) {
420
+ return (0, devkit_1.joinPathFragments)('{workspaceRoot}', (0, path_1.relative)(workspaceRoot, fullPath));
421
+ }
422
+ return (0, devkit_1.joinPathFragments)('{projectRoot}', pathRelativeToProjectRoot);
423
+ };
424
+ if (shouldOverrideOutputs(buildTarget.config.outputs)) {
425
+ buildTarget.config.outputs = buildTarget.config.outputs.map((output) => {
426
+ if (output === '{options.outputPath}') {
427
+ // the target won't have an outputPath option, so we replace it with the new output path
428
+ return normalizeOutput(newOutputPath, devkit_1.workspaceRoot, project.root);
429
+ }
430
+ const normalizedOutputPath = output
431
+ .replace('{workspaceRoot}/', '')
432
+ .replace('{projectRoot}', project.root)
433
+ .replace('{projectName}', '');
434
+ if (/\/browser\/?$/.test(normalizedOutputPath) &&
435
+ normalizedOutputPath.replace(/\/browser\/?$/, '') === newOutputPath) {
436
+ return normalizeOutput(newOutputPath, devkit_1.workspaceRoot, project.root);
437
+ }
438
+ return output;
439
+ });
440
+ }
441
+ else {
442
+ delete buildTarget.config.outputs;
443
+ }
444
+ if (buildTarget.config.syncGenerators?.length === 1 &&
445
+ buildTarget.config.syncGenerators[0] === '@nx/js:typescript-sync') {
446
+ delete buildTarget.config.syncGenerators;
447
+ }
448
+ else if (buildTarget.config.syncGenerators?.length) {
449
+ buildTarget.config.syncGenerators = Array.from(new Set([
450
+ ...buildTarget.config.syncGenerators,
451
+ '@nx/js:typescript-sync',
452
+ ]));
453
+ }
454
+ if (Object.keys(buildTarget.config).length) {
455
+ // there's extra target metadata left that wouldn't be inferred, we keep it
456
+ project.targets[inferredBuildTargetName] = buildTarget.config;
457
+ }
458
+ }
459
+ if (serveTarget) {
460
+ delete serveTarget.config.options;
461
+ delete serveTarget.config.configurations;
462
+ delete serveTarget.config.defaultConfiguration;
463
+ delete serveTarget.config.executor;
464
+ if (serveTarget.config.continuous) {
465
+ delete serveTarget.config.continuous;
466
+ }
467
+ if (serveTarget.config.syncGenerators?.length === 1 &&
468
+ serveTarget.config.syncGenerators[0] === '@nx/js:typescript-sync') {
469
+ delete serveTarget.config.syncGenerators;
470
+ }
471
+ else if (serveTarget.config.syncGenerators?.length) {
472
+ serveTarget.config.syncGenerators = Array.from(new Set([
473
+ ...serveTarget.config.syncGenerators,
474
+ '@nx/js:typescript-sync',
475
+ ]));
476
+ }
477
+ if (projectServePort !== DEFAULT_PORT) {
478
+ serveTarget.config.options = {};
479
+ serveTarget.config.options.port = projectServePort;
480
+ }
481
+ if (Object.keys(serveTarget.config).length) {
482
+ // there's extra target metadata left that wouldn't be inferred, we keep it
483
+ project.targets[inferredServeTargetName] = serveTarget.config;
484
+ }
485
+ }
486
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
343
487
  // This is needed to prevent a circular execution of the build target
344
488
  const rootPkgJson = (0, devkit_1.readJson)(tree, 'package.json');
345
489
  if (rootPkgJson.scripts?.build === 'nx build') {
@@ -349,6 +493,7 @@ async function convertToRspack(tree, schema) {
349
493
  if (!schema.skipInstall) {
350
494
  const installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
351
495
  '@nx/angular-rspack': versions_1.angularRspackVersion,
496
+ 'webpack-merge': versions_1.webpackMergeVersion,
352
497
  'ts-node': versions_1.tsNodeVersion,
353
498
  });
354
499
  tasks.push(installTask);
@@ -30,7 +30,7 @@ function convertWebpackConfigToUseNxModuleFederationPlugin(webpackConfigContents
30
30
  const withModuleFederationImportNodes = (0, tsquery_1.tsquery)(ast, 'ImportDeclaration:has(StringLiteral[value=@nx/module-federation/angular])');
31
31
  if (withModuleFederationImportNodes.length > 0) {
32
32
  const withModuleFederationImportNode = withModuleFederationImportNodes[0];
33
- newWebpackConfigContents = `${webpackConfigContents.slice(0, withModuleFederationImportNode.getStart())}import { NxModuleFederationPlugin, NxModuleFederationDevServerPlugin } from '@nx/module-federation/rspack';${webpackConfigContents.slice(withModuleFederationImportNode.getEnd())}`;
33
+ newWebpackConfigContents = `${webpackConfigContents.slice(0, withModuleFederationImportNode.getStart())}import { NxModuleFederationPlugin, NxModuleFederationDevServerPlugin } from '@nx/module-federation/angular';${webpackConfigContents.slice(withModuleFederationImportNode.getEnd())}`;
34
34
  ast = tsquery_1.tsquery.ast(newWebpackConfigContents);
35
35
  const exportedWithModuleFederationNodes = (0, tsquery_1.tsquery)(ast, 'ExportAssignment:has(CallExpression > Identifier[name=withModuleFederation])');
36
36
  if (exportedWithModuleFederationNodes.length > 0) {
@@ -13,7 +13,7 @@ async function directiveGenerator(tree, schema) {
13
13
  symbolName: options.symbolName,
14
14
  fileName: options.fileName,
15
15
  standalone: options.standalone,
16
- // Angular v19 or higher defaults to true, while v18 or lower defaults to false
16
+ // Angular v19 or higher defaults to true, while lower versions default to false
17
17
  setStandalone: (angularMajorVersion >= 19 && !options.standalone) ||
18
18
  (angularMajorVersion < 19 && options.standalone),
19
19
  tpl: '',
@@ -5,16 +5,21 @@ const devkit_1 = require("@nx/devkit");
5
5
  const artifact_name_and_directory_utils_1 = require("@nx/devkit/src/generators/artifact-name-and-directory-utils");
6
6
  const selector_1 = require("../../utils/selector");
7
7
  const validations_1 = require("../../utils/validations");
8
+ const version_utils_1 = require("../../utils/version-utils");
8
9
  async function normalizeOptions(tree, options) {
10
+ const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
11
+ if (angularMajorVersion < 20) {
12
+ options.type ??= 'directive';
13
+ }
9
14
  const { artifactName: name, directory, fileName, filePath, project: projectName, } = await (0, artifact_name_and_directory_utils_1.determineArtifactNameAndDirectoryOptions)(tree, {
10
15
  name: options.name,
11
16
  path: options.path,
12
- suffix: 'directive',
17
+ suffix: options.type,
13
18
  allowedFileExtensions: ['ts'],
14
19
  fileExtension: 'ts',
15
20
  });
16
21
  const { className } = (0, devkit_1.names)(name);
17
- const { className: suffixClassName } = (0, devkit_1.names)('directive');
22
+ const suffixClassName = options.type ? (0, devkit_1.names)(options.type).className : '';
18
23
  const symbolName = `${className}${suffixClassName}`;
19
24
  (0, validations_1.validateClassName)(symbolName);
20
25
  const { prefix } = (0, devkit_1.readProjectConfiguration)(tree, projectName);
@@ -8,6 +8,7 @@ export interface Schema {
8
8
  standalone?: boolean;
9
9
  module?: string;
10
10
  export?: boolean;
11
+ type?: string;
11
12
  skipFormat?: boolean;
12
13
  }
13
14
 
@@ -12,11 +12,15 @@
12
12
  "command": "nx g @nx/angular:directive mylib/src/lib/foo.directive.ts"
13
13
  },
14
14
  {
15
- "description": "Generate a directive without providing the file extension. It results in the directive `FooDirective` at `mylib/src/lib/foo.directive.ts`",
15
+ "description": "Generate a directive without providing the file extension. It results in the directive `Foo` at `mylib/src/lib/foo.ts`",
16
16
  "command": "nx g @nx/angular:directive mylib/src/lib/foo"
17
17
  },
18
18
  {
19
- "description": "Generate a directive with the exported symbol different from the file name. It results in the directive `CustomDirective` at `mylib/src/lib/foo.directive.ts`",
19
+ "description": "Generate a directive with a given type/suffix. It results in the directive `FooDirective` at `mylib/src/lib/foo.directive.ts`",
20
+ "command": "nx g @nx/angular:directive mylib/src/lib/foo --type=directive"
21
+ },
22
+ {
23
+ "description": "Generate a directive with the exported symbol different from the file name. It results in the directive `Custom` at `mylib/src/lib/foo.ts`",
20
24
  "command": "nx g @nx/angular:directive mylib/src/lib/foo --name=custom"
21
25
  }
22
26
  ],
@@ -78,6 +82,10 @@
78
82
  "default": false,
79
83
  "description": "The declaring NgModule exports this directive."
80
84
  },
85
+ "type": {
86
+ "type": "string",
87
+ "description": "Append a custom type to the directive's filename. It defaults to 'directive' for Angular versions below v20. For Angular v20 and above, no type is appended unless specified."
88
+ },
81
89
  "skipFormat": {
82
90
  "type": "boolean",
83
91
  "default": false,