Vue3源码分析--rollup打包

vue3打包使用的工具rollup

Rollup 是一个 JavaScript 模块打包工具,可以将多个小的代码片段编译为完整的库和应用。与传统的 CommonJS 和 AMD 这一类非标准化的解决方案不同,Rollup 使用的是 ES6 版本 Javascript 中的模块标准。新的 ES 模块可以让你自由、无缝地按需使用你最喜爱的库中那些有用的单个函数。这一特性在未来将随处可用,但 Rollup 让你现在就可以,想用就用

vue2与vue3打包的区别

在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 在打包的时候会遍历 在子线程进行打包
Vue3源码分析--rollup打包_第1张图片
同时给每个包进行单独配置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"
    ]
  }
}

下载rollup

安装
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

builder.ts 在子线程进行打包操作

// 进行打包
// 获取打包文件 获取打包文件
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);
})

解决一下问题
Vue3源码分析--rollup打包_第2张图片
Vue3源码分析--rollup打包_第3张图片

在项目文件中新建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源码 争取学完后跟着书复习复习

你可能感兴趣的:(vue.js,前端,javascript)