如何用 Rollup 打包 Javascript / TypeScript

2,092 阅读3分钟

系列

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

前言

相比 WebpackVite 打包,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"] // 指定需要校验的文件
  }