rollup.js

rollup.js是一个JavaScript模块打包器(Bundler),可将小块代码编译成大块复杂的代码。

  • 专注于ES6模块打包

模块化

rollup.js对代码模块化使用了ES6新的标准化格式,而非之前特殊的解决方案,比如CommonJS和AMD。

模块化描述加载
IIFE自执行函数通过<script>标签加载
AMD浏览器(Browser)的模块规范通过RequireJS加载
CommonJSNode服务端模块规范通过Webpack加载
UMD兼容IIFE、AMD、CJS三种模块规范-
ESMES2015 Module规范可用Webpack、Rollup加载

与Webpack偏向于应用打包定位不同,rollup.js更专注于JavaScript类库打包。Webpack对于代码分割和静态资源导入有着先天优势,并支持热模块替换(HRM)。rollup.js不支持代码拆分(Code Splitting)和运行时态加载(Dynamic Import)特性。

开发应用时可优先选择Webpack,rollup.js对于代码的Tree-shaking和ES6模块有着算法优势上的支持,若项目只需要打包一个简单的bundle包,并基于ES6模块开发则优先考虑使用rollup.js。其实Webpack2.x开始支持Tree-Shaking,并在使用babel-loader的情况下可支持ES6 Module的打包。

特性优势

  • Tree Shaking:自动移除未使用的代码,输出更小的文件。
  • Scope Hoisting:所有模块构建在一个函数内,执行效率更高。
  • Config:配置文件支持通过ESM模块格式书写
  • 一次输出多种格式
  • 文档精简

Tree-shaking

Tree-shaking指的是移除JavaScript上下文中未引用代码,它依赖于ES2015模块系统中的静态结构特性,比如importexport。静态结构的import类似变量引用,无需执行代码,编译时即可确定它是否引用到。若没有引用则不会将该段代码打包进来。

工作原理

rollup.js可将自己编写的JavaScript代码与第三方模块打包在一起形成一个文件,该文件可以是一个库(Library)或一个应用(App),打包过程中可应用各类插件实现特定功能。

Rollup打包原理

rollup.js默认采用ES模块标准,可通过rollup-plugin-commonjs插件是指支持CommonJS标准。

环境检测

rollup.js依赖于Node.js

$ node -v
v16.0.0
$ npm -v
7.10.0

全局安装rollup.js

$ npm view rollup
$ npm i -g rollup

环境搭建

创建项目

$ mkdir tsr && cd tsr

初始化Node.js项目,生成package.json项目依赖包配置文件。

$ npm init -y

项目目录结构

文件描述
src源文件目录
dist编译后的文件目录
package.jsonNode.js项目依赖包配置文件
tsconfig.jsonTypeScript配置文件,设置TypeScript编译选项。

package.json

Node.js中的模块(Module)是一个库或框架,同时也是一个Node.js项目。Node.js项目遵循模块化的架构,因此创建并初始化一个Node.js项目实际上也创建了一个模块,此模块的描述文件即package.json,又称为项目的依赖包管理文件。

修改包配置文件package.json

$ vim package.json
{
  "name": "tsr",
  "version": "1.0.0",
  "main": "lib/index.js",
  "module": "lib/index.esm.js",
  "browser": "lib/index.umd.js",
  "license": "MIT",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  },
  "devDependencies": {
    "@types/node": "^15.0.2",
    "rollup": "^2.47.0",
    "rollup-plugin-cleandir": "^1.0.0",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-typescript2": "^0.30.0",
    "typescript": "^4.2.4"
  }
}
属性描述
name包名
version包的版本号
description包的描述信息
homepage包的官网URL
author包的作者
contributors包的贡献者
dependencies生产环境依赖包列表,安装在node_modules目录下。
devDependencies开发环境依赖包列表,安装在node_modules目录下。
repository包代码的仓库信息,包括type和URL。
bin指定内部命令对应的可执行文件的位置

入口文件

$ vim package.json
{
  "main": "lib/index.js",
  "module": "lib/index.esm.js",
  "browser": "lib/index.umd.js",
  "typings": "types/index.d.ts",
}
属性描述限制
mainCommonJS入口文件browser环境和node环境均可使用
module定义NPM包ESM规范的入口文件browser环境和node环境均可使用
browser定义NPM包在browser环境下的入口文件仅browser环境可用
typingsTypeScript入口文件IDE环境可用
"main": "lib/index.js"

