rollup - Vue 项目打包

相关代码地址 https://gitee.com/han_xuehong/react_source.git

中文网站地址 https://www.rollupjs.com/

一、Learn Rollup - Vue 项目打包配置示例

这是一个基于 Rollup 的 Vue.js 项目打包配置示例,展示了如何使用 Rollup 构建现代前端应用。

  • 快速构建 - 使用 Rollup 进行高效的代码打包
  • 🔧 多环境配置 - 支持开发和生产环境的不同配置
  • 📦 代码分割 - 自动分包优化加载性能
  • 🎨 Vue 支持 - 完整的 Vue 3 + Vue Router 配置
  • 🖥️ 开发服务器 - 内置热重载开发服务器
  • 📱 ES 模块 - 输出现代 ES 模块格式

(一) 项目结构

learn_rollup/
├── config/                 # Rollup 配置文件
│   ├── rollup.config.dev.js    # 开发环境配置
│   ├── rollup.config.prod.js   # 生产环境配置
│   └── rollup.config.js        # 通用配置
├── src/                   # 源代码目录
│   ├── main.js            # 应用入口文件
│   ├── App.vue            # 根组件
│   ├── index.html         # HTML 模板
│   ├── js/                # JavaScript 工具文件
│   ├── pages/             # Vue 页面组件
│   └── router/            # 路由配置
├── dist/                  # 构建输出目录
├── package.json           # 项目配置和依赖
└── README.md             # 项目说明

(二) 快速开始

1. 安装依赖

npm install

2. 开发模式

启动开发服务器,支持热重载:

npm run dev

服务器将在 http://127.0.0.1:52036 启动(端口可能因环境而异)。

3. 生产构建

npm run build

构建产物将输出到 dist/ 目录。

4. 其他构建命令

# 构建 CommonJS 格式
npm run build:cjs

# 仅生产环境构建
npm run build:prod

(三) 配置说明

1. 环境变量

项目使用以下环境变量:

  • NODE_ENV: 环境标识 (development | production)

2. Rollup 配置详解

一、开发环境配置 (config/rollup.config.dev.js)

核心特性:

  • 输出格式:es (ES 模块)
  • 代码分割:使用 manualChunks 手动分包
  • 开发服务器:集成 rollup-plugin-live-server

关键配置:

export default {
  external: ['node_modules'],          // 排除 node_modules
  input: 'src/main.js',               // 入口文件
  output: {
    dir: 'dist',                     // 输出目录
    format: 'es',                    // ES 模块格式
    manualChunks: {                  // 手动分包配置
      'vue': ['vue'],
      'vue-router': ['vue-router'],
    }
  },
  plugins: [
    // Vue 文件处理
    vuePlugin(),
    // CSS 处理
    postcss(),
    // JS 转换
    babel(),
    // 模块解析
    nodeResolve(),
    // 环境变量替换
    replace(),
    // HTML 生成
    htmlTemplate(),
    // 开发服务器
    liveServer()
  ]
}
二、生产环境配置 (config/rollup.config.prod.js)

核心特性:

  • 输出格式:es (ES 模块)
  • 代码压缩:使用 terser 插件
  • CSS 优化:使用 cssnano 压缩样式

3. 插件配置

一、Vue 支持
import vuePlugin from 'rollup-plugin-vue';

// 配置
vuePlugin()
二、CSS 处理
import postcss from 'rollup-plugin-postcss';

postcss({
  extract: true,                    // 提取 CSS 到单独文件
  plugins: [
    autoprefixer({}),              // 自动添加浏览器前缀
    isPro ? cssnano() : null       // 生产环境压缩 CSS
  ]
})
三、Babel 配置
import { babel } from '@rollup/plugin-babel';

babel({
  babelHelpers: 'bundled',         // 打包 Babel 辅助函数
  exclude: 'node_modules/**'       // 排除 node_modules
})
四、代码分割
manualChunks: {
  'vue': ['vue'],                  // Vue 相关代码分包
  'vue-router': ['vue-router'],    // Vue Router 相关代码分包
}

(四) 常见问题与解决方案

1. 1. ES 模块语法错误

错误信息:

Uncaught SyntaxError: Cannot use import statement outside a module

原因:
使用 format: 'es' 输出 ES 模块,但 HTML 中 script 标签缺少 type="module" 属性。

解决方案:
确保 HTML 中的脚本标签包含 type="module"

<script type="module" src="main.js"></script>

2. 2. 代码分割与 IIFE 格式冲突

错误信息:

Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.

原因:
manualChunks 代码分割功能不支持 iifeumd 格式。

