前端组件/库打包利器rollup使用与配置实战

徐小夕 等级 841 0 0

目前主流的前端框架vue和react都采用rollup来打包,为了探索rollup的奥妙,接下来就让我们一步步来探索,并基于rollup搭建一个库打包脚手架,来发布自己的库和组件。

前端组件/库打包利器rollup使用与配置实战

前言

写rollup的文章是因为笔者最近要规范前端开发的业务流程和架构,并提供内部公有组件库和工具库供团队使用。在查阅大量资料并对比了webpack和rollup的优缺点之后,最终选择rollup来作为打包工具,我们最终要实现通过npm的方式安装我们的组件库和工具库:

// 安装
npm install @xuxi/tools
// 使用
import { sleep } from '@xuxi/tools'

下面我们一步步来复盘rollup的配置过程和最佳实践。

rollup介绍

Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD.

意思大致是说Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScript 的 ES6 版本中,而不是像CommonJS 和 AMD这种特殊解决方案。

rollup最大的亮点就是Tree-shaking,即可以静态分析代码中的 import,并排除任何未使用的代码。这允许我们架构于现有工具和模块之上,而不会增加额外的依赖或使项目的大小膨胀。如果用webpack做,虽然可以实现tree-shaking,但是需要自己配置并且打包出来的代码非常臃肿,所以对于库文件和UI组件,rollup更加适合。

搭建库打包脚手架

1. rollup入门

首先我们安装一下rollup:

npm i rollup -g

然后在本地创建一个项目:

mkdir -p my-project
cd my-project

其次我们创建一个入口并写入如下代码:

// src/main.js
import say from './say.js';
export { say }

// src/say.js
export default function(name){ 
    console.log(name) 
};

基本代码准备好了之后,我们写rollup的配置文件(rollup.config.js在根目录下):

// rollup.config.js
export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  }
};

这样,我们在终端执行:

// --config 或 -c 来使用配置文件
rollup -c

这样在更目录下就生成了一个bundle.js,就是我们想要的打包后的文件。我们也可以用package.json来设置打包配置信息,用npm run xxx来打包和测试代码。

2.rollup插件使用

为了更灵活的打包库文件,我们可以配置rollup插件,比较实用的插件有:

  • rollup-plugin-node-resolve ---帮助 Rollup 查找外部模块,然后导入
  • rollup-plugin-commonjs ---将CommonJS模块转换为 ES2015 供 Rollup 处理
  • rollup-plugin-babel --- 让我们可以使用es6新特性来编写代码
  • rollup-plugin-terser --- 压缩js代码,包括es6代码压缩
  • rollup-plugin-eslint --- js代码检测

打包一个库用以上插件完全够用了,不过如果想实现对react等组件的代码,可以有更多的插件可以使用,这里就不一一介绍了。

我们可以这样使用,类似于webpack的plugin配置:

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from "rollup-plugin-babel";
import { terser } from 'rollup-plugin-terser';
import { eslint } from 'rollup-plugin-eslint';

export default [
    {
        input: 'src/main.js',
        output: {
            name: 'timeout',
            file: '/lib/tool.js',
            format: 'umd'
        },
        plugins: [
            resolve(),  // 这样 Rollup 能找到 `ms`
            commonjs(), // 这样 Rollup 能转换 `ms` 为一个ES模块
            eslint(),
            babel(),
            terser()
        ]
    }
];

是不是很简单呢?个人觉得比webpack的配置简单很多。通过如上配置,虽然能实现基本的javascript文件打包,但是还不够健壮,接下来我们一步步来细化配置。

3.利用babel来编译es6代码

首先我们先安装babel相关模块:

npm i core-js @babel/core @babel/preset-env @babel/plugin-transform-runtime

然后设置.babelrc文件

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": "2.6.10",
        "targets": {
          "ie": 10
        }
      }
    ]
  ],
  "plugins": [
      // 解决多个地方使用相同代码导致打包重复的问题
      ["@babel/plugin-transform-runtime"]
  ],
  "ignore": [
      "node_modules/**"
    ]
}

@babel/preset-env可以根据配置的目标浏览器或者运行环境来自动将ES2015+的代码转换为es5。需要注意的是,我们设置"modules": false,否则 Babel 会在 Rollup 有机会做处理之前,将我们的模块转成 CommonJS,导致 Rollup 的一些处理失败。

为了解决多个地方使用相同代码导致打包重复的问题,我们需要在.babelrc的plugins里配置@babel/plugin-transform-runtime,同时我们需要修改rollup的配置文件:

babel({
  exclude: 'node_modules/**', // 防止打包node_modules下的文件
  runtimeHelpers: true,       // 使plugin-transform-runtime生效
}),

