Dark Dwarf Blog background

Nx 前端单体项目配置的一些记录

Nx 前端单体项目配置的一些记录

1. shadcn init

在 Nx 单体项目中,package.jsontsconfig.json都是放在根目录的,而前端代码在apps/frontend目录下,于是需要配置components.json让它指向前端项目:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "apps/frontend/tailwind.config.js",
    "css": "apps/frontend/src/app/global.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "iconLibrary": "lucide"
}

然后创建一个tsconfig.json文件来告诉 shadcn.ui 已经在项目中、不需要新建项目了:

{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["apps/frontend/src/*"]
    }
  },
  "include": [],
  "exclude": []
}

apps/frontend/tsconfig.json中也需要添加同样的配置。由于我创建了 Nx lib、会与 shadcn.ui 的@路由造成语义冲突,只需额外定义对应的 paths:

"paths": {
  "@/*": ["./src/*"],
  "@discord-platform/shared": ["../../shared/src/index.ts"]
}

然后 Nx 的 Next.js tailwind.config.js 中还有下面的配置:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./{src,pages,components,app}/**/*.{ts,tsx,js,jsx,html}",
    "!./{src,pages,components,app}/**/*.{stories,spec}.{ts,tsx,js,jsx,html}",
    ...createGlobPatternsForDependencies(__dirname),
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

这里的...createGlobPatternsForDependencies(__dirname)需要手动开启。这个是 Nx 专门写的辅助函数,它会分析依赖图、生成路径动态注入content中,而不需要手动注入在frontend/src外的库。

2. tailwind.css 配置

Nx 默认创建的 tailwind.css 是 v3 + postcss 配置(并且我后面换成了用 Webpack 打包而不是 Turbopack),因此需要在global.css中如下 import:

@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tw-animate-css";

3. 使用 Webpack 打包

Nx 创建的 Next.js 项目默认使用 Turbopack 打包,这个打包方式处理 Nx 的复杂依赖会出问题(比如报一大堆意义不明的错误日志),修改project.json指定Webpack打包方式:

"targets": {
  "build": {
    "command": "next build --webpack",
    "options": {
      "cwd": "apps/frontend"
    },
    "outputs": [
      "{projectRoot}/.next/!(cache)/**/*",
      "{projectRoot}/.next/!(cache)"
    ]
  }
}