Rollup 是一个 JavaScript 模块打包工具,可以将多个小的代码片段编译为完整的库和应用。与传统的 CommonJS 和 AMD 这一类非标准化的解决方案不同,Rollup 使用的是 ES6 版本 Javascript 中的模块标准。新的 ES 模块可以让你自由、无缝地按需使用你最喜爱的库中那些有用的单个函数。这一特性在未来将随处可用,但 Rollup 让你现在就可以,想用就用
在vue2中,打包采用的是webpack,而到了vue3中打包就变成了rollup,而且不仅仅vue3采用了rollup来打包,react也从webpack到rollup转变了。那么rollup打包工具是不是要比webpack打包要好呢?其实各自有各自的用途,我们通过对比vue2和vue3的一些用法就可以简单的看出来两者打包工具的一些区别,vue3最大的一个特性就说采用了组合式API,简单来说vue2更多的像一个百宝箱,我们可以开箱即用,而vue3更多的是提供一些基础功能,然后让使用者去选择,灵活使用。
两者打包工具各自有各自的好处,就像一句话说的"webpack是大而全,rollup是小而美"。首先相对于webpack来说rollup更加轻量级,同时rollup是一个JS模块打包器,更适合于JS库打包,而webpack更适合的是大型项目。
1 安装yarn
npm install -g yarn
2 开始进行打包
初始化
yarn init -y
生成的package.json配置如下
{
"private": true,
"workspaces": [
"packages/*"
],
"name": "vue3",
"type": "module",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "node scripts/build.js"
},
"license": "MIT",
}
在这里新建了两个包一个是reactivy一个是shared 在打包的时候会遍历 在子线程进行打包
同时给每个包进行单独配置package.json(需要在每个目录下yarn init -y)
如reactivty中的package.json
{
"name": "@vue/reactivity",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"buildOptions": {
"name": "VueReactivity",
"formats": [
"esm-bundler",
"cjs",
"global"
]
}
}
安装
yarn add typescript -D-W 进行全局安装
生成ts配置
npx tsc --init
打包相关插件
yarn add rollup rollup-plugin-typescript2 @rollup/plugin-node-resolve @rollup/plugin-json execa -D-W
// 进行打包
// 获取打包文件 获取打包文件
import * as fs from 'fs';
import {execa} from 'execa';
const dirs=fs.readdirSync('packages').filter(p=>{
if(!fs.statSync(`packages/${p}`).isDirectory()){
return false;
}
return true;
})
//打包的方法
async function build(target){
//execa 第一个参数是到包的形式 第二个是数组
// '-c' 执行 rollup 环境变量 --env 自动拿到
await execa('rollup',['-c','--environment',`TARGET:${target}`],{stdio:'inherit'})
//子进程的输出在父包输出
}
//进行打包 因为有很多包 并行打包
async function runParaller(dirs,itemfn){
//遍历
let result=[]
for(let item of dirs){
result.push(itemfn(item))
}
//存放打包的结果 等到打包完毕后调用成功
return Promise.all(result)
}
runParaller(dirs,build).then(()=>{
console.log('打包成功');
}).catch((err)=>{
console.log(err);
})
在项目文件中新建rollup.config.js用来写rullup执行时的配置
import ts from 'rollup-plugin-typescript2' //解析 ts
import json from '@rollup/plugin-json' //解析json
import resolvePlugin from '@rollup/plugin-node-resolve' //解析 第三方插件
import path from 'path' //处理路径
// 获取路径
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 讲require转换为模块
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
// (2)获取文件路径
let packagesDir = path.resolve(__dirname, 'packages')
// 获取需要打包的包
let packageDir = path.resolve(packagesDir, process.env.TARGET)
// 打包获取到每个包的项目配置
let resolve = p => path.resolve(packageDir, p)
const pkg = require(resolve(`package.json`))//获取json配置
const packageOptions = pkg.buildOptions || {}
// 获取文件名字
const name = path.basename(packageDir)
console.log(name);
const outputOpions = {
"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'
},
}
const options=pkg.buildOptions
//对每个格式进行打包 同时进行暴露
function createConfig(format,output){
//在window上面必须有个名字
output.name=options.name
output.sourcemap = true
// 通过build拿到进程 再从进程里面拿到路径
//生成rollup配置
return {
input:resolve('src/index.ts'),//导入
output,
plugins:[
json(),
ts({
tsconfig:path.resolve(__dirname,'tsconfig.json')
}),
resolvePlugin()
//解析第三方插件
]
}
}
//rullup需要这个方法 导出一个配置
export default options.formats.map(format => createConfig(format, outputOpions[format]))
如果在本目录下看到dist文件夹则打包成功
本周总结
vue3源码学习的过程其实有点绕 出现bug比较考验自己解决能力 其实源码的学习对逻辑处理还有解决问题的能力比较有帮助 rollup打包是学习自己手写源码的基础
下周计划
还是学习vue3源码 争取学完后跟着书复习复习