写一个axios-ts吧!学习Rollup(一)

2,293 阅读5分钟

导航

Rollup是什么

官方解读

Rollup 是一个 JavaScript 模块打包器,可以将小块代码编译成大块复杂的代码,例如 library 或应用程序。Rollup 对代码模块使用新的标准化格式,这些标准都包含在 JavaScriptES6 版本中,而不是以前的特殊解决方案,如 CommonJSAMDES6 模块可以使你自由、无缝地使用你最喜爱的 library 中那些最有用独立函数,而你的项目不必携带其他未使用的代码。ES6 模块最终还是要由浏览器原生实现,但当前 Rollup 可以使你提前体验。

我的理解

Rollup是一个js模块打包工具,可以将小的模块打包成一个大的模块。这种特性就很适用于打包一个库。Rollup 对代码模块使用新的标准化格式(ES模块)。

为什么要使用Rollup

官方解读

如果你将项目拆分成小的单独文件中,这样开发软件通常会很简单,因为这通常会消除无法预知的相互影响(remove unexpected interaction),以及显著降低了所要解决的问题的复杂度(complexity of the problem),并且可以在项目最初时,就简洁地编写小的项目(不一定是标准答案)。不幸的是,JavaScript 以往并没有将此功能作为语言的核心功能。

我的理解

  • 为了编写可读性更高,更利于维护的代码,通常会按照相似的功能建立很多目录和文件来,这样在使用的时候需要引入很多文件,远不如引用一个文件方便。手动的去打包代码是一个极其费劲的事情,打包工具的出现解决了这些问题,Rollup就是一个打包工具
  • Rollup更适用于库的打包,而Webpack更适用于应用程序的打包
  • 自带Tree-shaking(删掉未使用的代码)

怎样使用

官方文档

开始学习

Tree-shaking

是一种常见的优化方式,从名字可以很形象的理解,就像在摇一棵树,摇下一部分枯萎的叶子。不打包未使用的模块,从而减少最终的打包体积。

兼容性

导入

默认只支持es模块打包,将一些不符合es模块标准的模块(如CommonJS)以插件的方式支持。这样就可以导入一些不是es模块标准的库来使用。

导出

可以直接导出常见umdCommonJSes6的模块,并能感知package.json中有module

命令行

挑几个常用的参数,简单介绍,具体移步中文文档or英文文档

--config / -c

以配置的形式运行,多数的命令参数,会覆盖配置文件中的设置。

rollup --config // 默认的配置文件 rollup.config.js
// or
rollup -c
// 也可以指定自己命名的文件
rollup -c my.rollup.config.js

--input / -i

入口文件

rollup --input src/index.js // 必须指定入口
// or
rollup -i src/index.js

--file / -o

输出的文件

rollup --file // 默认是输出到控制台
// or
rollup -o dist/index.js

--format / -f

输出的文件类型(amd, cjs, esm, iife, umd)

rollup --file // 默认是esm
// or
rollup -o dist/index.js

--name / -n

生成UMD模块的名字

rollup --name xxx
// or
rollup -n xxx

--sourcemap / -m

生成sourcemap

rollup --sourcemap
// or
rollup -m

--watch / -w

监听文件变动,文件变动将会重新打包

rollup --watch
// or
rollup -w

Rollup 与其他工具集成

npm包

引入node_modules中的包,Rollup不能去node_modules中找到对应的包,需要插件的支持。例如:

import xxx from 'xxx';
console.log(xxx)

应该安装rollup-plugin-node-resolve来告诉rollup如何查找外部模块

npm i rollup-plugin-node-resolve -D

然后进行配置,使用插件。

// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';

export default {
  input: 'src/index.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  },
  plugins: [ resolve() ]
};

假如这个模块是CommonJS规范写的,而导出的时候又要导出es模块,这样就需要将 CommonJS 模块转换为 ES2015, 可利用的插件是rollup-plugin-commonjs

外部的引用的包

像lodash这种较大的包,并且他也不是本库的实现,完全可以外部引用(externals)

// rollup.config.js
import resolve from 'rollup-plugin-node-resolve';

export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  },
  plugins: [resolve({
    // 将自定义选项传递给解析插件
    customResolveOptions: {
      moduleDirectory: 'node_modules'
    }
  })],
  // 指出应将哪些模块视为外部模块
  external: ['lodash']
};

Babel

安装插件rollup-plugin-babel,然后配置babel就可以了。

npm i rollup-plugin-babe babel-preset-latest babel-plugin-external-helpers -D
  • 需要配置"modules": false,防止babelCommonJS进行转换
  • 使用 external-helpers 插件, 它允许 Rollup 在包的顶部只引用一次 helpers ,而不是每个使用它们的模块中都引用一遍
  • .babelrc 文件放在 src 中,划重点,在src中,在src中,在src中。
// src/.babelrc
{
  "presets": [
    ["latest", {
      "es2015": {
        "modules": false
      }
    }]
  ],
  "plugins": ["external-helpers"]
}

Gulp

gulp使用rollup.rollup,返回的是promises,这比较简单。

const gulp = require('gulp');
const rollup = require('rollup');
const rollupTypescript = require('rollup-plugin-typescript');

gulp.task('build', async function () {
  const bundle = await rollup.rollup({
    input: './src/main.ts',
    plugins: [
      rollupTypescript()
    ]
  });

  await bundle.write({
    file: './dist/library.js',
    format: 'umd',
    name: 'library',
    sourcemap: true
  });
});

高级功能

path

这些路径将被用于生成的包而不是模块ID,从而允许从CDN加载依赖关系

banner/footer

比如开头的注释 就很适用

等等

此处建议看文档。

结束

准备用ts模仿一个axios,用于整个学习过程中的记录。我的理解可能是错的,希望大家能够指出,我会及时修改文章避免把其他同学带跑偏。如果有什么问题,欢迎评论区讨论,共同学习,共同进步。奥利给!

参考资料