From 1aaa8e99c2ba0935e60ad3b2b5f2d4938dcbcc5a Mon Sep 17 00:00:00 2001 From: Qing Lin Date: Tue, 23 Dec 2025 16:20:19 +0000 Subject: [PATCH 1/2] Use npm workspaces instead of TS paths aliases --- .eslintrc.json | 8 ++++++-- apps/cart/src/app/app.tsx | 2 +- libs/cart/cart-page/package.json | 6 ++++++ package.json | 5 +++++ tsconfig.base.json | 2 +- yarn.lock | 6 ++++++ 6 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 libs/cart/cart-page/package.json diff --git a/.eslintrc.json b/.eslintrc.json index 46b63e71..dee660a3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,8 +13,12 @@ "allow": [], "depConstraints": [ { - "sourceTag": "*", - "onlyDependOnLibsWithTags": ["*"] + "sourceTag": "type:app", + "onlyDependOnLibsWithTags": [ + "type:no-such-type", + "scope:shared", + "type:ui" + ] } ] } diff --git a/apps/cart/src/app/app.tsx b/apps/cart/src/app/app.tsx index 4206822d..006c9bcf 100644 --- a/apps/cart/src/app/app.tsx +++ b/apps/cart/src/app/app.tsx @@ -2,7 +2,7 @@ import { Route, Routes } from 'react-router-dom'; import '@nx-example/shared/header'; -import { CartCartPage } from '@nx-example/cart/cart-page'; +import { CartCartPage } from '@nx-example/cart-cart-page/src/lib/cart-cart-page/cart-cart-page'; export const App = () => { return ( diff --git a/libs/cart/cart-page/package.json b/libs/cart/cart-page/package.json new file mode 100644 index 00000000..393ce05c --- /dev/null +++ b/libs/cart/cart-page/package.json @@ -0,0 +1,6 @@ +{ + "name": "@nx-example/cart-cart-page", + "version": "0.0.1", + "private": true, + "description": "" +} diff --git a/package.json b/package.json index b5e1c46e..5450198b 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,11 @@ "name": "nx-example", "version": "0.0.0", "license": "MIT", + "workspaces": [ + "apps/**/*", + "tools/**/*", + "libs/**/*" + ], "scripts": { "start": "nx serve", "build": "nx build", diff --git a/tsconfig.base.json b/tsconfig.base.json index 418e6fa3..dd19be52 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -17,7 +17,7 @@ "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { - "@nx-example/cart/cart-page": ["libs/cart/cart-page/src/index.ts"], + // "@nx-example/cart/cart-page": ["libs/cart/cart-page/src/index.ts"], "@nx-example/products/home-page": [ "libs/products/home-page/src/index.ts" ], diff --git a/yarn.lock b/yarn.lock index 03796ad5..99e84a94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5715,6 +5715,12 @@ __metadata: languageName: node linkType: hard +"@nx-example/cart-cart-page@workspace:libs/cart/cart-page": + version: 0.0.0-use.local + resolution: "@nx-example/cart-cart-page@workspace:libs/cart/cart-page" + languageName: unknown + linkType: soft + "@nx/angular@npm:22.4.0-beta.0": version: 22.4.0-beta.0 resolution: "@nx/angular@npm:22.4.0-beta.0" From 90c4d704257fa64e920710c43ee4bc568cbb4e36 Mon Sep 17 00:00:00 2001 From: Qing Lin Date: Tue, 23 Dec 2025 22:14:06 +0000 Subject: [PATCH 2/2] add noSelfCircularDependencies example --- .eslintrc.json | 18 +++++++++++++++++- apps/cart/src/app/app.tsx | 5 +++++ .../src/lib/cart-cart-page/cart-cart-page.tsx | 11 +++++++++++ libs/cart/cart-page/src/lib/utils/checkout.ts | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 libs/cart/cart-page/src/lib/utils/checkout.ts diff --git a/.eslintrc.json b/.eslintrc.json index dee660a3..49879f6c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -13,12 +13,28 @@ "allow": [], "depConstraints": [ { - "sourceTag": "type:app", + "allSourceTags": ["type:app", "scope:cart"], "onlyDependOnLibsWithTags": [ "type:no-such-type", "scope:shared", "type:ui" ] + }, + { + "sourceTag": "scope:products", + "onlyDependOnLibsWithTags": ["*"] + }, + { + "sourceTag": "type:feature", + "onlyDependOnLibsWithTags": ["*"] + }, + { + "sourceTag": "scope:shared", + "onlyDependOnLibsWithTags": ["*"] + }, + { + "sourceTag": "type:e2e", + "onlyDependOnLibsWithTags": ["*"] } ] } diff --git a/apps/cart/src/app/app.tsx b/apps/cart/src/app/app.tsx index 006c9bcf..cfe21c1f 100644 --- a/apps/cart/src/app/app.tsx +++ b/apps/cart/src/app/app.tsx @@ -2,6 +2,11 @@ import { Route, Routes } from 'react-router-dom'; import '@nx-example/shared/header'; +/** + * Should throw linting error because lib @nx-example/cart-cart-page only has tags "scope:cart" and "type:feature": + * + * A project tagged with "type:app" and "scope:cart" can only depend on libs tagged with "type:no-such-type", "scope:shared", "type:ui" @nx/enforce-module-boundaries + */ import { CartCartPage } from '@nx-example/cart-cart-page/src/lib/cart-cart-page/cart-cart-page'; export const App = () => { diff --git a/libs/cart/cart-page/src/lib/cart-cart-page/cart-cart-page.tsx b/libs/cart/cart-page/src/lib/cart-cart-page/cart-cart-page.tsx index 384ca9a1..de92017f 100644 --- a/libs/cart/cart-page/src/lib/cart-cart-page/cart-cart-page.tsx +++ b/libs/cart/cart-page/src/lib/cart-cart-page/cart-cart-page.tsx @@ -4,6 +4,17 @@ import styled from '@emotion/styled'; import '@nx-example/shared/product/ui'; +/** + * Should throw linting error: + * + * Projects should use relative imports to import from other files within the same project. + * Use "./path/to/file" instead of import from "@nx-example/cart-cart-page/src/lib/utils/checkout" @nx/enforce-module-boundaries + * + */ +import { checkoutUtils } from '@nx-example/cart-cart-page/src/lib/utils/checkout'; + +console.log('Checkout Utils:', checkoutUtils()); + import { CartItem, cartReducer, diff --git a/libs/cart/cart-page/src/lib/utils/checkout.ts b/libs/cart/cart-page/src/lib/utils/checkout.ts new file mode 100644 index 00000000..f673b45d --- /dev/null +++ b/libs/cart/cart-page/src/lib/utils/checkout.ts @@ -0,0 +1,2 @@ +export const checkoutUtils = () => + Math.random() > 0.5 ? 'Checkout Successful' : 'Checkout Failed';