- 操作系统
- 跨平台
- 开发语言
- JavaScript
- 开源协议
- 未知
-
2021-06-11 10:56:31
CommonJS
为服务器提供的一种模块形式的优化
CommonJS模块建议指定一个简单的用于声明模块服务器端的API,并且不像AMD那样尝试去广泛的操心诸如io,文件系统,约定以及更多的一揽子问题。
这种形式为CommonJS所建议--它是一个把目标定在设计,原型化和标准化Javascript API的自愿者工作组。迄今为止,他们已经在模块和包方面做出了批复标准的尝试。
入门
从架构的角度来看,CommonJS模块是一个可以复用的Javascript块,它出口对任何独立代码都起作用的特定对象。不同于AMD,通常没有针对此模块的功能封装(因此打个比方我们并没有在这里找到定义的相关语句)。
CommonJS模块基本上包括两个基础的部分:一个取名为exports的自由变量,它包含模块希望提供给其他模块的对象,以及模块所需要的可以用来引入和导出其它模块的函数。
理解CommonJS:require()和exports
// package/lib is a dependency we require
var lib = require( "package/lib" );
// behaviour for our module
function foo(){
lib.log( "hello world!" );
}
// export (expose) foo to other modules
exports.foo = foo;
exports的基础使用
// define more behaviour we would like to expose
function foobar(){
this.foo = function(){
console.log( "Hello foo" );
}
this.bar = function(){
console.log( "Hello bar" );
}
}
// expose foobar to other modules
exports.foobar = foobar;
// an application consuming "foobar"
// access the module relative to the path
// where both usage and module files exist
// in the same directory
var foobar = require("./foobar").foobar,
test = new foobar();
// Outputs: "Hello bar"
test.bar();
等同于AMD的第一个CommonJS示例
define(function(require){
var lib = require( "package/lib" );
// some behaviour for our module
function foo(){
lib.log( "hello world!" );
}
// export (expose) foo for other modules
return {
foobar: foo
};
});
这也可以用AMD支持的简化了的CommonJS特定做到。
消耗多重依赖
app.js
var modA = require( "./foo" );
var modB = require( "./bar" );
exports.app = function(){
console.log( "Im an application!" );
}
exports.foo = function(){
return modA.helloWorld();
}
bar.js
exports.name = "bar";
foo.js
require( "./bar" );
exports.helloWorld = function(){
return "Hello World!!"
}
加载器和框架对CommonJS提供了什么支持?
在浏览器端:
服务器端:
CommonJS适合浏览器么?
有开发者感觉CommonJS更适合于服务器端的开发,这是如今应该用哪种形式和将要来作为面向未来的备选事实标准,在这一问题上存在一定程度分歧的原因之一。一些争论指摘CommonJS包括许多面向服务器的特性,这些特性很容易可以看出并不能够用Javascript在浏览器级别中实现--例如,io,系统,而且js会被认为是借助于它们功能的性质无法实现的。
那就是说,无论如何了解如何构建CommonJS模块是有用的,那样我们就可以更好的理解它们如何适合于定义可以在任何地方使用的模块了。模块在客户端和服务器端都有包括验证,约定和模板引擎的应用程序。一些开发者趋向于选择那种形式的方式是当一个模块能够在服务器端环境使用时,就选择CommonJS,而如果不是这种场景,就使用AMD。
由于AMD模块具有使用插件的能力,并且能够定义更加精细的像构造器和函数之类的东西,如此是有道理的。
CommonJS模块只能够去定义使用起来会非常繁琐的对象,如果我们尝试从它们那里获取构造器的话。
尽管这超出了本节的讨论范畴,也要注意当论及AMD和CommonJS时,不同类型的“require”方法会被提到。带有类似命名空间的问题理所当然是令人迷惑的,而社区当前对全局的require功能的优点正存在着分歧。这里John Hann的建议是不去叫它“require”,它很可能在告知用户关于全局的和内部的require之间的差别,这一目标上取得失败,将全局加载器方法重新命名为其它什么东西(例如,库的名字)可能更加起作用。正式由于这个原因,像curl.js这样的加载器反对使用require,而使用curl()。
AMD 与 CommonJS 存在竞争,但都是同样有效的标准
AMD 和 CommonJS 都是有效的模块形式,它们带有不同的最终目标。
AMD采用浏览器先行的方针,它选择了异步的行为方式,并且简化了向后兼容性,但是它并没有任何文件I/O的概念。它支持对象,函数,构造器,字符串,JSON以及许多其它类型的模块,在浏览器进行本地运行。这是令人难以置信的灵活性。
CommonJS 则在另一个方面采用了服务器端先行的方针,承载着同步行为,没有全局的负担并且尝试去迎合(在服务器上的)未来。我们的意思是CommonJS支持无封装的模块,可以感觉到它跟ES.next/Harmony更接近一点,将我们从AMD强制使用的define()封装中解放出来。然而CommonJS仅支持对象作为模块。
UMD:AMD和兼容CommonJS模块的插件
对于希望创建在浏览器和服务器端环境都能够运作的模块的开发者而言,现有的解决方案感觉可能少了点。为了有助于缓解这个问题,James Burke , 我以及许许多多其他的开发者创造了UMD(通用模块定义)。
UMD是一种是实验性质的模块形式,允许在编写代码的时候,所有或者大多数流行的实用脚本加载技术对模块的定义在客户端和服务器环境下都能够起作用。另外一种模块格式的想法尽管可能是艰巨的,出于仔细彻底的考虑,我们将简要的概括一下UMD。最开始,我们通过简要的看一看AMD规范中所支持的对于CommonJS的简单封装,来定义UMD。对于希望把模块当做CommonJS模块来编写的开发者,可以应用下面的兼容CommonJS的形式:
基础的AMD混合格式:
define( function ( require, exports, module ){
var shuffler = require( "lib/shuffle" );
exports.randomize = function( input ){
return shuffler.shuffle( input );
}
});
然而,注意到如果一个模块并没有包含一个依赖数组,并且定义的函数只包含最少的一个参数,那么它就真的仅仅只是被当做CommonJS模块来对待,这一点是很重要的。这在某些设备(例如PS3)上面也不会正确的工作。如需进一步了解上述的封装,请看看:http://requirejs.org/docs/api.html#cjsmodule。
进一步的考虑,我们想要提供许多不同的模式,那不仅仅只是在AMD和CommonJS上起作用,同样也能解决开发者希望使用其它环境开发这样的模块时普遍遇到的问题。
下面我们可以看到这样的变化允许我们使用CommonJS,AMD或者浏览全局的对象创建一个模块。
使用 CommonJS,AMD或者浏览器全局对象创建模块
定义一个模块 commonJsStrict,它依赖于另外一个叫做B的模块。模块的名称暗示了文件的名称(,就是说一样的),而让文件名和导出的全局对象的名字一样则是一种最佳实践。
如果模块同时也在浏览器中使用了相同类型的样板,它就会创建一个global.b备用。如果我们不希望对浏览器全局补丁进行支持, 我们可以将root移除,并且把this传递到顶层函数作为其第一个参数。
(function ( root, factory ) {
if ( typeof exports === 'object' ) {
// CommonJS
factory( exports, require('b') );
} else if ( typeof define === 'function' && define.amd ) {
// AMD. Register as an anonymous module.
define( ['exports', 'b'], factory);
} else {
// Browser globals
factory( (root.commonJsStrict = {}), root.b );
}
}(this, function ( exports, b ) {
//use b in some fashion.
// attach properties to the exports object to define
// the exported module properties.
exports.action = function () {};
}));
UMD资源库包含了在浏览器中能够最优化运作的涵盖不同的模块,那些对于提供导出非常不错的,那些对于CommonJS的优化还有那些对于定义jQuery插件作用良好的,我们会在接下里看得到。
可以在所有环境下面起作用的jQuery插件
UMD提供了两种同jQuery一起工作的模式--一种模式定义了能够同AMD和浏览器全局对象一起工作得很好的插件,而另外一种模式也能够在CommonJS环境中起作用。jQuery并不像是能够运行在大多数CommonJS环境中的,因此除非我们工作在一个能够良好同jQuery一起运作的环境中,那就把这一点牢记于心。
现在我们将定义一个包含一个核心,以及对此核心的一个扩展的插件。核心插件被加载到一个$.core命名空间中,它可以简单的使用借助于命名空间模式的插件扩展进行扩展。通过脚本标签加载的插件会自动填充core下面的一个插件命名空间(比如,$core.plugin.methodName())。
这种模式操作起来相当的棒,因为插件扩展可以访问到底层定义的属性和方法,或者,做一些小小的调整就可以重写行为以便它能够被扩展来做更多的事情。加载器同样也不在需要面面俱到了。
想要了解更多需要做的详细信息,那就请看看下面代码示例中内嵌的注释吧:
usage.html
$(function(){
// Our plugin "core" is exposed under a core namespace in
// this example, which we first cache
var core = $.core;
// Then use use some of the built-in core functionality to
// highlight all divs in the page yellow
core.highlightAll();
// Access the plugins (extensions) loaded into the "plugin"
// namespace of our core module:
// Set the first div in the page to have a green background.
core.plugin.setGreen( "div:first");
// Here we're making use of the core's "highlight" method
// under the hood from a plugin loaded in after it
// Set the last div to the "errorColor" property defined in
// our core module/plugin. If we review the code further down,
// we can see how easy it is to consume properties and methods
// between the core and other plugins
core.plugin.setRed("div:last");
});
pluginCore.js
// Module/Plugin core
// Note: the wrapper code we see around the module is what enables
// us to support multiple module formats and specifications by
// mapping the arguments defined to what a specific format expects
// to be present. Our actual module functionality is defined lower
// down, where a named module and exports are demonstrated.
//
// Note that dependencies can just as easily be declared if required
// and should work as demonstrated earlier with the AMD module examples.
(function ( name, definition ){
var theModule = definition(),
// this is considered "safe":
hasDefine = typeof define === "function" && define.amd,
// hasDefine = typeof define === "function",
hasExports = typeof module !== "undefined" && module.exports;
if ( hasDefine ){ // AMD Module
define(theModule);
} else if ( hasExports ) { // Node.js Module
module.exports = theModule;
} else { // Assign to common namespaces or simply the global object (window)
( this.jQuery || this.ender || this.$ || this)[name] = theModule;
}
})( "core", function () {
var module = this;
module.plugins = [];
module.highlightColor = "yellow";
module.errorColor = "red";
// define the core module here and return the public API
// This is the highlight method used by the core highlightAll()
// method and all of the plugins highlighting elements different
// colors
module.highlight = function( el,strColor ){
if( this.jQuery ){
jQuery(el).css( "background", strColor );
}
}
return {
highlightAll:function(){
module.highlight("div", module.highlightColor);
}
};
});
pluginExtension.js
// Extension to module core
(function ( name, definition ) {
var theModule = definition(),
hasDefine = typeof define === "function",
hasExports = typeof module !== "undefined" && module.exports;
if ( hasDefine ) { // AMD Module
define(theModule);
} else if ( hasExports ) { // Node.js Module
module.exports = theModule;
} else {
// Assign to common namespaces or simply the global object (window)
// account for for flat-file/global module extensions
var obj = null,
namespaces,
scope;
obj = null;
namespaces = name.split(".");
scope = ( this.jQuery || this.ender || this.$ || this );
for ( var i = 0; i < namespaces.length; i++ ) {
var packageName = namespaces[i];
if ( obj && i == namespaces.length - 1 ) {
obj[packageName] = theModule;
} else if ( typeof scope[packageName] === "undefined" ) {
scope[packageName] = {};
}
obj = scope[packageName];
}
}
})( "core.plugin" , function () {
// Define our module here and return the public API.
// This code could be easily adapted with the core to
// allow for methods that overwrite and extend core functionality
// in order to expand the highlight method to do more if we wish.
return {
setGreen: function ( el ) {
highlight(el, "green");
},
setRed: function ( el ) {
highlight(el, errorColor);
}
};
});
UMD并不企图取代AMD或者CommonJS,而仅仅只是为如今希望让其代码运行在更多的环境下的开发者提供一些补充的援助。想要关于这种实验性质的形式的更多信息或者想要贡献建议,见:https://github.com/umdjs/umd。
更多相关内容 -
browser-commonjs:在浏览器中使用 CommonJS 模块
2021-06-26 10:27:43浏览器-commonjs 在浏览器中使用 CommonJS 模块。 安装 $ bower install browser-commonjs 用法 < script src =" contentloaded.js " > </ script > < script src =" browser-common.js " > &... -
babel-plugin-transform-amd-to-commonjs:将 AMD 转换为 CommonJS 的 Babel 插件
2021-07-23 22:01:11babel-plugin-transform-amd-to-commonjs 将 AMD 转换为 CommonJS 的 Babel 插件。 ,它使用这个插件来允许同步require AMD 模块。 用法 npm install --save-dev babel-plugin-transform-amd-to-commonjs 将转换... -
详谈commonjs模块与es6模块的区别
2020-11-29 07:55:31趁着这个机会,将commonjs模块与es6模块之间一些重要的的区别做个总结。语法上有什么区别就不具体说了,主要谈谈引用的区别。 commonjs 对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该... -
cjstoesm:可以将CommonJS转换为ESM的工具
2021-01-31 13:50:56可以将CommonJS转换为ESM的工具 描述 这是一个将转换为可摇树的。 这不仅使您可以为浏览器捆绑CommonJS模块,而且还可以将它们捆绑在等现代工具中。 cjstoesm可以从使用,作为,并为。 存在诸如和现有技术,但是此... -
利用webpack理解CommonJS和ES Modules的差异区别
2020-11-20 09:52:32问: CommonJS 和 ES Modules 中模块引入的区别? CommonJS 输出的是一个值的拷贝;ES Modules 生成一个引用,等到真的需要用到时,再到模块里面去取值,模块里面的变量,绑定其所在的模块。 我相信很多人已经把这个... -
Babel 7插件转换,可将CommonJS转换为ES模块-JavaScript开发
2021-05-26 04:41:59Babel转换:Node CommonJS到ES模块的Babel 7兼容转换,可将Node样式的CommonJS模块转换为ES模块规范。 它是专门为实验性模块捆绑器创建的,但具有许多Babel转换:Node CommonJS到ES模块一个Babel 7兼容的转换,可将... -
moduloze:将CommonJS(CJS)模块转换为UMD和ESM格式
2021-03-12 19:31:06将CommonJS(CJS)模块转换为UMD和ESM格式。 概述 Moduloze支持以Node.js生态系统固有的CommonJS(CJS)格式创作JS模块,并将这些模块转换为通用模块定义(UMD)和ES模块(ESM)格式。 UMD在尚未在应用程序中使用... -
ascjs:ES2015转换为CommonJS importexport转换器
2021-05-22 06:47:31ES2015到CommonJS导入/导出转换器 寻找CommonJS简约捆扎机吗? asbundle完全基于ascjs ,可以创建兼容浏览器的捆绑包。 不要错过! 该模块仅做一件事:它将ES2015 / 语句轻松地转换为有效的CommonJS ,以修复Node... -
cjs2es6import:将 CommonJS require 表达式转换为 ES6 模块导入语句
2021-06-17 07:54:04将 CommonJS/NodeJS 模块表达式的子集转换为语句。 用法: var cjs2es6import = require('cjs2es6import'); var src = "var foo = require('bar');"; var newSrc = cjs2es6import(src); // "import foo from '... -
commonjs.html
2019-08-01 09:29:02common 中 export module.exports import export default的用法 -
cjs2es6export:将 CommonJS 模块赋值转换为 ES6 模块导出语句
2021-06-17 07:59:49将 CommonJS/ 分配的子集转换为声明。 用法: var cjs2es6export = require('cjs2es6export'); var src = "module.exports = function() { return 42; };" var newSrc = cjs2es6export(src); // "export default... -
世界语:已弃用:一种将ES6模块转换为AMD和CommonJS的简便方法
2021-02-21 10:10:56将ES6模块移植到AMD和CommonJS的更好方法: 更容易-无需费力的配置 更简单-无需对项目设置做出危险的假设 更智能-无损源代码转换,无运行时Traceur依赖项以及仅ES5的功能 更快-大约比其他产品快10倍 在此处在线... -
rollup-plugin-commonjs, 将CommonJS模块转换为 ES2015.zip
2019-09-18 02:48:48rollup-plugin-commonjs, 将CommonJS模块转换为 ES2015 rollup-plugin-commonjs 将CommonJS模块转换为 ES6,以便它们可以包含在Rollup包中安装npm install --save-dev rollup-plugin-commonjs用法 -
gulp-ejs-compile-commonjs
2021-05-03 13:13:01gulp-ejs-compile-commonjs [![NPM版本] [npm-image]] [npm-url] [![构建状态] [travis-image]] [travis-url] [![Code Climate] [codeclimate-image]] [codeclimate-url ] [![覆盖状态] [coverage-image]] ... -
ES6与CommonJS中的模块处理的区别
2021-01-19 20:04:59ES6和CommonJS都有自己的一套处理模块化代码的措施,即JS文件之间的相互引用。 为了方便两种方式的测试,使用nodejs的环境进行测试 CommonJS的模块处理 使用require来引入其他模块的代码,使用module.exports来引出 ... -
transpile-node-modules::test_tube: CLI 使用 esbuild 将单个 ESM 包转换为 CommonJS
2021-07-24 15:13:31使用 esbuild 将单个 ESM 包转换为 CommonJS 的 。 安装 pnpm i -g transpile-node-modules 用法 transpile-node-modules < pkg> [target] pkg - 要转译的包 target - 可选的目标环境(默认: es2018 ) -
rcompile:将多个 CommonJS 代码(node.js 风格)编译成一个 JS 文件
2021-06-03 23:34:41将多个 CommonJS 代码(node.js 风格)编译成一个 JS 文件。 安装 npm install -g rcompile 用法 Usage: rcompile [OPTIONS] FILE ... Options: -b --base Base path to the root (default to current folder) -... -
grunt-amdify:用 AMD 包装 CommonJs 模块
2021-07-08 09:43:51在 AMD 中包装 CommonJs 模块 入门 这个插件需要 Grunt。 如果您以前没有使用过 ,请务必查看指南,因为它解释了如何创建以及安装和使用 Grunt 插件。 熟悉该过程后,您可以使用以下命令安装此插件: npm install ... -
详解CommonJS和ES6模块循环加载处理的区别
2021-01-21 13:53:05CommonJS模块规范使用require语句导入模块,module.exports导出模块,输出的是值的拷贝,模块导入的也是输出值的拷贝,也就是说,一旦输出这个值,这个值在模块内部的变化是监听不到的。 ES6模块的规范是使用import... -
使用Browserify来实现CommonJS的浏览器加载方法
2020-12-11 04:54:49Nodejs的模块是基于CommonJS规范实现的,可不可以应用在浏览器环境中呢? var math = require('math'); math.add(2, 3); 第二行math.add(2, 3),在第一行require(‘math’)之后运行,因此必须等math.js加载完成。也... -
selenium-webdriver-commonjs-mocha-chai-expect:selenium-webdriver端到端测试自动化样板,使用CommonJS,...
2021-03-13 07:38:33Selenium-WebDriver样板 Selenium-WebDriver端到端测试自动化样板,使用 , , 和 。... cd selenium-webdriver-commonjs-mocha-chai-expect 3. npm install 4. npm run test 有关更多样板,请单击 -
一个Babel7转换插件用于将CommonJS转换为ESM
2019-08-12 04:17:02一个Babel 7转换插件用于将CommonJS转换为ESM -
comeon:CommonJS浏览器模块加载器实验
2021-05-20 19:50:55用于浏览器的实验性CommonJS模块加载器。 用法 使用data-path和data-main属性将comeon.js链接到页面,这些属性分别定义模块的放置位置以及分别是模块的主要位置: [removed][removed] 或者在没有魔术的情况下做: ... -
vue-component-compiler:将单个文件Vue组件编译为CommonJS模块
2021-02-20 10:04:52@ vue / component-compiler 用于编译Vue单个文件组件的高级实用程序 该软件包包含高级实用程序,如果您正在为将Vue单个文件组件编译为JavaScript的捆绑器或模块系统编写插件/转换,则可以使用这些实用程序。... -
Node.js和CommonJs模块化的介绍、引入及使用
2021-01-08 10:41:201、什么是 CommonJs JavaScript是一个强大的面向对象语言 它有很多快速高效的解释器 然而 JavaScript标准定义的API只是为了构建基于浏览器的应用程序 并没有制定一个用于更广泛的应用程序的标准库 CommonJS规范的...