小帅の技术博客 小帅の技术博客
首页
  • 基础
  • 框架
  • 进阶
  • 工程化
  • NodeJS
  • 脚本
  • 拓展
  • 技术
  • 服务器
程序猿
关于
友链
  • 分类
  • 标签
  • 归档
GitHub

前端小帅

学而不思则罔,思而不学则殆
首页
  • 基础
  • 框架
  • 进阶
  • 工程化
  • NodeJS
  • 脚本
  • 拓展
  • 技术
  • 服务器
程序猿
关于
友链
  • 分类
  • 标签
  • 归档
GitHub
  • 基础

  • 工程化

    • 搭建一个标准化react+ts项目
    • Webpack项目优化系列一
    • 【rollup】Svelte框架初尝试
    • 【rollup】构建发布一个npm包
      • 背景
      • 目标
      • 介绍
        • 前言
        • ES Module
        • 概述
        • Tree-shaking 是什么
        • Rollup 对比 Webpack
        • 为什么使用rollup
      • 开干
      • 总结
      • 参考
    • 【vite】构建标准化react应用
    • 【vite】构建vue3+ts应用
    • 【前端组件化】系列第一篇
    • 【前端组件化】系列第二篇
  • 框架

  • 精进

  • 其他

  • 前端
  • 工程化
sunss
2021-07-09

【rollup】构建发布一个npm包

提示

本篇文章尚处在编写状态中...

# 背景

我们在项目开发的过程中,经常会封装组件与一些函数库方便使用。但每次开发不同项目时都要花费时间重新开发,其实很多组件与工具函数在多数场景都是可复用的。所以,我打算把日常使用频率较高的组件和函数库进行逻辑封装,发布成一个npm包小工具库等,这样做,一来可以借机完善组件与工具库业务逻辑,二来可以熟悉不同工具对打包构建的流程,最后还可以实战下npm发包。

虽然有大量现成的类库,类似lodash、moment这种,但对于其内部实现我们却很少了解,只是简单的使用。当然我们不可能把所有开源的源码都看一遍,但对于一些优秀的开源类库,还是很有必要学习下的,了解其内部实现逻辑与原理对于自身技术提升也是很有帮助的~

特别是开源项目的工程化配置与各种标准规范,具有很高的学习价值,redux的包发布方式就是采用的rollup,我们可以参照其实现方式来实现一个我们自己的npm包。

这篇文章主要就是记录我在使用rollup构建、发包的一些心得体会,如有错误,欢迎指正~

# 目标

  1. 现阶段开源项目基于ES6的写法越来越普遍,所以我们发布的包必须支持ESM标准。
  2. 因为还有不少项目是基于nodejs环境开发,使用的是commonjs协议,所以也应该做到对CJS的支持。
  3. 当然也必须要支持浏览器环境以CDN的形式直接引入使用,所以也要做到对UMD的支持。(该模式支持浏览器和Nodejs)
  • 支持以 Typescript 语法开发
  • 支持以 ES6 语法开发
  • 支持导出 ES module 规范
  • 支持导出 commonjs 规范
  • 支持导出 umd 规范
  • 支持配置兼容版本
  • 支持 tree-shaking
  • 支持代码压缩

# 介绍

本篇文章不做入门使用介绍,我们主要按业务需求做一些必要说明,以确保对整个逻辑有比较清晰的认识。

# 前言

市面上知名的库,如Vue、React、D3、Redux等项目都是使用的Rollup进行构建打包,而目前尤大新出的最火热的Vite构建工具在打包构建项目时也是使用的Rollup。

Rollup从设计之初就是面向ES module的,它诞生时AMD、CMD、UMD的格式之争还很火热,作者希望充分利用ES module机制,构建出结构扁平,性能出众的类库。

# ES Module