main包的主入口文件地址,定义引用依赖的文件地址,不同环境下引入包时会加载main字段中指定的文件,默认是模块根目录下的index.js文件。

"module": "lib/index.esm.js"

Rollup最早提出了pkg.module的概念,早期NPM包都是基于CommonJS规范,当require("package")时会根据package.jsonmain字段去查找入口文件。

从ES2015开始,JavaScript拥有了ES Module,相较于之前的模块化方案更为优雅,ESM也是官方标准的JS规范。CommonJS模块化是一种特殊的传统格式,在ESM提出前作为暂时的解决方案。由于CommonJS规范的包都是以main字段表示入口文件,ESM如果也使用main字段会对使用者造成困扰,因此Rollup使用了另一个字段module

"typings": "types/index.d.ts",
  • typings字段是为了方便IDE识别、编辑、智能提示JavaScript语法的工具。
  • typings入口文件中的代码只是为编辑器智能提示而服务,真正执行程序并不会使用。

TypeScript

项目安装TypeScript

$ npm i -D typescript

$ npm ls typescript
tsr@1.0.0 F:\TS\project\tsr
└── typescript@4.2.4

$ tsc --version
Version 4.2.4

tsconfig.json

初始化生成TypeScript编译器配置文件,当某目录下存在tsconfig.json文件则认为该目录为TypeScript项目的根目录。

$ tsc --init
message TS6071: Successfully created a tsconfig.json file.

tsconfig.json配置文件主要分为两部分:指定待编译文件和定义编译选项

$ vim tsconfig.json
{
  "compilerOptions": {

    "target": "esnext",
    "lib": ["dom","esnext"],

    "module": "esnext",
    "moduleResolution": "node",

    "declaration": false,
    "declarationMap": false,

    "sourceMap": true,
    "outDir": "./lib/",
    "removeComments": true,

    "strict": true,
    "noImplicitAny": false,

    "baseUrl": "./",
    "esModuleInterop": true,

    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,

    "allowJs": true,
    "resolveJsonModule": true
  },
  "include": ["src"]
}

编译选项compilerOptions

"target": "esnext"
  • target用于指定编译后的JavaScript目标版本
  • esnext是一个JavaScript库,可将ES6草案规范语法转换为当前JavaScript语法。
"lib": ["dom","esnext"]

lib选项表示编译过程中需引入的库文件,指定要包含在编译中的库文件。

库文件描述
domDOM运行环境
esnextES6转换为ES5的环境

lib没有指定默认注入的库的列表则默认注入的库为

编译目标(target)注入库(lib)
ES5DOM,ES5,ScriptHost
ES6DOM,ES6,DOM.Iterable,ScriptHost
"module": "esnext"
  • module选项用于指定模块化规范,即生成哪种模块系统代码。
模块系统描述
None-
CommonJS-
AMD-
System-
UMD-
ES6-
ES2015-
"moduleResolution": "node"
  • moduleResolution用于指定模块解析策略,拥有两种可选策略nodeclassic
  • 模块解析是指编译器在查找导入模块内容时所遵循的流程

编译器会尝试定位导入模块的文件,编译器会遵循两种策略之一:Classic和Node,这些策略会告知编译器到哪里去查找目标模块。

import Entry from "./components/Entry"
import { DefaultHeaders } from "../constants/http"
import * as $ from "jQuery"
import { Component } from "@angular/core"
解析策略描述
classicTS之前默认的解析策略,为向后兼容而保留。
node运行时模仿Node.js模块解析机制
"declaration": true
  • declaration选项用于指定是否在编译时生成相应地*.d.ts声明文件,若为true则表示编译每个.ts文件会自动生成一个.js文件和一个*.d.ts声明文件。
  • declarationallowJs选项不能同时设置为true
"declarationMap": false
  • declarationMap选项用于指定.ts文件编译时是否为其声明文件.d.ts生成.d.ts.map文件
"sourceMap": false
  • sourceMap选项用于指定编译.ts文件时是否生成.map文件

@types/node

在Node.js中搭建TypeScript开发环境后,才能使用TypeScript开发Node.js项目。

TypeScript中无法直接使用Node.js内置模块和第三方模块,无法直接在TypeScript文件中导入模块。根据TypeScript自身机制,需要*.d.ts的声明文件,来说明模块对外公开的方法和属性类型及内容。

TypeScript2.x以上获取类型声明文件只需使用NPM安装@types/node插件即可实现