解决方案:

  • 使用 esesm 格式进行代码分割
  • 或移除 manualChunks 配置使用单文件输出

3. 3. 外部模块与分包冲突

错误信息:

"vue" cannot be included in manualChunks because it is resolved as an external module

原因:
external 数组中声明的模块不能在 manualChunks 中使用。

解决方案:

  • external 数组中移除相关模块,或
  • manualChunks 配置中移除相关模块

4. 4. Node.js ES 模块支持问题

错误信息:

ReferenceError: require is not defined

原因:
package.json 中设置了 "type": "module",但代码中使用了 CommonJS 的 require 语法。

解决方案:

  • 使用 ES 模块的 import 语法
  • 或移除 "type": "module" 配置

5. 5. 开发服务器端口冲突

问题:
开发服务器提示端口已被占用。

解决方案:
服务器会自动尝试其他可用端口,或手动指定端口:

liveServer({
  port: 3000,  // 指定端口
  host: "0.0.0.0"
})

6. 6. CSS 提取问题

问题:
CSS 文件没有正确提取或处理。

解决方案:
确保 postcss 插件配置正确:

postcss({
  extract: true,           // 必须设置为 true
  plugins: [/* 插件列表 */]
})

(五) 依赖版本兼容性

1. Node.js 版本要求

  • 推荐版本: Node.js >= 18.0.0
  • 最低版本: Node.js >= 16.0.0 (可能有兼容性警告)

2. 主要依赖版本

{
  "rollup": "^4.55.1",
  "vue": "^3.5.26",
  "@rollup/plugin-babel": "^6.1.0",
  "@rollup/plugin-node-resolve": "^16.0.3"
}

(六) 构建优化建议

1. 1. 代码分割策略

根据应用大小和需求选择合适的分割策略:

// 按页面分割
manualChunks: {
  'vendor': ['vue', 'vue-router'],    // 第三方库
  'pages': ['./src/pages/**/*']       // 页面组件
}

// 或使用函数形式进行更精细的控制
manualChunks(id) {
  if (id.includes('node_modules')) {
    return 'vendor';
  }
}

2. 2. 缓存优化

添加缓存配置提高构建速度:

import { addons } from '@rollup/plugin-babel';

plugins: [
  babel({
    babelHelpers: 'runtime',     // 使用 runtime helpers
    plugins: [addons.runtime()]
  })
]

3. 3. 压缩优化

生产环境使用更强的压缩配置:

terser({
  compress: {
    drop_console: true,          // 移除 console 语句
    drop_debugger: true,         // 移除 debugger 语句
    pure_funcs: ['console.log'] // 移除特定函数调用
  }
})

(七) 故障排除

1. 构建失败

  1. 检查 Node.js 版本是否符合要求
  2. 清除 node_modules 并重新安装:rm -rf node_modules && npm install
  3. 检查配置文件语法错误

2. 运行时错误

  1. 检查浏览器是否支持 ES 模块
  2. 确认 HTML 中的脚本标签配置正确
  3. 检查网络请求是否正常加载分包文件

3. 性能问题

  1. 启用生产环境压缩
  2. 优化代码分割策略
  3. 使用更高效的 Babel 配置

(八) 参考资源

(九) 许可证

ISC License

二、Learn Rollup - 插件详解与配置指南

本项目展示了如何在 Rollup 中使用各种插件来构建现代前端应用。以下详细介绍项目中使用的所有插件及其配置方法。

(一) 📋 Rollup 输出格式对比:IIFE vs ES

1. 格式概述

Rollup 支持多种输出格式,其中 IIFE(Immediately Invoked Function Expression)和 ES(ES Modules)是最常用的两种。选择合适的格式对项目的兼容性、性能和开发体验有重要影响。

2. 🔍 详细对比

一、1. IIFE 格式 (Immediately Invoked Function Expression)

基本概念:

  • 立即执行函数表达式
  • 输出传统的 JavaScript 函数,可以直接在 <script> 标签中使用

输出示例:

// 输出结果
(function() {
  // 打包后的代码
  const app = { /* ... */ };
  window.MyApp = app;
})();

// 或者使用具名函数
var MyBundle = (function() {
  // 代码内容
  return { /* 导出对象 */ };
})();

核心配置:

export default {
  input: 'src/main.js',
  output: {
    format: 'iife',
    file: 'dist/bundle.js',
    name: 'MyApp',           // 全局变量名(可选)
    globals: {               // 外部依赖映射
      'vue': 'Vue',
      'lodash': '_'
    }
  }
}

特点:

  • 浏览器兼容性最好 - 支持所有现代浏览器
  • 无需额外配置 - 直接在 HTML 中使用 <script src="bundle.js"></script>
  • 全局变量支持 - 可创建全局变量供其他脚本使用
  • 立即执行 - 加载后自动运行
  • 不支持代码分割 - 不能使用 manualChunks
  • 不支持动态导入 - 不能使用 import() 语法
  • 文件较大 - 包含完整的运行时代码
二、2. ES 格式 (ES Modules)

基本概念:

  • 原生 ES6 模块语法
  • 使用 import/export 语句的现代 JavaScript 模块

输出示例:

// 输出结果
import { createApp } from './vue-vendor.js';
import App from './main.js';

const app = createApp(App);
// ... 应用代码
export { app };

核心配置:

export default {
  input: 'src/main.js',
  output: {
    format: 'es',
    dir: 'dist',             // 必须使用目录输出
    manualChunks: {          // 支持代码分割
      'vue-vendor': ['vue', 'vue-router']
    }
  }
}

特点:

  • 支持代码分割 - 可使用 manualChunks 优化加载
  • 支持动态导入 - 可使用 import() 进行懒加载
  • 现代语法 - 原生 ES6 模块,性能更好
  • 树摇优化 - 更好的死代码消除
  • 并行加载 - 多个 chunk 可并行下载
  • 浏览器兼容性 - 需要 <script type="module"> 支持
  • 需要服务器支持 - 某些服务器需要配置 MIME 类型
  • 不支持全局变量 - 不能直接创建全局变量

3. 🎯 使用场景选择

一、何时选择 IIFE?
  1. 传统项目迁移
    • 需要兼容旧版浏览器
    • 现有代码使用全局变量模式
    • 不需要复杂的代码分割
  1. 简单应用
    • 单页应用,无需代码分割
    • 需要全局变量供其他脚本使用
    • 对构建复杂度要求低
  1. 第三方库开发
    • 需要发布为可直接使用的库
    • 用户可能不使用现代构建工具
二、何时选择 ES?
  1. 现代 Web 应用
    • 使用现代浏览器
    • 需要代码分割和懒加载
    • 重视性能优化
  1. 微前端架构
    • 多个应用共享模块
    • 需要运行时动态加载
    • 现代开发工作流
  1. 框架和工具库
    • 面向现代开发者的库
    • 需要树摇优化
    • 支持服务端渲染

4. ⚙️ 配置对比

一、IIFE 配置示例
// rollup.config.js
export default {
  external: ['vue', 'vue-router'],  // 外部依赖
  input: 'src/main.js',
  output: {
    format: 'iife',
    file: 'dist/bundle.js',
    name: 'MyApp',
    globals: {
      'vue': 'Vue',              // 全局变量映射
      'vue-router': 'VueRouter'
    },
    sourcemap: true
  },
  plugins: [
    // ... 插件配置
  ]
}
二、ES 配置示例
// rollup.config.js
export default {
  external: [],                     // 通常不设置外部依赖
  input: 'src/main.js',
  output: {
    format: 'es',
    dir: 'dist',                   // 使用目录输出
    manualChunks: {                // 代码分割
      'vue-vendor': ['vue', 'vue-router'],
      'utils': ['lodash']
    },
    sourcemap: true
  },
  plugins: [
    // ... 插件配置
    htmlTemplate({
      attrs: ['type="module"']     // 重要:添加模块类型
    })
  ]
}

5. 🌐 HTML 使用方式

一、IIFE 在 HTML 中的使用
<!DOCTYPE html>
<html>
<head>
  <!-- 外部依赖 -->
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script src="https://unpkg.com/vue-router@4/dist/vue-router.global.js"></script>
</head>
<body>
  <div id="app"></div>
  <!-- 直接使用,无需特殊属性 -->
  <script src="dist/bundle.js"></script>
</body>
</html>
二、ES 在 HTML 中的使用
<!DOCTYPE html>
<html>
<head>
  <!-- 无需外部依赖CDN -->
</head>
<body>
  <div id="app"></div>
  <!-- 必须添加 type="module" -->
  <script type="module" src="dist/main.js"></script>
  <script type="module" src="dist/vue-vendor.js"></script>
</body>
</html>

6. 🚨 常见问题与解决方案

一、IIFE 模式问题
  1. 代码分割失败
Error: UMD and IIFE output formats are not supported for code-splitting builds

解决: 移除 manualChunks 配置,或改用 ES 格式

  1. 全局变量冲突
    解决: 使用不同的 name 配置,或调整 globals 映射
二、ES 模式问题
  1. 模块语法错误
Uncaught SyntaxError: Cannot use import statement outside a module

