npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

how-to-use-rollup

v1.0.6

Published

该项目用于介绍如何使用 `rollup` 打包 library,涉及代码压缩、babel、external、3rd-npm 的打包。

Downloads

10

Readme

项目介绍

该项目用于介绍如何使用 rollup 打包 library,涉及代码压缩、babel、external、3rd-npm 的打包。

一、如何使用 rollup 输出 UMD、ESM 的压缩和未压缩代码

// rollup.config.js
import { terser } from 'rollup-plugin-terser';

export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello'
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            terser()
        ]
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm'
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            terser()
        ]
    }]
};

二、如何使用 rollup 引入第三方模块 bundle 整个输出

参考:https://www.rollupjs.com/guide/tools/

rollup 打包时,默认不会处理第三方模块的代码,即 bundle 文件中不会引入第三方模块的源码。 对于 CommonJS 环境和 Webpack 项目,这并不会产生问题,因为项目中使用该 npm 模块时,会自动安装项目的 dependencies。 这个点可以从打包生成的文件看出,模块中会直接 require 第三方模块。

// bundle.esm.js
import { isString } from 'lodash-es';

function print(name) {
    return name;
}

...
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('lodash-es')) :
    typeof define === 'function' && define.amd ? define(['exports', 'lodash-es'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.sayHello = {}, global.lodashEs));
}(this, (function (exports, lodashEs) { 'use strict';
...

但如果在浏览器引入该模块,则需要将第三方模块打入 bundle 内容,使用 @rollup/plugin-node-resolve

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

export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello'
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            terser()
        ]
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm'
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            terser()
        ]
    }],
    plugins: [
        nodeResolve()
    ]
};

三、如何使用 rollup 引入第三方模块并定义 external 库

按照案例二,打包后的文件会包含所有第三方模块,但这并不利于代码体积优化,对于常用的工具库,例如 lodash-es,应用项目通常也会引入,因此重复打包将会增大代码体积。此时可以使用 external: ['module-name'] 来指明不需要打包的外部模块。

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

export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello'
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            terser()
        ]
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm'
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            terser()
        ]
    }],
    plugins: [
        nodeResolve()
    ],
    external: ['lodash-es']
};

对于不需要打包的模块,你需要告诉模块如何在全局环境中引用对应的模块,否则执行 npm run build 时会报如下错误:


> [email protected] build /Users/wuhonglei/Desktop/JS/how-to-use-rollup
> rollup -c ./rollup.config.js


src/main.js → ./dist/bundle.umd.js, ./dist/bundle.umd.min.js, ./dist/bundle.esm.js, ./dist/bundle.esm.min.js...
(!) Missing global variable names
Use output.globals to specify browser global variable names corresponding to external modules
lodash-es (guessing 'lodashEs')
lodash-es (guessing 'lodashEs')
created ./dist/bundle.umd.js, ./dist/bundle.umd.min.js, ./dist/bundle.esm.js, ./dist/bundle.esm.min.js in 1.1s

此时还需要将 lodash-es 与全局变量进行绑定:

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

export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello',
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            terser()
        ],
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm'
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            terser()
        ]
    }],
    plugins: [
        nodeResolve()
    ],
    external: ['lodash-es']
};

四、如何使用 rollup 结合 babel transform 转换 ES6 代码

当代码中使用了 ES6 语法和新的 API 时,需要使用 babel 进行 transform 和 polyfill。 因此需要进行如下设置:

rollup 配置:

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



export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello',
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            terser()
        ],
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm'
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            terser()
        ]
    }],
    plugins: [
        nodeResolve(),
        babel({
            babelHelpers: 'bundled',
            exclude: 'node_modules/**', // 只编译我们的源代码
        })
    ],
    external: ['lodash-es']
};
  1. babel 配置
// src/.babelrc.json
{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "corejs": 3,
                "modules": false
            }
        ]
    ]
}

注意:

  1. 配置文件中指明了 "modules": false, 是为了避免 babel 将 ESM 转为 CommonJS。
  2. .babelrc.json 是目录级的配置文件,和项目配置文件 babel.config.json 作用域不同,对于 npm 模块来说,通常会包含 test 测试目录,因此需要针对不同目录设置不同的 babel 方案。

五、ESM 和 CommonJS 使用不同的 babel 配置

ESM 运行在浏览器,CommonJS 运行在 Node 环境,两者的兼容性不一致,因此需要指明不同的 babel 配置。

import { terser } from 'rollup-plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import { getBabelOutputPlugin } from '@rollup/plugin-babel';
const path = require('path');

const babelPluginForUmd = getBabelOutputPlugin({
    configFile: path.resolve(__dirname, './src/.babelrc.umd.json'),
    allowAllFormats: true
});

const babelPluginForEsm = getBabelOutputPlugin({
    configFile: path.resolve(__dirname, './src/.babelrc.esm.json'),
    allowAllFormats: true
});

export default {
    input: 'src/main.js',
    output: [{
        file: './dist/bundle.umd.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            babelPluginForUmd
        ],
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.umd.min.js',
        format: 'umd',
        name: 'sayHello',
        plugins: [
            babelPluginForUmd,
            terser()
        ],
        globals: {
            'lodash-es': '_'
        }
    }, {
        file: './dist/bundle.esm.js',
        format: 'esm',
        plugins: [
            babelPluginForEsm,
        ]
    }, {
        file: './dist/bundle.esm.min.js',
        format: 'esm',
        plugins: [
            babelPluginForEsm,
            terser(),
        ]
    }],
    plugins: [
        nodeResolve(),
    ],
    external: ['lodash-es', /core-js/]
};