Rollup vs Webpack:一场“打包侠”的江湖对决(附代码段子)

92 阅读4分钟

副标题:  当你写库时,Rollup 是“断舍离大师”,而 Webpack 是“搬家公司的卡车司机” —— 别让工具人背锅,选错就翻车!


开场白:程序员の日常纠结

“写代码5分钟,打包工具选型2小时。”
今天,你的库代码即将出道,但打包工具选 Rollup 还是 Webpack?
别慌!咱们用一段“数学天才库”的代码,让两位“打包侠”当场 battle,顺便暴露它们的“人格差异”。


场景设定:一个被嫌弃的数学函数

假设你写了个库叫 math-utils,代码如下:

// 人见人爱的加法(被其他模块疯狂 import)
export const add = (a, b) => a + b;

// 平平无奇的乘法(被用了一次)
export const multiply = (a, b) => a * b;

// 没人要的减法(代码界的单身狗)
export const subtract = (a, b) => a - b; 

目标:  打包成库,让浏览器和 Node.js 都能用,并无情抛弃单身狗 subtract


Round 1:Rollup —— 极简主义の断舍离大师

配置:极客的优雅

安装依赖(命令行版碎碎念):

npm install rollup @rollup/plugin-node-resolve --save-dev  
# “我就装俩插件,多了算我输”  

配置文件 rollup.config.js(代码如诗):

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  input: 'src/index.js',
  output: [
    { 
      file: 'dist/math-utils.esm.js', 
      format: 'esm', 
      banner: '// Rollup:我狠起来连自己都优化!' 
    },
    { 
      file: 'dist/math-utils.cjs.js', 
      format: 'cjs', 
      banner: '// Rollup:CommonJS?给你个面子!' 
    }
  ],
  plugins: [nodeResolve()]
};

打包结果:冷酷无情

生成的 math-utils.esm.js

// Rollup:我狠起来连自己都优化!
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;

export { add, multiply };
// 单身狗 subtract:已拉黑,勿扰!

Rollup の杀手锏:

  1. Tree-shaking の奥义:静态分析代码,像灭霸一样打个响指,subtract 直接灰飞烟灭。
  2. 多格式の哲学:ESM、CJS、UMD 一键切换,仿佛在说:“格式?我全都要,但代码绝不掺水!”
  3. 体积焦虑终结者:产物体积比程序员的发量还精简。

Round 2:Webpack —— 全能の搬家卡车司机

配置:搬家公司的行囊清单

安装依赖(Webpack の仪式感):

npm install webpack webpack-cli --save-dev  
# “装个全家桶怎么了?安全感懂不懂!”  

配置文件 webpack.config.js(代码如合同):

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'math-utils.webpack.js',
    library: 'MathUtils',
    libraryTarget: 'umd',
    globalObject: 'this', // 防止在 Node 和浏览器里人格分裂
  },
  mode: 'production',
  optimization: {
    usedExports: true, // 试图 Tree-shaking(但手抖)
  },
};

打包结果:人间真实

生成的 math-utils.webpack.js

// Webpack:代码?拿来吧你!
(() => {
  // 1. 自创模块加载系统(仿佛在写微型操作系统)
  var __webpack_modules__ = {
    './src/add.js': (module, exports) => {
      exports.add = (a, b) => a + b;
    },
    './src/multiply.js': (module, exports) => {
      exports.multiply = (a, b) => a * b;
    },
    './src/subtract.js': (module, exports) => {
      exports.subtract = (a, b) => a - b; // 说好的 Tree-shaking 呢??
    }
  };

  // 2. 运行时代码(占体积 80% 的废话文学)
  function __webpack_require__(moduleId) { /* ... */ }

  // 3. 最终导出(仿佛在说:“代码给你,自己品吧”)
  return __webpack_require__('./src/index.js');
})();

Webpack の内心戏:

  1. “代码保险箱” :所有文件都打包,连你家的祖传 subtract 都塞进去,生怕你后悔。
  2. “运行时不请自来” :自带模块加载逻辑,仿佛在代码里藏了一本《Webpack 使用说明书》。
  3. “体积?不存在的” :产物体积比程序员的加班时间还膨胀。

Battle 总结:谁才是你的天选工具人?

对比项RollupWebpack
Tree-shaking灭霸级精准,单身狗直接消失渣男级犹豫,“要不留着当备胎?”
产物体积比程序员的 T 恤还清爽和需求文档一样又臭又长
配置复杂度极简风,配置文件像便利贴硬核风,配置文件像毕业论文
适用场景库/组件开发(代码洁癖患者福音)应用开发(“我有 CSS 和图片要打包!”)
哲学“Less is more.”“More is more!”

灵魂拷问:你该选谁?

  • 选 Rollup 的场景:

    • 你的库想当代码界的刘畊宏 —— 干净、高效、无赘肉。
    • 你讨厌运行时代码,就像讨厌产品经理的“再改一版”。
    • 你想一键输出 ESM/CJS/UMD,深藏功与名。
  • 选 Webpack 的场景:

    • 你的库要处理 CSS、图片、字体,宛如一个百货商店。
    • 你需要代码分割、懒加载,像极了时间管理大师。
    • 你热爱配置,觉得 “Webpack 的难度 = 程序员的荣誉勋章”。

彩蛋:当 Rollup 和 Webpack 互相吐槽

  • Rollup 对 Webpack 说:
    “你代码里写运行时,就像在鱼香肉丝里放草莓 —— 不讲武德!”
  • Webpack 反击:
    “你清高!你厉害!你倒是给我打包个 CSS 看看啊?”

终极建议(人话版)

  • 库/组件开发:无脑 Rollup,代码如初恋,多看一眼算你输。
  • 应用开发:拥抱 Webpack,虽然配置想砸键盘,但它能替你抗下所有。
  • 成年人不做选择:用 Rollup 打包库,再用 Webpack 集成到应用 —— 工具人,就要物尽其用!

最后的最后:
代码和人一样,没有完美工具,只有合适的选择。
毕竟 ——  “打包工具选得好,下班回家睡得早!”  🛌