解决: 在 HTML 中添加 <script type="module">

  1. CORS 问题
Failed to resolve module specifier "vue"

解决: 检查 external 配置,不要将需要打包的模块设为外部依赖

  1. MIME 类型错误
Loading module from "http://localhost:3000/main.js" was blocked

解决: 配置开发服务器正确处理 .js 文件的 text/javascript MIME 类型

7. 📊 性能对比

方面

IIFE

ES

初始加载

快(单文件)

可能慢(多文件)

缓存利用

差(全量更新)

优(按需更新)

代码分割

❌ 不支持

✅ 支持

树摇优化

一般

优秀

浏览器兼容

优秀

现代浏览器

调试体验

一般

优秀

文件大小

较大

较小(分割后)

8. 🔧 迁移指南

一、从 IIFE 迁移到 ES
  1. 修改输出配置:
// 之前
output: {
  format: 'iife',
  file: 'dist/bundle.js'
}

// 之后
output: {
  format: 'es',
  dir: 'dist'
}
  1. 移除外部依赖:
// 移除这些配置
external: ['vue', 'vue-router']
globals: { 'vue': 'Vue' }
  1. 添加代码分割:
manualChunks: {
  'vendor': ['vue', 'vue-router']
}
  1. 修改 HTML:
<!-- 添加 type="module" -->
<script type="module" src="dist/main.js"></script>
二、从 ES 迁移到 IIFE
  1. 修改输出配置:
// 之前
output: {
  format: 'es',
  dir: 'dist'
}

// 之后
output: {
  format: 'iife',
  file: 'dist/bundle.js'
}
  1. 移除代码分割:
// 删除 manualChunks 配置
  1. 添加外部依赖:
external: ['vue', 'vue-router']
globals: { 'vue': 'Vue' }
  1. 修改 HTML:
<!-- 添加 CDN 依赖 -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- 移除 type="module" -->
<script src="dist/bundle.js"></script>

9. 💡 最佳实践

  1. 开发环境: 建议使用 ES 格式,便于调试和开发
  2. 生产环境: 根据目标用户选择:
    • 现代应用:ES 格式 + 代码分割
    • 兼容性要求高:IIFE 格式 + CDN
  1. 混合使用: 可同时输出多种格式满足不同需求
// 同时输出多种格式
export default [
  {
    input: 'src/main.js',
    output: [
      { format: 'es', dir: 'dist/es' },
      { format: 'iife', file: 'dist/iife/bundle.js', name: 'MyApp' }
    ]
  }
]

(二) 🔧 Rollup 核心插件详解

1. 1. @rollup/plugin-node-resolve

作用: 解析 Node.js 模块,让 Rollup 能够找到 node_modules 中的第三方模块。

基本用法:

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

export default {
  plugins: [
    nodeResolve({
      // 解析的文件扩展名
      extensions: ['.mjs', '.js', '.json', '.node'],
      // 是否将符号链接解析为真实路径
      preferBuiltins: true,
      // 浏览器环境设置
      browser: true
    })
  ]
}

注意事项:

  • browser: true 确保解析适合浏览器的模块版本
  • preferBuiltins 在 Node.js 环境中优先使用内置模块
  • 默认不解析 .mjs 文件,需要显式添加扩展名

2. 2. @rollup/plugin-commonjs

作用: 将 CommonJS 模块转换为 ES 模块,使其能在 Rollup 中使用。

基本用法:

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

export default {
  plugins: [
    commonjs({
      // 包含的模块
      include: 'node_modules/**',
      // 排除的模块
      exclude: ['node_modules/foo/**', 'node_modules/bar/**'],
      // 转换选项
      transformMixedEsModules: true,
      // 默认导出处理
      defaultIsModuleExports: 'auto'
    })
  ]
}

注意事项:

  • 必须在 @rollup/plugin-node-resolve 之后使用
  • transformMixedEsModules: true 处理同时包含 ES 和 CommonJS 的包
  • defaultIsModuleExports: 'auto' 自动检测默认导出的处理方式

3. 3. @rollup/plugin-babel

作用: 使用 Babel 转译 JavaScript 代码,支持现代语法和浏览器兼容性。

基本用法:

import { babel } from '@rollup/plugin-babel';

export default {
  plugins: [
    babel({
      // Babel 辅助函数处理方式
      babelHelpers: 'bundled', // 'bundled' | 'runtime' | 'inline'
      // 排除的文件
      exclude: 'node_modules/**',
      // 包含的文件
      include: ['src/**/*'],
      // 扩展名处理
      extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
      // Babel 配置
      presets: [
        ['@babel/preset-env', {
          targets: '> 0.25%, not dead',
          modules: false
        }]
      ]
    })
  ]
}

