从同一个源构建分布式和NPM包



我经常制作小型开源工具,不想限制我的用户。我的软件包通常只是一个功能,所以这就是我希望我的用户得到的:

  1. 他们可以通过script标记中的src添加的JS文件。这个脚本应该添加我的函数,这样他们就可以在下面的脚本中调用它。对于根本不想使用包管理器的用户很有用:
<script src="https://amazingCDN.com/isEven.js"></script>
<script>
isEven()
</script>
  1. 一个可以作为包发布的JS文件,因此使用NPM的用户只需键入npm install isEven,然后导入我的包

两个JS文件都应该从同一个源构建。假设我的源代码只包含一个命名函数,该函数应该添加到window中,并且如果我使用Webpack,它应该是可导入的。假设我将自己发布一个包,我只希望我的构建管道从我的源代码中生成两个JS文件。CDN呢?假设我使用jsDelivr,它可以从Github检索我的JS文件并缩小它,这样我就不在乎自己缩小我的文件了。

我尝试将代码作为一个模块编写,并使用带有独立标志的Browserify。它实际上可以与CommonJS模块一起使用,但要使它与ES模块一起使用我必须使用esmify,而且它只返回一个带有default键的对象,所以我不能像foo()那样调用它,我必须像foo.default()那样调用它。这不是我想要的。

我还试着把它写成一个独立的文件,只做

echo 'export default ' | paste -d'' - src.js > module.js

这有点奏效,但我想知道是否有更复杂、更可靠的解决方案。

我该如何做到这一点?

听起来您可能想将项目打包为UMD

https://github.com/umdjs/umd

Rollup可以将UMD作为输出目标,并且比webpack或browserfy(尤其是对于微小的单功能库(要小一些

isEven.mjs

function isEven(x) {
return (x % 2) === 0 && x !== 0;
}
export {
isEven
};
$ rollup isEven.mjs --format=umd --name=isEven

将导致

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.isEven = {}));
}(this, (function (exports) { 'use strict';
function isEven(x) {
return (x % 2) === 0 && x !== 0;
}
exports.isEven = isEven;
Object.defineProperty(exports, '__esModule', { value: true });
})));

我想这正是你想要的。

我解决了这个问题,并为这个确切的任务创建了一个模板repo。

你可以从这个模板创建你的repo,将你的库实现为带有ES模块的NPM包,然后在推送时会创建dist文件夹,并且会有以你的库命名的分布式js文件。用户只需将其添加到脚本标记中,库就会出现在全局命名空间中。

最新更新