tsconfig.json配置中通过lib指定TypeScript环境为["dom", "esnext]表示采用Node.js环境,此时不存在Node.js环境,需安装@types/node插件来支持。

$ npm i -D @types/node

安装类型声明后即可直接在.ts文件中导入Node.js内置模块

$ vim rollup.config.ts
import * as path from "path";

如何在TypeScript中导入本地JSON文件呢?需在tsconfig.json配置文件的编译器选项(compilerOptions)中开启allowJsresolveJsonModule两个选项。

$ vim tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "resolveJsonModule": true
  }
}
编译选项默认值描述
allowJsfalse是否能在TypeScript文件中引入JavaScript库
checkJsfalse是否检查JavaScript代码合法性
resolveJsonModulefalse是否可以在TypeScript中导入JSON Module

ts-node

普通运行TypeScript需先通过tsc命令将.ts文件编译为.js文件后才能使用node命令运行node xxx.jsts-node包装了node可直接运行TypeScript代码,使用ts-node仅需ts-node xxx.ts即可直接运行TypeScript文件。

$ npm i -g ts-node

例如:使用ts-node命令执行TypeScript文件

$ ts-node index.ts

Rollup

项目安装rollup打包工具

$ npm i -D rollup
$ npm ls rollup
tsr@1.0.0 F:\TS\project\tsr
└── rollup@2.47.0
$ rollup -v
rollup v2.47.0
$ rollup --help

rollup version 2.47.0
命令参数完整参数描述
-i--input <filename>要导报的文件
-o--file <output>输出的文件,若无则直接输出到控制台。
-f--format <format>输出的文件类型(amd、cjs、esm、life、umd)
-e--external <ids>将模块ID的逗号分割列表排除
-g--globals <pairs>module ID:Global键值对形式
-n--name <name>生成UMD模块的名字
-h--help输出帮助信息
-m--sourcemap生成SourceMap信息
--amd.id-AMD模块的ID,默认为匿名函数。
--amd.define-使用Function来代替define
-w--watch监视文件打包与重新打包时的变化

自定义脚本命令

  • NPM允许在package.jsonscripts字段中自定义脚本命令
  • scripts字段是一个对象,每个属性对应一条脚本。
  • 自定义脚本命令使用npm run执行脚本
$ vim package.json
{
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  }
}

rollup.config.js

Rollup的配置文件是可选的,位于根目录下的rollup.config.js,是一个ES6模块对外暴露一个对象。

$ vim rollup.config.js
import * as path from "path";
import {cleandir} from "rollup-plugin-cleandir";
import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import nodeResolve from "rollup-plugin-node-resolve";

import * as pkg from "./package.json"
import * as tsconfig from "./tsconfig.json"

const outDir = path.join(__dirname, tsconfig.compilerOptions.outDir)

//配置规则
export default {
    //入口文件
    input:path.join(__dirname, "src/main.ts"),
    //输出文件
    output:[
        //输出CommonJS规范的代码
        {format:"cjs", name:pkg.name, file:path.join(outDir, "index.js")},
        //输出ESM规范的代码
        {format:"esm", name:pkg.name, file:path.join(outDir, "index.esm.js")}
    ],
    //配置插件
    plugins:[
        //自动读取tsconfig.json
        typescript(),
        //自动清除文件夹
        cleandir(outDir),
        //配置Rollup支持CommonJS规范用以识别CommonJS规范的依赖
        commonjs(),
        //解析node_modules中CommonJS规范的第三方模块
        nodeResolve({customResolveOptions:{moduleDirectory:"node_modules"}})
    ]
}

配置入口文件打包后输出文件,打包时可指定生成包的格式,打包后可通过<script>标签引入,也可通过import等方式引入作为JavaScript库使用。

Rollup配置选项

核心默认值描述命令
input"/src/main.ts"设置包的入口点-i/--input
output[]设置待写入的输出文件列表,可用于生成sourcemap。-

输出文件选项output

输出选项默认值描述命令
formatcjs生成包的格式-f/--output.format
name""生成包的名称-n/--name
file""待写入的文件,也可用生成sourcemap-o/--output.file
sourceMapfalse是否生成SourceMap文件-
{format:"cjs", name:pkg.name, file:dist("index.js"), sourceMap:false}

生成包的格式format

格式描述
amd异步模块定义,用于类似RequireJS这样的模块加载器。
cjsCommonJS,适用于Node.js和Browserify/Webpack打包工具。
ems将软件包保存为ES模块文件,现代浏览器可通过<script type="module">标签引入。
iife自执行函数,适用于<script>标签。
umd通用模块定义,以AMD、CommonJS、IIFE为一体。
systemSystemJS加载器格式