注意事项:

  • babelHelpers: 'bundled' 将辅助函数打包进每个文件
  • babelHelpers: 'runtime' 使用运行时辅助函数,需要额外安装 @babel/runtime
  • modules: false 让 Babel 不转换 ES 模块语法

4. 4. @rollup/plugin-replace

作用: 在构建时替换代码中的字符串,通常用于环境变量替换。

基本用法:

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

export default {
  plugins: [
    replace({
      // 环境变量替换
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      // 自定义变量
      __BUILD_TIME__: JSON.stringify(new Date().toISOString()),
      __VERSION__: JSON.stringify('1.0.0'),
      // 防止变量被意外赋值
      preventAssignment: true,
      // 值处理函数
      __COMMIT_HASH__: () => JSON.stringify(process.env.COMMIT_HASH || 'dev')
    })
  ]
}

注意事项:

  • preventAssignment: true 防止意外的变量赋值
  • 值可以是字符串、数字或返回值的函数
  • 替换发生在 AST 级别,性能较好

5. 5. @rollup/plugin-terser

作用: 使用 Terser 压缩和混淆 JavaScript 代码。

基本用法:

import { terser } from '@rollup/plugin-terser';

export default {
  plugins: [
    terser({
      // 压缩选项
      compress: {
        drop_console: true,
        drop_debugger: true,
        pure_funcs: ['console.log', 'console.info']
      },
      // 混淆选项
      mangle: {
        properties: {
          regex: /^_/ // 只混淆以_开头的属性
        }
      },
      // 格式化选项
      format: {
        comments: false // 移除注释
      },
      // 并行处理
      maxWorkers: 4
    })
  ]
}

注意事项:

  • 生产环境使用,避免开发时使用影响调试
  • drop_console: true 移除所有 console 语句
  • maxWorkers 设置并行处理数量以提高速度

(三) 🎨 样式处理插件

1. 1. rollup-plugin-postcss

作用: 处理 CSS 文件,支持 PostCSS 插件、CSS 模块、自动注入等功能。

基本用法:

import postcss from 'rollup-plugin-postcss';

export default {
  plugins: [
    postcss({
      // 是否提取 CSS 到单独文件
      extract: true,
      // 提取的文件名
      extract: 'bundle.css',
      // CSS 模块支持
      modules: {
        generateScopedName: '[name]__[local]___[hash:base64:5]'
      },
      // PostCSS 插件
      plugins: [
        require('autoprefixer'),
        require('cssnano')
      ],
      // 最小化选项
      minimize: true,
      // 源映射
      sourceMap: true
    })
  ]
}

注意事项:

  • extract: true 将 CSS 提取到单独文件
  • modules: true 启用 CSS 模块功能
  • 支持多种文件类型:.css, .scss, .sass, .less, .styl

2. 2. autoprefixer

作用: 自动为 CSS 属性添加浏览器前缀。

基本用法:

const autoprefixer = require('autoprefixer');

postcss({
  plugins: [
    autoprefixer({
      // 浏览器支持范围
      overrideBrowserslist: ['> 1%', 'last 2 versions'],
      // 网格布局前缀
      grid: true,
      // 是否添加前缀到不必要的属性
      add: true
    })
  ]
})

注意事项:

  • 需要与 browserslist 配置配合使用
  • 默认使用 .browserslistrcpackage.json 中的配置

3. 3. cssnano

作用: 压缩和优化 CSS 代码。

基本用法:

const cssnano = require('cssnano');

postcss({
  plugins: [
    cssnano({
      preset: ['default', {
        // 丢弃注释
        discardComments: { removeAll: true },
        // 规范化字符串
        normalizeString: true,
        // 颜色优化
        colormin: true,
        // 重复选择器移除
        mergeRules: true
      }]
    })
  ]
})

注意事项:

  • 仅在生产环境使用
  • preset: 'default' 使用默认优化配置
  • 可以自定义各种优化选项

(四) ⚛️ 框架支持插件

1. 1. rollup-plugin-vue

作用: 处理 Vue 单文件组件 (.vue 文件)。

基本用法:

import vue from 'rollup-plugin-vue';

export default {
  plugins: [
    vue({
      // CSS 处理方式
      css: true,
      // 编译模板
      compileTemplate: true,
      // 样式作用域
      style: {
        postcssPlugins: [require('autoprefixer')]
      },
      // 模板预编译
      template: {
        preprocessOptions: {
          pug: { doctype: 'html' }
        }
      },
      // 自定义块处理
      customBlocks: {
        docs: { defaultLang: 'markdown' }
      }
    })
  ]
}

