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

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

目前主流的前端框架vue和react都采用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')

如下是安装截图:



在npm上也可以搜索到自己的包:



是不是很有成就感呢?快让大家一起使用你开发的包吧!

目录
相关文章
|
22天前
|
前端开发 JavaScript Java
前端限制打包文件数量
前端限制打包文件数量
166 65
|
2月前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
94 0
|
18天前
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
1月前
|
前端开发 开发者
在前端开发中,webpack 作为一个强大的模块打包工具,为我们提供了丰富的功能和扩展性
【9月更文挑战第1天】在前端开发中,Webpack 作为强大的模块打包工具,提供了丰富的功能和扩展性。本文重点介绍 DefinePlugin 插件,详细探讨其原理、功能及实际应用。DefinePlugin 可在编译过程中动态定义全局变量,适用于环境变量配置、动态加载资源、接口地址配置等场景,有助于提升代码质量和开发效率。通过具体配置示例和注意事项,帮助开发者更好地利用此插件优化项目。
64 13
|
25天前
|
Web App开发 前端开发 JavaScript
Web前端项目的跨平台桌面客户端打包方案之——CEF框架
Chromium Embedded Framework (CEF) 是一个基于 Google Chromium 项目的开源 Web 浏览器控件,旨在为第三方应用提供嵌入式浏览器支持。CEF 隔离了底层 Chromium 和 Blink 的复杂性,提供了稳定的产品级 API。它支持 Windows、Linux 和 Mac 平台,不仅限于 C/C++ 接口,还支持多种语言。CEF 功能强大,性能优异,广泛应用于桌面端开发,如 QQ、微信、网易云音乐等。CEF 开源且采用 BSD 授权,商业友好,装机量已超 1 亿。此外,GitHub 项目 CefDetector 可帮助检测电脑中使用 CEF
101 3
|
29天前
|
缓存 监控 前端开发
前端性能优化实战:让你的网站快如闪电的十大秘籍
【9月更文挑战第3天】通过以上十大秘籍的实践,您可以显著提升网站的前端性能,让您的网站在竞争激烈的互联网环境中脱颖而出,为用户带来更加流畅和愉悦的体验。记住,前端性能优化是一个永无止境的过程,只有不断迭代和优化,才能保持网站的竞争力。
|
2月前
|
前端开发 JavaScript 开发者
前端JS按钮点击事件、跳出弹窗、遮罩的实战示例
本文提供了一个前端JS按钮点击事件、弹出式窗口和遮罩层的实战示例,包括HTML、CSS和JavaScript的具体实现代码,以及功能解析,演示了如何实现按钮点击后触发弹窗显示和遮罩层,并在2秒后自动关闭或点击遮罩层关闭弹窗的效果。
前端JS按钮点击事件、跳出弹窗、遮罩的实战示例
|
2月前
|
C# 前端开发 UED
WPF数据验证实战:内置控件与自定义规则,带你玩转前端数据验证,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据验证是确保输入正确性的关键环节。前端验证能及时发现错误,提升用户体验和程序可靠性。本文对比了几种常用的WPF数据验证方法,并通过示例展示了如何使用内置验证控件(如`TextBox`)及自定义验证规则实现有效验证。内置控件结合`Validation`类可快速实现简单验证;自定义规则则提供了更灵活的复杂逻辑支持。希望本文能帮助开发者更好地进行WPF数据验证。
49 0
|
2月前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
76 0
|
2月前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
44 0

热门文章

最新文章