搭建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 打包的格式
}
}