注意事项:

  • 需要在 postcss 插件之前配置
  • 支持 Pug、Haml 等模板预处理器
  • 自动处理组件中的样式和模板

(五) 🛠️ 开发工具插件

1. 1. rollup-plugin-live-server

作用: 启动开发服务器,支持热重载和静态文件服务。

基本用法:

import { liveServer } from 'rollup-plugin-live-server';

export default {
  plugins: [
    liveServer({
      // 端口号
      port: 3000,
      // 主机地址
      host: '0.0.0.0',
      // 根目录
      root: 'dist',
      // 入口文件
      file: 'index.html',
      // 是否打开浏览器
      open: false,
      // 等待时间(毫秒)
      wait: 500,
      // HTTPS 配置
      https: false,
      // 中间件
      middleware: []
    })
  ]
}

注意事项:

  • 服务器会自动寻找可用端口
  • wait: 500 等待构建完成后再刷新
  • 支持自定义中间件扩展功能

2. 2. rollup-plugin-clear

作用: 在构建前清理输出目录。

基本用法:

import clear from 'rollup-plugin-clear';

export default {
  plugins: [
    clear({
      // 要清理的目录
      targets: ['dist', 'build'],
      // 是否监听模式下也清理
      watch: false
    })
  ]
}

注意事项:

  • 建议放在插件列表的开头
  • watch: false 在监听模式下不清理,提高开发效率

3. 3. rollup-plugin-generate-html-template

作用: 根据模板生成 HTML 文件,并自动注入构建产物。

基本用法:

import htmlTemplate from 'rollup-plugin-generate-html-template';

export default {
  plugins: [
    htmlTemplate({
      // 模板文件路径
      template: 'src/index.html',
      // 输出文件路径
      target: 'dist/index.html',
      // 自定义替换变量
      attrs: ['type="module"'],
      // 是否注入产物
      inject: true
    })
  ]
}

注意事项:

  • 模板中需要有 <!-- inject:js --> 注释来指定注入位置
  • 支持 EJS 模板语法
  • 自动处理 CSS 和 JS 文件的注入

(六) 🧰 Babel 生态插件

1. 1. @babel/core

作用: Babel 编译器的核心包,提供代码转换功能。

配置要点:

{
  "babel": {
    "presets": [
      ["@babel/preset-env", {
        "targets": "> 0.25%, not dead",
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": "3.32.0"
      }]
    ],
    "plugins": [
      ["@babel/plugin-transform-runtime", {
        "helpers": true,
        "regenerator": true
      }]
    ]
  }
}

2. 2. @babel/preset-env

作用: 根据目标环境自动确定需要的 Babel 插件。

配置选项:

  • targets: 目标浏览器环境
  • modules: false: 不转换 ES 模块
  • useBuiltIns: "usage": 按需引入 polyfill

3. 3. @babel/plugin-transform-runtime

作用: 避免重复打包 Babel 辅助函数,使用运行时版本。

配置要点:

["@babel/plugin-transform-runtime", {
  "helpers": true,        // 启用辅助函数转换
  "regenerator": true,    // 启用生成器函数支持
  "version": "^7.28.0"    // 指定运行时版本
}]

(七) 📦 工具库

1. 1. cross-env

作用: 跨平台设置环境变量。

使用方法:

{
  "scripts": {
    "dev": "cross-env NODE_ENV=development rollup -c",
    "build": "cross-env NODE_ENV=production rollup -c"
  }
}

注意事项:

  • Windows 和 Unix 系统环境变量语法不同
  • 解决 NODE_ENV=production 在 Windows 下的兼容性问题

2. 2. sass (Dart Sass)

作用: Sass 预处理器,支持 SCSS 和 Sass 语法。

在 Rollup 中的使用:

postcss({
  plugins: [
    // 自动处理 Sass 文件
    require('sass')
  ]
})

注意事项:

  • 需要安装 sass 包(Dart Sass)
  • 支持 .scss.sass 文件
  • 自动处理 @import 和嵌套语法

(八) ⚠️ 常见配置问题与解决方案

1. 1. ES 模块兼容性问题

问题: Cannot use import statement outside a module

解决方案:

// 正确配置
output: {
  format: 'es',  // 使用 ES 模块格式
  // HTML 中需要 type="module"
  // <script type="module" src="..."></script>
}

2. 2. 代码分割冲突

问题: IIFE format is not supported for code-splitting

解决方案:

// 错误配置
output: {
  format: 'iife',  // 不支持代码分割
  manualChunks: { ... }  // 冲突
}

// 正确配置
output: {
  format: 'es',    // 使用 ES 格式
  manualChunks: { ... }  // 支持代码分割
}

3. 3. 外部模块分包冲突

问题: cannot be included in manualChunks because it is external

解决方案:

// 错误配置
export default {
  external: ['vue'],           // 外部模块
  output: {
    manualChunks: {
      vue: ['vue']             // 冲突!
    }
  }
}

// 正确配置 - 选择其一
// 方案1:移除 external
external: [],

// 方案2:移除 manualChunks 中的外部模块
manualChunks: {
  // 移除 vue 相关配置
}

4. 4. Babel 辅助函数重复打包

问题: 构建产物中包含大量重复的辅助函数

解决方案:

babel({
  babelHelpers: 'runtime',  // 使用运行时版本
  plugins: [
    ['@babel/plugin-transform-runtime']
  ]
})
// 需要额外安装 @babel/runtime

5. 5. PostCSS 插件顺序问题

问题: CSS 压缩或前缀添加不生效

解决方案:

postcss({
  plugins: [
    // 顺序很重要:先处理,再压缩
    require('autoprefixer'),  // 1. 添加前缀
    require('cssnano')        // 2. 压缩(生产环境)
  ]
})

6. 6. 开发服务器端口冲突

问题: Port 3000 is already in use

解决方案:

liveServer({
  port: 3000,
  // 自动寻找可用端口
  // 或手动指定不同端口
  port: 3001
})

7. 7. CSS 模块作用域问题

问题: CSS 模块类名重复或样式不生效

解决方案:

postcss({
  modules: {
    // 生成唯一类名
    generateScopedName: '[name]__[local]___[hash:base64:5]',
    // 全局模块识别
    globalModulePaths: [/global/]
  }
})

(九) 🔍 性能优化建议

1. 1. 构建速度优化

export default {
  plugins: [
    // 使用缓存
    babel({ cache: true }),
    // 并行处理
    terser({ maxWorkers: 4 }),
    // 排除不必要的文件
    nodeResolve({
      preferBuiltins: false  // 减少不必要的解析
    })
  ]
}

2. 2. 产物大小优化

output: {
  // 启用压缩
  compact: true,
  // 代码分割
  manualChunks: {
    vendor: ['vue', 'vue-router'],  // 分离第三方库
    utils: ['lodash']               // 分离工具库
  }
}

3. 3. 开发体验优化

// 启用源码映射
output: {
  sourcemap: true
},

plugins: [
  // 热重载
  liveServer({
    wait: 100  // 减少等待时间
  })
]

(十) 📚 参考资源

(十一) 📄 许可证

ISC License

(十二) 快速开始

1. 安装依赖

npm install

2. 开发模式

启动开发服务器,支持热重载:

npm run dev

服务器将在 http://127.0.0.1:52036 启动(端口可能因环境而异)。

3. 生产构建

npm run build

构建产物将输出到 dist/ 目录。

4. 其他构建命令

# 构建 CommonJS 格式
npm run build:cjs

# 仅生产环境构建
npm run build:prod

(十三) 配置说明

1. 环境变量

项目使用以下环境变量:

  • NODE_ENV: 环境标识 (development | production)

2. Rollup 配置详解

一、开发环境配置 (config/rollup.config.dev.js)

核心特性:

  • 输出格式:es (ES 模块)
  • 代码分割:使用 manualChunks 手动分包
  • 开发服务器:集成 rollup-plugin-live-server

关键配置:

export default {
  external: ['node_modules'],          // 排除 node_modules
  input: 'src/main.js',               // 入口文件
  output: {
    dir: 'dist',                     // 输出目录
    format: 'es',                    // ES 模块格式
    manualChunks: {                  // 手动分包配置
      'vue': ['vue'],
      'vue-router': ['vue-router'],
    }
  },
  plugins: [
    // Vue 文件处理
    vuePlugin(),
    // CSS 处理
    postcss(),
    // JS 转换
    babel(),
    // 模块解析
    nodeResolve(),
    // 环境变量替换
    replace(),
    // HTML 生成
    htmlTemplate(),
    // 开发服务器
    liveServer()
  ]
}
二、生产环境配置 (config/rollup.config.prod.js)

核心特性:

  • 输出格式:es (ES 模块)
  • 代码压缩:使用 terser 插件
  • CSS 优化:使用 cssnano 压缩样式

3. 插件配置

一、Vue 支持
import vuePlugin from 'rollup-plugin-vue';

