docs(core): tutorial preview bug (#30903)

- Fix tutorial bug with the preview pane
- Bump Nx version to 20.8 for all 3 tutorials
This commit is contained in:
Isaac Mann 2025-04-29 13:49:03 -04:00 committed by GitHub
parent c1d375883f
commit 13ebf4359a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
78 changed files with 22582 additions and 44558 deletions

View File

@ -13,7 +13,7 @@
"devDependencies": {
"tslib": "^2.8.0",
"typescript": "~5.5.2",
"nx": "20.6.4"
"nx": "20.8.1"
},
"dependencies": {}
}
}

View File

@ -11,11 +11,11 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@nx/js": "^20.6.4",
"@nx/js": "^20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"nx": "20.6.4",
"nx": "20.8.1",
"tslib": "^2.8.0",
"typescript": "~5.5.2"
},

View File

@ -5,7 +5,7 @@ focus: /nx.json
previews:
- {
port: 4211,
title: 'Nx Graph',
title: 'Project Details',
pathname: 'project-details/%40tuskdesign%2Fzoo',
}
---

View File

@ -11,12 +11,12 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@nx/js": "^20.6.4",
"@nx/js": "^20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@types/node": "18.16.9",
"nx": "20.6.4",
"nx": "20.8.1",
"tslib": "^2.8.0",
"typescript": "~5.5.2"
},

View File

@ -5,7 +5,7 @@ focus: /nx.json
previews:
- {
port: 4211,
title: 'Nx Graph',
title: 'Project Details',
pathname: 'project-details/%40tuskdesign%2Fzoo',
}
---

View File

@ -4,7 +4,7 @@ title: Checkpoint
previews:
- {
port: 4211,
title: 'Nx Graph',
title: 'Task Graph',
pathname: 'tasks/serve?projects=%40tuskdesign%2Fzoo',
}
---

View File

@ -40,6 +40,10 @@ export default [
sourceTag: "scope:shared",
onlyDependOnLibsWithTags: ["scope:shared"]
},
{
sourceTag: "*",
onlyDependOnLibsWithTags: ["*"]
},
],
},
],

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/orders",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:feature",
"scope:orders"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "orders",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/orders/src",
"projectType": "library",
"tags": ["type:feature", "scope:orders"],
"// targets": "to see all targets run: nx show project orders --web",
"targets": {}
}

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/products",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:feature",
"scope:products"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "products",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/products/src",
"projectType": "library",
"tags": ["type:feature", "scope:products"],
"// targets": "to see all targets run: nx show project products --web",
"targets": {}
}

View File

@ -0,0 +1,15 @@
import styles from './products.module.css';
// This import is not allowed 👇
import { Orders } from '@react-monorepo/orders';
export function Products() {
return (
<div className={styles['container']}>
<h1>Welcome to Products!</h1>
<p>This is a change. 👋</p>
</div>
);
}
export default Products;

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/ui",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:ui",
"scope:shared"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "ui",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/shared/ui/src",
"projectType": "library",
"tags": ["type:ui", "scope:shared"],
"// targets": "to see all targets run: nx show project ui --web",
"targets": {}
}

View File