例如:为不同模块化规范输出不同的打包文件

$ vim rollup.config.js
import * as path from "path";
import * as pkg from "./package.json"

const dist = filename => filename!=null ? path.join(path.join(__dirname, "dist"), filename) : path.join(__dirname, "dist")

//配置规则
export default {
    //输出文件
    output:[
        //输出CommonJS规范的代码
        {format:"cjs", name:pkg.name, file:dist("index.js"), sourceMap:false},
        //输出ESM规范的代码
        {format:"es", name:pkg.name, file:dist("index.esm.js"), sourceMap:false}
    ]
}

使用Rollup的配置文件

$ rollup -c
$ rollup --config
$ rollup --config rollup.config.js

插件

Rollup的插件提供了统一的标准接口,通过约定大于配置定义公共配置,注入当前构造结果相关的属性和方法,供开发者实现增删改查操作。

一个Rollup插件是一个导出了一个函数的包,函数返回了一个对象,对象拥有遵循特定规范的属性和钩子。

  • 插件名称必须以rollup-plugin-开头
  • package.json设置keywordrollup-plugin
  • 插件应被测试,推荐采用mocha和ava。
  • 尽可能使用异步方法

搜索插件:https://github.com/rollup/awesome

插件描述
rollup核心包
typescript2让Rollup识别TypeScript
buble类似babel工具但比babel更轻
commonjs将CommonJS转换为ES6模块
json将JSON文件转换为ES6模块
node-resolve让Rollup能够识别node_modules中的包,引入第三方库默认是无法识别的。
terser代码压缩,代码最小化打包。
filesize显示打包出来的文件大小
sourcemaps生成sourcemaps文件
cleandir文件夹清除

rollup-plugin-typescript2

$ npm i -D rollup-plugin-typescript2

rollup-plugin-commonjs

NPM中大多数包是以CommonJS模块的形式出现的,使用前需将CommonJS模块转换为ES2015模块供Rollup处理。

rollup-plugin-commonjs应该用在其它插件转换自定义模块之前,以防止其他插件改变破坏CommonJS的检查。

$ npm i -D rollup-plugin-commonjs

rollup-plugin-node-resolve

rollup-plugin-node-resolve插件用于告知Rollup如何查找外部模块

$ npm i -D rollup-plugin-node-resolve

rollup-plugin-buble

buble插件作用是在`rollup.js打包过程中进行代码编译,将ES6+代码编译称为ES2015标准。

Node.js项目中安装buble插件

$ npm i -D rollup-plugin-buble

$ npm ls buble
tsr@1.0.0 F:\TS\project\tsr
└─┬ rollup-plugin-buble@0.19.8
  └── buble@0.19.8

Rollup配置插件

$ vim rollup.config.js
import buble from "rollup-plugin-buble"

//配置规则
export default {
    //配置插件
    plugins:[
        //将ES6+代码编译成ES2015
        buble()
    ]
}

rollup-plugin-alias

alias插件提供为模块起别名的功能

项目中安装alias插件

$ npm i -D rollup-plugin-alias

为项目添加插件配置

$ vim rollup.config.js
import alias from "rollup-plugin-alias"

//获取绝对路径
const pathResolve = p => path.resolve(__dirname, p)

//配置规则
export default {
    //配置插件
    plugins:[
        //为模块起别名
        alias({"@":pathResolve("src")})
    ]
}

提供pathResolve函数用于生成绝对路径,引入alias插件需传入一个对象作为参数,对象的key是模块中使用的别名,对象的value是别名对应的真实离苦精。

rollup-plugin-flow-no-whitespace

flow插件用于在rollup.js打包过程中清除flow类型检查部分的代码

rollup-plugin-replace

replace插件的作用是在Rollup打包时动态地替换代码中的内容

$ npm i -D rollup-plugin-replace

rollup-plugin-terser

terser插件用于在Rollup打包过程中实现代码压缩代码实现最小化打包,支持ES模块。

$ npm i -D rollup-plugin-terser

配置

$ vim rollup.config.js
import {terser} from "rollup-plugin-terser";

//配置规则
export default {
    //配置插件
    plugins:[
        //代码压缩
        terser({
            output:{ascii_only:true},//仅输出ASCII字符
            compress:{pure_funcs:["console.log"]}//去除console.log函数
        })
    ]
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值