// 配置
vuePlugin()
二、CSS 处理
import postcss from 'rollup-plugin-postcss';

postcss({
  extract: true,                    // 提取 CSS 到单独文件
  plugins: [
    autoprefixer({}),              // 自动添加浏览器前缀
    isPro ? cssnano() : null       // 生产环境压缩 CSS
  ]
})
三、Babel 配置
import { babel } from '@rollup/plugin-babel';

babel({
  babelHelpers: 'bundled',         // 打包 Babel 辅助函数
  exclude: 'node_modules/**'       // 排除 node_modules
})
四、代码分割
manualChunks: {
  'vue': ['vue'],                  // Vue 相关代码分包
  'vue-router': ['vue-router'],    // Vue Router 相关代码分包
}

(十四) 常见问题与解决方案

1. 1. ES 模块语法错误

错误信息:

Uncaught SyntaxError: Cannot use import statement outside a module

原因:
使用 format: 'es' 输出 ES 模块,但 HTML 中 script 标签缺少 type="module" 属性。

解决方案:
确保 HTML 中的脚本标签包含 type="module"

<script type="module" src="main.js"></script>

2. 2. 代码分割与 IIFE 格式冲突

错误信息:

Invalid value "iife" for option "output.format" - UMD and IIFE output formats are not supported for code-splitting builds.

原因:
manualChunks 代码分割功能不支持 iifeumd 格式。

解决方案:

  • 使用 esesm 格式进行代码分割
  • 或移除 manualChunks 配置使用单文件输出

3. 3. 外部模块与分包冲突

错误信息:

"vue" cannot be included in manualChunks because it is resolved as an external module

原因:
external 数组中声明的模块不能在 manualChunks 中使用。

解决方案:

  • external 数组中移除相关模块,或
  • manualChunks 配置中移除相关模块

4. 4. Node.js ES 模块支持问题

错误信息:

ReferenceError: require is not defined

原因:
package.json 中设置了 "type": "module",但代码中使用了 CommonJS 的 require 语法。

解决方案:

  • 使用 ES 模块的 import 语法
  • 或移除 "type": "module" 配置

5. 5. 开发服务器端口冲突

问题:
开发服务器提示端口已被占用。

解决方案:
服务器会自动尝试其他可用端口,或手动指定端口:

liveServer({
  port: 3000,  // 指定端口
  host: "0.0.0.0"
})

6. 6. CSS 提取问题

问题:
CSS 文件没有正确提取或处理。

解决方案:
确保 postcss 插件配置正确:

postcss({
  extract: true,           // 必须设置为 true
  plugins: [/* 插件列表 */]
})

(十五) 依赖版本兼容性

1. Node.js 版本要求

  • 推荐版本: Node.js >= 18.0.0
  • 最低版本: Node.js >= 16.0.0 (可能有兼容性警告)

2. 主要依赖版本

{
  "rollup": "^4.55.1",
  "vue": "^3.5.26",
  "@rollup/plugin-babel": "^6.1.0",
  "@rollup/plugin-node-resolve": "^16.0.3"
}

(十六) 构建优化建议

1. 1. 代码分割策略

根据应用大小和需求选择合适的分割策略:

// 按页面分割
manualChunks: {
  'vendor': ['vue', 'vue-router'],    // 第三方库
  'pages': ['./src/pages/**/*']       // 页面组件
}

// 或使用函数形式进行更精细的控制
manualChunks(id) {
  if (id.includes('node_modules')) {
    return 'vendor';
  }
}

2. 2. 缓存优化

添加缓存配置提高构建速度:

import { addons } from '@rollup/plugin-babel';

plugins: [
  babel({
    babelHelpers: 'runtime',     // 使用 runtime helpers
    plugins: [addons.runtime()]
  })
]

3. 3. 压缩优化

生产环境使用更强的压缩配置:

terser({
  compress: {
    drop_console: true,          // 移除 console 语句
    drop_debugger: true,         // 移除 debugger 语句
    pure_funcs: ['console.log'] // 移除特定函数调用
  }
})

(十七) 故障排除

1. 构建失败

  1. 检查 Node.js 版本是否符合要求
  2. 清除 node_modules 并重新安装:rm -rf node_modules && npm install
  3. 检查配置文件语法错误

2. 运行时错误

  1. 检查浏览器是否支持 ES 模块
  2. 确认 HTML 中的脚本标签配置正确
  3. 检查网络请求是否正常加载分包文件

3. 性能问题

  1. 启用生产环境压缩
  2. 优化代码分割策略
  3. 使用更高效的 Babel 配置

(十八) 参考资源

(十九) 许可证

ISC License

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值