如果你对babel不太熟,可以看我之前webpack的文章或者去官网学习。

4.区分测试环境和开发环境

我们可以在package.json中配置不同的执行脚本和环境变量来对开发和生产做不同的配置:

// package.json
"scripts": {
    "build": "NODE_ENV=production rollup -c",
    "dev": "rollup -c -w",
    "test": "node test/test.js"
  },

我们可以手动导出NODE_ENV为production和development来区分生产和开发环境,然后在代码中通过process.env.NODE_ENV来获取参数。这里我们主要用来设置在开发环境下不压缩代码:

const isDev = process.env.NODE_ENV !== 'production';
// ...
plugins: [
  !isDev && terser()
]

使用eslint来做代码检测

我们可以使用上面的提到的rollup-plugin-eslint来配置:

eslint({
    throwOnError: true,
    throwOnWarning: true,
    include: ['src/**'],
    exclude: ['node_modules/**']
})

然后建立.eslintrc.js来根据自己风格配置具体检测:

module.exports = {
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "extends": "eslint:recommended",
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly",
        "ENV": true
    },
    "parserOptions": {
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "rules": {
        "linebreak-style": [
          "error",
          "unix"
        ],
        "quotes": [
          "error",
          "single"
        ]
    }
};

详细的eslint配置可以去官网学习。

5. external属性

使用rollup打包,我们在自己的库中需要使用第三方库,例如lodash等,又不想在最终生成的打包文件中出现jquery。这个时候我们就需要使用external属性。比如我们使用了lodash,

import _ from 'lodash'

// rollup.config.js
{
    input: 'src/main.js',
    external: ['lodash'],
    globals: {
        lodash: '_'
    },
    output: [
    { file: pkg.main, format: 'cjs' },
    { file: pkg.module, format: 'es' }
    ]
}

6.导出模式

我们可以将自己的代码导出成commonjs模块,es模块,以及浏览器能识别的模块,通过如下方式设置:

{
  input: 'src/main.js',
  external: ['ms'],
  output: [
    { file: pkg.main, format: 'cjs' },
    { file: pkg.module, format: 'es' },
    { file: pkg.module, format: 'umd' }
  ]
}

发布到npm

如果你是之前没有注册npm账号,你可以通过如下方式配置:

npm adduser

然后输入用户名,邮箱,密码,最后使用npm publish发布。这里介绍包的配置文件,即package.json:

{
  "name": "@alex_xu/time",
  "version": "1.0.0",
  "description": "common use js time lib",
  "main": "dist/tool.cjs.js",
  "module": "dist/time.esm.js",
  "browser": "dist/time.umd.js",
  "author": "alex_xu",
  "homepage": "https://github.com/MrXujiang/timeout_rollup",
  "keywords": [
    "tools",
    "javascript",
    "library",
    "time"
  ],
  "dependencies": {
    // ...
  },
  "devDependencies": {
    // ...
  },
  "scripts": {
    "build": "NODE_ENV=production rollup -c",
    "dev": "rollup -c -w",
    "test": "node test/test.js",
    "pretest": "npm run build"
  },
  "files": [
    "dist"
  ]
}

name是包的名字,可以直接写包名,比如loadash,或者添加域,类似于@koa/router这种,@后面是你npm注册的用户名。key为包的关键字。

发布后,我们可以用类似于下面这种方式安装:

npm install @alex_xu/time
// 使用
import { sleep } from '@alex_xu/time'
// 或
const { sleep } = requrie('@alex_xu/time')

如下是安装截图:

前端组件/库打包利器rollup使用与配置实战 在npm上也可以搜索到自己的包:

前端组件/库打包利器rollup使用与配置实战 是不是很有成就感呢?快让大家一起使用你开发的包吧!

最后

完整配置文件我已经发布到github,地址: https://github.com/MrXujiang/timeout_rollup

如果想了解更多webpack,gulp,css3,javascript,nodeJS,canvas等前端知识和实战,欢迎在公众号《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。

前端组件/库打包利器rollup使用与配置实战

更多推荐

收藏
评论区

相关推荐

