Rollup实践指南(基础版)

1,575 阅读4分钟

一:介绍

Rollup 和 Webpack 是两个常用的 JavaScript 模块打包工具。但是二者应用场景不同。一句话,rollup用来打包构建库应用,webpack用来构建打包复杂应用。

Rollup

  1. Rollup主要用于 ES Modules模块,而Webpack支持多种模块格式。
  2. Rollup拥有强大的 Tree Shaking,Webpack也支持但配置复杂。
  3. Rollup打包体积小,适用于库,工具的打包,而Webpack适用于构建复杂的应用。

二:基础配置

1. 初始化项目

1.1创建文件,安装依赖

mkdir rollup-test
npm init -y
touch rollup.config.ejs
npm i rollup -D

1.2 配置package.json

"scripts": {
    "dev": "rollup -c"
 },
 

1.3 配置rollup.config.ejs

如果配置文件基于commonJS编写,则使用.cjs。如果使用ESModule语法则使用.ejs

  1. rollup.config.ejs

  2. rollup.config.cjs

     export default {
       input:'./src/index.js',//入口
       output:[//输出
         {
           file: 'dist/index.js',
           format: 'iife',
           name:'RollupBundle'//iife必须添加name,全局挂载在window上
         },
         {
           file: 'dist/cs.js',
           format: 'cjs',//CommandJS
         },
         {
           file: 'dist/es.js',
           format: 'es',//ESModule
         }
       ]
     }
    

1.4 创建入口文件 src/index.js

export const test1 = () => {
  let a = 10
  return a+1
}

2. rollup.config.js结构

2.1. input 打包的入口文件

2.2. output 打包的输出文件,可以一次输出多种格式。

2.3. plugins 打包时的插件,处理非js资源如css,json,图片,vue等

2.4. external 设置外部依赖,打包时不会打包这些文件。例如当前有react项目使用了rollup打包的工具,虽然工具依赖于react,但没必要将react打包到rollup,而是用消费者提供的react就行。

  export default {
      input:'./src/index.js',
      output:[
        {
          file: 'dist/index.js',
          format: 'iife',
          name:'RollupBundle'//iife必须添加name,全局挂载window
          plugins:[]
        },
        {
          file: 'dist/cs.js',
          format: 'cjs',//CommandJS
        },
        {
          file: 'dist/es.js',
          format: 'es',//ESModule
        }
      ],
      plugins:[
          plugins1(),
          plugins2(),
          xxxx
      ],
      external:[
          
      ]
}

3.output

3.1 output介绍

output可以输出多种文件包格式,常用的有3种

  1. iife(输出为js文件,通过script的外链导入),iife必须指定name,name是全局挂载在window上变量。
  2. cjs(输出为CommonModule,通过require导入)
  3. es(输出为ESModule,通过import导入)

3.2 output测试

如下rollup.config.ejs配置了打包后的输出方式。

export default {
  input:'./src/index.js',//入口
  output:[//输出
    {
      file: 'dist/iife.js',
      format: 'iife',
      name:'RollupBundle'//iife必须添加name,全局挂载在window上
    },
    {
      file: 'dist/cs.js',
      format: 'cjs',//CommandJS
    },
    {
      file: 'dist/es.js',
      format: 'es',//ESModule
    }
  ]
}

执行npm run dev,打包后的文件如下.

image.png

3.3 打包文件测试

  1. iife.js

创建html文件,导入打包的iife.js。控制台输出

<body>
  <script src="./dist/iife.js"></script>
  <script>
    console.log(RollupBundle)
  </script>
</body>
image.png
  1. es.js

     <body>
       <script type="module">
         import {test1} from "./dist/es.js"
         test1()
       </script>
     </body>
     
    
  2. cs.js(node环境)

     const a = require('./dist/cs.js')
     console.log(a.test1())
    

4. 导入外部工具必备

当我们的文件依赖第三方模块时,如lodash,moment.js,vue等,必须添加如下插件。

 npm i @rollup/plugin-commonjs -D
 npm i @rollup/plugin-node-resolve -D

