Vue源码分析 -- 起步(一、 了解rollup.js)

357 阅读5分钟

rollup.js

写在前面

这是我自己在学习过程中的一些笔记,有些内容理解不深或者只是将官网的文档拷了过来,所以有错误的地方,希望大家可以指出。

这是什么?

一款JavaScript模块打包器,使用最新的标准化格式(ES6标准)

为什么要看?

Vue2.x使用rollup.js进行打包,无论从那个方向看,想要对Vue的源码进行分析都需要对rollup.js有一定的了解

怎么看?

根据官方文档,由浅入深。(全部完成之后,需要回头重新梳理知识点)

正式开始

安装

npm install --global rollup // 进行全局安装

使用(假设入口文件为main.js,并且想把项目中的文件打包到一个bundle.js的文件中)

// 对于浏览器
rollup main.js --file bundle.js --format iife

// 对于NodeJS
rollup main.js --file bundle.js --format cjs

// 对于浏览器和NodeJS
rolllup main.js --file bundle.js --format umd --name "myBundle"

特性:Tree-shaking(live code inclusion)

rollup会分析代码中的import(引入),排除从未使用过的代码,以此来保证rollup只引入最基本最精简的代码。

// 使用CommentJS导入utils对象
var utils = require('utils')
var query = 'Rollup'
// 使用utils的Ajax方法
utils.ajax('https://api.example.com?search=' + query).then(handleResponse)


// 使用ES6 import语句导入ajax函数
import {ajax} from 'utils'
var query = 'Rollup'
// 调用ajax函数
ajax('https://api.example.com?search=' + query).then(handleResponse)

开始第一个bundle

  1. 全局安装rollup.js文件,安装方法请看上方

  2. 运行rollup命令,检查是否全局安装成功

  3. 创建自己的项目

    mkdir my-rollup-project
    cd my-rollup-project
    mkdir src
    cd src
    touch main.js foo.js
    
    // src/main.js
    import foo from './foo.js'
    export default function () {
        console.log(foo)
    }
    
    //src/foo.js
    export default 'hello world'
    
  4. 使用rollup.js进行打包

    // -f 是 --output.format的缩写,指定打包的类型 
    rollup src/main.js -f cjs
    
    // 由于没有指定输出文件,所以默认打印在stdout中
    src\main.js → stdout...
    'use strict';
    
    var foo = 'hello world';
    
    function main () {
        console.log(foo);
    }
    
    module.exports = main;
    created stdout in 66ms
    
    // 也可以使用-o来指定输出的文件名
    rollup src/main.js -o bundle.js -f cjs
    // 或者
    rollup src/main.js -f cjs > bundle.js
    // 即可在项目根目录得到一个bundle.js文件
    
  5. 验证bundle.js文件

    λ node
    Welcome to Node.js v12.3.1.
    Type ".help" for more information.
    > var myBundle = require('./bundle.js')
    undefined
    > myBundle()
    hello world
    

使用配置文件

在上面你已经成功的构建了一个bundle.js文件。但命令行的形式可能对新手不太友好,我们可以通过配置文件来配置所有的选项

  1. 在项目根目录下创建一个rollup.config.js

    // ./rollup.config.js
    touch rollup.config.js
    
  2. 填入以下内容

    export default {
        // 入口文件
        input: 'src/main.js',
        // 输出选项
        output: {
            // 输出文件
            file: 'bundle.js',
            // 输出文件格式为CommentJS
            format: 'cjs'
        }
    }
    
  3. 通过命令行创建

    // 默认配置
    rollup -c
    rollup --config
    
    // 更改输出文件
    rollup -c -o bundle2.js
    
    // 也可以为不同的环境设置不同的配置文件
    // 开发环境
    rollup --config rollup.config.dev.js
    // 生产环境
    rollup --config rollup.config.prod.js
    

使用插件

和webpack相似,插件可以让rollup的功能更加强大,具体的插件列表可以查看the Rollup wiki,下面我们和官网一样将会以rollup-plugin-json举例

安装