@ -22,7 +22,7 @@ When building these kinds of constraints you usually have two dimensions:
Nx comes with a generic mechanism that allows you to assign "tags" to projects. "tags" are arbitrary strings you can assign to a project that can be used later when defining boundaries between projects. For example, go to the `package.json` of your `orders` library and assign the tags `type:feature` and `scope:orders` to it.
```json title="libs/orders/package.json"
```solution:/libs/orders/package.json title="/libs/orders/package.json" collapse={2-13}
{
...
"nx": {
@ -33,7 +33,7 @@ Nx comes with a generic mechanism that allows you to assign "tags" to projects.
Then go to the `package.json` of your `products` library and assign the tags `type:feature` and `scope:products` to it.
```json title="libs/products/package.json"
```solution:/libs/products/package.json title="/libs/products/package.json" collapse={2-13}
{
...
"nx": {
@ -44,7 +44,7 @@ Then go to the `package.json` of your `products` library and assign the tags `ty
Finally, go to the `package.json` of the `shared-ui` library and assign the tags `type:ui` and `scope:shared` to it.
```json title="libs/shared/ui/package.json"
```solution:/libs/shared/ui/package.json title="/libs/shared/ui/package.json" collapse={2-13}
{
...
"nx": {
@ -64,75 +64,14 @@ Next, let's come up with a set of rules based on these tags:
To enforce the rules, Nx ships with a custom ESLint rule. Open the `eslint.config.mjs` at the root of the workspace and add the following `depConstraints` in the `@nx/enforce-module-boundaries` rule configuration:
```js title="eslint.config.mjs"
import nx from '@nx/eslint-plugin';
```solution:/eslint.config.mjs title="/eslint.config.mjs" collapse={1-2,4-9,52-65}
export default [
// ...
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
rules: {
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?js$'],
depConstraints: [
{
sourceTag: 'type:feature',
onlyDependOnLibsWithTags: ['type:feature', 'type:ui'],
},
{
sourceTag: 'type:ui',
onlyDependOnLibsWithTags: ['type:ui'],
},
{
sourceTag: 'scope:orders',
onlyDependOnLibsWithTags: [
'scope:orders',
'scope:products',
'scope:shared',
],
},
{
sourceTag: 'scope:products',
onlyDependOnLibsWithTags: ['scope:products', 'scope:shared'],
},
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
{
sourceTag: '*',
onlyDependOnLibsWithTags: ['*'],
},
],
},
],
},
},
// ...
];
```
To test it, go to your `libs/products/src/lib/products.tsx` file and import the `Orders` component from the `orders` project:
```tsx title="libs/products/src/lib/products.tsx"
import styles from './products.module.css';
```solution:/libs/products/src/lib/products.tsx title="/libs/products/src/lib/products.tsx"
// This import is not allowed 👇
import { Orders } from '@react-monorepo/orders';
export function Products() {
return (
<div className={styles['container']}>
<h1>Welcome to Products!</h1>
<p>This is a change. 👋</p>
</div>
);
}
export default Products;
```
If you lint your workspace you'll get an error now:

View File

@ -7,10 +7,10 @@ export default defineConfig({
cypressDir: 'src',
bundler: 'vite',
webServerCommands: {
default: 'npx nx run @react-monorepo/react-store:dev',
production: 'npx nx run @react-monorepo/react-store:preview',
default: 'npx nx run react-store:dev',
production: 'npx nx run react-store:preview',
},
ciWebServerCommand: 'npx nx run @react-monorepo/react-store:preview',
ciWebServerCommand: 'npx nx run react-store:preview',
ciBaseUrl: 'http://localhost:4300',
}),
baseUrl: 'http://localhost:4200',

View File

@ -3,10 +3,8 @@
"version": "0.0.1",
"private": true,
"nx": {
"projectType": "application",
"sourceRoot": "apps/react-store-e2e/src",
"implicitDependencies": [
"@react-monorepo/react-store"
"react-store"
]
}
}

View File

@ -1,5 +1,8 @@
{
"name": "@react-monorepo/react-store",
"version": "0.0.1",
"private": true
"private": true,
"nx": {
"name": "react-store"
}
}

View File

@ -1,8 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "out-tsc/react-store",
"tsBuildInfoFile": "out-tsc/react-store/tsconfig.app.tsbuildinfo",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo",
"jsx": "react-jsx",
"lib": ["dom"],
"types": [

View File

@ -5,7 +5,11 @@ export default [
...nx.configs['flat/typescript'],
...nx.configs['flat/javascript'],
{
ignores: ['**/dist'],
ignores: [
'**/dist',
'**/vite.config.*.timestamp*',
'**/vitest.config.*.timestamp*',
],
},
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],

View File

@ -4,18 +4,18 @@
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/cypress/**/*",
"!{projectRoot}/**/*.cy.[jt]s?(x)",
"!{projectRoot}/cypress.config.[jt]s"
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
"sharedGlobals": []
},
"nxCloudId": "67bf6d71702b69753e7b3e85",
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [
{
"plugin": "@nx/js/typescript",
@ -31,6 +31,23 @@
}
}
},
{
"plugin": "@nx/react/router-plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"watchDepsTargetName": "watch-deps",
"buildDepsTargetName": "build-deps",
"typecheckTargetName": "typecheck"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/vite/plugin",
"options": {
@ -44,26 +61,14 @@
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/cypress/plugin",
"options": {
"targetName": "e2e",
"openTargetName": "open-cypress",
"componentTestingTargetName": "component-test",
"ciTargetName": "e2e-ci"
}
}
],
"targetDefaults": {
"test": {
"dependsOn": ["^build"]
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"generators": {

View File

@ -11,16 +11,16 @@
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/js": "20.8.1",
"@nx/react": "20.8.1",
"@nx/vite": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/cli": "~0.6.0",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
@ -31,9 +31,9 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
@ -41,7 +41,7 @@
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",

View File

@ -15,6 +15,7 @@
"noUnusedLocals": true,
"skipLibCheck": true,
"strict": true,
"target": "es2022"
"target": "es2022",
"customConditions": ["development"]
}
}

View File

@ -3,7 +3,8 @@ type: lesson
title: Generate a Starter Repository
filesystem:
watch: ['/react-monorepo/*', '/react-monorepo/apps/**']
prepareCommands: []
prepareCommands:
- ['chmod +x git', 'Stubbing git']
---
## Creating a new React Monorepo

View File

@ -4,18 +4,18 @@
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/cypress/**/*",
"!{projectRoot}/**/*.cy.[jt]s?(x)",
"!{projectRoot}/cypress.config.[jt]s"
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
"sharedGlobals": []
},
"nxCloudId": "67bf6d71702b69753e7b3e85",
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [
{
"plugin": "@nx/js/typescript",
@ -31,6 +31,23 @@
}
}
},
{
"plugin": "@nx/react/router-plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"watchDepsTargetName": "watch-deps",
"buildDepsTargetName": "build-deps",
"typecheckTargetName": "typecheck"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/vite/plugin",
"options": {
@ -44,26 +61,14 @@
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/cypress/plugin",
"options": {
"targetName": "e2e",
"openTargetName": "open-cypress",
"componentTestingTargetName": "component-test",
"ciTargetName": "e2e-ci"
}
}
],
"targetDefaults": {
"test": {
"dependsOn": ["^build", "^build", "^build", "^build"]
"dependsOn": ["^build"]
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"generators": {

View File

@ -13,16 +13,16 @@
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/js": "20.8.1",
"@nx/react": "20.8.1",
"@nx/vite": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/cli": "~0.6.0",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
@ -33,9 +33,9 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
@ -43,7 +43,7 @@
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",
@ -53,7 +53,6 @@
},
"workspaces": [
"apps/*",
"libs/*",
"libs/shared/*"
"libs/*"
]
}

View File

@ -10,17 +10,19 @@
"react-router-dom": "6.29.0"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/js": "20.8.1",
"@nx/react": "20.8.1",
"@nx/vite": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/cli": "~0.6.0",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
@ -31,9 +33,9 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
@ -41,7 +43,7 @@
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",
@ -51,7 +53,6 @@
},
"workspaces": [
"apps/*",
"libs/*",
"libs/shared/*"
"libs/*"
]
}

View File

@ -1,59 +0,0 @@
{
"name": "@react-monorepo/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {},
"private": true,
"dependencies": {
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router-dom": "^6.29.0"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
"@testing-library/react": "16.1.0",
"@types/node": "^20.0.0",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",
"typescript-eslint": "^8.19.0",
"vite": "^6.0.0",
"vitest": "^3.0.0"
},
"workspaces": [
"apps/*",
"libs/*",
"libs/shared/*"
]
}

View File

@ -65,11 +65,7 @@ Serving your app (`npx nx serve react-store`) and then navigating to `/products`
![products route](/documentation/shared/tutorials/react-tutorial-products-route.png)
Let's apply the same for our `orders` library.
- import the `Orders` component from `libs/orders` into the `app.tsx` and render it via the routing mechanism whenever a user hits the `/orders` rout
e
Let's apply the same for our `orders` library. Import the `Orders` component from `libs/orders` into the `app.tsx` and render it via the routing mechanism whenever a user hits the `/orders` route.
In the end, your `app.tsx` should look similar to this:

View File

@ -0,0 +1,15 @@
import styles from './products.module.css';
// This import is not allowed 👇
import { Orders } from '@angular-monorepo/orders';
export function Products() {
return (
<div className={styles['container']}>
<h1>Welcome to Products!</h1>
<p>This is a change. 👋</p>
</div>
);
}
export default Products;

View File

@ -22,29 +22,20 @@ When building these kinds of constraints you usually have two dimensions:
Nx comes with a generic mechanism that allows you to assign "tags" to projects. "tags" are arbitrary strings you can assign to a project that can be used later when defining boundaries between projects. For example, go to the `project.json` of your `orders` library and assign the tags `type:feature` and `scope:orders` to it.
```json title="libs/orders/project.json"
{
...
"tags": ["type:feature", "scope:orders"]
}
```solution:/libs/orders/project.json title="/libs/orders/project.json" collapse={2-5,7-19}
```
Then go to the `project.json` of your `products` library and assign the tags `type:feature` and `scope:products` to it.
```json title="libs/products/project.json"
{
...
"tags": ["type:feature", "scope:products"]
}
```solution:/libs/products/project.json title="/libs/products/project.json" collapse={2-5,7-19}
```
Finally, go to the `project.json` of the `shared-ui` library and assign the tags `type:ui` and `scope:shared` to it.
```json title="libs/shared/ui/project.json"
{
...
"tags": ["type:ui", "scope:shared"]
}
```solution:/libs/shared/ui/project.json title="/libs/shared/ui/project.json" collapse={2-5,7-19}
```
Notice how we assign `scope:shared` to our UI library because it is intended to be used throughout the workspace.
@ -58,69 +49,14 @@ Next, let's come up with a set of rules based on these tags:
To enforce the rules, Nx ships with a custom ESLint rule. Open the `eslint.config.mjs` at the root of the workspace and add the following `depConstraints` in the `@nx/enforce-module-boundaries` rule configuration:
```js title="eslint.config.mjs"
export default [
// ...
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
rules: {
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?js$'],
depConstraints: [
{
sourceTag: 'type:feature',
onlyDependOnLibsWithTags: ['type:feature', 'type:ui'],
},
{
sourceTag: 'type:ui',
onlyDependOnLibsWithTags: ['type:ui'],
},
{
sourceTag: 'scope:orders',
onlyDependOnLibsWithTags: [
'scope:orders',
'scope:products',
'scope:shared',
],
},
{
sourceTag: 'scope:products',
onlyDependOnLibsWithTags: ['scope:products', 'scope:shared'],
},
{
sourceTag: 'scope:shared',
onlyDependOnLibsWithTags: ['scope:shared'],
},
],
},
],
},
},
// ...
];
```solution:/eslint.config.mjs title="/eslint.config.mjs" collapse={1-2,4-9,52-65}
```
To test it, go to your `libs/products/src/lib/products.tsx` file and import the `Orders` component from the `orders` project:
```tsx title="libs/products/src/lib/products.tsx"
import styles from './products.module.css';
```solution:/libs/products/src/lib/products.tsx title="/libs/products/src/lib/products.tsx" {3-4}
// This import is not allowed 👇
import { Orders } from '@angular-monorepo/orders';
export function Products() {
return (
<div className={styles['container']}>
<h1>Welcome to Products!</h1>
<p>This is a change. 👋</p>
</div>
);
}
export default Products;
```
If you lint your workspace you'll get an error now:

View File

@ -17,7 +17,7 @@
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
},
"nxCloudId": "67b34f1b5f0dc34dcae257e2",
"nxCloudId": "6810b7447beee15fcea96208",
"targetDefaults": {
"@angular-devkit/build-angular:application": {
"cache": true,
@ -45,6 +45,9 @@
"codeCoverage": true
}
}
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"plugins": [

View File

@ -23,14 +23,16 @@
"@angular/compiler-cli": "~19.2.0",
"@angular/language-service": "~19.2.0",
"@eslint/js": "^9.8.0",
"@nx/angular": "20.6.4",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/jest": "20.6.4",
"@nx/js": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/angular": "20.8.1",
"@nx/devkit": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/jest": "20.8.1",
"@nx/js": "20.8.1",
"@nx/playwright": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@playwright/test": "^1.36.0",
"@schematics/angular": "~19.2.0",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
@ -39,14 +41,13 @@
"@types/node": "18.16.9",
"@typescript-eslint/utils": "^8.19.0",
"angular-eslint": "^19.2.0",
"cypress": "^13.13.0",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-playwright": "^1.6.2",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-preset-angular": "~14.4.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"ts-jest": "^29.1.0",
"ts-node": "10.9.1",

View File

@ -3,7 +3,8 @@ type: lesson
title: Generate a Starter Repository
filesystem:
watch: ['/angular-monorepo/*', '/angular-monorepo/apps/**']
prepareCommands: []
prepareCommands:
- ['chmod +x git', 'Stubbing git']
---
## Creating a new Angular Monorepo

View File

@ -31,84 +31,36 @@ export * from './lib/products/products.component';
We're ready to import it into our main application now. First (if you haven't already), let's set up the Angular router. Remove the `app-nx-welcome` component from `app.component.html`:
```ts title="/apps/angular-store/src/app/app.component.html"
<router-outlet></router-outlet>
```solution:/apps/angular-store/src/app/app.component.html title="/apps/angular-store/src/app/app.component.html"
```
Then we can add the `ProductsComponent` component to our `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/products` route.
```ts title="/apps/angular-store/src/app/app.routes.ts" {10-14}
import { Route } from '@angular/router';
import { NxWelcomeComponent } from './nx-welcome.component';
```solution:/apps/angular-store/src/app/app.routes.ts title="/apps/angular-store/src/app/app.routes.ts" {10-14} collapse={15-19}
export const appRoutes: Route[] = [
{
path: '',
component: NxWelcomeComponent,
pathMatch: 'full',
},
{
path: 'products',
loadComponent: () =>
import('@angular-monorepo/products').then((m) => m.ProductsComponent),
},
];
```
Serving your app (`npx nx serve angular-store`) and then navigating to `/products` should give you the following result:
![products route](/documentation/shared/tutorials/app-products-route.png)
Let's apply the same for our `orders` library.
- import the `OrdersComponent` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` rout
e
Let's apply the same for our `orders` library. Import the `OrdersComponent` from `libs/orders` into the `app.routes.ts` and render it via the routing mechanism whenever a user hits the `/orders` route
In the end, your `app.routes.ts` should look similar to this:
```ts title="apps/angular-store/src/app/app.routes.ts" {15-19}
import { Route } from '@angular/router';
import { NxWelcomeComponent } from './nx-welcome.component';
```solution:/apps/angular-store/src/app/app.routes.ts title="apps/angular-store/src/app/app.routes.ts" {15-19}
export const appRoutes: Route[] = [
{
path: '',
component: NxWelcomeComponent,
pathMatch: 'full',
},
{
path: 'products',
loadComponent: () =>
import('@angular-monorepo/products').then((m) => m.ProductsComponent),
},
{
path: 'orders',
loadComponent: () =>
import('@angular-monorepo/orders').then((m) => m.OrdersComponent),
},
];
```
Let's also show products in the `inventory` app.
```ts title="apps/inventory/src/app/app.component.ts" {2,5}
import { Component } from '@angular/core';
import { ProductsComponent } from '@angular-monorepo/products';
```solution:/apps/inventory/src/app/app.component.ts title="/apps/inventory/src/app/app.component.ts" {2,5}
@Component({
imports: [ProductsComponent],
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'inventory';
}
```
```ts title="apps/inventory/src/app/app.component.html"
<lib-products></lib-products>
```solution:/apps/inventory/src/app/app.component.html title="/apps/inventory/src/app/app.component.html"
```
## Testing and Linting

View File

@ -17,7 +17,7 @@
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
},
"nxCloudId": "67b34f1b5f0dc34dcae257e2",
"nxCloudId": "6810b7447beee15fcea96208",
"targetDefaults": {
"@angular-devkit/build-angular:application": {
"cache": true,
@ -45,18 +45,12 @@
"codeCoverage": true
}
}
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"plugins": [
{
"plugin": "@nx/cypress/plugin",
"options": {
"targetName": "e2e",
"openTargetName": "open-cypress",
"componentTestingTargetName": "component-test",
"ciTargetName": "e2e-ci"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {

File diff suppressed because it is too large Load Diff

View File

@ -23,14 +23,14 @@
"@angular/compiler-cli": "~19.2.0",
"@angular/language-service": "~19.2.0",
"@eslint/js": "^9.8.0",
"@nx/angular": "20.6.4",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/jest": "20.6.4",
"@nx/js": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/angular": "20.8.1",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/jest": "20.8.1",
"@nx/js": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@schematics/angular": "~19.2.0",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
@ -39,14 +39,14 @@
"@types/node": "18.16.9",
"@typescript-eslint/utils": "^8.19.0",
"angular-eslint": "^19.2.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-preset-angular": "~14.4.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"ts-jest": "^29.1.0",
"ts-node": "10.9.1",

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/orders",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:feature",
"scope:orders"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "orders",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/orders/src",
"projectType": "library",
"tags": ["type:feature", "scope:orders"],
"// targets": "to see all targets run: nx show project orders --web",
"targets": {}
}

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/products",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:feature",
"scope:products"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "products",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/products/src",
"projectType": "library",
"tags": ["type:feature", "scope:products"],
"// targets": "to see all targets run: nx show project products --web",
"targets": {}
}

View File

@ -0,0 +1,20 @@
{
"name": "@react-monorepo/ui",
"version": "0.0.1",
"main": "./src/index.ts",
"types": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"import": "./src/index.ts",
"default": "./src/index.ts"
},
"./package.json": "./package.json"
},
"nx": {
"tags": [
"type:ui",
"scope:shared"
]
}
}

View File

@ -1,9 +0,0 @@
{
"name": "ui",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/shared/ui/src",
"projectType": "library",
"tags": ["type:ui", "scope:shared"],
"// targets": "to see all targets run: nx show project ui --web",
"targets": {}
}

View File

@ -1,13 +0,0 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@ -1,46 +0,0 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
dist
tmp
out-tsc
# dependencies
node_modules
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db
.nx/cache
.nx/workspace-data
vite.config.*.timestamp*
vitest.config.*.timestamp*
test-output

View File

@ -1,5 +0,0 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
/.nx/cache
/.nx/workspace-data

View File

@ -1,3 +0,0 @@
{
"singleQuote": true
}

View File

@ -7,10 +7,10 @@ export default defineConfig({
cypressDir: 'src',
bundler: 'vite',
webServerCommands: {
default: 'npx nx run @react-monorepo/react-store:dev',
production: 'npx nx run @react-monorepo/react-store:preview',
default: 'npx nx run react-store:dev',
production: 'npx nx run react-store:preview',
},
ciWebServerCommand: 'npx nx run @react-monorepo/react-store:preview',
ciWebServerCommand: 'npx nx run react-store:preview',
ciBaseUrl: 'http://localhost:4300',
}),
baseUrl: 'http://localhost:4200',

View File

@ -3,10 +3,8 @@
"version": "0.0.1",
"private": true,
"nx": {
"projectType": "application",
"sourceRoot": "apps/react-store-e2e/src",
"implicitDependencies": [
"@react-monorepo/react-store"
"react-store"
]
}
}

View File

@ -1,5 +1,8 @@
{
"name": "@react-monorepo/react-store",
"version": "0.0.1",
"private": true
"private": true,
"nx": {
"name": "react-store"
}
}

View File

@ -1,8 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "out-tsc/react-store",
"tsBuildInfoFile": "out-tsc/react-store/tsconfig.app.tsbuildinfo",
"outDir": "dist",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo",
"jsx": "react-jsx",
"lib": ["dom"],
"types": [

View File

@ -5,7 +5,11 @@ export default [
...nx.configs['flat/typescript'],
...nx.configs['flat/javascript'],
{
ignores: ['**/dist'],
ignores: [
'**/dist',
'**/vite.config.*.timestamp*',
'**/vitest.config.*.timestamp*',
],
},
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],

View File

@ -4,18 +4,18 @@
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/cypress/**/*",
"!{projectRoot}/**/*.cy.[jt]s?(x)",
"!{projectRoot}/cypress.config.[jt]s"
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
"sharedGlobals": []
},
"nxCloudId": "67bf6d71702b69753e7b3e85",
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [
{
"plugin": "@nx/js/typescript",
@ -31,6 +31,23 @@
}
}
},
{
"plugin": "@nx/react/router-plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"watchDepsTargetName": "watch-deps",
"buildDepsTargetName": "build-deps",
"typecheckTargetName": "typecheck"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/vite/plugin",
"options": {
@ -44,17 +61,14 @@
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
}
],
"targetDefaults": {
"test": {
"dependsOn": ["^build"]
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"generators": {

File diff suppressed because it is too large Load Diff

View File

@ -11,16 +11,16 @@
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/js": "20.8.1",
"@nx/react": "20.8.1",
"@nx/vite": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/cli": "~0.6.0",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
@ -31,9 +31,9 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
@ -41,7 +41,7 @@
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",

View File

@ -15,6 +15,7 @@
"noUnusedLocals": true,
"skipLibCheck": true,
"strict": true,
"target": "es2022"
"target": "es2022",
"customConditions": ["development"]
}
}

View File

@ -4,18 +4,18 @@
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"production": [
"default",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
"!{projectRoot}/tsconfig.spec.json",
"!{projectRoot}/src/test-setup.[jt]s",
"!{projectRoot}/.eslintrc.json",
"!{projectRoot}/eslint.config.mjs",
"!{projectRoot}/cypress/**/*",
"!{projectRoot}/**/*.cy.[jt]s?(x)",
"!{projectRoot}/cypress.config.[jt]s"
],
"sharedGlobals": ["{workspaceRoot}/.github/workflows/ci.yml"]
"sharedGlobals": []
},
"nxCloudId": "67bf6d71702b69753e7b3e85",
"nxCloudId": "68101bb54a6391016e75634c",
"plugins": [
{
"plugin": "@nx/js/typescript",
@ -31,6 +31,23 @@
}
}
},
{
"plugin": "@nx/react/router-plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"watchDepsTargetName": "watch-deps",
"buildDepsTargetName": "build-deps",
"typecheckTargetName": "typecheck"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/vite/plugin",
"options": {
@ -44,26 +61,14 @@
"buildDepsTargetName": "build-deps",
"watchDepsTargetName": "watch-deps"
}
},
{
"plugin": "@nx/eslint/plugin",
"options": {
"targetName": "lint"
}
},
{
"plugin": "@nx/cypress/plugin",
"options": {
"targetName": "e2e",
"openTargetName": "open-cypress",
"componentTestingTargetName": "component-test",
"ciTargetName": "e2e-ci"
}
}
],
"targetDefaults": {
"test": {
"dependsOn": ["^build", "^build", "^build", "^build"]
"dependsOn": ["^build"]
},
"e2e-ci--**/**": {
"dependsOn": ["^build"]
}
},
"generators": {

File diff suppressed because it is too large Load Diff

View File

@ -10,17 +10,19 @@
"react-router-dom": "6.29.0"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@nx/cypress": "20.8.1",
"@nx/eslint": "20.8.1",
"@nx/eslint-plugin": "20.8.1",
"@nx/js": "20.8.1",
"@nx/react": "20.8.1",
"@nx/vite": "20.8.1",
"@nx/web": "20.8.1",
"@nx/workspace": "20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/cli": "~0.6.0",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
@ -31,9 +33,9 @@
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"cypress": "^14.2.1",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-config-prettier": "^10.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
@ -41,7 +43,7 @@
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"nx": "20.8.1",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",
@ -51,7 +53,6 @@
},
"workspaces": [
"apps/*",
"libs/*",
"libs/shared/*"
"libs/*"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -1,59 +0,0 @@
{
"name": "@react-monorepo/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {},
"private": true,
"dependencies": {
"react": "19.0.0",
"react-dom": "19.0.0",
"react-router-dom": "^6.29.0"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"@eslint/js": "^9.8.0",
"@nx/cypress": "20.6.4",
"@nx/eslint": "20.6.4",
"@nx/eslint-plugin": "20.6.4",
"@nx/js": "20.6.4",
"@nx/react": "20.6.4",
"@nx/vite": "20.6.4",
"@nx/web": "20.6.4",
"@nx/workspace": "20.6.4",
"@swc-node/register": "~1.9.1",
"@swc/cli": "~0.3.12",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@testing-library/dom": "10.4.0",
"@testing-library/react": "16.1.0",
"@types/node": "^20.0.0",
"@types/react": "19.0.0",
"@types/react-dom": "19.0.0",
"@vitejs/plugin-react": "^4.2.0",
"@vitest/coverage-v8": "^3.0.5",
"@vitest/ui": "^3.0.0",
"cypress": "^13.13.0",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-cypress": "^3.5.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsx-a11y": "6.10.1",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "5.0.0",
"jiti": "2.4.2",
"jsdom": "~22.1.0",
"nx": "20.6.4",
"prettier": "^2.6.2",
"tslib": "^2.3.0",
"typescript": "~5.7.2",
"typescript-eslint": "^8.19.0",
"vite": "^6.0.0",
"vitest": "^3.0.0"
},
"workspaces": [
"apps/*",
"libs/*",
"libs/shared/*"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
"devDependencies": {
"tslib": "^2.8.0",
"typescript": "~5.5.2",
"nx": "20.6.4"
"nx": "20.8.1"
},
"dependencies": {}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,11 +11,11 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@nx/js": "^20.6.4",
"@nx/js": "^20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"nx": "20.6.4",
"nx": "20.8.1",
"tslib": "^2.8.0",
"typescript": "~5.5.2"
},

File diff suppressed because it is too large Load Diff

View File

@ -11,12 +11,12 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@nx/js": "^20.6.4",
"@nx/js": "^20.8.1",
"@swc-node/register": "~1.9.1",
"@swc/core": "~1.5.7",
"@swc/helpers": "~0.5.11",
"@types/node": "18.16.9",
"nx": "20.6.4",
"nx": "20.8.1",
"tslib": "^2.8.0",
"typescript": "~5.5.2"
},

View File

@ -163,8 +163,8 @@
"@typescript-eslint/rule-tester": "^8.19.0",
"@typescript-eslint/type-utils": "^8.19.0",
"@typescript-eslint/utils": "^8.19.0",
"@webcontainer/api": "1.5.1",
"@vitejs/plugin-react": "^4.2.0",
"@webcontainer/api": "1.5.1",
"@xstate/immer": "0.3.1",
"@xstate/inspect": "0.7.0",
"@xstate/react": "3.0.1",
@ -412,5 +412,10 @@
"check-codeowners"
]
},
"packageManager": "pnpm@9.8.0"
"packageManager": "pnpm@9.8.0",
"pnpm": {
"patchedDependencies": {
"@tutorialkit/react": "patches/@tutorialkit__react.patch"
}
}
}

