如何在2018年编写和构建JS库

在开始之前,建议您阅读我以前的文章,有关创建额外的小型JavaScript

编写小于1TB大小的JS库
创建额外的小型图书馆的小指南 medium.com

今天的问题:

  • 为什么在库中使用捆绑器和转译器可能会引起问题?
  • 如何正确构建库?
  • 为什么我说不使用进出口? 您真的需要吗?

介绍

我将从与本文主题不太相关但很重要的那一刻开始—为什么我们需要构建库?

如果我们使用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

不要忘记添加名称字段

而且…这是我们拥有的:

看起来好像多了9行

我们不想在纳米库中看到两件事:

  • 红色:不必要的代码。 在Node.js中,您可以只使用require ,而在可加载的 ,只需将其传递给window 。 头顶。
  • 蓝色:因为UMD构建也应在浏览器中工作,所以我们需要将所有依赖项添加到捆绑中。 我们不能像源代码一样保留var EventBus = require('eventbus')

UMD看起来不错,但是简单的纳米库却不是这种情况。

解:

创建分离的IIFE和CJS构建而不是UMD

IIFE构建很干净,并且不包含不必要的代码。 您也可以丑化它,它会小得多。

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

为什么不好? 我给你看。

第二个错误-解决CJS构建中的依赖关系

在库中没有依赖项的源代码是没有意义的。 您可以只保留requireimport ,将外部依赖项添加到package.json的 dependencies中。 而且会没事的。

但是,在构建库时会发生什么?

想象一下,我们的库(或两个不同的库 )中有两个具有共同依赖性的独立文件 。 我将重复前面的示例:

然后,让我们构建它:

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

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

构建它:

结果:

Basum tss

现在我们的捆绑包中有两个 EventBus ,但它们100%相等!

注意:如果您认为它仅由于CJS发生,则可以重复ES输出并再次检查。

现在,让我们尝试在不解决依赖关系的情况下构建文件。 我只是将导入文件替换为我们的未构建变体。

结果:

真好。 我们没有重复,这很好! 为什么? 由于汇总足够聪明,因此不会两次粘贴相似的依赖项。 我们在代码中看到了相等的导入(或要求),因此无需为每个导入粘贴它。

注意1:它还会影响内部库文件。 避免解决库内部文件的类似需求,因为它也会重复。

注意2:如果您有疑问“当两个库需要一个库的不同版本时如何工作” ,您可以阅读NPM解决版本冲突的方式。

可能的解决方案:

只是不使用进口

如果不需要,可以使用require“按原样”显示您的库。

将所有依赖项设置为外部

汇总可以将依赖项标记为外部。 这意味着您的依赖项将不会被捆绑,汇总将不会importrequire “原样”

汇总官方文档中的示例

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

看不到好/坏名。 这是以前的例子

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

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

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

因此我们可以禁用它:

看起来还可以:

大! (但是它也可以不带变量地导出,但是可以)

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

在绿色文件中还可以,但是红色文件有另一个根

替代解决方案

如果仍然阅读此内容,则可以使用babel而不是rollup 。 它只会替换您的import / exportCJS类似物。

与汇总不同,babel不会使您将每个文件和每个外部依赖项添加到配置中。 它只从folder1中获取文件,并将结果存储在folder2中

有官方的babel-plugin-transform-es2015-modules-common-js (如果您认为它是最长的软件包,则可以看到此软件包)

创建.babelrc

然后转换所有源文件:

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