// 这个插件可以使rollup读取JSON文件
npm install --save-dev rollup-plugin-json

更新main.js文件

import {version} from '../package.json'

export default function () {
    console.log(`version ${version}`)
}

更新rollup.config.js文件

+ // 引入JSON插件
+ import json from 'rollup-plugin-json'

  export default {
+     // 配置插件
+     plugins: [json()]
  }

注:package.json文件并不会自动生成,需要通过npm init来手动生成

命令行

一般情况下在命令行中使用rollup,你任然可以为其添加一份配置文件来简化命令

配置文件

上面的示例已经简单的讲述了怎么样配置一个rollup.config.js文件。从文件名可以看出它是一个JS文件,它使用ES6的模块化语法,对外暴露了一个的对象(包含Rollup所需的一些选项)

export default {
	// 核心选项
    input,// 必须 包的入口文件
    external, // 外链,可以是一个数组或者函数
    plugins, // 插件 一个数组或者是对象 注意:格式为 plugins:[json()] 插件名要加括号
    
    // 额外选项
    onwarn, // 拦截警告信息
    
    // danger zone(危险区)
    acorn, // 任何应该传递给Acorn的选项
    context, // 默认情况下模块的上下文,即顶级的this的值为undefined
    moduleContext, // 和context一样,但是每个模块可以是id: context的对象,或者是id => context的函数
    legacy, // 对IE8之类的旧版环境的支持
    treeshake, // 是否应用tree-shaking
    
    // 必须(如果输出多个,可以是一个数组)
    output: {
    	// 核心选项
    	file, // 写入的文件
    	format, // 生成包的格式 (amd, cjs, es, iife(立即执行函数表达式), umd(通用模块))
    	name, // 生成包名称
    	globals, // 全局模块 用于umd/iife包 是一个对象
    
    	// 额外选项
    	paths, // 函数或者是一个对象
    	banner, // 作为前置加入文件束
    	footer, // 作为后置加入文件束
    	intro, // 类似于banner
    	outro, // 类似于footer
    	sourcemap, // 创建一个单独的sourcemap文件
    	sourcemapFile, // 生成包的位置
    	interop, // 布尔值 默认为true 是否添加interop
    
    	// 高危选项
    	exports, // 使用什么导出模式 default、named、none 
    	amd, // id 软件包的id、define 要使用的函数名
    	indent, // 缩进的字符串
    	strict // 是否使用严格模式 
	}
    
    watch: {
		chokidar, // 
    	include, // 限制文件监听某些文件
    	exclude// 防止文件被监听
    }
}

通过rollup -c或者rolluo --config使用配置文件

命令行的一些参数

-h --help					 打印帮助文档
-v --version				 打印已安装的Rollup版本号
-w --watch					 监听源文件是否有改动,如果有改动,重新打包
-i --input					 要打包的文件(必须)
-o --output.file			 输出的文件 
-n --name					 生成UMD模块的名字
-f --output.format			 输出的文件类型 (amd, cjs, es, iife, umd)
-e --external				 将模块ID的逗号分隔列表排除
-g --globals				 以`module ID:Global` 键值对的形式,用逗号分隔开任何定义在这里模块ID定义添加到外部依赖
-m --sourcemap				 生成 sourcemap (`-m inline` for inline map)
--amd.id					 AMD模块的ID,默认是个匿名函数
--amd.define				 使用Function来代替`define`
--no-strict					 在生成的包中省略`"use strict";`
--no-conflict 				 对于UMD模块来说,给全局变量生成一个无冲突的方法
--intro						 在打包好的文件的块的内部(wrapper内部)的最顶部插入一段内容
--outro						 在打包好的文件的块的内部(wrapper内部)的最底部插入一段内容
--banner					 在打包好的文件的块的外部(wrapper外部)的最顶部插入一段内容
--footer					 在打包好的文件的块的外部(wrapper外部)的最底部插入一段内容
--interop					 包含公共的模块(这个选项是默认添加的)
---silent					 不要将警告打印到控制台

未完待续~