ES module的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西,举例来说:

  1. ES import只能作为模块顶层的语句出现,不能出现在 function 里面或是 if 里面。
  2. ES import的模块名只能是字符串常量。
  3. 不管 import 的语句出现的位置在哪里,在模块初始化的时候所有的 import 都必须已经导入完成。
  4. import binding 是 immutable 的,类似 const。比如说你不能 import { a } from './a' 然后给 a 赋值个其他什么东西。

这些设计虽然使得灵活性不如CommonJS的require,但却保证了 ES modules 的依赖关系是确定的,和运行时的状态无关,从而也就保证了ES modules是可以进行可靠的静态分析的。

# 概述

Rollup 是一个使用新的ES6标准化格式的 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码。通过 Tree-shaking 静态分析代码中的 import,排除任何未实际使用的代码。

# Tree-shaking 是什么

Tree-shaking, 也被称为 "live code inclusion," 它是清除实际上并没有在给定项目中使用的代码的过程,但是它可以更加高效。

  • 在使用 CommonJS 时,必须导入(import)完整的工具(tool)或库(library)对象。
// 使用 CommonJS 导入(import)完整的 utils 对象
var utils = require( 'utils' );
var query = 'Rollup';
// 使用 utils 对象的 ajax 方法
utils.ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
1
2
3
4
5
  • 但是在使用 ES6 模块时,无需导入整个 utils 对象,我们可以只导入(import)我们所需的 ajax 函数:
// 使用 ES6 import 语句导入(import) ajax 函数
import { ajax } from 'utils';
var query = 'Rollup';
// 调用 ajax 函数
ajax( 'https://api.example.com?search=' + query ).then( handleResponse );
1
2
3
4
5

因为 Rollup 只引入最基本最精简代码,所以可以生成轻量、快速,以及低复杂度的 library 和应用程序。因为这种基于显式的 import 和 export 语句的方式,它远比「在编译后的输出代码中,简单地运行自动 minifier 检测未使用的变量」更有效。

# Rollup 对比 Webpack

首先我们要清楚这两种工具的定位是不同的。

rollup 倾向于类库方向,而webpack则是倾向于复杂SPA的模块化应用构建。

就目前webpack的强大生态在构建应用程序开发上市具有很大的优势的,各种工具、loader、plugin都很全面。

# webpack

  • 强大的插件生态
  • 通过loader处理各种各样的资源依赖
  • HMR模块热替换
  • 按需加载、路由拆分、资源缓存
  • 提取公共模块
  • 支持各类型的模块依赖处理

# rollup

  • 编译出来的代码可读性好
  • 不会像webpack打包后会生成__webpack_require__等冗余runtime代码,相对干净和小巧。
  • 支持tree-shaking
  • 支持导出es模块文件(webpack不支持导出es模块)

# 缺点

  • 模块过于静态化,HMR很难实现
  • 仅面向ES module,无法可靠的处理commonjs以及umd依赖

# 为什么使用rollup

rollup不是为了替代webpack而出现,webpack有自身丰富的生态圈,但webpack对于多模块打开之后产生的额外开销有很多,比如各种没用的依赖,使用webpack打包,你会发现,原来只有几kb的文件,打包后会多出很多无关的代码。

# 开干

# 总结

# 参考

  • https://rollupjs.org/guide/zh/
  • 什么是amd、commonjs、umd、esm
  • 为什么说rollup比webpack更适合打包库
  • 【第九期】Rollup:下一代ES模块打包工具
编辑
#rollup
上次更新: 2024/04/15, 14:35:14
【rollup】Svelte框架初尝试
【vite】构建标准化react应用

← 【rollup】Svelte框架初尝试 【vite】构建标准化react应用→

最近更新
01
说说call、apply、bind是如何改变this的
03-29
02
从输入 URL 到页面加载完成发生了什么?
03-29
03
JavaScript进阶—— new 的执行过程
03-26
更多文章>
sunss | © 2020.08-2024.04 浙ICP备2022002957号-1
载入天数... 载入时分秒...  |  总访问量 次
提供CDN加速/云存储服务
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式