View File

@ -0,0 +1,14 @@
diff --git a/dist/Panels/PreviewPanel.js b/dist/Panels/PreviewPanel.js
index 8fe07230d31399924442517a2cae4f80aefcbb11..f7733c0ca44c8abcb2d12cb230f56452e4a5714e 100644
--- a/dist/Panels/PreviewPanel.js
+++ b/dist/Panels/PreviewPanel.js
@@ -83,6 +83,9 @@ function Preview({ preview, iframe, previewCount, first, last, toggleTerminal, i
iframe.ref.title = preview.title;
}
}, [preview.url, iframe.ref]);
+ useEffect(() => {
+ reload();
+ }, [preview.url]);
function reload() {
if (iframe.ref) {
reloadPreview(iframe.ref);

13
pnpm-lock.yaml generated
View File

@ -8,6 +8,11 @@ overrides:
minimist: ^1.2.6
underscore: ^1.12.1
patchedDependencies:
'@tutorialkit/react':
hash: kkebbkg5j2fp5xasb2zxj4epiu
path: patches/@tutorialkit__react.patch
importers:
.:
@ -489,7 +494,7 @@ importers:
version: 1.5.0(@types/node@20.16.10)(@types/react-dom@18.3.0)(astro@4.15.0(@types/node@20.16.10)(less@4.1.3)(rollup@4.22.0)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(typescript@5.7.3))(less@4.1.3)(postcss@8.4.38)(rollup@4.22.0)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
'@tutorialkit/react':
specifier: 1.5.0
version: 1.5.0(@types/react-dom@18.3.0)(@types/react@18.3.1)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
version: 1.5.0(patch_hash=kkebbkg5j2fp5xasb2zxj4epiu)(@types/react-dom@18.3.0)(@types/react@18.3.1)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
'@tutorialkit/theme':
specifier: 1.5.0
version: 1.5.0(postcss@8.4.38)(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
@ -29138,7 +29143,7 @@ snapshots:
'@expressive-code/plugin-line-numbers': 0.35.6
'@nanostores/react': 0.7.2(nanostores@0.10.3)(react@18.3.1)
'@stackblitz/sdk': 1.11.0
'@tutorialkit/react': 1.5.0(@types/react-dom@18.3.0)(@types/react@18.3.20)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
'@tutorialkit/react': 1.5.0(patch_hash=kkebbkg5j2fp5xasb2zxj4epiu)(@types/react-dom@18.3.0)(@types/react@18.3.20)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
'@tutorialkit/runtime': 1.5.0
'@tutorialkit/theme': 1.5.0(postcss@8.4.38)(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))
'@tutorialkit/types': 1.5.0
@ -29179,7 +29184,7 @@ snapshots:
- terser
- vite
'@tutorialkit/react@1.5.0(@types/react-dom@18.3.0)(@types/react@18.3.1)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))':
'@tutorialkit/react@1.5.0(patch_hash=kkebbkg5j2fp5xasb2zxj4epiu)(@types/react-dom@18.3.0)(@types/react@18.3.1)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))':
dependencies:
'@codemirror/autocomplete': 6.18.6
'@codemirror/commands': 6.8.1
@ -29226,7 +29231,7 @@ snapshots:
- supports-color
- vite
'@tutorialkit/react@1.5.0(@types/react-dom@18.3.0)(@types/react@18.3.20)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))':
'@tutorialkit/react@1.5.0(patch_hash=kkebbkg5j2fp5xasb2zxj4epiu)(@types/react-dom@18.3.0)(@types/react@18.3.20)(postcss@8.4.38)(react-dom@18.3.1(react@18.3.1))(rollup@4.22.0)(vite@6.2.0(@types/node@20.16.10)(jiti@1.21.6)(less@4.1.3)(sass-embedded@1.85.1)(sass@1.55.0)(stylus@0.64.0)(terser@5.39.0)(yaml@2.6.1))':
dependencies:
'@codemirror/autocomplete': 6.18.6
'@codemirror/commands': 6.8.1