在开始之前,建议您阅读我以前的文章,有关创建额外的小型JavaScript库。
编写小于1TB大小的JS库
创建额外的小型图书馆的小指南 medium.com
今天的问题:
- 为什么在库中使用捆绑器和转译器可能会引起问题?
- 如何正确构建库?
- 为什么我说不使用进出口? 您真的需要吗?
介绍
我将从与本文主题不太相关但很重要的那一刻开始—为什么我们需要构建库?
- Criando efeitos de background com o particle.js
- 毫无原因地蒸发。 (失去Juul的故事)。 Mojoleli#1(2019年4月9日)
- 让图书馆再次变得凉爽:我不后悔在2018年借书的书
- Glencoe图书馆适应数字世界
- 促进幼儿园的准备和注册
如果我们使用require ,则根本不需要构建库( 因为我们已经阅读了上一篇文章,并且不在库中使用ES6功能,并且根本不需要使用bundlers / transpilers / etc) 。
当我们使用Node.js仍不支持的ES6模块时,情况会发生变化。 如前所述,您只能在带有— experimental-modules标志的Node v9中使用ES6模块。 后端开发人员是否已经使用它? 我不这么认为。 我们还有这些:

这意味着我们应该将导入/导出替换为旧的 require / module.exports。 为此,我们需要一些工具。
典型的开发人员如何构建他的代码?
- 安装汇总
- 安装babel , 汇总插件以查找模块,解决问题以及其他一些功能
- 使用umd格式进行构建
- 哦,等等,为什么这么大???
第一个错误-使用umd build
UMD(统一模块定义)意味着您可以在浏览器中使用一个捆绑软件(如 )并与require 。 但这并不是您所想的完美–它向捆绑包添加了更多代码。
假设我们有一些模块(例如EventBus)。 所以我们要使用它:

我们想在Node.js应用程序中使用它。 因此,让我们使用汇总来构建UMD :

而且…这是我们拥有的:

我们不想在纳米库中看到两件事:
- 红色:不必要的代码。 在Node.js中,您可以只使用
require,而在可加载的,只需将其传递给window。 头顶。 - 蓝色:因为UMD构建也应在浏览器中工作,所以我们需要将所有依赖项添加到捆绑中。 我们不能像源代码一样保留
var EventBus = require('eventbus')。
UMD看起来不错,但是简单的纳米库却不是这种情况。
解:
创建分离的IIFE和CJS构建而不是UMD
IIFE构建很干净,并且不包含不必要的代码。 您也可以丑化它,它会小得多。

CJS构建也可以,但是我们仍然有蓝色问题。

为什么不好? 我给你看。
第二个错误-解决CJS构建中的依赖关系
在库中没有依赖项的源代码是没有意义的。 您可以只保留require和import ,将外部依赖项添加到package.json的 dependencies中。 而且会没事的。
但是,在构建库时会发生什么?
想象一下,我们的库(或两个不同的库 )中有两个具有共同依赖性的独立文件 。 我将重复前面的示例:

然后,让我们构建它:

现在,我们有两个捆绑包。 他们两个都有EventBus:

您认为它们将被合并到我们的应用程序中吗? 因此,让我们检查一下。 我创建了导入了两个文件的文件:

构建它:

结果:

现在我们的捆绑包中有两个 EventBus ,但它们100%相等!
注意:如果您认为它仅由于CJS发生,则可以重复ES输出并再次检查。
现在,让我们尝试在不解决依赖关系的情况下构建文件。 我只是将导入文件替换为我们的未构建变体。
结果:

真好。 我们没有重复,这很好! 为什么? 由于汇总足够聪明,因此不会两次粘贴相似的依赖项。 我们在代码中看到了相等的导入(或要求),因此无需为每个导入粘贴它。
注意1:它还会影响内部库文件。 避免解决库内部文件的类似需求,因为它也会重复。
注意2:如果您有疑问“当两个库需要一个库的不同版本时如何工作” ,您可以阅读NPM解决版本冲突的方式。
可能的解决方案:
只是不使用进口
如果不需要,可以使用require并“按原样”显示您的库。
将所有依赖项设置为外部
汇总可以将依赖项标记为外部。 这意味着您的依赖项将不会被捆绑,汇总将不会import或require “原样”

但这使您可以将每个导入的文件手动添加到外部。 如果您有很多导入和文件,可能会很无聊。

额外的技巧:如果您想将所有程序包依赖项添加为外部程序,则只需从package.json获取它们 :

因此,让我们看一下我们的捆绑包:

几乎可以,但是我们在那里互操作了 。 什么是互操作 ? 最好读这个而不是我的话:

因此我们可以禁用它:

看起来还可以:

注意:此外,您还应注意路径。 如果您将在导入和更改文件夹结构中使用绝对路径(如上),则将失败。

替代解决方案
如果仍然阅读此内容,则可以使用babel而不是rollup 。 它只会替换您的import / export到CJS类似物。
与汇总不同,babel不会使您将每个文件和每个外部依赖项添加到配置中。 它只从folder1中获取文件,并将结果存储在folder2中 。
有官方的babel-plugin-transform-es2015-modules-common-js (如果您认为它是最长的软件包,则可以看到此软件包)
创建.babelrc

然后转换所有源文件:

输出不是很好,但是我们已经有require而不是源代码了: