Rollup个人笔记

Posted mcgee0731

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rollup个人笔记相关的知识,希望对你有一定的参考价值。

Rollup

与webpack作用类似,Rollup更为小巧,它仅仅是一款ESM打包器,并没有其他额外功能,

例如自动化的插件,HMR等在Rollup中不支持

它的诞生并不是要与webpack全民竞争,只是提供一个充分利用ESM各项特性的高效打包器

安装: yarn add rollup --dev(^1.26.3)

使用:yarn rollup ./src/index.js入口文件 --format iife --file dist/bundle.js输出文件

查看rollup命令yarn rollup

# index.js 根文件

// 导入模块成员
import { log } from \'./logger\'
import messages from \'./messages\'

// 使用模块成员
const msg = messages.hi

log(msg)

使用打包命令后,会生成 dist/bundle.js 文件

代码相比webpack大量引导代码和模块函数,这里的输出很简略清晰,没有多余代码

输出代码中只会保留用到的部分,对于未引用的部分都没有输出,这是因为rollup默认会自动开启tree shaking,树摇最早在rollup中提出

# bundle.js

(function () {
  \'use strict\';

  const log = msg => {
    console.log(\'---------- INFO ----------\');
    console.log(msg);
    console.log(\'--------------------------\');
  };

  var messages = {
    hi: \'Hey Guys, I am zce~\'
  };

  // 导入模块成员

  // 使用模块成员
  const msg = messages.hi;

  log(msg);

}());

配置文件

rollup.config.js运行在node环境中,rollup会额外处理这个文件,因此也允许使用ESM

export default {
  input:\'src/index.js\', // 入口文件路径
  output:{ // 输出相关配置
    file:\'dist/bundle.js\' // 输出文件名
    format:\'iife\' // 输出格式
  }
}

执行需要通过 yarn rollup --config , 默认情况下它是不会读取配置文件的

指定配置名称来打包文件 yarn rollup --config rollup.production.js

使用插件

rollup的自身功能就是esm模块的合并打包

如果有加载其他类型资源文件,导入Commonjs,编译ES6+新特性等需要使用插件扩展实现

插件是Rollup唯一扩展途径(webpack loader plugins minimizer)

例子

导入json插件,yarn add rollup-plugin-json --dev

# index.js

import { log } from \'./logger\'
import messages from \'./messages\'
import { name, version } from \'../package.json\' // 导入json

// 使用模块成员
const msg = messages.hi

log(msg)


log(name) // 使用json
log(version)

配置rollup.config.js

import json from \'rollup-plugin-json\'

export default {
  input: \'src/index.js\',
  output: {
    file: \'dist/bundle.js\',
    format: \'iife\'
  },
  plugins: [
    json() // json函数调用结果放入plugins
  ]
}

查看打包结果

(function () {
  \'use strict\';
  
  ...

  var name = "03-plugins"; // json会被tree shaking,只显示引用成员
  var version = "0.1.0";

  log(name);
  log(version);

}());

加载 NPM 模块

rollup默认只能按文件路径的方式加载本地文件模块,对于node_modules下的第三方模块,并不能像webapck,通过模块名称导入对应模块

yarn add rollup-plugin-node-resolve --dev可以解决rollup使用第三方模块名称导入模块的问题。

import json from \'rollup-plugin-json\'
import resolve from \'rollup-plugin-node-resolve\'

export defalut{
  input:\'src/index.js\',
  output:{
    file:\'dist/bundle.js\',
    format:\'\'iife
  },
  plugins:[
    json(),
    resolve()
  ]
}

此时就可以导入 NPM 模块了!

例如
yarn add lodash-es 安装一个模块

# index.js

import _ from \'lodash-es\' //引入 NPM 模块

_.camelCase(\'hello world\')

注意:使用 lodash-es(lodash esm版本) 而不是 lodash 是因为 rollup 默认只能处理 esm 模块,如果使用普通版本需要做额外处理

加载CommonJS模块

yarn add rollup-plugin-commonjs --dev 为了解决commonjs模块打包问题

import json from \'rollup-plugin-json\'
import resolve from \'rollup-plugin-node-resolve\'
import commonjs from \'rollup-plugin-commonjs\'

export default {
  input: \'src/index.js\',
  output: {
    file: \'dist/bundle.js\',
    format: \'iife\'
  },
  plugins: [
    json(),
    resolve(),
    commonjs()
  ]
}

此时,尝试添加一个 commonjs 模块文件

# cjs-module.js

module.exports = {
  foo:\'bar\'
}
# index.js 入口

import cjs from \'./cjs-module\' 

console.log(cjs.foo)

注意:如果改用const cjs = requrie(\'./cjs-module.js\') 引入,需要注意不可以esm和commonjs两个混用,不然require不会被解析

Code Splitting

Dynamic Imports实现按需加载,rollup内部会进行代码拆分

# index.js

import(\'./logger\').then(({log})=>{
  log(\'code splitting!\')
})

此时打包会报错,yarn rollup --config,告诉我们代码拆分打包,format不能使用iife模式,

因为iife会把所有模块放在同一个函数中,相比于webpack并没有引导代码,没法实现代码拆分,因此修改format为amd or commonjs

执行yarn rollup --config --format amd

依然报错,代码分割输出多文件trunk需要修改,file为dir

export default {
  input: \'src/index.js\',
  output: {
    // file: \'dist/bundle.js\',
    // format: \'iife\'

    dir: \'dist\',
    format: \'amd\'
  }
}

多入口打包

公共部分也会提取出来作为独立的bundle

export default {
  // input: [\'src/index.js\', \'src/album.js\'],
  input: {
    foo: \'src/index.js\',
    bar: \'src/album.js\'
  },
  output: {
    dir: \'dist\',
    format: \'amd\' 
  }
}

注意:多入口打包内部会自动提前公共模块(内部会代码拆分),就不能用iife,

amd规范无法在浏览器直接引用,通过实现amd标准的库加载(Require.js)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <!-- AMD 标准格式的输出 bundle 不能直接引用 -->
  <!-- <script src="foo.js"></script> -->
   
  <!-- 需要 Require.js 这样的库 -->
  <script src="https://unpkg.com/requirejs@2.3.6/require.js" data-main="foo.js"></script>
  <!-- data-main执行入口模块路径 -->
</body>
</html>

用live server打开这个html

选用原则

优点

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

缺点

  • 加载非 ESM 的第三方模块比较复杂
  • 模块最终被打包到一个函数中,无法实现 HMR
  • 浏览器环境中,代码拆分功能依赖 AMD 库

如果我们正在开发应用程序,需要大量引入第三方模块,应用过大还要分包

如果我们开发一个框架或者类库,很少依赖第三方模块,大多数知名框架/库都在使用Rollup作为模块打包

Webpack大而全,Rollup小而美,应用程序用webpack,库/框架Rollup

optimization:{
    concatenateModules:true // 抹平了rollup的优势
}

以上是关于Rollup个人笔记的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

从webpack到rollup

关于Vite的小小笔记

使用 rollup 打包一个原生 js + canvas 实现的移动端手势解锁功能组件

Vue 是如何用 Rollup 打包的?

rollup 实战第二节 搭建开发环境