搭建Monorepo项目
pnpm workspace实现项目搭建,pnpm是快速、节省磁盘空间的包管理器。主要采用符号链接的方式管理模块
全局安装pnpm
// 全局安装pnpm
npm install pnpm -g
// 初始化配置文件
pnpm init -y(已无效,执行npm init -y)
根目录下创建packages文件夹
根目录下创建pnpm-workspace.yaml
内容中的packages对应刚创建的文件夹名字,代表所有的包都在此文件夹packages下。 内容:
packages:
- 'packages/*'
全局安装vue
执行pnpm install vue -w
-w的意思是:workspace-root(工作目录的根路径下) 根目录下会生成node_modules
根目录下创建.npmrc文件
第三方依赖一也有依赖,要是项目中使用了,第三方的依赖,要是哪天第三方卸载了,那就找不到了,称之为“幽灵依赖” 所以:羞耻提升,暴露到外层中,即是在node_modules下,而非在.pnpm文件夹中。 内容:
shamefully-hoist = true
安装typescript、minimist、esbuild
pnpm install typescript minimist esbuild -w -D
packages文件夹下创建reactivity跟shared文件夹
初始化reactivity项目的package.json
添加buildOptions配置
"buildOptions": {
"name": "VueReactivity",
"formats": [
"global",
"cjs",
"esm-bundler"
]
},
同理,shared项目
shared中不需要配置buildOptions.formats: global,因为几乎不会使用script标签来引入该项目,并且使用其中的某个子功能方法的情况。
reactivity跟shared项目下创建src目录,并创建index.ts
试验,manage路径下执行
pnpm uninstall vue
把manage中的node_modules删除,执行完删除vue的指令后,vscode其实还是看得到vue的东西还在node_modules中,这是因为缓存,vscode点击刷新一下文件就看不到vue相关了
所以需要将reactivity跟shared关联起来。
初始化ts配置文件ts.config.json
执行:
tsc --init
ts.config.json 内容:
{
"compilerOptions": {
"outDir":"dist", // 输出的目录
"sourceMap": true, //采用sourcemap
"target": "es2016", // 目标语法
"module": "esnext", // 模块格式
"moduleResolution": "node", // 模块解析
"strict": false, // 严格模式
"resolveJsonModule": true, // 解析json模块
"esModuleInterop": true,// 允许通过es6语法引入commonjs模块
"jsx":"preserve",// jsx不转义
"lib":["esnext","dom"],// 支持的类库esnext及dom
"baseUrl": ".",// 当前是以该路径进行查找
"paths":{
"@vue/*":["packages/*/src"], // 即以@vue开头的都去该路径下查找,是个数组
}
}
}
创建scripts/dev.js
const args = require("minimist")(process.argv.slice(2)); // node scripts/dev.js reactivity -f global
const { build } = require("esbuild");
// node 中的内置模块
const { resolve } = require("path");
// minist 用来解析命令参数
const target = args._[0] || "reactivity";
const format = args.f || "global";
// 开发环境只打包某一个
const pkg = require(resolve(__dirname, `../packages/${target}/package.json`));
// iife 立即执行函数(function(){})()
// cjs node中的模块 module.exports
// esm 浏览器中的esModule模块 import
const outpuFormat = format.startsWith("global")
? "iife"
: format === "cjs"
? "cjs"
: "esm";
//
const outfile = resolve(
__dirname,
`../packages/${target}/dist/${target}.${format}.js`
);
build({
entryPoints:[resolve(__dirname,`../packages/${target}/src/index.ts`)],
outfile,
bundle:true,
sourcemap:true,
format:outpuFormat,
globalName:pkg.buildOptions?.name,
platform:format==='cjs'?'node':'browser',
watch:{
onRebuild(error){
if(!error){
console.log(`rebuild~~~`)
}
}
}
}).then(() => {
console.log('watching~~~')
})