环境配置
TIP
vue3.0采用Monorepo管理项目,代码采用ts编写,rollup打包
一、安装依赖
依赖 | 说明 |
---|---|
typescript | 支持ts |
rollup | 打包工具 |
rollup-plugin-typescript2 | rollup 和 ts的 桥梁 |
@rollup/plugin-node-resolve | 解析node第三方模块 |
@rollup/plugin-json | 支持引入json |
execa | 开启子进程方便执行命令 |
mkdir demo
cd demo
yarn init -y
yarn add typescript rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve @rollup/plugin-json execa -D
tsc --init
二、目录结构
├─packages # N个repo
│ └─reactivity # 响应式目录
│ │ package.json
│ └─src
│ index.ts
│ └─shared #公共方法目录
│ │ package.json
│ └─src
│ │ index.ts
└─scripts # 打包命令
│ │ build.js # 全部打包
| | dev.js # 单个打包
│ package.json # 配置运行命令
│ rollup.config.js # rollup配置文件
│ tsconfig.json # ts配置文件 更改为esnext
│ yarn.lock
三、代码文件
- 配置模块名称和打包选项
- packages/reactivity/package.json
{
"name": "@vue/reactivity", // 模块名称
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"module": "dist/reactivity.esm-bundler.js",
"buildOptions":{ // 打包选项
"name":"VueReactivity", // 打包模块的全局变量名称
"formats":[ // 打包的输出格式
"cjs",
"esm-bundler",
"global"
]
}
}
- packages/shared/package.json
{
"name": "@vue/shared",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"module": "dist/shared.esm-bundler.js",
"buildOptions":{
"name":"VueShared",
"formats":[
"cjs",
"esm-bundler"
]
}
}
- package.json
{
"private": true, //私有项目
"workspaces": [ // 工作目录
"packages/*"
],
"scripts": { // 打包脚本
"dev": "node scripts/dev.js",
"build": "node scripts/build.js"
}
}
- scripts/build.js
// 把packages 目录下的所有包都进行打包
// 读取文件
const fs = require('fs');
// 开启子进程 进行打包, 最终还是使用rollup来进行打包
const execa = require('execa');
// 1.读取packages下面的所有文件,并过滤出文件夹
const targets = fs.readdirSync('packages').filter(f => fs.statSync(`packages/${f}`).isDirectory());
// 2. 定义构建函数:开启子进程,构建rollup打包命令
async function build(target) {
// 当子进程打包的信息共享给父进程 rollup -c --environment TARGET:shared
await execa('rollup', ['-c', '--environment', `TARGET:${target}`], {stdio: 'inherit'});
}
// 3.定义并行打包函数:循环进行依次打包,最终返回promise.all的执行结果
function runParallel(targets, iteratorFn) {
const res = [];
for (const item of targets) {
const p = iteratorFn(item);
res.push(p);
}
return Promise.all(res);
}
// 4.并行打包
runParallel(targets, build);
- scripts/dev.js
// 只针对把packages下具体的某个包打包
// 读取文件
const fs = require('fs');
// 开启子进程 进行打包, 最终还是使用rollup来进行打包
const execa = require('execa');
// 1.手动控制需要打包的目录
const target = 'reactivity';
// 2. 定义构建函数:开启子进程,构建rollup打包命令
async function build(target) {
// 当子进程打包的信息共享给父进程 rollup -c --environment TARGET:shared
await execa('rollup', ['-cw', '--environment', `TARGET:${target}`], {stdio: 'inherit'});
}
// 3.单个打包
build(target);
- rollup.config.js
// rollup 的配置文件
import path from 'path';
import json from '@rollup/plugin-json';
import resolvePlugin from '@rollup/plugin-node-resolve';
import ts from 'rollup-plugin-typescript2';
// 1.找到packages
const packagesDirs = path.resolve(__dirname, 'packages');
// 2.找到具体要打包的基准目录
const packagesDir = path.resolve(packagesDirs, process.env.TARGET);
// 3.定义针对某个模块的拼接函数
const resolve = p => path.resolve(packagesDir, p);
// 4.找到package.json
const pkg = require(resolve('package.json'));
// 5.拿到具体文件夹名称
const name = path.basename(packagesDir);
// 6.定义打包类型的映射表,根据你提供的formats 来格式化需要打包的内容
const outputConfig = {
'esm-bundler': {
file: resolve(`dist/${name}.esm-bundler.js`),
format: 'es'
},
"cjs": {
file: resolve(`dist/${name}.cjs.js`),
format: 'cjs'
},
"global": {
file: resolve(`dist/${name}.global.js`),
format: 'iife'
}
}
// 7.拿到自己包在package.json中定义的选项
const options = pkg.buildOptions;
// 8.定义函数用于创建rollup的配置文件
function createConfig(format, output) {
// 选项覆盖和配置
output.name = options.name;
output.sourcemap = true;
// 生成rollup的配置文件
return {
input: resolve(`src/index.ts`),
output,
plugins: [
// 解析json
json(),
// ts配置
ts({
tsconfig: path.resolve(__dirname, 'tsconfig.json')
}),
// 解析第三方模块
resolvePlugin()
]
}
}
// 9.导出rollup的最终配置文件
export default options.formats.map(format => createConfig(format, outputConfig[format]));
- tsconfig.json
{
"compilerOptions": {
"target": "ESNEXT",
"module": "ESNEXT",
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"@vue/*":[
"packages/*/src"
]
}
}
}
四、执行命令
# 单个编译
yarn run dev
# 全部编译
yarn run build