如何用 Rollup 打包 Javascript / TypeScript

2,892 阅读3分钟

系列

  1. 如何用 Rollup 打包 JavaScript / TypeScript (本章节)
  2. 如何用 Rollup 打包 Vue2.x UI 组件 (下章节)
  3. 如何用 Rollup 打包 Vue3.x UI 组件 (已完成)
  4. 如何用 Rollup 打包 React UI 组件 (已完成)

前言

相比 Webpack 和 Vite 打包,Rollup 自身轻量化的插件机制,确实更适合作为类库的打包工具。而本章节主要对 rollup 插件、选项以及 tsconfig 的配置进行分享。


rollup 常用插件

  • @rollup/plugin-alias: 路径别名映射
  • @rollup/plugin-replace: 替换文件中目标字符串,例: process.env.NODE_ENV 情况
  • @rollup/plugin-node-resolve: 解析在 node_modules 中的第三方模块
  • @rollup/plugin-commonjs: 将 CommonJS 模块转换为 ESM,以便 Rollup 解析处
  • @rollup/plugin-json: 构建中处理 JSON 文件
  • @rollup/plugin-typescript: 将 typescript 解析 JavaScript, 常与 tsconfig.json 配合使用
  • @rollup/plugin-babel: babel 插件,常通过 babel.config.js 配置启用 presets 或 plugin
  • @rollup/plugin-terser: 压缩源码插件
  • rollup-plugin-copy: 拷贝文件资源至指定文件夹
  • rollup-plugin-dts: 汇总生成声明文件,即 .d.ts 文件
  import { defineConfig } from 'rollup'
  import alias from '@rollup/plugin-alias'
  import replace from '@rollup/plugin-replace'
  import nodeResolve from '@rollup/plugin-node-resolve'
  import commonjs from '@rollup/plugin-commonjs'
  import json from '@rollup/plugin-json'
  import typescript from '@rollup/plugin-typescript'
  import babel from '@rollup/plugin-babel'
  import terser from '@rollup/plugin-terser'
  import copy from 'rollup-plugin-copy'
  import dts from 'rollup-plugin-dts'

  export default defineConfig([
    {
      // ...
      
      plugins: [
        alias({
          entries: [{
            find: '@',
            replacement: new URL('./src', import.meta.url).pathname
          }]
        }),

        replace({
          'preventAssignment': true,
          'process.env.NODE_ENV': JSON.stringify('development')
        }),

        nodeResolve(),
        commonjs(),
        json(),

        typescript({
          sourceMap: false
        }),

        babel({
          babelHelpers: 'bundled',
          extensions: ['.js', '.vue']
        }),

        copy({
          targets: [{
            dest: ['dist'],
            src: ['src/assets/*', '!src/assets/*.ts'],
            rename: (name, ext) => `assets/${name}.${ext}`
          }],
          expandDirectories: false
        }),

        terser(),
        dts(),
      ]
    }
  ])

rollup 常用配置

  • input: 需要处理的资源路径

  • output: 打包成指定格式的配置选项

    • dir: 输出目录
    • format: 输出指定格式,常用有 'es' | 'cjs' | 'umd' | 'iife'
    • exports: 导出模式, 常用 'named' | 'auto' | 'default'
    • hoistTransitiveImports: 是否允许空导入,默认允许。例 import 'vue' or require('vue')
    • entryFileNames: 打包入口文件命名,例:'[name][hash].cjs',
    • chunkFileNames: 公共块文件命名,例:'[name]-[hash].cjs',
    • manualChunks: 自定义共享公共块,例:将 node_modules 中资源都打包到 vendor 中
    • sourcemap: 是否启用 sourcemap
    • paths: 将外部模块ID映射到路径,例:转换成来自于CDN的外部路径
  • plugins: 使用 Rollup 插件(官方或自定义的插件)

  • external: 需要排除打包的一些插件


rollup 编译运行

  • rollup.config.js: rollup --config rollup.config.js

  • rollup.config.ts: rollup --config rollup.config.ts --configPlugin typescript


tsconfig 常用配置

  {
    "compilerOptions": {
      "baseUrl": "./", // 解析非相对模块的基地址,以便TS智能识别。当Rollup 打包时还是需要配置alias
      "rootDir": "./", // 指定输入的根目录
      "outDir": "dist", // 指定打包输出的目录
      "target": "ESNext", // 目标语言的版本
      "module": "ESNext", // 生成代码的模板标准
      "jsx": "preserve", // 指定 jsx 格式处理方式,preserve 保留了所有的 JSX
      "moduleResolution": "Node", // 模块解析策略
      "allowSyntheticDefaultImports": true, // 允许有没有默认导出的模块导入
      "strict": true, // 开启所有严格的类型检查
      "sourceMap": true, // 生成目标文件的sourceMap文件
      "resolveJsonModule": true, // 是否允许把json文件当做模块进行解析
      "isolatedModules": true, // 将每个文件作为单独的模块
      "esModuleInterop": true, // 支持使用`import d from 'cjs'`的方式引入`commonjs`包
      "skipLibCheck": true, // tsc 编译中跳过类型声明文件的类型检查
      "declaration": true, // 生成声明文件
      "lib": ["ESNext","DOM"], // 扩展类型定义集
      "paths": {
        "@/*": ["src/*"] // TS智能识别,当Rollup 打包时还是需要配置alias,否则会报错
      }
    },
    "include": ["src/**/*.ts","src/**/*.d.ts"] // 指定需要校验的文件
  }