Compare commits

...

36 Commits

Author SHA1 Message Date
Jason Jean ac802ed6db fix(repo): downgrade to macos-13 in publish workflow (#22961) 2024-04-29 12:50:07 -04:00
Jason Jean 63883a44a4 fix(core): fix changelog configuration (#20138) 2024-04-29 12:24:14 -04:00
Jason Jean d1c0272359 chore(repo): update nx to 17.1.0-beta.4 (#20124)
(cherry picked from commit c7d0d21761)
2024-04-29 12:19:10 -04:00
Leosvel Pérez Espinosa b46485f9be fix(angular): import rxjs operators from 'rxjs/operators' for backwards compatibility (#21417) 2024-04-04 11:31:39 -04:00
Jason Jean df252a6dc0 fix(repo): fix freebsd hanging issue (#20042)
(cherry picked from commit f28fc3bc84)
2023-11-03 16:13:08 -04:00
beeman 1877db6f64 fix(nx-plugin): move tests from 'tests' to 'src' directory (#19866)
(cherry picked from commit 0f7363e2de)
2023-11-03 16:13:05 -04:00
Jonathan Cammisuli c17da55c14 fix(core): properly sort all workspace files (#20013)
(cherry picked from commit 9c0e6a1a98)
2023-11-03 16:12:03 -04:00
Tine Kondo 17932150ba fix(plugins): change locally published packages version from 1.0.0 -> `0.0.0-e2e… (#20023)
(cherry picked from commit 00248aa85d)
2023-11-03 16:11:56 -04:00
Altan Stalker 3bf8cbdc62 chore(repo): remove stop-all-agents (#19967)
(cherry picked from commit 95ae6fd2a3)
2023-11-03 16:11:48 -04:00
Jason Jean 232db2ed49 fix(js): handle empty objects for migration to remove deprecated buil… (#19996)
(cherry picked from commit 61ad9c3d21)
2023-11-03 16:11:32 -04:00
Katerina Skroumpelou e2f155391e fix(vue): remove jest generators (#19997)
(cherry picked from commit 41f276b84e)
2023-11-02 11:31:38 -04:00
Nicholas Cunningham e665be4d4d fix(module-federation): refactor federate-module generator (#19979)
(cherry picked from commit 67f47c287a)
2023-11-01 18:37:05 -04:00
Craigory Coppola 83531de539 fix(core): ensure project order in graph is deterministic (#19968)
(cherry picked from commit c83afeb260)
2023-11-01 18:36:59 -04:00
Nicholas Cunningham 0e9993fcf1 fix(detox): Update jest transform to point to correct tsconfig (#19977)
(cherry picked from commit b32452ad3c)
2023-11-01 18:36:54 -04:00
Jason Jean f9c138ce76 chore(js): fix flaky assets test (#19966)
(cherry picked from commit 8fe80a5ea8)
2023-11-01 18:36:46 -04:00
Craigory Coppola ada1599219 fix(misc): create-nx-workspace should not log undefined for preset deprecation (#19960)
(cherry picked from commit 4dfa45ca24)
2023-11-01 18:36:39 -04:00
Craigory Coppola 5d32213b87 fix(misc): nx init should add .nx/cache to gitignore (#19961)
(cherry picked from commit 18f71d25e0)
2023-11-01 18:36:35 -04:00
Craigory Coppola 713bdf1d56 fix(core): generate should handle multiselect shorthand (#19790)
(cherry picked from commit 7db366b1be)
2023-11-01 18:36:31 -04:00
Colum Ferry 981b8eaf4d fix(angular): extract remotes from manifest correctly #19880 (#19894)
(cherry picked from commit 8ec589d0b9)
2023-11-01 18:36:23 -04:00
Nicholas Cunningham 4d35cc7d4f fix(nextjs): Setup Tailwind should work with nextjs app router (#19934)
(cherry picked from commit 23ef97e4ce)
2023-11-01 18:35:43 -04:00
Miroslav Jonaš 45c98676ce fix(linter): fix flat config migration (#19742)
(cherry picked from commit fc468a582b)
2023-11-01 18:35:40 -04:00
Miroslav Jonaš 5ab53625e2 fix(js): add dlx to pm commands (#19743)
(cherry picked from commit 936b814cd7)
2023-11-01 18:35:37 -04:00
Katerina Skroumpelou 75fd85f1e7 fix(vue): dont require project when generating component (#19885)
(cherry picked from commit c2aa6ef4f4)
2023-11-01 18:35:31 -04:00
Leosvel Pérez Espinosa d41a8e0df0 fix(angular): allow numbers following a dash in application prefix (#19926)
(cherry picked from commit 91c83cbd13)
2023-11-01 18:35:28 -04:00
Jonathan Cammisuli 36d9ca3365 chore(repo): fix publishing on freebsd (#19907)
(cherry picked from commit babb2e0569)
2023-11-01 18:35:22 -04:00
Emily Xiong 06dcc69d32 chore(misc): remove dependenciesFieldType from esbuild (#19883)
(cherry picked from commit e4d1ef3cf3)
2023-11-01 18:35:15 -04:00
Juri Strumpflohner b4b5dd7ed5 fix(nx-dev): mobile menu, adding ai chat and changelog (#19887)
(cherry picked from commit b897303815)
2023-11-01 18:35:05 -04:00
Nicholas Cunningham 574fe37d91 fix(react): Update types version so that there is no mismatch when using yarn (#19882)
(cherry picked from commit f9fc3dd42b)
2023-11-01 18:35:02 -04:00
Dan Roujinsky 377b70cd98 fix(js): add @babel/plugin-transform-class-properties to babel preset (#19818)
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
(cherry picked from commit 2ea9f18fad)
2023-11-01 18:34:59 -04:00
Jason Jean 2757bda2df fix(js): fix typescript analysis for imports in objects in arrays (#19862)
(cherry picked from commit bf97dbb2ba)
2023-11-01 18:34:53 -04:00
Katerina Skroumpelou a0cf68ec87 fix(vue): remove filter from cnw (#19879)
(cherry picked from commit a09ad2bd62)
2023-11-01 18:34:50 -04:00
Nicholas Cunningham 05893ff5d5 fix(js): should respect vitest test environment (#19859)
(cherry picked from commit 04e4e25db1)
2023-11-01 18:34:43 -04:00
Craigory Coppola 8951a7c3ab fix(core): package json configuration should never override project.json in generators (#19874)
(cherry picked from commit fe162290eb)
2023-11-01 18:34:32 -04:00
sonikasharma1403 8e6a4854e7 fix(js): add missing entry to migrations.json (#19869)
Co-authored-by: Sonika Sharma <sonikasharma@csod.com>
(cherry picked from commit 4a04ee44dd)
2023-11-01 18:34:28 -04:00
Jonathan Cammisuli fe1a82c9e4 fix(core): canonicalize watch event paths on all linux distros (#19848)
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
(cherry picked from commit a7e0abd3e4)
2023-11-01 18:34:22 -04:00
Emily Xiong b3ac4d5cfc fix(testing): add e2e for root project should not add eslintrc.base (#19860)
(cherry picked from commit f5f31ab979)
2023-11-01 18:34:13 -04:00
108 changed files with 1475 additions and 1350 deletions
-5
View File
@@ -161,11 +161,6 @@ jobs:
command: |
pnpm nx affected -t e2e-macos --parallel=1 --base=$NX_BASE --head=$NX_HEAD
no_output_timeout: 45m
- run:
name: Close CI group
command: |
pnpm nx-cloud stop-all-agents
no_output_timeout: 45m
# -------------------------
# WORKFLOWS(JOBS)
+20 -15
View File
@@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
settings:
- host: macos-latest
- host: macos-13
target: x86_64-apple-darwin
build: |
pnpm nx run-many --target=build-native -- --target=x86_64-apple-darwin
@@ -37,7 +37,7 @@ jobs:
target: x86_64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: set -e && pnpm nx run-many --target=build-native -- --target=x86_64-unknown-linux-musl
- host: macos-latest
- host: macos-13
target: aarch64-apple-darwin
build: |
sudo rm -Rf /Library/Developer/CommandLineTools/SDKs/*;
@@ -155,34 +155,35 @@ jobs:
build-freebsd:
runs-on: macos-12
name: Build FreeBSD
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- name: Build
id: build
uses: vmactions/freebsd-vm@v0
uses: cross-platform-actions/action@v0.21.0
env:
DEBUG: napi:*
RUSTUP_HOME: /usr/local/rustup
CARGO_HOME: /usr/local/cargo
RUSTUP_IO_THREADS: 1
with:
envs: DEBUG RUSTUP_HOME CARGO_HOME RUSTUP_IO_THREADS
usesh: true
mem: 4096
prepare: |
pkg install -y -f curl node libnghttp2 npm
npm install --location=global --ignore-scripts pnpm
operating_system: freebsd
version: '13.2'
architecture: x86-64
environment_variables: DEBUG RUSTUP_IO_THREADS CI
shell: bash
run: |
env
whoami
sudo pkg install -y -f node libnghttp2 npm git
sudo npm install --location=global --ignore-scripts pnpm
curl https://sh.rustup.rs -sSf --output rustup.sh
sh rustup.sh -y --profile minimal --default-toolchain stable
export PATH="/usr/local/cargo/bin:$PATH"
source "$HOME/.cargo/env"
echo "~~~~ rustc --version ~~~~"
rustc --version
echo "~~~~ node -v ~~~~"
node -v
echo "~~~~ pnpm --version ~~~~"
pnpm --version
run: |
export PATH="/usr/local/cargo/bin:$PATH"
pwd
ls -lah
whoami
@@ -191,9 +192,13 @@ jobs:
mkdir -p /Users/runner/work/_temp/_github_workflow
echo "{}" > /Users/runner/work/_temp/_github_workflow/event.json
pnpm install --frozen-lockfile --ignore-scripts
pnpm nx run-many --target=build-native -- --target=x86_64-unknown-freebsd
pnpm nx run-many --outputStyle stream --target=build-native -- --target=x86_64-unknown-freebsd
pnpm nx reset
rm -rf node_modules
rm -rf dist
echo "KILL ALL NODE PROCESSES"
killall node
echo "COMPLETE"
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
Generated
-10
View File
@@ -1353,7 +1353,6 @@ dependencies = [
"napi-build",
"napi-derive",
"once_cell",
"os_type",
"parking_lot",
"rayon",
"regex",
@@ -1380,15 +1379,6 @@ version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "os_type"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e24d44c0eea30167516ed8f6daca4b5e3eebcde1bde1e4e6e08b809fb02c7ba5"
dependencies = [
"regex",
]
[[package]]
name = "overload"
version = "0.1.1"
+1 -1
View File
@@ -139,7 +139,7 @@ Package manager to use
Type: `string`
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing
@@ -15,19 +15,19 @@
],
"type": "object",
"properties": {
"path": {
"type": "string",
"$default": { "$source": "argv", "index": 0 },
"description": "The path to locate the federated module.",
"x-prompt": "What is the path to the module to be federated?"
},
"name": {
"description": "The name of the module.",
"type": "string",
"$default": { "$source": "argv", "index": 0 },
"x-prompt": "What name would you like to use for the module?",
"pattern": "^[a-zA-Z][^:]*$",
"x-priority": "important"
},
"path": {
"type": "string",
"description": "The path to locate the federated module.",
"x-prompt": "What is the path to the module to be federated?"
},
"remote": {
"type": "string",
"description": "The name of the remote.",
@@ -155,12 +155,6 @@
"type": "boolean",
"description": "Includes third-party packages in the bundle (i.e. npm packages)."
},
"dependenciesFieldType": {
"type": "string",
"description": "When `bundleInternalProjectsOnly` is true, this option determines whether external packages should be in 'dependencies' or 'peerDependencies' field in the generated package.json file.",
"enum": ["dependencies", "peerDependencies"],
"default": "dependencies"
},
"esbuildOptions": {
"type": "object",
"description": "Additional options to pass to esbuild. See https://esbuild.github.io/api/. Cannot be used with 'esbuildConfig' option.",
@@ -139,7 +139,7 @@ Package manager to use
Type: `string`
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
Customizes the initial content of your workspace. Default presets include: ["apps", "empty", "core", "npm", "ts", "web-components", "angular-monorepo", "angular-standalone", "react-monorepo", "react-standalone", "vue-monorepo", "vue-standalone", "next", "nextjs-standalone", "react-native", "expo", "nest", "express", "react", "angular", "node-standalone", "node-monorepo", "ts-standalone"]. To build your own see https://nx.dev/extending-nx/recipes/create-preset
### routing
@@ -56,6 +56,13 @@
"default": false,
"description": "Do not add dependencies to `package.json`.",
"x-priority": "internal"
},
"rootProject": {
"description": "Create a application at the root of the workspace",
"type": "boolean",
"default": false,
"hidden": true,
"x-priority": "internal"
}
},
"required": ["project"],
@@ -15,19 +15,19 @@
],
"type": "object",
"properties": {
"path": {
"type": "string",
"$default": { "$source": "argv", "index": 0 },
"description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.",
"x-prompt": "What is the path to the module to be federated?"
},
"name": {
"description": "The name of the module.",
"type": "string",
"$default": { "$source": "argv", "index": 0 },
"x-prompt": "What name would you like to use for the module?",
"pattern": "^[a-zA-Z][^:]*$",
"x-priority": "important"
},
"path": {
"type": "string",
"description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.",
"x-prompt": "What is the path to the module to be federated?"
},
"remote": {
"type": "string",
"description": "The name of the remote.",
@@ -79,7 +79,7 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "vitest", "none"],
"enum": ["vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "vitest"
@@ -100,15 +100,9 @@
"type": "boolean",
"default": false,
"x-priority": "internal"
},
"unitTestRunner": {
"type": "string",
"enum": ["vitest", "jest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "What unit test runner should be used?"
}
},
"required": ["name", "project"],
"required": ["name"],
"presets": []
},
"aliases": ["c"],
@@ -46,7 +46,7 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["vitest", "jest", "none"],
"enum": ["vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "What unit test runner should be used?"
},
@@ -46,14 +46,14 @@ Now that we have created the module, we need to configure it to be federated.
{%tab label="React"%}
```shell
nx generate @nx/react:federate-module Hello --remote=greeting --path=hello/src/index.ts --projectNameAndRootFormat=as-provided
nx generate @nx/react:federate-module hello/src/index.ts --name=hello --remote=greeting --projectNameAndRootFormat=as-provided
```
{% /tab %}
{%tab label="Angular"%}
```shell
nx generate @nx/angular:federate-module Hello --remote=greeting --path=hello/src/index.ts --projectNameAndRootFormat=as-provided
nx generate @nx/angular:federate-module hello/src/index.ts --name=hello --remote=greeting --projectNameAndRootFormat=as-provided
```
{% /tab %}
@@ -326,7 +326,7 @@ describe('Angular Module Federation', () => {
// Federate Module
runCLI(
`generate @nx/angular:federate-module ${module} --remote=${remote} --path=${lib}/src/index.ts --no-interactive`
`generate @nx/angular:federate-module ${lib}/src/index.ts --name=${module} --remote=${remote} --no-interactive`
);
updateFile(`${lib}/src/index.ts`, `export { isEven } from './lib/${lib}';`);
@@ -403,7 +403,7 @@ describe('Angular Module Federation', () => {
// Federate Module
runCLI(
`generate @nx/angular:federate-module ${module} --remote=${childRemote} --path=${lib}/src/index.ts --no-interactive`
`generate @nx/angular:federate-module ${lib}/src/index.ts --name=${module} --remote=${childRemote} --no-interactive`
);
updateFile(`${lib}/src/index.ts`, `export { isEven } from './lib/${lib}';`);
-1
View File
@@ -9,7 +9,6 @@
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "e2e/eslint/jest.config.ts",
"passWithNoTests": true,
"runInBand": true
},
"outputs": ["{workspaceRoot}/coverage/e2e/eslint"]
+12 -4
View File
@@ -680,7 +680,9 @@ describe('Linter', () => {
// should have plugin extends
expect(appEslint.overrides[0].extends).toBeDefined();
expect(appEslint.overrides[1].extends).toBeDefined();
expect(e2eEslint.overrides[0].extends).toBeDefined();
expect(
e2eEslint.overrides.some((override) => override.extends)
).toBeTruthy();
runCLI(`generate @nx/js:lib ${mylib} --unitTestRunner=jest`);
verifySuccessfulMigratedSetup(myapp, mylib);
@@ -691,7 +693,9 @@ describe('Linter', () => {
// should have no plugin extends
expect(appEslint.overrides[0].extends).toBeUndefined();
expect(appEslint.overrides[1].extends).toBeUndefined();
expect(e2eEslint.overrides[0].extends).toBeUndefined();
expect(
e2eEslint.overrides.some((override) => override.extends)
).toBeFalsy();
});
it('(Angular standalone) should set root project config to app and e2e app and migrate when another lib is added', () => {
@@ -708,7 +712,9 @@ describe('Linter', () => {
// should have plugin extends
expect(appEslint.overrides[1].extends).toBeDefined();
expect(e2eEslint.overrides[0].extends).toBeDefined();
expect(
e2eEslint.overrides.some((override) => override.extends)
).toBeTruthy();
runCLI(`generate @nx/js:lib ${mylib} --no-interactive`);
verifySuccessfulMigratedSetup(myapp, mylib);
@@ -720,7 +726,9 @@ describe('Linter', () => {
expect(appEslint.overrides[1].extends).toEqual([
'plugin:@nx/angular-template',
]);
expect(e2eEslint.overrides[0].extends).toBeUndefined();
expect(
e2eEslint.overrides.some((override) => override.extends)
).toBeFalsy();
});
it('(Node standalone) should set root project config to app and e2e app and migrate when another lib is added', async () => {
@@ -475,7 +475,7 @@ describe('React Module Federation', () => {
// Federate Module
runCLI(
`generate @nx/react:federate-module ${module} --remote=${remote} --path=${lib}/src/index.ts --no-interactive`
`generate @nx/react:federate-module ${lib}/src/index.ts --name=${module} --remote=${remote} --no-interactive`
);
updateFile(
@@ -566,7 +566,7 @@ describe('React Module Federation', () => {
// Federate Module
runCLI(
`generate @nx/react:federate-module ${module} --remote=${childRemote} --path=${lib}/src/index.ts --no-interactive`
`generate @nx/react:federate-module ${lib}/src/index.ts --name=${module} --remote=${childRemote} --no-interactive`
);
updateFile(
+6 -1
View File
@@ -1,11 +1,12 @@
import { FeedContainer } from '@nx/nx-dev/feature-ai';
import { DocumentationHeader } from '@nx/nx-dev/ui-common';
import { DocumentationHeader, SidebarContainer } from '@nx/nx-dev/ui-common';
import { NextSeo } from 'next-seo';
import { useNavToggle } from '../../lib/navigation-toggle.effect';
import { cx } from '@nx/nx-dev/ui-primitives';
export default function AiDocs(): JSX.Element {
const { toggleNav, navIsOpen } = useNavToggle();
return (
<>
<NextSeo
@@ -38,6 +39,10 @@ export default function AiDocs(): JSX.Element {
role="main"
className="flex h-full flex-1 overflow-y-hidden"
>
<div className="hidden">
<SidebarContainer menu={{ sections: [] }} navIsOpen={navIsOpen} />
</div>
<FeedContainer />
</main>
</div>
+17 -4
View File
@@ -180,7 +180,10 @@ export function SidebarMobile({
const isNxCloud: boolean = router.asPath.startsWith('/nx-cloud');
const isAPI: boolean = router.asPath.startsWith('/nx-api');
const isPlugins: boolean = router.asPath.startsWith('/extending-nx');
const isNx: boolean = !isNxCloud && !isAPI && !isPlugins;
const isChangelog: boolean = router.asPath.startsWith('/changelog');
const isAiChat: boolean = router.asPath.startsWith('/ai-chat');
const isNx: boolean =
!isNxCloud && !isAPI && !isPlugins && !isChangelog && !isAiChat;
const sections = [
{ name: 'Home', href: '/', current: false },
@@ -190,15 +193,25 @@ export function SidebarMobile({
href: '/nx-cloud/intro/ci-with-nx',
current: isNxCloud,
},
{
name: 'Extending Nx',
href: '/extending-nx/intro/getting-started',
current: isPlugins,
},
{
name: 'API',
href: '/nx-api',
current: isAPI,
},
{
name: 'Extending Nx',
href: '/extending-nx/intro/getting-started',
current: isPlugins,
name: 'Changelog',
href: '/changelog',
current: isChangelog,
},
{
name: 'AI Chat (beta)',
href: '/ai-chat',
current: isAiChat,
},
];
return (
+1 -2
View File
@@ -10,8 +10,7 @@
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/nx-dev/ui-home"],
"options": {
"jestConfig": "nx-dev/ui-home/jest.config.ts",
"passWithNoTests": true
"jestConfig": "nx-dev/ui-home/jest.config.ts"
}
}
}
+1 -8
View File
@@ -28,14 +28,7 @@
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "nx-dev/util-ai/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
"jestConfig": "nx-dev/util-ai/jest.config.ts"
}
}
},
+20 -3
View File
@@ -26,6 +26,13 @@
]
},
"release": {
"releaseTagPattern": "{version}",
"changelog": {
"workspaceChangelog": {
"createRelease": "github",
"file": false
}
},
"groups": {
"npm": {
"projects": [
@@ -181,9 +188,6 @@
],
"cache": true
},
"lint-base": {
"cache": true
},
"build-ng": {
"cache": true
},
@@ -195,6 +199,19 @@
},
"copy-docs": {
"cache": true
},
"@nx/jest:jest": {
"cache": true,
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
"options": {
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
},
"plugins": ["@monodon/rust"],
+19 -19
View File
@@ -66,19 +66,19 @@
"@nguniversal/builders": "~16.2.0",
"@nuxt/kit": "^3.7.4",
"@nuxt/schema": "^3.7.4",
"@nx/angular": "17.0.0-rc.2",
"@nx/cypress": "17.0.0-rc.2",
"@nx/devkit": "17.0.0-rc.2",
"@nx/esbuild": "17.0.0-rc.2",
"@nx/eslint-plugin": "17.0.0-rc.2",
"@nx/jest": "17.0.0-rc.2",
"@nx/js": "17.0.0-rc.2",
"@nx/next": "17.0.0-rc.2",
"@nx/playwright": "17.0.0-rc.2",
"@nx/react": "17.0.0-rc.2",
"@nx/storybook": "17.0.0-rc.2",
"@nx/web": "17.0.0-rc.2",
"@nx/webpack": "17.0.0-rc.2",
"@nx/angular": "17.1.0-beta.4",
"@nx/cypress": "17.1.0-beta.4",
"@nx/devkit": "17.1.0-beta.4",
"@nx/esbuild": "17.1.0-beta.4",
"@nx/eslint-plugin": "17.1.0-beta.4",
"@nx/jest": "17.1.0-beta.4",
"@nx/js": "17.1.0-beta.4",
"@nx/next": "17.1.0-beta.4",
"@nx/playwright": "17.1.0-beta.4",
"@nx/react": "17.1.0-beta.4",
"@nx/storybook": "17.1.0-beta.4",
"@nx/web": "17.1.0-beta.4",
"@nx/webpack": "17.1.0-beta.4",
"@parcel/watcher": "2.0.4",
"@phenomnomnominal/tsquery": "~5.0.1",
"@playwright/test": "^1.36.1",
@@ -93,10 +93,10 @@
"@rollup/plugin-url": "^7.0.0",
"@schematics/angular": "~16.2.0",
"@side/jest-runtime": "^1.1.0",
"@storybook/addon-essentials": "7.2.2",
"@storybook/core-server": "7.2.2",
"@storybook/react": "7.2.2",
"@storybook/react-webpack5": "7.2.2",
"@storybook/addon-essentials": "7.5.3",
"@storybook/core-server": "7.5.3",
"@storybook/react": "7.5.3",
"@storybook/react-webpack5": "7.5.3",
"@storybook/types": "^7.1.1",
"@supabase/supabase-js": "^2.26.0",
"@svgr/rollup": "^8.0.1",
@@ -230,7 +230,7 @@
"ng-packagr": "~16.2.0",
"node-fetch": "^2.6.7",
"npm-package-arg": "11.0.1",
"nx": "17.0.0-rc.2",
"nx": "17.1.0-beta.4",
"octokit": "^2.0.14",
"open": "^8.4.0",
"openai": "~4.3.1",
@@ -296,7 +296,7 @@
"xstate": "4.34.0",
"yargs": "^17.6.2",
"yargs-parser": "21.1.1",
"@nx/eslint": "17.0.0-rc.2"
"@nx/eslint": "17.1.0-beta.4"
},
"author": "Victor Savkin",
"license": "MIT",
@@ -21,7 +21,8 @@ import {
getRemotes,
} from '@nx/webpack/src/utils/module-federation';
import { fork } from 'child_process';
import { combineLatest, concatMap, from, switchMap } from 'rxjs';
import { combineLatest, from } from 'rxjs';
import { concatMap, switchMap } from 'rxjs/operators';
export function executeModuleFederationDevServerBuilder(
schema: Schema,
@@ -31,6 +31,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
skipPackageJson: options.skipPackageJson,
skipFormat: true,
devServerTarget: `${options.name}:serve:development`,
rootProject: options.rootProject,
});
} else if (options.e2eTestRunner === 'playwright') {
const { configurationGenerator: playwrightConfigurationGenerator } =
@@ -57,6 +58,7 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
options.name
}`,
webServerAddress: `http://localhost:${options.port ?? 4200}`,
rootProject: options.rootProject,
});
}
}
@@ -12,22 +12,22 @@
],
"type": "object",
"properties": {
"name": {
"description": "The name of the module.",
"path": {
"type": "string",
"$default": {
"$source": "argv",
"index": 0
},
"description": "The path to locate the federated module.",
"x-prompt": "What is the path to the module to be federated?"
},
"name": {
"description": "The name of the module.",
"type": "string",
"x-prompt": "What name would you like to use for the module?",
"pattern": "^[a-zA-Z][^:]*$",
"x-priority": "important"
},
"path": {
"type": "string",
"description": "The path to locate the federated module.",
"x-prompt": "What is the path to the module to be federated?"
},
"remote": {
"type": "string",
"description": "The name of the remote.",
@@ -10,14 +10,14 @@ export function normalizeNewProjectPrefix(
): string {
// Prefix needs to be a valid html selector, if npmScope it's not valid, we don't default
// to it and let it fall through to the Angular schematic to handle it
// https://github.com/angular/angular-cli/blob/1c634cd327e5a850553b258aa2d5e6a6b2c75c65/packages/schematics/angular/component/index.ts#L130
// https://github.com/angular/angular-cli/blob/aa9f0528f174e856a4923cb24861fdf6e6f96b48/packages/schematics/angular/component/index.ts#L64
const htmlSelectorRegex =
/^[a-zA-Z][.0-9a-zA-Z]*(:?-[a-zA-Z][.0-9a-zA-Z]*)*$/;
/^[a-zA-Z][.0-9a-zA-Z]*((:?-[0-9]+)*|(:?-[a-zA-Z][.0-9a-zA-Z]*(:?-[0-9]+)*)*)$/;
if (prefix) {
if (!htmlSelectorRegex.test(prefix)) {
throw new Error(
'The provided "prefix" is invalid. The prefix must start with a letter, and must contain only alphanumeric characters or dashes. When adding a dash the segment after the dash must also start with a letter.'
'The provided "prefix" is invalid. The prefix must start with a letter, and must contain only alphanumeric characters or dashes.'
);
}
@@ -33,7 +33,7 @@ There are two options that can be followed to resolve this issue:
If you encountered this error when creating a new Nx Workspace, the workspace name or "npmScope" is invalid to use as the selector prefix for the application being generated.
Valid selector prefixes must start with a letter, and must contain only alphanumeric characters or dashes. When adding a dash the segment after the dash must also start with a letter.`);
Valid selector prefixes must start with a letter, and must contain only alphanumeric characters or dashes.`);
}
return npmScope || fallbackPrefix;
@@ -112,10 +112,6 @@ export const commandsObject: yargs.Argv<Arguments> = yargs
describe: chalk.dim`Customizes the initial content of your workspace. Default presets include: [${Object.values(
Preset
)
// TODO(v17): Remove this option when @nx/vue is released.
.filter(
(p) => p !== Preset.VueStandalone && p !== Preset.VueMonorepo
)
.map((p) => `"${p}"`)
.join(
', '
@@ -244,7 +240,6 @@ function normalizeAndWarnOnDeprecatedPreset(
return async (args: yargs.Arguments<Arguments>): Promise<void> => {
if (!args.preset) return;
if (deprecatedPresets[args.preset]) {
args.preset = deprecatedPresets[args.preset] as Preset;
output.addVerticalSeparator();
output.note({
title: `The "${args.preset}" preset is deprecated.`,
@@ -256,6 +251,7 @@ function normalizeAndWarnOnDeprecatedPreset(
}" preset instead.`,
],
});
args.preset = deprecatedPresets[args.preset] as Preset;
}
};
}
@@ -36,6 +36,7 @@ export interface CypressE2EConfigSchema {
linter?: Linter;
port?: number | 'cypress-auto';
jsx?: boolean;
rootProject?: boolean;
}
type NormalizedSchema = ReturnType<typeof normalizeOptions>;
@@ -91,7 +92,7 @@ In this case you need to provide a devServerTarget,'<projectName>:<targetName>[:
return {
...options,
bundler: options.bundler ?? 'webpack',
rootProject: projectConfig.root === '.',
rootProject: options.rootProject ?? projectConfig.root === '.',
linter: options.linter ?? Linter.EsLint,
devServerTarget:
options.devServerTarget ??
@@ -12,5 +12,12 @@
"reporters": ["detox/runners/jest/reporter"],
"testEnvironment": "detox/runners/jest/testEnvironment",
"verbose": true,
"setupFilesAfterEnv": ["<rootDir>/test-setup.ts"]
"setupFilesAfterEnv": ["<rootDir>/test-setup.ts"],
"transform": {
"^.+\\.(ts|js|html)$": [
"ts-jest",
{ "tsconfig": "<rootDir>/tsconfig.e2e.json" }
]
}
}
-1
View File
@@ -8,7 +8,6 @@ export interface EsBuildExecutorOptions {
assets: (AssetGlob | string)[];
bundle?: boolean;
deleteOutputPath?: boolean;
dependenciesFieldType?: boolean;
esbuildOptions?: Record<string, any>;
esbuildConfig?: string;
external?: string[];
@@ -130,12 +130,6 @@
"type": "boolean",
"description": "Includes third-party packages in the bundle (i.e. npm packages)."
},
"dependenciesFieldType": {
"type": "string",
"description": "When `bundleInternalProjectsOnly` is true, this option determines whether external packages should be in 'dependencies' or 'peerDependencies' field in the generated package.json file.",
"enum": ["dependencies", "peerDependencies"],
"default": "dependencies"
},
"esbuildOptions": {
"type": "object",
"description": "Additional options to pass to esbuild. See https://esbuild.github.io/api/. Cannot be used with 'esbuildConfig' option.",
@@ -99,7 +99,6 @@ function migrateEslintFile(projectEslintPath: string, tree: Tree) {
'plugin:@nrwl/typescript',
'plugin:@nrwl/javascript',
]);
console.warn('Flat eslint config is not supported yet for migration');
tree.write(projectEslintPath, config);
} else {
updateJson(tree, projectEslintPath, (json) => {
@@ -335,18 +335,24 @@ export function addBlockToFlatConfigExport(
});
const insert = printer.printNode(ts.EmitHint.Expression, config, source);
if (options.insertAtTheEnd) {
const index =
exportsArray.length > 0
? exportsArray.at(exportsArray.length - 1).end
: exportsArray.pos;
return applyChangesToString(content, [
{
type: ChangeType.Insert,
index: exportsArray[exportsArray.length - 1].end,
index,
text: `,\n${insert}`,
},
]);
} else {
const index =
exportsArray.length > 0 ? exportsArray.at(0).pos : exportsArray.pos;
return applyChangesToString(content, [
{
type: ChangeType.Insert,
index: exportsArray[0].pos,
index,
text: `\n${insert},`,
},
]);
+1
View File
@@ -99,6 +99,7 @@ module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) {
require.resolve('@babel/plugin-proposal-decorators'),
options.decorators ?? { legacy: true },
],
[require.resolve('@babel/plugin-transform-class-properties'), { loose }],
].filter(Boolean),
overrides: [
// Convert `const enum` to `enum`. The former cannot be supported by babel
+6
View File
@@ -23,6 +23,12 @@
"version": "16.8.2-beta.0",
"description": "Remove invalid options (strict, noInterop) for ES6 type modules.",
"factory": "./src/migrations/update-16-8-2/update-swcrc"
},
"update-17-0-0-remove-deprecated-build-options": {
"cli": "nx",
"version": "17.0.2",
"description": "Remove deprecated build options",
"implementation": "./src/migrations/update-17-0-0/remove-deprecated-build-options"
}
},
"packageJsonUpdates": {
+1
View File
@@ -33,6 +33,7 @@
"@babel/core": "^7.22.9",
"@babel/plugin-proposal-decorators": "^7.22.7",
"@babel/plugin-transform-runtime": "^7.22.9",
"@babel/plugin-transform-class-properties": "^7.22.5",
"@babel/preset-env": "^7.22.9",
"@babel/preset-typescript": "^7.22.5",
"@babel/runtime": "^7.22.6",
@@ -1359,4 +1359,32 @@ describe('lib', () => {
expect(tree.exists('web/my-lib/src/lib/my-lib.ts')).toBeTruthy();
});
});
describe('--testEnvironment', () => {
it('should generate a vite config with testEnvironment set to node', async () => {
await libraryGenerator(tree, {
...defaultOptions,
name: 'my-node-lib',
unitTestRunner: 'vitest',
testEnvironment: 'node',
});
const content = tree.read('my-node-lib/vite.config.ts', 'utf-8');
expect(content).toContain(`environment: 'node'`);
});
it('should generate a vite config with testEnvironment set to jsdom by default', async () => {
await libraryGenerator(tree, {
...defaultOptions,
name: 'my-jsdom-lib',
unitTestRunner: 'vitest',
testEnvironment: undefined,
});
const content = tree.read('my-jsdom-lib/vite.config.ts', 'utf-8');
expect(content).toContain(`environment: 'jsdom'`);
});
});
});
@@ -99,6 +99,7 @@ export async function libraryGeneratorInternal(
project: options.name,
includeLib: true,
includeVitest: options.unitTestRunner === 'vitest',
testEnvironment: options.testEnvironment,
},
false
);
@@ -136,6 +137,7 @@ export async function libraryGeneratorInternal(
project: options.name,
includeLib: false,
includeVitest: true,
testEnvironment: options.testEnvironment,
},
true
);
@@ -53,6 +53,17 @@ describe('remove-deprecated-build-options', () => {
await expect(migration(tree)).resolves.not.toThrow();
});
it('should work if a target is an empty object', async () => {
addProjectConfiguration(tree, 'proj', {
root: 'proj',
targets: {
build: {},
},
});
await expect(migration(tree)).resolves.not.toThrow();
});
it('should not update community executors', async () => {
addProjectConfiguration(tree, 'proj', {
root: 'proj',
@@ -19,7 +19,8 @@ export default async function (tree: Tree) {
for (const target of Object.values(projectConfig.targets)) {
if (
target.executor.startsWith('@nx/') &&
target.executor?.startsWith('@nx/') &&
target.options &&
('buildableProjectDepsInPackageJsonType' in target.options ||
'updateBuildableProjectDepsInPackageJson' in target.options)
) {
@@ -0,0 +1,33 @@
import { addLocalRegistryScripts } from './add-local-registry-scripts';
import { Tree, writeJson } from '@nx/devkit';
import { createTree } from '@nx/devkit/testing';
describe('addLocalRegistryScripts', () => {
let tree: Tree;
const startLocalRegistryPath = 'tools/scripts/start-local-registry.ts';
const stopLocalRegistryPath = 'tools/scripts/stop-local-registry.ts';
beforeEach(() => {
tree = createTree();
writeJson(tree, 'project.json', {
name: 'mylib',
});
});
it('should add "start-local-registry.ts" and "stop-local-registry.ts" in workspace\'s "tools/scripts" folder', () => {
expect(addLocalRegistryScripts(tree)).toEqual({
startLocalRegistryPath,
stopLocalRegistryPath,
});
expect(tree.exists(startLocalRegistryPath)).toBe(true);
expect(tree.exists(stopLocalRegistryPath)).toBe(true);
});
it('should set published version to "0.0.0-e2e"', () => {
addLocalRegistryScripts(tree);
const startLocalRegistry = tree.read(startLocalRegistryPath, 'utf-8');
expect(/'0\.0\.0-e2e'/.test(startLocalRegistry)).toBe(true);
});
});
@@ -22,7 +22,7 @@ export default async () => {
const nx = require.resolve('nx');
execFileSync(
nx,
['run-many', '--targets', 'publish', '--ver', '1.0.0', '--tag', 'e2e'],
['run-many', '--targets', 'publish', '--ver', '0.0.0-e2e', '--tag', 'e2e'],
{ env: process.env, stdio: 'inherit' }
);
};
@@ -118,70 +118,54 @@ describe('AssetInputOutputHandler', () => {
deletedMockedWatchedFile(path.join(projectDir, 'docs/test1.md'));
deletedMockedWatchedFile(path.join(projectDir, 'docs/test2.md'));
expect(callback.mock.calls).toEqual([
[
[
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
],
],
[
[
{
type: 'create',
src: path.join(rootDir, 'mylib/README.md'),
dest: path.join(rootDir, 'dist/mylib/README.md'),
},
],
],
[
[
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
],
],
[
[
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
],
],
[
[
{
type: 'update',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
],
],
[
[
{
type: 'delete',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
],
],
[
[
{
type: 'delete',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
],
],
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'mylib/README.md'),
dest: path.join(rootDir, 'dist/mylib/README.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'update',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'delete',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'delete',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
]);
dispose();
@@ -202,39 +186,31 @@ describe('AssetInputOutputHandler', () => {
await sut.processAllAssetsOnce();
expect(callback.mock.calls).toEqual([
[
[
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
],
],
[
[
{
type: 'create',
src: path.join(rootDir, 'mylib/README.md'),
dest: path.join(rootDir, 'dist/mylib/README.md'),
},
],
],
[
[
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
],
],
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'LICENSE'),
dest: path.join(rootDir, 'dist/mylib/LICENSE'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'mylib/README.md'),
dest: path.join(rootDir, 'dist/mylib/README.md'),
},
]);
expect(callback).toHaveBeenCalledWith([
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test1.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test1.md'),
},
{
type: 'create',
src: path.join(rootDir, 'mylib/docs/test2.md'),
dest: path.join(rootDir, 'dist/mylib/docs/test2.md'),
},
]);
});
});
+1 -2
View File
@@ -7,8 +7,7 @@
"test": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/nuxt/jest.config.ts",
"passWithNoTests": true
"jestConfig": "packages/nuxt/jest.config.ts"
},
"outputs": ["{workspaceRoot}/coverage/packages/nuxt"]
},
@@ -18,7 +18,6 @@ import { getRelativePathToRootTsConfig } from '@nx/js';
import { updateGitIgnore } from '../../utils/update-gitignore';
import { addBuildTarget, addServeTarget } from './lib/add-targets';
import { Linter } from '@nx/eslint';
import { addJest } from '@nx/vue';
import { addE2e } from './lib/add-e2e';
import { nxVersion } from '../../utils/versions';
import { addLinting } from '../../utils/add-linting';
@@ -74,14 +73,6 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
})
);
if (options.unitTestRunner === 'jest') {
tasks.push(
await addJest(tree, {
name: options.name,
projectRoot: options.appProjectRoot,
})
);
}
if (options.unitTestRunner === 'vitest') {
const { vitestGenerator } = ensurePackage('@nx/vite', nxVersion);
tasks.push(
+1 -1
View File
@@ -7,7 +7,7 @@ export interface Schema {
projectNameAndRootFormat?: ProjectNameAndRootFormat;
linter?: Linter;
skipFormat?: boolean;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
e2eTestRunner?: 'cypress' | 'playwright' | 'none';
tags?: string;
js?: boolean;
@@ -42,7 +42,7 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "vitest", "none"],
"enum": ["vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "none"
-1
View File
@@ -9,5 +9,4 @@ export interface Schema {
inSourceTests?: boolean;
skipFormat?: boolean;
directory?: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
}
@@ -79,12 +79,6 @@
"type": "boolean",
"default": false,
"x-priority": "internal"
},
"unitTestRunner": {
"type": "string",
"enum": ["vitest", "jest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "What unit test runner should be used?"
}
},
"required": ["name", "project"]
+1 -1
View File
@@ -16,7 +16,7 @@ export async function addLinting(
linter: Linter;
projectName: string;
projectRoot: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
rootProject?: boolean;
}
) {
-1
View File
@@ -14,7 +14,6 @@ ignore = '0.4'
ignore-files = "1.3.0"
itertools = "0.10.5"
once_cell = "1.18.0"
os_type = "2.6.0"
parking_lot = { version = "0.12.1", features = ["send_guard"] }
napi = { version = '2.12.6', default-features = false, features = [
'anyhow',
+1
View File
@@ -209,6 +209,7 @@ function handleAngularCLIFallbacks(workspace: WorkspaceTypeAndRoot) {
}
} else {
try {
// nx-ignore-next-line
const cli = require.resolve('@angular/cli/lib/init.js', {
paths: [workspace.dir],
});
+1
View File
@@ -200,6 +200,7 @@ function resolveNx(workspace: WorkspaceTypeAndRoot | null) {
} catch {
// TODO(v17): Remove this
// fallback for old CLI install setup
// nx-ignore-next-line
return require.resolve('@nrwl/cli/bin/nx.js', {
paths: [workspace ? workspace.dir : globalsRoot],
});
@@ -13,6 +13,7 @@ import {
initCloud,
printFinalMessage,
runInstall,
updateGitIgnore,
} from './utils';
type Options = Pick<InitArgs, 'nxCloud' | 'interactive' | 'cacheable'>;
@@ -88,6 +89,7 @@ export async function addNxToMonorepo(options: Options) {
scriptOutputs
);
updateGitIgnore(repoRoot);
addDepsToPackageJson(repoRoot);
output.log({ title: '📦 Installing dependencies' });
@@ -23,6 +23,7 @@ import {
markRootPackageJsonAsNxProject,
printFinalMessage,
runInstall,
updateGitIgnore,
} from './utils';
import { nxVersion } from '../../../utils/versions';
@@ -117,6 +118,7 @@ export async function addNxToNest(options: Options, packageJson: PackageJson) {
const pmc = getPackageManagerCommand();
updateGitIgnore(repoRoot);
addDepsToPackageJson(repoRoot);
addNestPluginToPackageJson(repoRoot);
markRootPackageJsonAsNxProject(
@@ -11,6 +11,7 @@ import {
markRootPackageJsonAsNxProject,
printFinalMessage,
runInstall,
updateGitIgnore,
} from './utils';
type Options = Pick<InitArgs, 'nxCloud' | 'interactive' | 'cacheable'>;
@@ -72,6 +73,7 @@ export async function addNxToNpmRepo(options: Options) {
const pmc = getPackageManagerCommand();
updateGitIgnore(repoRoot);
addDepsToPackageJson(repoRoot);
markRootPackageJsonAsNxProject(
repoRoot,
@@ -17,6 +17,7 @@ import {
} from '../../../utils/package-manager';
import { joinPathFragments } from '../../../utils/path';
import { nxVersion } from '../../../utils/versions';
import { readFileSync, writeFileSync } from 'fs';
export async function askAboutNxCloud(): Promise<boolean> {
return await enquirer
@@ -121,6 +122,17 @@ export function addDepsToPackageJson(repoRoot: string) {
writeJsonFile(path, json);
}
export function updateGitIgnore(root: string) {
const ignorePath = join(root, '.gitignore');
try {
let contents = readFileSync(ignorePath, 'utf-8');
if (!contents.includes('.nx/cache')) {
contents = [contents, '', '.nx/cache'].join('\n');
writeFileSync(ignorePath, contents, 'utf-8');
}
} catch {}
}
export function runInstall(
repoRoot: string,
pmc: PackageManagerCommands = getPackageManagerCommand()
@@ -2,7 +2,6 @@ import { execSync } from 'child_process';
import { prompt } from 'enquirer';
import { existsSync } from 'fs';
import { prerelease } from 'semver';
import * as parser from 'yargs-parser';
import { addNxToMonorepo } from './implementation/add-nx-to-monorepo';
import { addNxToNest } from './implementation/add-nx-to-nest';
import { addNxToNpmRepo } from './implementation/add-nx-to-npm-repo';
@@ -207,22 +207,24 @@ function readAndCombineAllProjectConfigurations(tree: Tree): {
const json = readJson(tree, projectFile);
const config = buildProjectFromProjectJson(json, projectFile);
mergeProjectConfigurationIntoRootMap(rootMap, config);
} else {
} else if (basename(projectFile) === 'package.json') {
const packageJson = readJson<PackageJson>(tree, projectFile);
const config = buildProjectConfigurationFromPackageJson(
packageJson,
projectFile,
readNxJson(tree)
);
mergeProjectConfigurationIntoRootMap(
rootMap,
// Inferred targets, tags, etc don't show up when running generators
// This is to help avoid running into issues when trying to update the workspace
{
name: config.name,
root: config.root,
}
);
if (!rootMap.has(config.root)) {
mergeProjectConfigurationIntoRootMap(
rootMap,
// Inferred targets, tags, etc don't show up when running generators
// This is to help avoid running into issues when trying to update the workspace
{
name: config.name,
root: config.root,
}
);
}
}
}
@@ -14,7 +14,9 @@ use swc_common::{BytePos, SourceMap, Spanned};
use swc_ecma_ast::EsVersion::EsNext;
use swc_ecma_parser::error::Error;
use swc_ecma_parser::lexer::Lexer;
use swc_ecma_parser::token::Keyword::{Class, Default_, Export, Function, Import};
use swc_ecma_parser::token::Keyword::{
Catch, Class, Default_, Export, Finally, Function, Import, Try,
};
use swc_ecma_parser::token::Word::{Ident, Keyword};
use swc_ecma_parser::token::{BinOpToken, Token, TokenAndSpan};
use swc_ecma_parser::{Syntax, Tokens, TsConfig};
@@ -43,6 +45,7 @@ enum BlockType {
Object,
ObjectType,
ArrowFunction,
TryCatchFinally,
}
fn is_identifier(token: &Token) -> bool {
@@ -55,6 +58,7 @@ struct State<'a> {
pub previous_token: Option<TokenAndSpan>,
pub import_type: ImportType,
open_brace_count: i128,
open_bracket_count: i128,
blocks_stack: Vec<BlockType>,
next_block_type: BlockType,
}
@@ -66,6 +70,7 @@ impl<'a> State<'a> {
current_token: None,
previous_token: None,
open_brace_count: 0,
open_bracket_count: 0,
blocks_stack: vec![],
next_block_type: BlockType::Block,
import_type: ImportType::Dynamic,
@@ -106,11 +111,19 @@ impl<'a> State<'a> {
// The block has closed so remove it from the block stack
self.blocks_stack.pop();
}
Token::LBracket => {
self.open_bracket_count += 1;
}
Token::RBracket => {
self.open_bracket_count -= 1;
}
_ => {}
}
// Keep track of when we are in an object declaration because colons mean different things
let in_object_declaration = self.blocks_stack.contains(&BlockType::Object);
// Keep track of when we are in an array declaration because commas mean different things
let in_array_declaration = self.open_bracket_count > 0;
let new_line = self.lexer.had_line_break_before_last();
@@ -141,6 +154,13 @@ impl<'a> State<'a> {
Keyword(keyword) if *keyword == Class => {
self.next_block_type = BlockType::Class;
}
// If a try/catch/finally keyword appears, the next open brace will start a function block
Keyword(keyword)
if *keyword == Try || *keyword == Catch || *keyword == Finally =>
{
self.next_block_type = BlockType::TryCatchFinally;
}
_ => {}
},
Token::AssignOp(_) => {
@@ -167,6 +187,25 @@ impl<'a> State<'a> {
}
}
}
// When an array opens, the next brace will be an object
// Matches [{ }]
Token::LBracket => {
if let Some(t) = &self.previous_token {
match t.token {
Token::Colon => {
self.next_block_type = BlockType::ObjectType;
}
_ => {
self.next_block_type = BlockType::Object;
}
}
}
}
Token::Comma => {
if in_array_declaration {
self.next_block_type = BlockType::Object;
}
}
Token::BinOp(op) => match op {
BinOpToken::Lt => {
// Matches things like Foo<typeof import('a')>
@@ -407,9 +446,15 @@ fn find_specifier_in_require(state: &mut State) -> Option<(String, ImportType)>
Token::LParen |
// Matches things like require.resolve
Token::Dot |
Token::Comma |
Token::LBrace |
Token::RBrace |
Token::LBracket |
Token::RBracket |
Token::Colon |
Token::Word(Ident(_)) => {}
// This could be a string literal
Token::Str { value, .. } => {
Token::Str { value, .. } if import.is_none() => {
import = Some(value.to_string());
}
@@ -434,6 +479,8 @@ fn find_specifier_in_require(state: &mut State) -> Option<(String, ImportType)>
return None;
}
}
// If we found an import, definitely wait for the RParen so it gets added
_ if import.is_some() => {}
// Anything else means this is not a require of a string literal
_ => {
return None;
@@ -560,7 +607,7 @@ fn process_file(
let code_is_not_ignored = |(specifier, pos): (String, BytePos)| {
let line_with_code = cm.lookup_line(pos).expect("All code is on a line");
if lines_with_nx_ignore_comments.contains(&(line_with_code - 1)) {
if line_with_code > 0 && lines_with_nx_ignore_comments.contains(&(line_with_code - 1)) {
None
} else {
Some(specifier)
@@ -618,8 +665,13 @@ fn find_imports(
#[cfg(test)]
mod find_imports {
use super::*;
use crate::native::utils::glob::build_glob_set;
use crate::native::utils::path::Normalize;
use crate::native::walker::nx_walker;
use assert_fs::prelude::*;
use assert_fs::TempDir;
use std::env;
use std::path::PathBuf;
use swc_common::comments::NoopComments;
#[test]
@@ -820,7 +872,7 @@ import 'a4'; import 'a5';
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -977,6 +1029,20 @@ import('./dynamic-import.vue')
}
const a = 1;
export class App {}
const a: [{ a: typeof import('static-import-in-array-type-in-object')}] = [];
const a = [{ a: import('dynamic-import-in-object-in-array')}];
const a = { a: [import('dynamic-import-in-array-in-object')]};
const routes = [
{},
{
lazy: () => import('dynamic-import-lazy-route')
}
]
"#,
)
.unwrap();
@@ -990,7 +1056,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1048,7 +1114,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1087,7 +1153,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1135,7 +1201,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1220,7 +1286,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1272,7 +1338,7 @@ import('./dynamic-import.vue')
.unwrap();
let result = results.get(0).unwrap();
let ast_results: ImportResult = find_imports_with_ast(test_file_path);
let ast_results: ImportResult = find_imports_with_ast(test_file_path).unwrap();
assert_eq!(
result.static_import_expressions,
@@ -1284,8 +1350,60 @@ import('./dynamic-import.vue')
);
}
#[test]
#[ignore]
fn should_find_imports_properly_for_all_files_in_nx_repo() {
let current_dir = env::current_dir().unwrap();
let mut ancestors = current_dir.ancestors();
ancestors.next();
ancestors.next();
let root = PathBuf::from(ancestors.next().unwrap());
let files = nx_walker(root.clone(), move |receiver| {
let mut files = vec![];
let glob = build_glob_set(&["**/*.[jt]s"]).unwrap();
for (path, _) in receiver {
if glob.is_match(&path) {
files.push(root.join(path).to_normalized_string());
}
}
files
});
let results: HashMap<_, _> =
find_imports(HashMap::from([(String::from("nx"), files.clone())]))
.unwrap()
.into_iter()
.map(|import_result| (import_result.file.clone(), import_result))
.collect();
let ast_results: HashMap<_, _> = files
.into_iter()
.filter_map(|p| find_imports_with_ast(p).ok())
.map(|import_result| (import_result.file.clone(), import_result))
.collect();
for (path, import_result) in results {
let ast_result = ast_results.get(&path);
if let Some(ast_result) = ast_result {
dbg!(&path, &import_result, &ast_result);
assert_eq!(
import_result.static_import_expressions,
ast_result.static_import_expressions
);
assert_eq!(
import_result.dynamic_import_expressions,
ast_result.dynamic_import_expressions
);
}
}
}
// This function finds imports with the ast which verifies that the imports we find are the same as the ones typescript finds
fn find_imports_with_ast(file_path: String) -> ImportResult {
fn find_imports_with_ast(file_path: String) -> anyhow::Result<ImportResult> {
let cm = Arc::<SourceMap>::default()
.load_file(Path::new(file_path.as_str()))
.unwrap();
@@ -1306,7 +1424,7 @@ import('./dynamic-import.vue')
None,
&mut errs,
)
.unwrap();
.map_err(|_| anyhow::anyhow!("Failed to create ast"))?;
let comments = NoopComments;
let deps = swc_ecma_dep_graph::analyze_dependencies(&module, &comments);
@@ -1333,11 +1451,11 @@ import('./dynamic-import.vue')
static_import_expressions.push(dep.specifier.to_string());
}
}
ImportResult {
Ok(ImportResult {
source_project: String::from("source"),
file: file_path,
static_import_expressions,
dynamic_import_expressions,
}
})
}
}
+1 -5
View File
@@ -1,7 +1,5 @@
use ignore::WalkBuilder;
use ignore_files::IgnoreFile;
use once_cell::sync::Lazy;
use os_type::{OSInformation, OSType};
use std::{fs, path::PathBuf};
use tracing::trace;
use watchexec_events::{Event, Tag};
@@ -56,10 +54,8 @@ pub(super) fn get_ignore_files<T: AsRef<str>>(root: T) -> Vec<IgnoreFile> {
// .collect()
// }
static OS_PLATFORM: Lazy<OSInformation> = Lazy::new(os_type::current_platform);
pub(super) fn transform_event(watch_event: &Event) -> Option<Event> {
if OS_PLATFORM.os_type == OSType::Debian || OS_PLATFORM.os_type == OSType::Arch {
if cfg!(linux) {
let tags = watch_event
.tags
.clone()
@@ -23,7 +23,10 @@ export async function normalizeProjectNodes(
nxJson: NxJsonConfiguration
) {
const toAdd = [];
const projects = Object.keys(ctx.projects);
// Sorting projects by name to make sure that the order of projects in the graph is deterministic.
// This is important to ensure that expanded properties referencing projects (e.g. implicit dependencies)
// are also deterministic, and thus don't cause the calculated project configuration hash to shift.
const projects = Object.keys(ctx.projects).sort();
// Used for expanding implicit dependencies (e.g. `@proj/*` or `tag:foo`)
const partialProjectGraphNodes = projects.reduce((graph, project) => {
@@ -258,7 +258,9 @@ function buildAllWorkspaceFiles(
): FileData[] {
performance.mark('get-all-workspace-files:start');
let fileData: FileData[] = Object.values(projectFileMap).flat();
fileData = fileData.concat(globalFiles).sort();
fileData = fileData
.concat(globalFiles)
.sort((a, b) => a.file.localeCompare(b.file));
performance.mark('get-all-workspace-files:end');
performance.measure(
'get-all-workspace-files',
@@ -25,6 +25,7 @@ export interface WorkspaceTypeAndRoot {
function isAngularCliInstalled(root: string): boolean {
try {
// nx-ignore-next-line
require.resolve('@angular/cli', {
paths: [root],
});
+6 -2
View File
@@ -22,6 +22,7 @@ export interface PackageManagerCommands {
addDev: string;
rm: string;
exec: string;
dlx: string;
list: string;
run: (script: string, args: string) => string;
}
@@ -74,13 +75,14 @@ export function getPackageManagerCommand(
addDev: useBerry ? 'yarn add -D' : 'yarn add -D -W',
rm: 'yarn remove',
exec: 'yarn',
dlx: useBerry ? 'yarn dlx' : 'yarn',
run: (script: string, args: string) => `yarn ${script} ${args}`,
list: useBerry ? 'yarn info --name-only' : 'yarn list',
};
},
pnpm: () => {
const pnpmVersion = getPackageManagerVersion('pnpm', root);
const useExec = gte(pnpmVersion, '6.13.0');
const modernPnpm = gte(pnpmVersion, '6.13.0');
const includeDoubleDashBeforeArgs = lt(pnpmVersion, '7.0.0');
const isPnpmWorkspace = existsSync(join(root, 'pnpm-workspace.yaml'));
@@ -90,7 +92,8 @@ export function getPackageManagerCommand(
add: isPnpmWorkspace ? 'pnpm add -w' : 'pnpm add',
addDev: isPnpmWorkspace ? 'pnpm add -Dw' : 'pnpm add -D',
rm: 'pnpm rm',
exec: useExec ? 'pnpm exec' : 'pnpx',
exec: modernPnpm ? 'pnpm exec' : 'pnpx',
dlx: modernPnpm ? 'pnpm dlx' : 'pnpx',
run: (script: string, args: string) =>
includeDoubleDashBeforeArgs
? `pnpm run ${script} -- ${args}`
@@ -109,6 +112,7 @@ export function getPackageManagerCommand(
addDev: 'npm install -D',
rm: 'npm rm',
exec: 'npx',
dlx: 'npx',
run: (script: string, args: string) => `npm run ${script} -- ${args}`,
list: 'npm ls',
};
+38
View File
@@ -1743,6 +1743,44 @@ describe('params', () => {
]);
});
it('should use a multiselect if type is array and x-prompt uses shorthand', () => {
const prompts = getPromptsForSchema(
{},
{
properties: {
pets: {
type: 'array',
'x-prompt': 'What kind of pets do you have?',
items: {
enum: ['cat', 'dog', 'fish'],
},
},
},
},
{
version: 2,
projects: {},
}
);
expect(prompts).toMatchInlineSnapshot(`
[
{
"choices": [
"cat",
"dog",
"fish",
],
"limit": 10,
"message": "What kind of pets do you have?",
"name": "pets",
"type": "multiselect",
"validate": [Function],
},
]
`);
});
describe('Project prompts', () => {
it('should use an autocomplete prompt for a property named project', () => {
const prompts = getPromptsForSchema(
+17 -4
View File
@@ -785,10 +785,23 @@ export function getPromptsForSchema(
// Normalize x-prompt
if (typeof v['x-prompt'] === 'string') {
const message = v['x-prompt'];
v['x-prompt'] = {
type: v.type === 'boolean' ? 'confirm' : 'input',
message,
};
if (v.type === 'boolean') {
v['x-prompt'] = {
type: 'confirm',
message,
};
} else if (v.type === 'array' && v.items?.enum) {
v['x-prompt'] = {
type: 'multiselect',
items: v.items.enum,
message,
};
} else {
v['x-prompt'] = {
type: 'input',
message,
};
}
}
question.message = v['x-prompt'].message;
@@ -46,7 +46,7 @@ export async function configurationGenerator(
js: options.js,
directory: options.directory,
setParserOptionsProject: options.setParserOptionsProject,
rootProject: projectConfig.root === '.',
rootProject: options.rootProject ?? projectConfig.root === '.',
})
);
@@ -21,4 +21,5 @@ export interface ConfigurationGeneratorSchema {
* @example: "http://localhost:4200"
**/
webServerAddress?: string;
rootProject?: boolean;
}
@@ -55,6 +55,13 @@
"default": false,
"description": "Do not add dependencies to `package.json`.",
"x-priority": "internal"
},
"rootProject": {
"description": "Create a application at the root of the workspace",
"type": "boolean",
"default": false,
"hidden": true,
"x-priority": "internal"
}
},
"required": ["project"]
@@ -51,7 +51,7 @@ describe('NxPlugin e2e-project Generator', () => {
expect(tree.exists('apps/my-plugin-e2e/tsconfig.json')).toBeTruthy();
expect(
tree.exists('apps/my-plugin-e2e/tests/my-plugin.spec.ts')
tree.exists('apps/my-plugin-e2e/src/my-plugin.spec.ts')
).toBeTruthy();
});
@@ -109,7 +109,7 @@ async function addJest(host: Tree, options: NormalizedSchema) {
addProjectConfiguration(host, options.projectName, {
root: options.projectRoot,
projectType: 'application',
sourceRoot: `${options.projectRoot}/tests`,
sourceRoot: `${options.projectRoot}/src`,
targets: {},
implicitDependencies: [options.pluginName],
});
@@ -43,6 +43,7 @@ export async function addE2e(
skipFormat: true,
devServerTarget: `${options.projectName}:serve`,
jsx: true,
rootProject: options.rootProject,
});
}
case 'playwright': {
@@ -68,6 +69,7 @@ export async function addE2e(
options.name
}`,
webServerAddress: 'http://localhost:4200',
rootProject: options.rootProject,
});
}
case 'none':
@@ -12,22 +12,22 @@
],
"type": "object",
"properties": {
"name": {
"description": "The name of the module.",
"path": {
"type": "string",
"$default": {
"$source": "argv",
"index": 0
},
"description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.",
"x-prompt": "What is the path to the module to be federated?"
},
"name": {
"description": "The name of the module.",
"type": "string",
"x-prompt": "What name would you like to use for the module?",
"pattern": "^[a-zA-Z][^:]*$",
"x-priority": "important"
},
"path": {
"type": "string",
"description": "The path to locate the federated module. This path should be relative to the workspace root and the file should exist.",
"x-prompt": "What is the path to the module to be federated?"
},
"remote": {
"type": "string",
"description": "The name of the remote.",
@@ -19,6 +19,10 @@ const knownLocations = [
'pages/styles.css',
'pages/styles.scss',
'pages/styles.less',
'app/global.css',
'app/global.scss',
'app/global.less',
];
export function addTailwindStyleImports(
+2 -2
View File
@@ -8,8 +8,8 @@ export const reactDomVersion = '18.2.0';
export const reactIsVersion = '18.2.0';
export const swcLoaderVersion = '0.1.15';
export const babelLoaderVersion = '^9.1.2';
export const typesReactVersion = '18.2.24';
export const typesReactDomVersion = '18.2.9';
export const typesReactVersion = '18.2.33';
export const typesReactDomVersion = '18.2.14';
export const typesReactIsVersion = '18.2.2';
export const typesNodeVersion = '18.14.2';
@@ -11,9 +11,9 @@ exports[`@nx/storybook:init dependencies for package.json should add angular rel
"@angular/forms": "*",
"@nx/js": "0.0.1",
"@nx/storybook": "0.0.1",
"@storybook/addon-essentials": "7.2.2",
"@storybook/angular": "7.2.2",
"@storybook/core-server": "7.2.2",
"@storybook/addon-essentials": "7.5.3",
"@storybook/angular": "7.5.3",
"@storybook/core-server": "7.5.3",
"@swc-node/register": "~1.6.7",
"@swc/core": "~1.3.85",
"existing": "1.0.0",
@@ -15,7 +15,7 @@ export function callUpgrade(schema: Schema): 1 | Buffer {
});
execSync(
`${pm.exec} storybook@latest upgrade ${
`${pm.dlx} storybook@latest upgrade ${
schema.autoAcceptAllPrompts ? '--yes' : ''
}`,
{
@@ -73,7 +73,7 @@ export function callAutomigrate(
Object.entries(allStorybookProjects).forEach(
([projectName, storybookProjectInfo]) => {
const pm = getPackageManagerCommand();
const commandToRun = `${pm.exec} storybook@latest automigrate --config-dir ${storybookProjectInfo.configDir} --renderer ${storybookProjectInfo.uiFramework}`;
const commandToRun = `${pm.dlx} storybook@latest automigrate --config-dir ${storybookProjectInfo.configDir} --renderer ${storybookProjectInfo.uiFramework}`;
try {
output.log({
title: `Calling sb automigrate for ${projectName}`,
+1 -2
View File
@@ -7,8 +7,7 @@
"test": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/vite/jest.config.ts",
"passWithNoTests": true
"jestConfig": "packages/vite/jest.config.ts"
},
"outputs": ["{workspaceRoot}/coverage/packages/vite"]
},
+1 -1
View File
@@ -805,7 +805,7 @@ function handleViteConfigFileExists(
cache: {
dir: `${offsetFromRoot}node_modules/.vitest`,
},
environment: 'jsdom',
environment: options.testEnvironment ?? 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
};
-1
View File
@@ -33,7 +33,6 @@
"nx",
"typescript",
"@nx/cypress",
"@nx/jest",
"@nx/playwright",
"@nx/storybook"
]
-1
View File
@@ -9,6 +9,5 @@ export {
} from './src/generators/stories/stories';
export { type InitSchema } from './src/generators/init/schema';
export { vueInitGenerator } from './src/generators/init/init';
export { addJest } from './src/generators/application/lib/add-jest';
export * from './src/utils/versions';
export * from './src/utils/add-linting';
+1 -2
View File
@@ -34,8 +34,7 @@
"@nx/js": "file:../js",
"@nx/eslint": "file:../eslint",
"@nx/vite": "file:../vite",
"@nx/web": "file:../web",
"@phenomnomnominal/tsquery": "~5.0.1"
"@nx/web": "file:../web"
},
"publishConfig": {
"access": "public"
+1 -2
View File
@@ -7,8 +7,7 @@
"test": {
"executor": "@nx/jest:jest",
"options": {
"jestConfig": "packages/vue/jest.config.ts",
"passWithNoTests": true
"jestConfig": "packages/vue/jest.config.ts"
},
"outputs": ["{workspaceRoot}/coverage/packages/vue"]
},
@@ -14,7 +14,6 @@ import { addLinting } from '../../utils/add-linting';
import { addE2e } from './lib/add-e2e';
import { createApplicationFiles } from './lib/create-application-files';
import { addVite } from './lib/add-vite';
import { addJest } from './lib/add-jest';
import { extractTsConfigBase } from '../../utils/create-ts-config';
export async function applicationGenerator(
@@ -62,14 +61,6 @@ export async function applicationGenerator(
tasks.push(await addVite(tree, options));
if (options.unitTestRunner === 'jest')
tasks.push(
await addJest(tree, {
name: options.name,
projectRoot: options.appProjectRoot,
})
);
tasks.push(await addE2e(tree, options));
if (options.js) toJS(tree);
@@ -1,42 +0,0 @@
import {
addDependenciesToPackageJson,
ensurePackage,
GeneratorCallback,
runTasksInSerial,
Tree,
} from '@nx/devkit';
import { nxVersion, vueJest3Version } from '../../../utils/versions';
import { setupJestProject } from '../../../utils/setup-jest';
export async function addJest(
tree: Tree,
options: { name: string; projectRoot: string }
): Promise<GeneratorCallback> {
const tasks: GeneratorCallback[] = [];
const { configurationGenerator } = ensurePackage<typeof import('@nx/jest')>(
'@nx/jest',
nxVersion
);
tasks.push(
await configurationGenerator(tree, {
project: options.name,
skipFormat: true,
testEnvironment: 'jsdom',
compiler: 'babel',
})
);
setupJestProject(tree, options.projectRoot);
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
'@vue/vue3-jest': vueJest3Version,
}
)
);
return runTasksInSerial(...tasks);
}
+1 -1
View File
@@ -8,7 +8,7 @@ export interface Schema {
directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
tags?: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
inSourceTests?: boolean;
e2eTestRunner: 'cypress' | 'playwright' | 'none';
linter: Linter;
@@ -85,7 +85,7 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "vitest", "none"],
"enum": ["vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "Which unit test runner would you like to use?",
"default": "vitest"
@@ -102,13 +102,7 @@
"type": "boolean",
"default": false,
"x-priority": "internal"
},
"unitTestRunner": {
"type": "string",
"enum": ["vitest", "jest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "What unit test runner should be used?"
}
},
"required": ["name", "project"]
"required": ["name"]
}
@@ -27,151 +27,6 @@ exports[`lib nested should create a local tsconfig.json 1`] = `
}
`;
exports[`lib should add correct jest.config.ts and dependencies to package.json 1`] = `
{
"dependencies": {
"tslib": "^2.3.0",
"vue": "^3.3.4",
},
"devDependencies": {
"@nx/cypress": "0.0.1",
"@nx/eslint": "0.0.1",
"@nx/eslint-plugin": "0.0.1",
"@nx/jest": "0.0.1",
"@nx/js": "0.0.1",
"@nx/rollup": "0.0.1",
"@nx/vite": "0.0.1",
"@nx/vue": "0.0.1",
"@swc-node/register": "~1.6.7",
"@swc/core": "~1.3.85",
"@types/jest": "^29.4.0",
"@types/node": "16.11.7",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"@vitejs/plugin-vue": "^4.3.1",
"@vue/eslint-config-prettier": "7.1.0",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.4.1",
"@vue/tsconfig": "^0.4.0",
"@vue/vue3-jest": "^29.2.6",
"babel-jest": "^29.4.1",
"eslint": "~8.46.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-vue": "^9.16.1",
"jest": "^29.4.1",
"jest-environment-jsdom": "^29.4.1",
"prettier": "^2.6.2",
"ts-jest": "^29.1.0",
"ts-node": "10.9.1",
"typescript": "~5.1.3",
"vue-tsc": "^1.8.8",
},
"name": "@proj/source",
}
`;
exports[`lib should add correct jest.config.ts and dependencies to package.json 2`] = `
{
"ignorePatterns": [
"**/*",
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx",
"*.vue",
],
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"allow": [],
"depConstraints": [
{
"onlyDependOnLibsWithTags": [
"*",
],
"sourceTag": "*",
},
],
"enforceBuildableLibDependency": true,
},
],
},
},
{
"extends": [
"plugin:@nx/typescript",
],
"files": [
"*.ts",
"*.tsx",
],
"rules": {},
},
{
"extends": [
"plugin:@nx/javascript",
],
"files": [
"*.js",
"*.jsx",
],
"rules": {},
},
{
"env": {
"jest": true,
},
"files": [
"*.spec.ts",
"*.spec.tsx",
"*.spec.js",
"*.spec.jsx",
],
"rules": {},
},
],
"plugins": [
"@nx",
],
"root": true,
}
`;
exports[`lib should add correct jest.config.ts and dependencies to package.json 3`] = `
"/* eslint-disable */
export default {
displayName: 'my-lib',
preset: '../jest.preset.js',
coverageDirectory: '../coverage/my-lib',
moduleFileExtensions: ['js', 'ts', 'json', 'vue'],
transform: {
'^.+.[tj]sx?$': ['babel-jest'],
'^.+.vue$': [
'@vue/vue3-jest',
{
tsConfig: './tsconfig.spec.json',
},
],
},
testEnvironment: 'jsdom',
testMatch: ['**/*.spec.ts?(x)', '**/__tests__/*.ts?(x)'],
};
"
`;
exports[`lib should add correct jest.config.ts and dependencies to package.json 4`] = `
"{
"presets": ["@nx/js/babel"]
}
"
`;
exports[`lib should add vite types to tsconfigs and generate correct vite.config.ts file 1`] = `
"/// <reference types='vitest' />
import { defineConfig } from 'vite';
@@ -1,41 +0,0 @@
import {
addDependenciesToPackageJson,
ensurePackage,
GeneratorCallback,
runTasksInSerial,
Tree,
} from '@nx/devkit';
import { nxVersion, vueJest3Version } from '../../../utils/versions';
import { setupJestProject } from '../../../utils/setup-jest';
import { NormalizedSchema } from '../schema';
export async function addJest(
tree: Tree,
options: NormalizedSchema
): Promise<GeneratorCallback> {
const tasks: GeneratorCallback[] = [];
const { configurationGenerator } = ensurePackage<typeof import('@nx/jest')>(
'@nx/jest',
nxVersion
);
const jestTask = await configurationGenerator(tree, {
project: options.name,
skipFormat: true,
testEnvironment: 'jsdom',
compiler: 'babel',
});
tasks.push(jestTask);
setupJestProject(tree, options.projectRoot);
tasks.push(
addDependenciesToPackageJson(
tree,
{},
{
'@vue/vue3-jest': vueJest3Version,
}
)
);
return runTasksInSerial(...tasks);
}
@@ -1,53 +0,0 @@
import type { Tree } from '@nx/devkit';
import { Linter } from '@nx/eslint';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { normalizeOptions } from './normalize-options';
describe('normalizeOptions', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
});
it('should set unitTestRunner=jest and bundler=none by default', async () => {
const options = await normalizeOptions(tree, {
name: 'test',
linter: Linter.None,
unitTestRunner: 'vitest',
});
expect(options).toMatchObject({
bundler: 'none',
unitTestRunner: 'vitest',
});
});
it('should set unitTestRunner=vitest by default when bundler is vite', async () => {
const options = await normalizeOptions(tree, {
name: 'test',
linter: Linter.None,
bundler: 'vite',
unitTestRunner: 'vitest',
});
expect(options).toMatchObject({
bundler: 'vite',
unitTestRunner: 'vitest',
});
});
it('should set maintain unitTestRunner when bundler is vite', async () => {
const options = await normalizeOptions(tree, {
name: 'test',
linter: Linter.None,
bundler: 'vite',
unitTestRunner: 'vitest',
});
expect(options).toMatchObject({
bundler: 'vite',
unitTestRunner: 'vitest',
});
});
});
@@ -84,14 +84,6 @@ describe('lib', () => {
expect(readJson(tree, '/package.json')).toMatchSnapshot();
});
it('should add correct jest.config.ts and dependencies to package.json', async () => {
await libraryGenerator(tree, { ...defaultSchema, unitTestRunner: 'jest' });
expect(readJson(tree, '/package.json')).toMatchSnapshot();
expect(readJson(tree, '.eslintrc.json')).toMatchSnapshot();
expect(tree.read('my-lib/jest.config.ts', 'utf-8')).toMatchSnapshot();
expect(tree.read('my-lib/.babelrc', 'utf-8')).toMatchSnapshot();
});
it('should update root tsconfig.base.json', async () => {
await libraryGenerator(tree, defaultSchema);
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
@@ -17,7 +17,6 @@ import { createLibraryFiles } from './lib/create-library-files';
import { extractTsConfigBase } from '../../utils/create-ts-config';
import componentGenerator from '../component/component';
import { addVite } from './lib/add-vite';
import { addJest } from './lib/add-jest';
export async function libraryGenerator(tree: Tree, schema: Schema) {
const tasks: GeneratorCallback[] = [];
@@ -52,9 +51,6 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
tasks.push(await addVite(tree, options));
if (options.unitTestRunner === 'jest')
tasks.push(await addJest(tree, options));
if (options.component) {
await componentGenerator(tree, {
name: options.name,
+2 -2
View File
@@ -22,7 +22,7 @@ export interface Schema {
skipTsConfig?: boolean;
strict?: boolean;
tags?: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
minimal?: boolean;
e2eTestRunner?: 'cypress' | 'none';
}
@@ -37,5 +37,5 @@ export interface NormalizedSchema extends Schema {
parsedTags: string[];
appMain?: string;
appSourceRoot?: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
}
@@ -46,7 +46,7 @@
},
"unitTestRunner": {
"type": "string",
"enum": ["vitest", "jest", "none"],
"enum": ["vitest", "none"],
"description": "Test runner to use for unit tests.",
"x-prompt": "What unit test runner should be used?"
},
@@ -116,7 +116,7 @@ export async function createTestUILib(libName: string): Promise<Tree> {
component: true,
skipFormat: true,
skipTsConfig: false,
unitTestRunner: 'jest',
unitTestRunner: 'vitest',
projectNameAndRootFormat: 'as-provided',
});
+1 -1
View File
@@ -19,7 +19,7 @@ export async function addLinting(
linter: Linter;
name: string;
projectRoot: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
unitTestRunner?: 'vitest' | 'none';
setParserOptionsProject?: boolean;
skipPackageJson?: boolean;
rootProject?: boolean;

Some files were not shown because too many files have changed in this diff Show More