跨公共开发/浏览器开发的最佳实践
目前,我沿着IS_CJS
和IS_BROWSER
方向通过Google Closure Compiler使用了一些defines
,只是有不同的文件( browser.myproject.js
, cjs.myproject.js
等)。
这是做事的标准方式吗? 如果不是,那么它有什么优势?
我一直在我的所有项目中使用以下序言,对于由浏览器和服务器代码加载的库:
if (define === undefined) { var define = function(f) { require.paths.unshift('.'); f(require, exports, module); }; } define(function(require, exports, module) { ... // main library here ... // use require to import dependencies var v = require(something); ... // use exports to return library functions exports.<stuff> = { some stuff }; ... });
这可以用来在我的节点服务器上运行一个require(<library>)
调用来加载这个库,也可以用requireJS调用require(<library>)
。 在浏览器中,嵌套的require
调用是在库执行之前由RequireJS预取的,在Node上,这些依赖被同步加载。 由于我没有使用我的库作为独立脚本(通过HTML中的脚本标签),而只是作为通过脚本标记加载的脚本的依赖关系,这对我来说很好。
然而,看看独立的图书馆,看起来像下面的序言似乎是最灵活的。 (从Q诺库中剪切粘贴)
(function (definition, undefined) { // This file will function properly as a <script> tag, or a module // using CommonJS and NodeJS or RequireJS module formats. In // Common/Node/RequireJS, the module exports the Q API and when // executed as a simple <script>, it creates a Q global instead. // The use of "undefined" in the arguments is a // micro-optmization for compression systems, permitting // every occurrence of the "undefined" variable to be // replaced with a single-character. // RequireJS if (typeof define === "function") { define(function (require, exports, module) { definition(require, exports, module); }); // CommonJS } else if (typeof exports === "object") { definition(require, exports, module); // <script> } else { Q = definition(undefined, {}, {}); } })(function (serverSideRequire, exports, module, undefined) { ... main library here ... /* * In module systems that support ``module.exports`` assignment or exports * return, allow the ``ref`` function to be used as the ``Q`` constructor * exported by the "q" module. */ for (var name in exports) ref[name] = exports[name]; module.exports = ref; return ref; });
虽然罗嗦,它是令人印象深刻的灵活性, 只是工作 ,不pipe你的执行环境是什么。
您可以使用uRequire将通过模板系统将使用AMD或CommonJS编写的模块转换为AMD,CommonJS或UMD。
可选地,uRequire将您的整个bundle构build为一个在所有环境(nodejs,AMD或者无模块浏览器<script />)中运行的combinedFile.js
,这些环境使用rjs优化器和杏仁 。
uRequire使您无需在每个模块中维护任何样板文件 – 只需编写普通的AMD或CommonJS模块(如.js,.coffee,.coco,.ls等)而无需使用噱头。
另外,您可以声明性地添加标准function,例如将模块导出到全局(如window.myModule
以及noConflict()
方法,或者有select地运行runtimeInfo(例如__isNode,__isAMD)或者在构build时replace/删除/注入依赖项,自动缩小,操作模块代码等等。
所有这些configuration选项可以打开或closures每个包或每个模块,并且可以有不同的构buildconfiguration文件(开发,testing,生产等),从彼此派生(inheritance)。
它通过grunt-urequire或standalone的grunt工作得很好,它有一个伟大的手表选项,只重build只更改文件。
你有没有试过这个: https : //github.com/medikoo/modules-webmake#modules-webmake ?
这是我采取的方法,它运作得非常好。 代码中没有样板,您可以在服务器和客户端上运行相同的模块