关于CommonJS中Module实现的问题

2011-04-28 12:22:06 +08:00
 real_newbie
原生的JavaScript中可以通过Closure来实现模块化. 比如像这里所做的这样: http://yuiblog.com/blog/2007/06/12/module-pattern/

在CommonJS的实现中, 是这样做的: http://wiki.commonjs.org/wiki/Modules/1.1#Sample_Code

CommonJS中的这种module的方式是怎么实现的呢?
8604 次点击
所在节点    JavaScript
31 条回复
aligo
2011-04-29 11:53:03 +08:00
@kuno 我试了一下
bar.js:
var foo = 'bar'

exports.bar = function () {
return foo
}

foo.js:
require.paths.unshift('.')

var bar = require('bar')

console.log(typeof bar.foo == 'undefined')
console.log(typeof bar.bar == 'function')

console.log(bar.foo)
console.log(bar.bar())


node foo.js结果是:
true
true
undefined
bar

这里新require进来的js并不是一个global scope,如果拿来和ruby比较的话
module Bar
BAR = 'bar'
def ...
end
然后在别的地方是可以Bar::BAR的
real_newbie
2011-04-29 11:56:18 +08:00
@kuno,

恩, 我也是这么理解的. 只是单纯的把原来放在一个文件里的东西分散到了不同的文件, 便于管理而已.
aligo
2011-04-29 11:57:51 +08:00
@kuno 并且如果再加入一个rab.js如下
exports.rab = function () {
return exports.bar()
}

然后在原来的的foo.js
var rab = require('rab')
console.log(rab.rab())

这样是会出错的
aligo
2011-04-29 12:02:53 +08:00
@kuno 最后,再创建一个oof.js:
exports.oof = function () {
return oof_text
}
exports.test_oof = function () {
return typeof oof_text == 'undefined'
}

foo.js改为:
var oof_text = 'oof!'
require.paths.unshift('.')
var oof = require('oof')

console.log(oof.test_oof())
console.log(oof.oof())

你会看到true然后出错
real_newbie
2011-04-29 12:04:09 +08:00
我不明白这个所谓global scope是什么意思.

如果要复用bar()似乎应该是这样子做:

function bar() {}

exports.bar = function() {
return bar();
}

exports.rab = function() {
return bar();
}
aligo
2011-04-29 12:06:17 +08:00
总之我要说的是这里require进来的东西就是module,每个js都是自己的scope,只有通过exports.的东西才会被require返回,但是这个exports在次require之间也是互相独立的
aligo
2011-04-29 12:13:13 +08:00
然后再来玩个新的bar.js:
var foo = 'b'
var_foo = 'ar'

Bar = function () {
return foo + var_foo
}


然后这是新foo.js

require.paths.unshift('.')

require('bar')

console.log(typeof bar == 'undefined')
console.log(typeof var_bar == 'undefined')
console.log(typeof Bar == 'function')

console.log(Bar)
console.log(Bar())
console.log(bar)
console.log(var_bar)

结果是
true
true
true
[Function]
bar
到最后2个就出错了
n2n3
2011-04-29 12:25:47 +08:00
real_newbie
2011-04-29 12:33:30 +08:00
我总算是搞明白了.

@kuno 的require实现其实没有错. 但是return module.exports时候, 那些在module里却没有被exports的东西还是在的. 所以return的还是一个Closure.

@aligo的理解是正确的.
real_newbie
2011-04-29 12:42:30 +08:00
@n2n3, 果然还是源代码最高啊. module.js里的"Module._load"很清楚了.
aligo
2011-04-29 15:06:03 +08:00
恩,所以继续离题一下,如果要在前端里实现这样的效果,就需要像你上面提到的那个requirejs那样,在每个js中用一个define()包裹,像#9那样

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/12256

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX