aurora blog
  • JS

    • 基本汇总
    • Date时间
    • Array方法
    • String 方法
    • Object方法
    • RegExp正则
    • Es6 新特性等
    • Event-Loop
    • Http and Https
    • for in和for of区别
    • Web Worker
    • Promise && async
    • 堆内存 & 栈内存
    • JS设计模式探索
    • npm & yarn
    • Fetch和Axios的区别
    • 学习及面试问题整理
    • URL 输入到页面加载过程
    • 跨域&nginx本地项目代理
  • FE框架

    • react

      • 基本用法
      • react生命周期
      • hooks 16.8版本后
      • Route原理
      • Redux源码解析
      • React16 Fiber
      • React-VirtualDOM
      • React事件委托机制
      • React性能优化
      • 状态管理方案对比
      • React 18新特性
    • vue

      • vue 基本用法
      • vue 生命周期
      • VirtualDOM
      • vue 事件委托
      • vue 架构
      • vue 状态管理
      • 问题等
    • React-Native

      • React-Native 基本用法
    • 微前端

      • 遇到的问题
    • 鸿蒙 harmony

      • harmony 基础
  • 构建工具

    • webpack

      • Webpack配置详解
      • Webpack的使用
      • Babel-polyfill
      • webpack面试题
    • vite

      • vite配置详解
      • vite面试题
    • rollup

      • Rollup配置详解
      • rollup面试题
    • 构建工具对比
  • 性能优化

    • 性能优化策略
    • 缓存策略
    • 性能优化面试题
  • 浏览器

    • 浏览器渲染原理
    • 浏览器缓存机制
    • 浏览器面试题
  • 工程化

    • 代码规范
    • 工程化面试题
  • 前端安全

    • XSS 攻击与防护
    • CSRF 攻击与防护
    • 前端安全面试题
  • 移动端开发

    • 移动端适配
    • 移动端开发面试题
  • 前端监控

    • 错误监控
    • 性能监控
    • 前端监控面试题
  • Typescript

    • Typescript详解
  • Servers

    • Nodejs
    • Nginx
  • Git命令

    • git常用规范
  • 数据库

    • mongodb
    • mongodb
  • Other

    • Jenkins自动化部署

Rollup 面试题

  • 基础概念
    • Rollup 是什么?它的核心特点是什么?
    • Rollup 和 Webpack 的主要区别是什么?
    • Rollup 的工作原理是什么?
    • 为什么 Rollup 的 Tree Shaking 效果最好?
  • 配置相关
    • Rollup 如何配置多入口?
    • Rollup 如何配置代码分割?
    • Rollup 如何处理外部依赖?
    • Rollup 的输出格式有哪些?如何选择?
  • 插件系统
    • Rollup 常用插件有哪些?
    • 如何编写一个 Rollup 插件?
  • Tree Shaking
    • Rollup 的 Tree Shaking 原理是什么?
    • 如何确保 Tree Shaking 生效?
    • Tree Shaking 的局限性是什么?
  • 性能优化
    • 如何提升 Rollup 构建速度?
    • Rollup 如何处理大型项目?
  • 常见问题
    • Rollup 如何处理 CommonJS 模块?
    • Rollup 支持 HMR 吗?
    • Rollup 如何处理 CSS?
    • Rollup 如何处理 TypeScript?
    • Rollup 如何处理环境变量?
  • 库开发
    • 如何用 Rollup 开发一个库?
    • 为什么库开发推荐使用 Rollup?
    • Rollup 如何生成类型声明文件?
  • 最佳实践
    • Rollup 最佳实践
    • Rollup 常见错误及解决方案
  • 与其他工具对比
    • Rollup vs Webpack
    • Rollup vs Vite
    • 什么时候选择 Rollup?

基础概念

Rollup 是什么?它的核心特点是什么?

Rollup 是一个 JavaScript 模块打包器,专注于将小块代码编译成更大、更复杂的代码库。

核心特点:

  1. Tree Shaking:自动移除未使用的代码,效果最好
  2. ES Modules 优先:原生支持 ES modules
  3. 代码体积小:生成的代码更小、更高效
  4. 适合库开发:输出代码质量高
  5. 配置简单:相比 Webpack 配置更简洁

Rollup 和 Webpack 的主要区别是什么?

特性RollupWebpack
定位库开发应用开发
Tree Shaking默认启用,效果最好需要配置
代码体积更小较大
HMR需要插件内置
配置复杂度简单复杂
插件生态较小丰富
适用场景库、框架大型应用

Rollup 的工作原理是什么?

工作流程:

  1. 解析入口文件:读取入口文件,解析为 AST
  2. 依赖分析:递归分析所有依赖模块
  3. Tree Shaking:静态分析,移除未使用的代码
  4. 代码转换:使用插件转换代码(Babel、TypeScript 等)
  5. 代码合并:将所有模块合并成单个文件或多个 chunk
  6. 代码生成:生成目标格式的代码(ES、CommonJS、UMD 等)

为什么 Rollup 的 Tree Shaking 效果最好?

原因:

  1. ES Modules 优先:ES modules 是静态的,可以在编译时分析
  2. 静态分析:在打包前就能确定哪些代码被使用
  3. 精确标记:可以精确标记和移除未使用的代码
  4. 无副作用假设:默认假设代码无副作用,可以安全移除

配置相关

Rollup 如何配置多入口?

export default {
  input: {
    main: 'src/index.js',
    utils: 'src/utils.js',
  },
  output: {
    dir: 'dist',
    format: 'es',
    entryFileNames: '[name].js',
  },
};

Rollup 如何配置代码分割?

export default {
  input: 'src/index.js',
  output: {
    dir: 'dist',
    format: 'es',
    manualChunks: {
      vendor: ['react', 'react-dom'],
      utils: ['./src/utils/helper1', './src/utils/helper2'],
    },
  },
};

Rollup 如何处理外部依赖?

export default {
  external: [
    'react',
    'react-dom',
    /^lodash/, // 正则匹配
    (id) => id.includes('node_modules'), // 函数匹配
  ],
  output: {
    globals: {
      react: 'React',
      'react-dom': 'ReactDOM',
    },
  },
};

Rollup 的输出格式有哪些?如何选择?

输出格式:

  • es:ES modules,适合现代浏览器和 Node.js
  • cjs:CommonJS,适合 Node.js
  • umd:通用模块定义,支持浏览器和 Node.js
  • iife:立即执行函数,适合浏览器直接使用
  • amd:AMD 格式
  • system:SystemJS 格式

选择建议:

  • 库开发:同时输出 es 和 cjs
  • 浏览器使用:umd 或 iife
  • Node.js 使用:cjs

插件系统

Rollup 常用插件有哪些?

核心插件:

  • @rollup/plugin-node-resolve:解析 node_modules 中的模块
  • @rollup/plugin-commonjs:将 CommonJS 转换为 ES modules
  • @rollup/plugin-json:导入 JSON 文件

编译插件:

  • @rollup/plugin-babel:Babel 转换
  • @rollup/plugin-typescript:TypeScript 支持
  • rollup-plugin-esbuild:esbuild 转换(更快)

其他插件:

  • @rollup/plugin-replace:替换代码中的变量
  • @rollup/plugin-alias:路径别名
  • rollup-plugin-terser:代码压缩
  • rollup-plugin-postcss:CSS 处理

如何编写一个 Rollup 插件?

export default function myPlugin(options = {}) {
  return {
    name: 'my-plugin',
    // 构建开始时
    buildStart() {
      console.log('Build started');
    },
    // 解析导入
    resolveId(id) {
      if (id === 'virtual-module') {
        return id;
      }
    },
    // 加载模块
    load(id) {
      if (id === 'virtual-module') {
        return 'export default "virtual"';
      }
    },
    // 转换代码
    transform(code, id) {
      if (id.endsWith('.js')) {
        return code.replace('foo', 'bar');
      }
    },
    // 生成代码
    generateBundle(options, bundle) {
      // 修改输出文件
    },
  };
}

Tree Shaking

Rollup 的 Tree Shaking 原理是什么?

原理:

  1. 静态分析:分析 ES modules 的导入导出
  2. 标记使用:标记哪些导出被使用
  3. 移除未使用:移除未被使用的代码
  4. 副作用检测:检测代码副作用,安全移除

条件:

  • 使用 ES modules 语法
  • 代码无副作用或标记为纯函数
  • 使用 /*#__PURE__*/ 标记副作用

如何确保 Tree Shaking 生效?

方法:

  1. 使用 ES modules 语法
  2. 避免副作用
  3. 使用 /*#__PURE__*/ 标记
  4. 配置 treeshake 选项
export default {
  treeshake: {
    moduleSideEffects: false, // 假设模块无副作用
    propertyReadSideEffects: false,
    tryCatchDeoptimization: false,
  },
};

Tree Shaking 的局限性是什么?

局限性:

  1. 动态导入:无法静态分析动态导入
  2. 副作用代码:无法移除有副作用的代码
  3. CommonJS:对 CommonJS 支持有限
  4. 运行时行为:无法分析运行时行为

性能优化

如何提升 Rollup 构建速度?

优化方法:

  1. 使用 esbuild:替代 Babel,速度提升 10-100 倍
  2. 并行构建:使用 Promise.all 并行构建多个格式
  3. 缓存:使用 Rollup 的缓存机制
  4. 减少插件:只使用必要的插件
  5. 外部依赖:合理配置 external
import { esbuild } from 'rollup-plugin-esbuild';

export default {
  plugins: [
    esbuild({
      target: 'es2015',
      minify: true,
    }),
  ],
};

Rollup 如何处理大型项目?

策略:

  1. 代码分割:使用 manualChunks
  2. 外部依赖:将大型库设为 external
  3. 并行处理:使用多进程
  4. 增量构建:使用缓存

常见问题

Rollup 如何处理 CommonJS 模块?

处理方式:

  1. 使用 @rollup/plugin-commonjs 插件
  2. 将 CommonJS 转换为 ES modules
import commonjs from '@rollup/plugin-commonjs';

export default {
  plugins: [
    commonjs({
      include: /node_modules/,
      transformMixedEsModules: true,
    }),
  ],
};

Rollup 支持 HMR 吗?

支持方式:

  • 需要额外插件,如 rollup-plugin-serve + rollup-plugin-livereload
  • 或使用开发工具如 rollup-plugin-dev
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';

export default {
  plugins: [
    serve({
      open: true,
      contentBase: 'dist',
    }),
    livereload('dist'),
  ],
};

Rollup 如何处理 CSS?

处理方式: 使用 rollup-plugin-postcss 插件

import postcss from 'rollup-plugin-postcss';

export default {
  plugins: [
    postcss({
      extract: true, // 提取 CSS
      minimize: true, // 压缩
      plugins: [
        require('autoprefixer'),
      ],
    }),
  ],
};

Rollup 如何处理 TypeScript?

处理方式:

  1. 使用 @rollup/plugin-typescript
  2. 或使用 rollup-plugin-esbuild(更快)
import typescript from '@rollup/plugin-typescript';

export default {
  plugins: [
    typescript({
      tsconfig: './tsconfig.json',
      declaration: true,
      declarationDir: './dist/types',
    }),
  ],
};

Rollup 如何处理环境变量?

处理方式: 使用 @rollup/plugin-replace

import replace from '@rollup/plugin-replace';

export default {
  plugins: [
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
      __VERSION__: JSON.stringify(require('./package.json').version),
    }),
  ],
};

库开发

如何用 Rollup 开发一个库?

配置示例:

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import { terser } from 'rollup-plugin-terser';
import pkg from './package.json';

export default {
  input: 'src/index.ts',
  output: [
    {
      file: pkg.main, // CommonJS
      format: 'cjs',
      sourcemap: true,
    },
    {
      file: pkg.module, // ES modules
      format: 'es',
      sourcemap: true,
    },
    {
      file: pkg.browser, // UMD
      format: 'umd',
      name: 'MyLibrary',
      sourcemap: true,
    },
  ],
  plugins: [
    resolve(),
    commonjs(),
    typescript({
      declaration: true,
      declarationDir: './dist/types',
    }),
    terser(),
  ],
  external: [
    ...Object.keys(pkg.dependencies || {}),
    ...Object.keys(pkg.peerDependencies || {}),
  ],
};

为什么库开发推荐使用 Rollup?

原因:

  1. Tree Shaking 效果好:生成的代码更小
  2. 代码质量高:输出代码更接近手写代码
  3. 多格式支持:可以同时输出多种格式
  4. 配置简单:相比 Webpack 配置更简单
  5. 性能好:构建速度快

Rollup 如何生成类型声明文件?

方式: 使用 @rollup/plugin-typescript 插件

import typescript from '@rollup/plugin-typescript';

export default {
  plugins: [
    typescript({
      declaration: true,
      declarationDir: './dist/types',
    }),
  ],
};

最佳实践

Rollup 最佳实践

  1. 使用 ES modules:充分利用 Tree Shaking
  2. 合理使用 external:避免打包大型依赖
  3. 多格式输出:同时输出 ES、CommonJS、UMD
  4. 类型声明:生成 TypeScript 类型声明文件
  5. 代码压缩:生产环境启用压缩
  6. Source Map:开发环境生成 Source Map

Rollup 常见错误及解决方案

问题1:CommonJS 模块无法解析

  • 使用 @rollup/plugin-commonjs 插件

问题2:Node.js 内置模块报错

  • 在 resolve 插件中设置 preferBuiltins: false

问题3:动态导入问题

  • 使用 @rollup/plugin-dynamic-import-vars

问题4:循环依赖

  • Rollup 会自动处理,但建议重构代码

问题5:Tree Shaking 不生效

  • 确保使用 ES modules 语法
  • 检查是否有副作用
  • 配置 treeshake 选项

与其他工具对比

Rollup vs Webpack

特性RollupWebpack
Tree Shaking⭐⭐⭐⭐⭐⭐⭐⭐⭐
代码体积最小较大
HMR需插件内置
配置简单复杂
适用场景库开发应用开发

Rollup vs Vite

特性RollupVite
开发模式需要打包无需打包
启动速度较慢极快
生产构建RollupRollup
适用场景库开发应用开发

什么时候选择 Rollup?

选择 Rollup 如果:

  • 开发库或框架
  • 需要 Tree Shaking 效果最好
  • 追求代码体积最小
  • 项目相对简单
  • 不需要复杂的开发服务器功能
最近更新:: 2025/11/20 14:50
Contributors: liyulai
Prev
Rollup配置详解