yarn3 PnP + workspace + typescript 从零开始搭建一个 monorepo

使用 yarn3 PnP + workspace + typescript 从零开始搭建一个 monorepo

先看下项目的整体结构:

目录

使用 yarn 初始化项目


  1. 先执行 yarn set version stable 使用稳定版本, 当前是 v3.4.1。
  2. 执行 yarn init 初始化项目
  3. 执行 mkdir packages 新建 packages 文件夹
  4. 修改 package.json, 声明 workspace

  "workspaces": [
    "packages/*"
  ]

yarn v2+ 默认开启 PnP 模式, 因此无需修改 .yarnrc.yml 文件

初始化子项目


1. 执行以下命令

yarn create react-app packages/app1 --template typescript
yarn create react-app packages/app2 --template typescript

按照 monorepo 的惯例,子项目的名称最好命名为@<主项目名称>/<子项目名称>。分别进入 app1 和 app2 的package.json 中修改 name :

@yarn3-demo/app1
@yarn3-demo/app2

然后删除这两个子项目中的 node_modules文件夹。

create-react-app 在初始化项目的过程中就会安装依赖到 .yarn/cache 中。

接着,手动创建 common 子项目备用

  1. 进入 packages 文件夹,执行 mkdir common
  2. 进入 common 文件夹,按照下面目录新建文件

   └── common
       ├── README.md
       ├── components
       │   └── test.ts
       ├── index.d.ts
       ├── index.ts
       └── package.json

  1. 修改 common 子项目名称为 @yarn3-demo/common

在 test.ts 中编写一个测试函数


export function add(x: number, y: number) {
  return x + y;
}

在 index.ts 中导出


export { add } from './components/test';

修改 package.json 中的 main 字段:

"main": "index.ts"

2.tsconfig.json 共享和 ts 支持

tsconfig.json 共享

把子项目中的 tsconfig.json copy 一份到顶层并删除其中的 include 属性

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  }
}

修改子项目的 tsconfig.json


{
 "extends": "../../tsconfig.json",
 "include": ["src"]
}

ts 支持

这个时候 ts 还找不到依赖包的定义。这是因为 .yarn/cache 下都是 .zip 文件,ts 解析器无法直接读取 .d.ts 文件。

typescript 官方目前也不支持读取 .zip 下的 .d.ts,尽管 yarn 团队已经为 PnP 提了 PR。 https://link.juejin.cn/?target=https%3A%2F%2Fyarnpkg.com%2Fgetting-started%2Fqa%23why-is-typescript-patched-even-if-i-dont-use-plugnplay

下面按照官方给出的步骤一步步操作:https://link.juejin.cn/?target=https%3A%2F%2Fyarnpkg.com%2Fgetting-started%2Feditor-sdks

  1. 在 vscode 中安装 ZipFS
  2. 在根目录下执行
yarn dlx @yarnpkg/sdks vscode

  1. 这个时候 vscode 会弹窗提示选择一个 typescirpt 版本,我们选择 Use Workspace Version 即可。
    这个时候就会发现 ts 已经可以找到依赖的定义了😀。

1

共享配置文件

配置文件包括 .prettierrc .eslintrc.js .editorconfig 等, 这里我们只着重说项目构建相关配置

在根目录执行



yarn workspace @yarn3-demo/app2 run eject

这个是 create-react-app 给我们提供的一个用来自定义构建的命令。执行后 CRA 项目中的 config 文件夹和 scripts 文件夹会弹出来, 这两个文件夹下的文件的依赖会放在项目的package.json 中。我们需要做的就是:

  1. 把 config 文件夹和 scripts 文件夹移动到根目录下
  2. 在 config/paths.js 中新增 packages 路径
packages: path.resolve(__dirname, '../packages/')

  1. 在 config/webpack.config.js 中修改 babel-loader 配置
include:paths.appSrc  -> include: [paths.appSrc, paths.packages]

  1. 修改 package.json 中的 scripts
"start": "yarn node ../../scripts/start.js",
"build": "yarn node ../../scripts/build.js",

注意这里要使用 yarn node

https://link.juejin.cn/?target=https%3A%2F%2Fyarnpkg.com%2Fgetting-started%2Fmigration%2F%23call-your-scripts-through-yarn-node-rather-than-node

依赖管理

1. 给子项目安装第三方依赖

拿 lodash 举例, 执行命令

yarn workspace @yarn3-demo/app2 add lodash


删除依赖

yarn workspace @yarn3-demo/app2 remove lodash



