拒绝重复劳动,自动为项目添加 target


这是一系列博文中的一篇,用来记录将我将公司的前端项目改造为 monorepo 的过程。

2 / 4 of Nx Monorepo Experience

完成了自制的插件过后,我们得往需要使用 lingui 的项目中添加相关的 target,项目少还好说,项目一多,这就变成纯体力劳动了。还好, nx 提供了 Project Inference 机制,给插件加上几行代码,就可以让 nx 自动为项目添加合适的 target。

与 executor 不同,project inference 功能需要在 nx.json 中注册:

{
  "plugins": [
    "my-nx-plugin"
  ]
}

Project inference 功能由 my-nx-plugin 模块默认导出的两个变量来实现:

  • projectFilePatterns 主要用来识别项目文件,项目目录中匹配的文件会作为参数传递给 registerProjectTargets
  • registerProjectTargets 是一个用来根据项目文件推断 targets 的函数,它返回一个 Record<string, TargetConfiguration>,即我们在 project.json/targets 中编写的内容。

一个给项目添加 lingui target 的实现如下:

import { workspaceRoot } from '@nrwl/devkit';
import * as path from 'path';  
import * as fs from 'fs';
import type { TargetConfiguration } from '@nrwl/devkit';

export const projectFilePatterns = ['package.json'];

export function registerProjectTargets(projectFilePath: string): Record<string, TargetConfiguration> {
 // 通过导入的 workspaceRoot 变量来获取当前 nx workspace 的根目录,这样可以将 projectFilePath 转换为绝对路径
 const projectRoot = path.join(workspaceRoot, path.dirname(projectFilePath));  
 return { 
   ...linguiTargets(projectRoot),  
 };  
}

function linguiTargets(projectRoot) {
  const packageJSON = fs.readFileSync(path.join(projectRoot, 'package.json'), 'utf8');
  // 只要项目依赖了 lingui,就给它添加 lingui target
  if (packageJSON.indexOf('lingui') > 0) {
    return {
      lingui: {
        executor: 'nx-plugin:lingui',
        options: {
          locales: path.join(projectRoot, 'locales'),
        }
      }
    }
  }
}

在实现这个功能的时候需要注意几点 registerProjectTargets 必须是个同步函数,所以不能使用任何异步 API,也没法用之前提到的方法来引用 ESM。另外,nx 出于性能考量,会缓存 registerProjectTargets 的结果,所以在 Debug 的时候,一定要记得设置环境变量 NX_CACHE_PROJECT_GRAPH=false

在处理文件路径的时候,建议尽量使用绝对路径,使用相对路径需要思考是相对于 workspace root 还是 cwd,用绝对路径可以减少这方面的心智负担。

虽然功能实现了,但是现在还不能立马使用,需要将插件源码转译成 CJS 代码。前面的文章提到过用 postinstall 来编译自定义 nx 插件,在实现了今天的功能后,编译自定义插件的命令必须不能用 nx 来执行,因为 nx 执行任何命令都会加载插件模块,如果我们的插件没有编译成 CJS,通过 nx 调用的编译插件命令也会失败。

Project Inference 功能非常强大,可以很大地减少我们维护项目 targets 的负担,在我看来,这算得上 nx 的旗舰功能了,后面我也会再演示一些其他使用 Project Reference 的典型场景。

Series Navigation<< 年轻人的第一个 nx 插件如何使用 nx 缓存构建产物 >>
,

《“拒绝重复劳动,自动为项目添加 target”》 有 1 条评论

回复 如何使用 nx 缓存构建产物 - 网上冲浪指南 取消回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

You can use markdown syntax in comment

  1. […] 拒绝重复劳动,自动为项目添加 target […]