一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu

使用 pnpm 构建 Monorepo 项目

背景

尝试一下使用pnpm构建大仓。

大仓常用的场景是:多个项目依赖于一个公共包,并且公共包经常不发npm包,在多人合作的大工程中经常会被使用。

多个项目中会有共享的代码则可以分包引用。并且每个 package 也可以在自己的作用域引入自己的 dependencies。

如果项目不是过于依赖建议不使用大仓形式。

搭建构建步骤

  1. 创建目录 test-monorep-v1
  2. 在项目目录中执行pnpm init ,并创建 packagesprojects 两个文件夹。
  3. 创建在根目录下创建 pnpm-workspace.yaml ,并输入用于配制包目录的路径。
packages:
 - 'packages/*'
 - 'projects/*'
  1. 在 projects 目录中创建react项目,或者是从现有的项目中复制进来。 复制进来的注意把node_modules删除掉。

这里进行创建一个新的app1项目。

cd projects
pnpm create vite app1 --template react-ts

先不对app1进行install

  1. 在packages中创建utils文件夹,并执行 pnpm init

修改生成的package.json文件,并将name 修改为 @test/utils 修改入口 mainindex.ts

最终utils中的 package.json 如下:

{
  "name": "@test/utils",
  "version": "1.0.0",
  "description": "",
  "main": "index.ts",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

index.ts 文件中内容如下:

export const add = (a: number, b: number) => a + b + 10000002;
  1. 配置eslint用来进行语法检查

.eslintrc.cjs 文件内容如下:

module.exports = {
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'airbnb-base',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:react-hooks/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended'
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  plugins: ['react', 'import', '@typescript-eslint'],
  rules: {
    semi: ['error', 'always'],
    quotes: ['error', 'single'],
    'max-len': ['error', { code: 120, tabWidth: 2 }],
    indent: ['error', 2],
    'space-before-function-paren': ['error', 'always'], // 表达式后边的空格
    'comma-dangle': ['error', 'never'],
    'no-multi-spaces': 1, // 不能用多余的空格
    'comma-spacing': [2, { before: false, after: true }], // 控制逗号前后的空格
    'no-dupe-keys': 2, // 在创建对象字面量时不允许键重复 {a:1,a:1}
    'no-else-return': 2, // 如果if语句里面有return,后面不能跟else语句
    'no-empty': 2, // 块语句中的内容不能为空
    'no-extra-parens': 2, // 禁止非必要的括号
    'no-extra-semi': 2, // 禁止多余的冒号
    'no-spaced-func': 2, // 函数调用时 函数名与()之间不能有空格
    'no-use-before-define': 2, // 未定义前不能使用
    'arrow-parens': 0, // 箭头函数用小括号括起来
    'arrow-spacing': 1, // =>的前/后括号
    'key-spacing': [1, { beforeColon: false, afterColon: true }], // 对象字面量中冒号的前后空格
    'lines-around-comment': 1, // 行前/行后备注
    'spaced-comment': 1// 注释风格不要有空格什么的
  }
};

当前项目结构如下:

├── .eslintrc.cjs
├── package.json
├── packages
│   └── utils
│       ├── index.ts
│       └── package.json
├── pnpm-workspace.yaml
└── projects
    └── app1
        ├── .eslintrc.cjs
        ├── .gitignore
        ├── index.html
        ├── package.json
        ├── public
        │   └── vite.svg
        ├── src
        │   ├── App.css
        │   ├── App.tsx
        │   ├── assets
        │   │   └── react.svg
        │   ├── index.css
        │   ├── main.tsx
        │   └── vite-env.d.ts
        ├── tsconfig.json
        ├── tsconfig.node.json
        └── vite.config.ts

安装依赖包

  1. 向根目录中安装

需要的话使用-w(–workspace-root) 例如下面eslint相关包。

pnpm add eslint eslint-config-airbnb-base eslint-plugin-import -w -D 
pnpm add @typescript-eslint/parser @typescript-eslint/eslint-plugin -w -D
pnpm add eslint-plugin-react eslint-plugin-react-hooks -w -D
  1. 向单个目录中安装 某个pack的依赖

pnpm --filter app1 i @test/utils -r 这样我们就在 app1 项目中安装了@test/utils 依赖。

执行完成后,会在app1package.json 中产生如下配置

"dependencies": {
    "@test/utils": "workspace:^1.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },

启动某个项目

启动 app1 (pnpm语法其实很好记,对某个仓库操作直接使用 –filter)

pnpm --filter app1 run dev

项目中使用包

这样在项目中app1中就可以使用 @test\utils 模块

import { add } from '@test/utils';
console.log(add(1, 5));

其他

  1. 修改被依赖包是否会进行HMR?

是的,使用vite作为开发工具时,修改依赖是可以进行热更新的。

  1. WARN  Issues with peer dependencies found

在依赖文件时会出现如下问题:

 WARN  Issues with peer dependencies found
projects/app1
├─┬ @project1/modle1 0.1.32
│ ├── ✕ unmet peer react@^16.8.0: found 17.0.2

什么是peeDependencies

当我们在一些npm包当中中,用到一些核心的依赖,这些依赖又是跟顶部应用的依赖的一样的时候,会把这些放到peerDependencies当中。

而且这个peerDependencies通常在插件当中出现。

问题来了,为什么不能直接把这些依赖直接放到dependencies当中呢?

例如: 想象一下,您正在开发一个ReactApp,他依赖React,有两个插件plugin1,plugin2,他们也依赖React,如果在两个插件中使用dependencies,那么在 install 之后,在两个插件下都会出现对React 的依赖。

React在顶层已经安装了一次,但是在plugin1 和 plugin2 中又进行了重复的安装,所以被安装了三次。

peerDependencies 就是干这事情的,避免重复安装依赖。

网上说了很多方法,不管哪种解决方法,都是需要用户自己去解决这些不一致问题。

所以说现在npm,pnpm本身并没很好的办法去解决库当中版本依赖不一致的问题,终局还需要手动升级包或者插件。

具体的结局方法可以参照: 传送门

如我上面所说,警告⚠️就是告诉你不一定会报异常,但是也不确定能一定能正常。

库当中的版本依赖不一致是有可能造成一些不不要的麻烦的,所以你看到如babel-loader, babel这些库在升级版本时候,官方要求多个库同步升级,否则会构建失败。

原文链接:https://juejin.cn/post/7243725147110391867 作者:大熊全栈分享

(0)
上一篇 2023年6月13日 上午10:11
下一篇 2023年6月13日 上午10:21

相关推荐

发表评论

登录后才能评论