前端监控2:接入 Rollup

1,399 阅读3分钟

前言

本次监控系统选型用了rollup做构建,阅读本文了解基础的rollup

一、Rollup 是什么?

官方文档:

Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。

与 Webpack 偏向于应用打包的定位不同, Rollup 更加专注于 Javascript类库的打包。

二、为什么要采用 Rollup?

相比较 Webpack, Rollup的优势在于

  1. 有简单的API,易于使用
  2. 专注于 Javascript,只是把我们的代码转码成目标js,没有注入很多其他的代码。
  3. 现在流行的vite 也采用它当生产构建工具。

三、Rollup 应用?

创建实例

  1. 全局安装

yarn global add rollup

  1. 创建配置文件 rollup.config.js
import typescript from 'rollup-plugin-typescript2'
const overrides = {
    compilerOptions: {declaration: true},
    exclude: ["tests/**/*.ts", "tests/**/*.tsx"]
}

export default {
    input: 'src/main.ts',
    output: [
        {
          file: 'out/amd/bundle.js',
          format: 'amd',
          amd: {
            id: 'Test'
          }
        },
        {
          file: 'out/cjs/bundle.js',
          format: 'cjs'
        },
        {
          file: 'out/esm/bundle.js',
          format: 'esm'
        },
        {
          file: 'out/iife/bundle.js',
          format: 'iife',
          name: 'Test',
          globals: {
            lodash: 'lodash'
          }
        },
        {
          file: 'out/umd/bundle.js',
          format: 'umd',
          name: 'Test',
          globals: {
            lodash: 'lodash'
          },
          amd: {
            id: 'Test'
          }
        },
        {
          file: 'out/system/bundle.js',
          format: 'system'
        }
      ],
    plugins: [
        typescript({tsconfigOverride: overrides}),
    ],
  };
  

3.调整 package.json

{
  "devDependencies": {
    "rollup": "^2.76.0",
    "rollup-plugin-typescript2": "^0.29.0"
  },
  "scripts": {
    "build": "rollup -c"
  }
}
  1. 测试文件 main.ts

该文件作为入口

export const sayHello = (message) => {
    console.log(message, "message")
}

sayHello('你好')

class People {
    public name: string;
    public age: number;
    constructor (name, age) {
        this.name = name;
        this.age = age
    }
}
const a: number = 5;

console.log(new People('狮小阳', "38"), a)

核心配置

  1. output 输出配置
output: [
    {
      file: 'out/amd/bundle.js',
      format: 'amd',
      amd: {
        id: 'Test'
    }
]
  • file 表示输出的路径
  • format 表示输出的格式
  • nameformatiifeumd时必须提供,将作为全局变量挂在window(浏览器环境)下:window.A=...
  1. input 输入配置
input: 'src/main.js',
  • input 输入的路径
  1. plugin 插件配置
  2. external
external:['lodash']

告诉rollup 不要将此lodash打包,而作为外部依赖

  1. globals 全局模块 Object 形式的 id: name 键值对,用于umd/iife包。
import $ from 'jquery';

告诉 Rollup jquery 模块的id等同于 $ 变量:

// rollup.config.js
export default {
  ...,
  format: 'iife',
  name: 'MyBundle',
  globals: {
    jquery: '$'
  }
};

常用插件

  1. 引入TS

yarn add rollup-plugin-typescript2 -D

// rollup.config.js

import typescript from 'rollup-plugin-typescript2'

const overrides = {
    compilerOptions: {declaration: true},
    exclude: ["tests/**/*.ts", "tests/**/*.tsx"]
}

plugins: [
        typescript({tsconfigOverride: overrides}),
],
    

……持续更新

最佳实践

react-redux 配置

import nodeResolve from 'rollup-plugin-node-resolve' // 帮助寻找node_modules里的包
import babel from 'rollup-plugin-babel' // rollup 的 babel 插件,ES6转ES5
import replace from 'rollup-plugin-replace' // 替换待打包文件里的一些变量,如process在浏览器端是不存在的,需要被替换
import commonjs from 'rollup-plugin-commonjs' // 将非ES6语法的包转为ES6可用
import uglify from 'rollup-plugin-uglify' // 压缩包

const env = process.env.NODE_ENV

const config = {
  input: 'src/index.js',
  external: ['react', 'redux'], // 告诉rollup,不打包react,redux;将其视为外部依赖
  output: { 
    format: 'umd', // 输出 UMD格式,各种模块规范通用
    name: 'ReactRedux', // 打包后的全局变量,如浏览器端 window.ReactRedux 
    globals: {
      react: 'React', // 这跟external 是配套使用的,指明global.React即是外部依赖react
      redux: 'Redux'
    }
  },
  plugins: [
    nodeResolve(),
    babel({
      exclude: '**/node_modules/**'
    }),
    replace({
      'process.env.NODE_ENV': JSON.stringify(env)
    }),
    commonjs()
  ]
}

if (env === 'production') {
  config.plugins.push(
    uglify({
      compress: {
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        warnings: false
      }
    })
  )
}

export default config

……持续更新

四、Rollup 在本项目中要达到的效果?

打包出IIFE 和 ESM 两种格式的包,根据需要使用,并且安装必要的插件。

五、Rollup 打包结果

1. 自执行函数(IIFE)

IIFE 会构建一个匿名函数,然后我们执行这个匿名函数,对外部的依赖通过入参的形式传入,最后返回该模块的输出。

使用时直接引入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./out/iife/bundle.js"></script>
</body>
</html>

2. ESM

ESM 代表 ES 模块。这是 Javascript 提出的实现一个标准模块系统的方案

import React from 'react';

使用时引入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type=module>
        import {sayHello} from './out/esm/bundle.js'
    sayHello('hello')
    </script>
</body>
</html>
参考文章
  1. Rollup打包工具的使用(超详细,超基础,附代码截图超简单)
  2. 说不清rollup能输出哪6种格式😥差点被鄙视
  3. rollup.js 官方文档
  4. 借助rollup构建npm包最佳实践