rollup.config.ejs

import nodeResolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
export default {
  input:'./src/index.js',
  output:[
    {
      file: 'dist/iife.js',
      format: 'iife',
      name:'RollupBundle'//iife必须添加name,全局挂载window
    },
    {
      file: 'dist/cs.js',
      format: 'cjs',//CommandJS
    },
    {
      file: 'dist/es.js',
      format: 'es',//ESModule
    }
  ],
  plugins:[
    nodeResolve(),
    commonjs()
  ]
}

5. Babel

babel用于将es6语法转换为es5。

5.1 安装

npm i @babel/core @babel/preset-env @rollup/plugin-babel -D

5.2 创建babel.config.js

module.exports = {
  presets: [
    ["@babel/preset-env"]
  ]
}

5.3 rollup.config.ejs配置

import nodeResolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import { babel } from '@rollup/plugin-babel'
export default {
  input:'./src/index.js',
  output:[
    {
      file: 'dist/iife.js',
                  format: 'iife',
      name:'RollupBundle'//iife必须添加name,全局挂载window
    },
    {
      file: 'dist/cs.js',
                  format: 'cjs',//CommandJS
    },
    {
      file: 'dist/es.js',
                  format: 'es',//ESModule
    }
  ],
  plugins:[
    nodeResolve(),
    commonjs(),
    babel({
      babelHelpers: "bundled",
      exclude: /node_modules/
    }),
  ]
}

5.4效果对比

未添加babel前

image.png

添加babel后

image.png

6. tenser代码压缩

6.1 安装

npm i @rollup/plugin-terser -D

6.2 rollup.config.ejs

import terser from '@rollup/plugin-terser'
plugins:[
    terser(),
]

7. ts

7.1 安装

npm i @rollup/plugin-typescript -D

7.2 创建tsconfig.json

{
  "compilerOptions": {
    "target": "es6",  // 或 "esnext" 根据需要调整
    "module": "esnext", // 使用 ES Module
    "declaration": true,  // 生成 .d.ts 声明文件
    "outDir": "dist",  // 输出目录
    "strict": true,  // 启用严格模式
    "esModuleInterop": true,  // 允许 CommonJS 和 ES 模块之间的兼容
    "skipLibCheck": true,  // 跳过库文件类型检查(可以加快构建速度)
    "moduleResolution": "node"  // Node 模块解析策略
  },
  "include": ["src/**/*.ts"],  // 包含的 TypeScript 文件
  "exclude": ["node_modules", "dist"]
}

7.3 rollup.config.ejs

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

plugins:[
    typescript({
      tsconfig: './tsconfig.json' 
    })
]

三:npm发布(组件库,工具函数)

基于Rollup可以便捷的将个人封装的组件库,工具函数打包发布到npm。

1. package.json

  1. name包名

  2. version 版本号

  3. main 打包后的目标文件

  4. files:指定打包后上传npm哪些文件,只上传打包后的文件

     {
       "name": "@mtfe/rollup-test1",
       "version": "1.0.0",
       "description": "",
       "main": "dist/cs.js",
       "files": [
         "dist/*"
       ],
       "scripts": {
         "dev": "rollup -c"
       },
       "keywords": [],
       "author": "",
       "license": "ISC",
       "dependencies": {
         "lodash": "4.17.21",
         "rollup": "4.21.0"
       },
       "devDependencies": {
         "@babel/core": "7.25.2",
         "@babel/preset-env": "7.25.4",
         "@rollup/plugin-babel": "6.0.4",
         "@rollup/plugin-commonjs": "26.0.1",
         "@rollup/plugin-node-resolve": "15.2.3",
         "@rollup/plugin-terser": "0.4.4",
         "@rollup/plugin-typescript": "11.1.6",
         "@types/lodash": "4.17.7"
       }
     }
    

2. 发布

npm publish

3. 使用

假设当前是react项目,导入目标包

import {test1} from "@mtfe/rollup-test1"
test1()

假设当前是node项目,导入目标包

const {test1} = require('@mtfe/rollup-test1')
test1()