另外,我们一般安装第三方依赖的时候会把其对应的 @types/xxx 也安装,比如 ```bash yarn add lodash @types/lodash

比较麻烦也有可能会忘记安装 types 文件,yarn 提供了一个插件可以自动为我们安装 types 文件,执行

yarn plugin import typescript

然后重新安装 lodash

这样 @types/lodash 就会自动被安装在 devDependencies

2. 子项目安装其他作为本地依赖的子项目

现在我们要在子项目 app2 中引用 common,在根目录下执行

yarn workspace @yarn3-demo/app2 add @yarn3-demo/common


查看 app2 的 package.json 文件会发现 dependencies 中多了

 "@yarn3-demo/common": "workspace:^"

测试一下,在 app2/src/index.tsx 中

import { add } from '@yarn3-demo/common';
console.log(add(1, 2));

几个需要注意的点:

  1. 子项目不能使用父级依赖。
  2. 无论是父级还是子项目都只能使用自己的 package.json 中显示声明的依赖,这是因为 PnP 默认为严格模式,不建议更改。
  3. 如果是手动修改了 package.json 一定要记得执行 yarn isntall 重新生成 .pnp.cjs,目的是重新构建依赖树让 node 可以定位到我们的依赖。

启动子项目

以上所有准备已经完成,启动子项目试试吧~

执行命令

 yarn workspace @yarn3-demo/app2 start

success😀

版本控制

现在我们要发布 app2 了,如果只是修复了一个小 bug , 那我们可以

执行命令, 安装 version 插件

yarn plugin import version

修改版本

yarn workspace @yarn3-demo/app2 version patch

查看 package.json 会发现 app2 的版本从 0.1.0 变成了 0.1.1。

更多可以查看 yarn version 命令

打包

执行命令

yarn workspace @yarn3-demo/app2 run build   

总结

PnP

yarn v2 版本起默认开启了 PnP 的功能,这个功能开启后项目将不再存在 node_modules 文件夹,所有的依赖都会被压缩成一个 .zip 文件存放在 .yarn/cache 中。

零安装

由于压缩后的包体积很小,而且包的数量不会很多,我们可以直接把 .yarn/cache 上传到 git 仓库, 这样一来的好处:

  1. 更好的开发体验。你每次使用 git clone git pull 等命令更新完你的代码后无需使用 yarn install 进行依赖的安装,这样可以避免一些问题的出现,例如别人更新了某个依赖的版本后,如果你没有进行对应的更新的话,你的代码可能会报错。
  2. 代码 review 的时候可以更清楚哪些依赖发生了改变。
  3. 更快,更简单,更稳定的 CI 部署。由于每次部署代码的时候,yarn install 占用的时间都是一个大头,去掉这个步骤后部署速度将会大大提升。
  4. 不会存在本地运行没问题,发布线上环境的时候挂掉了的问题。
  5. 不用你在 CI 文件里面进行一些安装依赖的配置。

零安装好处毋庸置疑,但显得比较激进,.yarn/cache 对于开发者更像一个黑盒:

  1. monorepo 下无论是子项目依赖还是父级依赖都安装在 .yarn/cache,没有一个清晰的结构

  2. 因为 .zip 格式,ts 支持不友好,需要额外工作量(上面已经提到)

  3. 同样因为 .zip 格式,想要调试某个依赖的话需要额外工作量(需要 yarn unplug)

  4. 实际测试中 vscode 的 ts 服务有时候会挂掉(可能是因为根目录没有安装 typescript 或者版本过低)

123

优劣对比之下,通过 yarn3 PnP + workspace + typescript 来搭建 monorepo 还是非常值得一试的~

后续还会尝试一下 pnpm + workspace + typescript 来搭建 monorepo,敬请期待~

本文产出 git 仓库地址:github.com/ohguaiguai/… 如想尝试可直接 git clone, 无需 yarn install 体验下零安装👏👏👏

git clone 之后,启动项目会报错:


Error: Required unplugged package missing from disk. This may happen when switching branches without running installs (unplugged packages must be fully materialized on disk to work).

Missing package: open@npm:8.4.0

Expected package location: /Users/zhangxing/Desktop/yarn3-demo/.yarn/unplugged/open-npm-8.4.0-df63cfe537/node_modules/open/

这是因为部分包是默认 unplugged 的, 比如上面的 open@npm:8.4.0, 可能还需要 yarn install 一次。感谢大佬@洛冰河指正~
按照官网说的配置 enableScripts: false 之后,还是无法在 git clone 之后直接运行。看起来如果使用了默认为 unplugged 的包必须要重新 yarn install 一次。

_转载 _

  1. https://juejin.cn/post/7197767400098758717

  2. https://zhuanlan.zhihu.com/p/107343333

  3. https://juejin.cn/post/6913788953971654663#heading-19

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下步骤在 Vue3 + Vite3 + Typescript 中使用 WangEditor 编辑器: 1. 安装 WangEditor。可以使用 npm 或 yarn 安装。 ```bash npm install wangeditor --save # 或者 yarn add wangeditor ``` 2. 在 `main.ts` 中引入 WangEditor 和 CSS 文件。 ```typescript import WangEditor from 'wangeditor'; import 'wangeditor/release/wangEditor.css'; const app = createApp(App); app.config.globalProperties.$WangEditor = WangEditor; // 挂载编辑器到全局 app.mount('#app'); ``` 3. 在组件中使用 WangEditor。 ```vue <template> <div class="editor-wrapper"> <div ref="editorRef"></div> </div> </template> <script lang="ts"> import { defineComponent, onMounted, ref } from 'vue'; export default defineComponent({ name: 'Editor', setup() { const editorRef = ref<HTMLDivElement>(); onMounted(() => { const editor = new (window as any).$WangEditor(editorRef.value); editor.create(); }); return { editorRef, }; }, }); </script> <style lang="scss"> .editor-wrapper { height: 400px; .w-e-text-container { height: 100%; } } </style> ``` 在 `onMounted` 钩子函数中,使用 `new (window as any).$WangEditor` 来创建编辑器实例,并传入编辑器容器的 DOM 节点。调用 `editor.create()` 方法来创建编辑器。 注意:由于 WangEditor 的类型定义文件并不完善,因此可以在 `tsconfig.json` 中添加以下配置来避免类型检查报错。 ```json { "compilerOptions": { "skipLibCheck": true } } ``` 这样,就可以在 Vue3 + Vite3 + Typescript 中使用 WangEditor 编辑器了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值