前端组件/库打包利器rollup使用与配置实战
目前主流的前端框架vue和react都采用rollup来打包,为了探索rollup的奥妙,接下来就让我们一步步来探索,并基于rollup搭建一个库打包脚手架,来发布自己的库和组件。 (https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/16cb1c297071015523fb08d9e0f
基于create-react-app打包编译自己的第三方UI组件库并发布到npm
前言 这篇文章主要是总结一下我们在工作中如何为公司开发内部的第三方UI组件,并通过npm install的方式安装的一些步骤和思路。在学习完这套发布方法后大家也可以快速的发布自己的UI库到npm,供他人使用,就比如elementUI或者Ant Design。 如果想学习如何发布一个js库或者框架,那么使用rollup更为适合,可以参考如下文章: 前端组
Vue3.0系列——「vue3.0学习手册」第一期
Vue3.0一、项目搭建vite是尤大大开发的一款意图取代webpack的工具。其实现原理是利用ES6的import发送请求加载文件的特性。拦截这些请求,做一些编译,省去webpack冗长的打包时间。并将其与Rollup捆绑在一起用于生产。在开发过程中没有捆绑。源代码中的ES Import语法直接提供给浏览器,浏览器通过本机<script module支持对
vscode+vue简单安装教程
1、安装vscode、node.js。2、打开vscode终端,全局安装vuecli:npm install g vuecli用于构建项目。3、继续安装webpack(打包工具):npm install g webpack。4、安装完成创建一个文件夹用于存放项目,比如myvue,cd到该文件夹,使用项目创建命令:vue init webpack myvue。
Vue 从安装到创建项目
1.安装Node可以直接在官网中下载安装默认自动安装Node和NPM(Node Package Manager) 完成后检查安装版本:node v npm v2.安装webpack webpack全局安装npm install webpack g3.安装vue脚手架 全局安装脚手架3npm install @vue/cli g 备注
CommonJS,ES2015,AMD,CMD区别
本文你将学到: 1. Rollup 是什么 2. CommonJS、AMD、CMD、UMD、ES6 分别的介绍 3. ES6 模块与 CommonJS 模块的区别 4. 模块演进的产物 —— Tree Shaking 5. Tree Shaking 应该注意什么 本文所有例子都存放于 [https://github.com/hua1995116
Oracle的rollup、cube、grouping sets函数
Group by、rollup、cube、grouping sets区别 ==================================== oracle除了group by基本用法之外,还有ROLLUP,CUBE,GROUPING SETS 等扩展方法,这些可以理解为Group By 分组函数封装后的精简用法,相当于多个union all 的组合显
vite2 引入 vectorize
这个库在webpack中是正常的, 但是在vite2项目中无法使用也不报错, 只是结果总是空....看了下是个老项目了, 依赖的也都是好几年没更新的库... 看来webpack在兼容性方面还是要强不少的     尝试使用parcel打包后使用, 不太行... 用webpack打包后使用.... 也不行... 有时间再研究研究, 看看能不能写个类似的.
20k以上面试必问,Webpack原理和优化
我身边很多朋友都觉得 Webpack 不重要,认为只要团队里有人会就可以,而那个人不需要是自己。 那么我就给你一个必须学它的理由: **Webpack 原理和优化** ****工资20k以上的面试必问**** 如果你想拿到高薪,Webpack就是你绕不过去的一道门槛。 而即便不提面试,对于 每一个前端工程师来说
Apache Kylin VS Apache Doris全方位对比
* 1 系统架构 * 1.1 What is Kylin * 1.2 What is Doris * 2 数据模型 * 2.1 Kylin的聚合模型 * 2.2 Doris的聚合模型 * 2.3 Kylin Cuboid VS Doris RollUp *
HttpURLConnection(http 1.1) 用法、状态码、状态描述
最近研究了java的HttpURLConnection的用法, 这里简单的做一下记录: Java中可以使用HttpURLConnection来请求WEB资源。 **1、 URL请求的类别** 分为二类,GET与POST请求。二者的区别在于:       a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
Mint UI文档
Mint UI文档:[http://elemefe.github.io/mint-ui/#/](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Felemefe.github.io%2Fmint-ui%2F%23%2F) 一、Mint UI的安装和基本用法。 1.**NPM :**npm i
Optimsim Rollup详解
Optimism Rollup是目前最流行的以太坊L2解决方案。本文将解释Optimism Rollup每个设计决策背后的动机,剖析Optimism的系统实现,并提供指向每个分析组件的相应代码的链接,适用于希望了解Optimism解决方案的工作原理并评估所提议系统的性能和安全性的开发人员。 > 区块链开发教程链接:[以太坊](https://www.osc
Sass预编译
sass基于Ruby               ruby的模块管理器叫gem   正规的安装方式是gem install sass                调用命令     sass    sass文件    css文件 **webpack编译sass**         需要的模块 style-loader  css-loader  sas
storybook配置之基本配置和webpack配置
#默认配置 Storybook有一个默认的适合(suits)大型项目开发的webpack配置,假如你使用react app,他类似于创建一个react app的配置,并经过调整(tweaked ),使其与vue cli的webpack配置非常相似 开始学习Storybook配置 学习内容(Table of Contents) - Babel ES2016+