遇见Nx.dev
什么是Nx
- 简单来讲,Nx可以快速搭建一个新的独立项目甚至整个
monorepo。它可以逐步采用,并随着项目的扩展而增长。 - 官方介绍:nx.dev/getting-sta…
- monorepo很多包管理工具都支持,熟知的:npm、pnpm、lerna
- 那什么是
monorepo呢?monorepo.tools(它会给你答案)
以我这个小白的角度来想,即要满足可以同时开发、维护、规范一系列子包,还要能同时构建、发布等一系流流程...,实际场景:对于前端业务子包、UI团队子包要相互引用...
😃我想用monorepo并且采用Nx的原因:有些公司招聘需要、同时我想要写一些业务场景的小项目,合在一项目里又不太适合,分开又要创建不同的GitHub仓库,所以决定
all in one即可
⚠️ 本博客主要以记录为主,非常推荐大家如果感兴趣,一定要将文档过一遍
搭建React子包
# 根据提示创建一个空的monorepo
npx create-nx-workspace@latest --preset=npm
npm install -D @nrwl/react
nx g @nrwl/react:app my-new-app # 根据提示走完流程
.
├── README.md
├── babel.config.json
├── jest.config.ts
├── jest.preset.js
├── nx.json # nx配置文件
├── package.json
├── packages
│ ├── web-print # 我们的react项目
│ │ ├── jest.config.ts
│ │ ├── project.json # 项目nx配置文件,如lint、serve、build命令
│ │ ├── src
│ │ ├── tsconfig.app.json # 3个根TS相关的配置
│ │ ├── tsconfig.json
│ │ ├── tsconfig.spec.json
│ │ └── webpack.config.js # webpack配置
│ └── web-print-e2e # e2e测试项目
└── tsconfig.base.json
- 配置webpack别名
// webpack.config.js
const { composePlugins, withNx } = require("@nrwl/webpack");
const { withReact } = require("@nrwl/react");
const { resolve } = require("path");
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), withReact(), (config) => {
config["resolve"].alias = {
"@": resolve(__dirname, "./src"),
assets: resolve(__dirname, "./src/assets"),
};
return config;
});
// tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"paths": { // 添加TS别名(仅为了编译通过,webpack会处理别名)
"@/*": ["./src"],
"assets/*": ["./src/assets"],
}
},
// ...
}
- 开发
nx run web-print:serve # 运行dev
Nx:运行任务
- 运行单个任务
nx run web-print:lint
nx lint web-print # 上面cli的简写
# 使用特定的配置项并覆盖默认
nx build web-print --configuration=production
- 运行所有子项目的任务
nx run-many -t lint # 运行所有子项目的lint命令
- 运行受git改动影响的子项目
nx affected -t lint
Nx:受影响的项目
affected:依赖于git元数据来确定您的workspace中提交影响到的项目
# commit代码后,修改部分代码,可以通过`nx affected:graph`查看受影响的项目
nx affected --target lint # 受影响的项目全部执行lint命令
nx affected -t lint # 受影响的项目全部执行lint命令
Nx:缓存任务结果
- nx.json
{
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
// 针对以下命令启用缓存,如果文件未改动则无需再运行(前提:未改动属性需要生成一致输出,比如后台和数据库交互就不行,因为数据库可能随时变动)
"cacheableOperations": ["build", "lint", "test", "e2e"]
}
}
},
}
nx build web-print # 第一次会进行build编译
nx build web-print # 第二次因为相同文件则会直接读取缓存
# 缓存提示如下
> NX Successfully ran target build for project web-print (24ms)
Nx read the output from the cache instead of running the command for 1 out of 1 tasks.
Nx可视化
- Nx创建了存储库中所有项目之间的依赖关系图
nx graph # 启动一个前端项目并打开浏览器窗口
NX Project graph started at http://127.0.0.1:4211/projects
Nx集成进编辑器
project.json任务执行器
{
"serve": {
// executor:运行哪个NX执行器(plugin名:命令名)
// [包名, 执行器名] = [@nrwl/linter, eslint]
"executor": "@nrwl/webpack:dev-server",
"defaultConfiguration": "development",
"options": { // 默认配置选项
"buildTarget": "web-print:build",
"hmr": true
},
"configurations": { // 配置,都以options key作为选项,使用时进行覆盖
"development": {
"buildTarget": "web-print:build:development"
},
"production": {
"buildTarget": "web-print:build:production",
"hmr": false
}
}
},
"echo": {
"command": "echo 'hello world'" // 运行指定命令行
}
}
Nx:环境变量
- nx可以识别的环境变量:nx.dev/recipes/env…
// 一般env文件名使用如下
.env // 生产环境
.env.local // 开发环境
⚠️ 所有环境变量都要以
NX_作为前缀开头
// 例如react TSX中获取
console.log(process.env);
{ NX_CLI_SET: 'true', NX_LOAD_DOT_ENV_FILES: 'true', NX_STREAM_OUTPUT: 'true' , ...}