01-Vue3源码学习开发环境搭建

211 阅读2分钟

搭建Monorepo环境

Vue3中使用pnpm workspace 来实现 monoreop

pnpm 是快速、节省磁盘空间的包管理。主要采用符号连接的方式管理模块。

全局安装 pnpm

npm install pnpm -g # 全局安装 pnpm

pnpm init # 初始化配置文件

创建 .npmrc 文件

shamefully-hoist = true

创建 pnpm-workspace.yaml 文件

# 定义包所在文件夹
packages:
    - 'packages/*'
  • 注意 pnpm install **报错, 记得使用以下命令,执行包的安装
pnpm install ** -w # -w 将包下载到根目录下

下载 typescript esbuild minimist

pnpm install esbuild typescript minimist -w -D

packages文件下每个项目进行初始化并进行配置

packages/reactive包为例

  • 初始化
# 执行初始化
pnpm init
  • 配置包自己的package.json文件
{
    "name":"@vue/reactivity",
    # 需要配置 buildOptions
    "buildOptions":{
        "name":"VueReactivity", // 名称 global 模式下,暴露给全局使用的
        "formats":[
            "global", // (function(){})()
            "cjs", // module.exports
            "esm-bundler", // export
        ]
    }
}

初始化 typscriopt 配置

pnpm tsc --init

配置 tsconfig.json

{
    "compilerOptions": {
        "outDir":"dist" , // 输出的目录
        "sourceMap":true, // 采用 sourcemap
        "target":"es2016", // 目标语法
        "module":"esnext", // 模块格式
        "moduleResolution":"node", // 模块解析方式
        "strict":true, // 严格模式
        "resolveJsonModule":true, // 解析json模块
        "esModuleInterop":true, // 允许通过es6语法引入commonjs模块
        "jsx":"preserve", // jsx 不转义
        "lib":["esnext","dom"], // 支持的类库 esnext & dom
        "baseUrl":".", // 解析非相对模块的基地址,默认是当前目录
        "paths": { // 路径映射,相对于baseUrl
            // 当使用 "@/vue/..." 引入模块时,会自动到 src下寻找模块
            "@vue/*":"packages/*/src/"
        }
    }
}

配置打包命令

  • 在根目录下,新建scripts文件夹,该文件夹下创建dev.js
// dev.js
const { build } = require('esbuild')
const { resolve } = require('path')

// 解析命令行参数
const args = require('minimist')(process.argv.slice(2))

// 获取打包那个模块
const target = args._[0] || 'reactivity'
// 获取打包格式
const format = args.f || 'global'

// 取出当前打包的 package.json文件
const pkg = require(resolve(__dirname, `../packages/${target}/package.json`))

const outfile = resolve(__dirname, `../packages/${target}/dist/${target}.${format}.js`)

// iife (function(){})()  立即执行函数
// cjs node中的模块 module.exports
// esm 浏览器中的 esModule import

const outputFormat = format.startsWith('global') ? 'iife' : format === 'cjs' ? 'cjs' : 'esm'
console.log(pkg.buildOptions.name)
build({
  entryPoints: [resolve(__dirname, `../packages/${target}/src/index.ts`)], // 入口文件
  outfile, // 打包输出文件的位置
  bundle: true, // 将任何导入的依赖内联到文件本身中去,这个过程是递归的,因此依赖关系也会被内联
  sourcemap: true,
  format: outputFormat, // 输出的格式
  globalName: pkg.buildOptions?.name, //全局挂载的时候的名字  window.xxx
  platform: format === 'cjs' ? 'node' : 'browser',
  watch: {
    // 监听文件变化
    onRebuild(error) {
      if (!error) {
        console.log(`rebuilt`)
      }
    }
  }
}).then(() => {
  console.log('watching...')
})


  • 在根目录下的package.json中配置打包命令
{
    "scripts":{
        "dev":"node scripts/dev.js reactivity -f global", // -f global 打包的格式
    }
}