打包工具rollup

926 阅读3分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。

  • rollup和webpack类似,但是小巧的多。webpack配合一些插件的使用下,几乎可以完成前端工程化的所有功能

  • rollup仅仅是一款ESM打包器

  • 提供一个充分利用ESM各项特性的高效打包器

一 rollup实例

  • 项目目录
src
 - index.js
 - logger.js
 - messages.js
package.json
  • 文件内容
// message.js
export default {
    hi: 'hello world'
}
// logger.js
export const log = msg => {
    console.log(msg)
}
export const error = msg => {
    console.error(msg)
}
// index.js
import { log } from './logger.js'
import message from './message.js'

const msg = messages.hi

log(msg)
  • yarn add rollup --dev // 会在.bin目录下有一个rollup的命令
  • yarn rollup // 不传任何参数的情况下,会打印出rollup的帮助信息
  • yarn rollup ./src/index.js --format iife //指定打包文件的路径和输出的格式
  • rollup默认会开启tree shaking

二 rollup配置文件

  • rollup.config.js
export default {
    // 输入的文件路径
    input:'src/index.js',
    // 输出的文件路径
    output: {
        file:'dist/bundle.js',
        // 输出的格式
        format:'iife'
    }
}
  • yarn rollup --config //默认是不会使用配置文件,所以需要指定配置文件,如果配置文件只有一个,就不会要指定,只需要--config

三 rollup使用插件

  • 插件是rollup唯一扩展途径
  • yarn add rollup-plugin-json --dev
// rollup.config.js
import json from 'rollup-plugin-json'

export default {
    input:'src/index.js',
    output: {
        file:'dist/bundle.js',
        format:'iife'
    },
    plugins:[
        // 需要注意的是,并不是将插件加入plugin中,而是将函数返回的结果加入插件数组之中
        json()
    ]
}
  • 有这个插件之后,就可以通过import的方式导入json了

四 rollup加载NPM模块

  • rollup只能通过文件路径去加载模块, 而不能像webpack一样通过模块名称去加载模块
  • 为了抹平这种差异,rollup官方提供了rollup-plugin-node-reslove
  • yarn add rollup-plugin-node-reslove --dev
// rollup.config.js
import json from 'rollup-plugin-json'
import reslove from 'rollup-plugin-node-reslove'

export default {
    input:'src/index.js',
    output: {
        file:'dist/bundle.js',
        format:'iife'
    },
    plugins:[
        json(),
        resolve()
    ]
}
  • 这样在其他地方就能通过模块名称直接导入npm模块
//index.js
import _ from 'lodash-es'
  • yarn rollup --config //进行打包
  • rollup只能处理ESmodule的版本,所以这里导入的lodsh,其他模块需要做处理

五 rollup加载CommonJS模块

// rollup.config.js
import json from 'rollup-plugin-json'
import reslove from 'rollup-plugin-node-reslove'
import commomjs from 'rollup-plugin-commonjs'

export default {
    input:'src/index.js',
    output: {
        file:'dist/bundle.js',
        format:'iife'
    },
    plugins:[
        json(),
        resolve(),
        commonjs()
    ]
}
  • 这样在其他文件中就能导出从commonJS模块
// cjs-common.js
module.exports = {
    foo:'bar'
}
// index.js
import cjs from './cjs-common'
  • yarn rollup --config
  • 这样bundle里面也有common的代码

六 rollup代码拆分

  • rollup支持代码拆分也是通过动态导入的方式
// index.js

import('./logger').then(({log})=>{
    log('code splitting')
})
  • yarn rollup --config //但直接使用打包会报错,显示导出的格式不能是iife,但可以用amd的方式输出
  • 但继续运行,会继续报错,就是如果是动态打包,那么就不能指定一个文件输出,需要修改输出的文件方式
export default {
    input:'src/index.js',
    output: {
        // 通过指定输出目录的方式来替换输出文件
        dir: 'dist',
        format:'amd'
    },
}
  • 再次运行打包,会生成两个文件

七 rollup多入口打包

export default {
    // 配置多入口打包很简单,输入的值改成一个数组 
    // input:['src/index.js','src/album.js'],
    // 或者以对象的形式
    // 多入口打包会自动提取公共模块,所以不能使用iife这种全部打包到一起的格式
    input :{
        foo:'src/index.js',
        bar:'src/album.js'
    }
    output: {
        dir: 'dist',
        format:'amd'
    },
}

注意:amd格式不能直接引用到页面中,需要符合amd标准的引入方式

  • 优点:

    • 输出结果更加扁平
    • 自动移除未引用的代码
    • 打包结果依然完全可以读
  • 缺点:

    • 加载非ESM的第三方模块比较复杂

    • 模块最终都被打包到一个函数中,无法实现HMR

    • 浏览器环境,代码拆分依赖AMD库

  • 应用程序选择webpack

  • 库/框架开发使用rollup