如今如何模块化和打包客户端Javascript库?


11

我一直在追赶现代的客户端JS生态系统,并阅读CommonJS和AMD(包括相关工具-browserify,requirejs,onejs,jam等等)。如果我正在编写Javascript库,如何对它进行模块化/打包,以便可以最广泛地访问它(理想情况下,对CommonJS,AMD尤其是两者都不满意的用户)?

像jQuery这样的流行库似乎只是使用老式文件串联来构建自身,并动态检测它是否应该写入exports或全局上下文。我目前正在做同样的事情,但是主要的缺点是,如果我(与jQuery不同)依赖于一些库,那么不必要求用户手动预先包含传递集就很好了。(尽管我目前只有两个依赖项。)当然还有全局名称空间污染。

还是为每个上下文生成我的库的多个版本是最干净的?

我也想知道打包和发布。有几种系统,但是我相信主要的系统是bower,它很容易处理,因为它所做的只是获取。但是,我想知道是否也应该针对其他组件系统,例如component(需要CommonJS)。

我还应该注意其他相关方面吗?是否有所有这些都可以遵循的良好示例项目?


这是一个很棒的教程: youtube.com/watch ?v=USk1ie30z5k这个人提到了requirejs(r.js),节点,bower,主干网...

@MattFenwick我已经使用了所有提到的工具;该视频没有回答我的任何问题。

你看过吗?我似乎记得那个家伙带领我们走过一个库,并解释了使它能够与多个模块系统一起使用而无需使用任何模块的特定代码行。

Answers:


2

我一直习惯使用的编译文件,但自从我开始我的第一个项目的NodeJS我开始使用 browserify。使用browerify和其他类似的库,您的代码就是您的构建文件。我利用了可以在两者上运行的客户端和服务器库的优势,但它也可以与纯客户端代码一起工作。综上所述,browserify为您提供了在节点中编写代码的所有好处(没有用于避免全局变量,npm,简单要求的匿名函数),它使您可以使用一条命令将该代码打包在客户端上运行,并且仅加载一个文件。

借助browserify,您可以执行以下操作(名为app.js):

var MyLib = require('../myLib');

if(typeof window !== 'undefined') {
    window.MyLib = MyLib;
    window._ = require('underscore');
    window.$ = require('$');
    window.MyLib.myCan = require('./3rdParty/can/can');
}

browserify app.js> client.js

会产生类似:

[function(require,module,exports){
    window.MyLib = //MyLib code
},
function(require,module,exports){
     window._ = //_ code
},
function(require,module,exports){
    window.$ = //$ code
},
function(require,module,exports){
    window.MyLib.myCan = //can code
}

您将定义的文件可能包含所有第3方库,并且不会与使用该文件的任何开发人员冲突。

-编辑以回应评论(以及对该问题的完整遗漏)

我猜这将取决于您的依赖关系以及您要花费多少时间来确保它们在所有版本和库中都能正常工作。如果您的依赖关系很普遍,并且版本之间使用相同的api,则可以采用主干路线,只要求用户使用$和_。我建议将更晦涩的libs作为捆绑文件的一部分。选件也不必切割和干燥。您可以提供预构建的或构建您自己的软件包。


+1进行浏览器验证,更多的人需要了解该工具
Benjamin Gruenbaum

@BenjaminGruenbaum这是一个非常好的工具。我很幸运,我再次检查了一下。我最初忽略了它,因为它用于异步加载文件,这可能会在浏览器中触发N#个文件加载。现在只有一个,并且可以启用源映射。
2013年

1
看,这是问题所在-我在问如何发布图书馆。我实际上了解过基于browserify / onejs /其他基于CommonJS的系统,但是如果我开始require()在我的代码中使用它,这意味着它将不再对用户可用,除非他们也改变了自己的项目以使用CommonJS。如果我发布了一个已编译的脚本,那么它将潜在地包括对其自己项目的冗余依赖关系,并可能极大地削弱可交付成果(例如,多个jquery)。

0

客户端库的种类:

  1. 接触DOM
  2. 不接触DOM

对于第一种(UI小部件等),通常会假定存在jQuery。您还可以编写“与DOM库无关的文档”,并使其与不太受欢迎的DOM库一起使用,但我不会打扰。

与第二种。首先,不要使其成为jQuery插件,例如“ jQuery cookie plugin”是荒谬的,但实际上存在这样的库。

这两种类型可能都没有依赖性,小的依赖性或巨大的依赖性-从这个意义上讲,dom库不算作依赖性。对于前两个,您只需将它们串联在库范围内,而不必担心可能的重复。例如,isArrayLike即使用户可能已经从一些随机的工具带库中包含了自己的函数,jQuery仍将其内部函数连接在一起。

在开发库(实际上是一种语言)时,我只有非常丰富的个人经验- moment.js。在这种情况下,我将提供2个构建,其中一个连接了moment.js,一个不包含,由用户负责将其包括在内。我不知道这是否是一个好的解决方案。

是的,在每种情况下,都采用了构建一个最终有效的最终大文件的jQuery方法。它的底部有模块样板(require / AMD / global等检测)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.