vue3学习与my-vue3实现01: 基于pnpm与rollup搭建框架学习环境

147 阅读3分钟

以pnpm构建monorepo

// 新建项目文件夹
mkdir my-vue3 && mkdir my-vue3
// 使用pnpm项目初始化
pnpm init

搭建my-vue3项目基本结构

├── package.json
├── packages				# 多子项目的目录
│   ├── vue		                # 打包、测试实例、项目整体入口模块
│   │   ├── src/*
│   │   └── package.json
│   ├── reactivity			# 响应性模块
│   │   ├── src/*
│   │   └── package.json
│   ├── shared			        # 共享公共方法模块
│   │   ├── src/*
│   │   └── package.json
├── scripts    				#存放项目通用编译脚本
└── pnpm-workspace.yaml                 #monorepo项目配置文件

上面的项目结构并没有包含所有的vue项目目录,在后续的开发中,会逐渐增减。

需要注意每一个包目录里面也需要一个 package.json 文件进行声明这是一个 NPM 包目录。所以我们需要进入每个包目录进行初始一个 package.json 文件。以 vue 包为例,我们进入到 vue 目录底下初始化一个 package.json 文件,更改包名:@my-vue3/vue。文件内容如下:

{
  "name": "@my-vue3/vue",
  "version": "0.0.1",
  "description": "",
  "main": "index.ts",
}

配置pnpm的monorepo工作区

创建pnpm-workspace.yaml,进行 monorepo 的项目配置

packages:
  - packages/*

仓库项目内的包相互调用

@my-vue3/vue需要调用@my-vue3/reactivity,就需要把它安装到根目录下的node_modules目录中

// -w 表示安装到共公模块的 packages.json 中,也就是根目录下的 packages.json。
pnpm install @my-vue3/reactivity -w

TS配置

pnpm add -D typescript @types/node -w
{
  "compilerOptions": {
    "outDir": "dist", // 指定输出目录
    "target": "es2018", // 目标语言的版本
    "module": "esnext", // 生成代码的模板标准
    "baseUrl": ".", // 解析非相对模块的基地址,默认是当前目录
    "sourceMap": false, // 是否生成相应的Map映射的文件,默认:false
    "moduleResolution": "node", // 指定模块解析策略,node或classic
    "allowJs": false, // 是否允许编译器编译JSJSX文件
    "strict": true, // 是否启动所有严格检查的总开关,默认:false,启动后将开启所有的严格检查选项
    "noUnusedLocals": true, // 是否检查未使用的局部变量,默认:false
    "resolveJsonModule": true, // 是否解析 JSON 模块,默认:false
    "allowSyntheticDefaultImports": true, // 是否允许从没有默认导出的模块中默认导入,默认:false
    "esModuleInterop": true, // 是否通过为所有导入模块创建命名空间对象,允许CommonJS和ES模块之间的互操作性,开启改选项时,也自动开启allowSyntheticDefaultImports选项,默认:false
    "removeComments": false, // 删除注释
    "rootDir": ".", // 指定输出文件目录(用于输出),用于控制输出目录结构
    "types": [],
    "paths": { // 路径映射,相对于baseUrl
      "@my-vue3/*": ["packages/*/src"]
    }
  },
  "include": ["packages/*/src"]
}

rollup配置

pnpm add -D rollup-plugin-typescript2 tslib @rollup/plugin-node-resolve @rollup/plugin-commonjs -w

创建rollup.config.js文件

import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from 'rollup-plugin-typescript2'

/**
 * 默认导出一个数组,数组的每一个对象都是一个单独的导出文件配置,详细可查:https://www.rollupjs.com/guide/big-list-of-options
 */
export default [
  {
    // 入口文件
    input: 'packages/vue/src/index.ts',
    // 打包出口
    output: [
      // 导出 iife 模式的包
      {
        // 开启 SourceMap
        sourcemap: true,
        // 导出的文件地址
        file: './packages/vue/dist/vue.js',
        // 生成的包格式:一个自动执行的功能,适合作为<script>标签
        format: 'iife',
        // 变量名
        name: 'Vue'
      }
    ],
    // 插件
    plugins: [
      // ts 支持
      typescript(),
      // 模块导入的路径补全
      resolve(),
      // 将 CommonJS 模块转换为 ES2015
      commonjs()
    ]
  }
]

并在package.json新增一个scripts:

"build": "rollup -c -w"

然后从packages/vue/src/index.ts中导出一个变量,在执行npm run bulid,代码如下图所示,则打包成功

引入代码格式工具

pnpm add -D -w eslint @antfu/eslint-config

新建.eslintrc文件,并写入以下内容:

{
  "extends": "@antfu"
}

因为我使用的webstorm,以下是我的配置截图:

测试

此时我们可以在vue/src/index.ts中导出一个变量

export const name = 'echo'

然后运行命令npm run build即可在vue/dist文件夹下看到编译后的结果

var Vue = (function (exports) {
   'use strict';

   const name = 'echo';

   exports.name = name;

   return exports;

})({});
//# sourceMappingURL=vue.js.map

总结

以上内容完成后,为我们后续源码的学习提供了学习的开发环境。

感谢

本系列文章的撰写参考了《vue.js设计与实现》、发表在掘金上的系列文章《vue3 源码学习,实现一个 mini-vue》,特此感谢在我学习vue路上给予的帮助。

代码示例

github.com/KoiraCMT/my…