module.js源碼(html module)

  • 1、nodejs 運行錯誤:module.js:340 throw err;是什麼原因
  • 2、如何載入Nodejs模塊
  • 3、為什麼nodejs的module.js里用了readFileSync而不用readFile
  • 4、node.js的module.export 和 export方法的區別
  • 5、cocos creator怎麼寫邏輯

複製網上一個教程里的一段代碼,一個簡易伺服器,但運行不起來,不知道是什麼原因。我把運行結果和代碼都貼出來,望解答。

代碼:

var http = require(“http”);

http.createServer(function(request, response) {

response.writeHead(200, {“Content-Type”: “text/plain”});

response.write(“Hello World”);

response.end();

}).listen(8888);

運行結果:

D:\testnode server.js

module.js:340

throw err;

^

Error: Cannot find module ‘D:\test\server.js’

at Function.Module._resolveFilename (module.js:338:15)

at Function.Module._load (module.js:280:25)

at Function.Module.runMain (module.js:497:10)

at startup (node.js:119:16)

at node.js:906:3

nodejs的幾種模塊載入方式

一.直接在exports對象中添加方法

1. 首先創建一個模塊(module.js)module.js

exports.One = function(){

console.log(‘first module’);

};

2.load.jsvar module =require(‘./module’);

module.One();

這樣我們就可以在引入了該模塊後,返回一個exports對象,這裡是指module對象,其實都只是兩個引用或者句柄,只是都指向了同一個資源,在load.js里,module的名字可以是任意取的,因為它僅僅是指向require(‘./module’);返回後的一個實例對象的引用,在load.js文件里的module和在module.js里的exports對象是同一個東西.因此上述兩個文件可以用一個文件來表示:exports.One = function(){

console.log(‘first module’);

};

exports.One();

其運行結果是一致的,這裡我們可以很清晰的看到,我們在使用require(‘./xxxx’)後其實返回的總是在 xxxx.js文件中的exports對象的引用,這個引用的名字我們可以任意取,但是為了規範我們還是最好取符號某些非標準規定(後面說道),但是這樣會有不妥的地方,因為它是始終指向exports的實例對象,也就是說,我們雖然有了這個模塊,但是這個模塊我們只能使用一次,這取決於rquire(‘./module’)只會加在一次該模塊.比如我們修改上述代碼,

module.js

var name ;

exports.setName = function(oName){

name = oName;

};

exports.getName = function(){

console.log(name);

};

load.jsvar module1 = require(‘./module’);

module1.setName(“felayman1”);

module1.getName();

var module2 = require(‘./module’);

module2.setName(“felayman2”);

module2.getName();

module1.getName();

我們可以看到,雖然我們使用了兩次require(‘./module’);,但是當我們修改module2後,module1的內容也被修改,這恰恰說明了,module1和module2是指向的同一個對象.有時候這並不影響我們的程序,但是如果我們的module是Person呢?我們希望我們require(‘./person’)後返回的是不同的對象.因此,這種方式是有缺陷的,儘管很方便,這種方式在大部分nodejs的模塊中都是很常見,比如fs模塊,http模塊等.

二.將模塊中的函數掛載到exports對象的屬性上

person.js

function Person{

var name;

this.setName = function(theName){

name = theName;

};

this.sayHello = function(){

console.log(‘Hello’,name);

};

}

exports.Person = Person;

load.js

var Person = require(‘./person’).Person;

var person1 = new Person();

person1.setName(“felayman1”);

person1.sayHello();

var person2 = new Person();

person2.setName(“felayman2”);

person2.sayHello();

person1.sayHello();

這樣我們可以看到,我們就可以引入一個函數了,我們把在person.js文件中的Person函數設置為eports對象的一個屬性,我們只需要在load.js文件中引入該屬性,就可以獲取到多個該函數的實例,在nodejs中的EventEmitter就是基於這種方式,但是這樣我們總是在使用 require(‘./person’).Person;這樣的寫法有點太複雜,因此nodejs允許我們使用其他更簡潔的方式,利用全局變數–module,這樣我們在其他文件中引入其他模塊的時候,就更方便了.

三.利用全局變數module

person.js

function Person(){

var name;

this.setName = function(theName){

name = theName;

};

this.sayHello = function(){

console.log(‘Hello’,name);

};

}

// exports.Person = Person;

module.exports = Person;

load.jsvar Person = require(‘./person’);

var person1 = new Person();

person1.setName(“felayman1”);

person1.sayHello();

var person2 = new Person();

person2.setName(“felayman2”);

person2.sayHello();

person1.sayHello();

這樣一修改,我們就在使用require函數的時候就方便了,如果覺得這裡難以理解,我們可以把兩個文件里語法放到一起:var Person = require(‘./person’);

module.exports = Person;

這樣,我們就可以看出,其實就是這樣var Person = Person.

因為上述我們都已經說過,require(‘./person’)其實就是module.exports 對象的,這裡的module我們不用太在意,就跟javascript中的window一樣,是一個全局變數,即 module.exports =exports就類似於window.alert() =alert()差不多的效果,這樣我們就能看出,我們再次使用require(‘./person’)的時候其實就是導入了我們所需要的exports對象的屬性函數模板了,這樣我們也可以多次實例化我們所需要的對象了.這種方式是綜合了前兩種的方法,因此也是官方推薦的使用方法.

進一步說,之所以同步是 Node.js 所遵循的 CommonJS 的模塊規範要求的。

在當年,CommonJS 社區對此就有很多爭議,導致了堅持非同步的 AMD 從 CommonJS 中分裂出來。

CommonJS

模塊是同步載入和同步執行,AMD 模塊是非同步載入和非同步執行,CMD(Sea.js)模塊是非同步載入和同步執行。ES6

的模塊體系最後選擇的是非同步載入和同步執行。也就是 Sea.js 的行為是最接近 ES6 模塊的。不過 Sea.js

這樣做是需要付出代價的——需要掃描代碼提取依賴,所以它不像 CommonJS/AMD 是純運行時的模塊系統。

注意 Sea.js 是

2010年之後開發的,提出 CMD 更晚。Node.js 當年(2009年)只有 CommonJS 和 AMD 兩個選擇。就算當時已經有

CMD 的等價提案,從性能角度出發,Node.js 不太可能選擇需要靜態分析開銷的 類 CMD 方案。考慮到 Node.js

的模塊是來自於本地文件系統,最後 Node.js 選擇了看上去更簡單的 CommonJS 模塊規範,直到今天。

node.js中module.export與export的區別。

可能是有史以來最簡單通俗易懂的有關Module.exports和exports區別的文章了。

exports = module.exports = {}

所以module.exports和exports的區別就是var a={}; var b=a;,a和b的區別

看起來木有什麼太大區別,但實際用起來的時候卻又有區別,這是為啥呢,請聽我細細道來

關於Module.exports和exports有什麼區別,網上一搜一大把,但是說的都太複雜了…聽說exports是Module.exports對象的一個引用(reference)^1,什麼是引用?!…_(:з」∠)_

當然啦,如果要徹底理解這兩個導出的區別,最好肯定是去看源碼,看看都是怎麼封裝的,功力深厚的童鞋應該一看就懂了。不過,源碼我也是看不懂的…(ಥ_ಥ)

但是最近感覺雜七雜八看了好多文章做了好多實驗之後,像是打開了任督二脈,機智的我好像有點上道了…

首先要明確的一點,module是一個對象 {Object}。當你新建一個文件,比如mo.js,文件內容如下:

1 console.log(module)

然後在CMD里執行這個文件node mo.js,就能看到module其實是一個Module實例,你可以這麼理解,NodeJS中定義了一個Module類,這個類中有很多屬性和方法,exports是其中的一個屬性:

12345 function Module { id : ‘blabla’, exports : {}, blabla…}

當每個js文件在執行或被require的時候,NodeJS其實創建了一個新的實例var module = new Module(),這個實例名叫module。這也就是為什麼你並沒有定義module這個變數,卻能console.log出來而不會報錯的原因。

假設我有一個JS文件內容如下:

有了上面的基礎,很容易理解module.export其實是給Module實例中的exports對象中添加方法/屬性。

通常使用exports的時候,是這麼用的:

假設我有一個JS文件內容如下:

由此也能看出,傳說中的exports其實是module.exports的引用,你可以這麼理解,NodeJS在你的代碼之前悄悄的加了以下代碼:

這也就是為什麼你並沒有定義exports這個變數,卻能console.log出來而不會報錯的原因。

當你從外部調用某個模塊,require其實是在require什麼?^2require的時候NodeJS會到處去找有沒有這個模塊,如果有,return的就是module.exports里的東東。

主要兩個js源碼:

HelloWorld.js

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

cc.Class({

extends: cc.Component,

properties: {

label: {

default: null,

type: cc.Label

},

text: ‘Hello, World!’,

t_prefab:{

default:null,

type:cc.Prefab

},

t_sprite:{//定義一個cc的類型,並定義上常用屬性

default:null,

type:cc.SpriteFrame,//類型的定義

// url:cc.Texture2D, //Raw Asset(cc.Texture2D, cc.Font, cc.AudioClip)

visible:true,//屬性檢查器中是否可見

displayName:’himi’,//屬性檢查器中屬性的名字

tooltip:”測試腳本”,//屬性檢查器中停留此屬性名稱顯示的提示文字

readonly:false,//屬性檢查器中顯示(readonly)且不可修改[當前有bug,設定只讀也能修改]

serializable:true,//設置false就是臨時變數

editorOnly:false//導出項目前剔除此屬性

},

t_url:{

default:null,

url:cc.Texture2D

},

t_count_2:200,//基礎類型

//可以只定義 get 方法,這樣相當於一份 readonly 的屬性。[當前有bug,只設定get也能修改]

t_getSet:{

default:12,

get:function(){return this.t_getSet},//get

set:function(value){this.t_getSet =value;}//set

},

t_array:{//定義一個數組

default:[],

type:[cc.Sprite]

}

},

// use this for initialization

onLoad: function () {

//— 獲取組件的幾種形式:

//1. 通過屬性檢查器被賦值的label組件,直接拿到得到實例

//2. 通過屬性檢查器被賦值的label組件所在的node節點,然後通過getComponent獲取

// this.label.string = this.text;

//3. 獲取當前this(node)節點上的label組件

// var _label = this.getComponent(cc.Label);

//4. 先獲取目標組件所在的節點,然後通過getComponent獲取目標組件

var _label = cc.find(“Canvas/label”).getComponent(cc.Label);

//5.也可以如下形式【注意此種方式,目前有BUG,無法正常使用 (0.7.1) 】

// var _label = cc.find(“Canvas/labelcc.Label”);

console.log(_label.string);

console.log(this.t_getSet);

//—全局變數的訪問

/* 任意腳本中定義如下:【注意不要有var哦】

t_global = {

tw:100,

th:200

};

*/

t_global.th = 2000;

console.log(t_global.th);

//—模塊之間的訪問

/*任意腳本中定義如下 【注意關鍵字是module.exports】

module.exports= {

tme_pa1:”100″,

tme_pa2:333221

};

*/

//—用 require + 文件名(不含路徑) 來獲取到其他 模塊 的對象

var tModuleData = require(“testJs”);

tModuleData.tme_pa2 = 991;

console.log(tModuleData.tme_pa2);

//—在當前節點下添加一個組件

var mySprite = new cc.Node().addComponent(cc.Sprite);

mySprite.spriteFrame = this.t_sprite;

mySprite.node.parent = this.node;

mySprite.node.setPosition(300,200);

//—複製節點/或者複製 prefab

//複製節點

var lLabel = cc.instantiate(this.label);

lLabel.node.parent = this.node;

lLabel.node.setPosition(-200,0);

//複製prefab

var tPrefab = cc.instantiate(this.t_prefab);

tPrefab.parent = this.node;

tPrefab.setPosition(-210,100);

//— 銷毀節點(銷毀節點並不會立刻發生,而是在當前 幀邏輯更新結束後,統一執行)

if (cc.isValid(this.label.node) ) {

console.log(“有效存在,進行摧毀”);

this.label.destroy();

}else{

console.log(“已摧毀”);

}

//— 事件監聽 on 4種形式

//枚舉類型註冊

var tFun =function (event){

console.log(“touchend event:”+event.touch.getLocation().x +”|”+event.touch.getLocation().y);

};

this.node.on(cc.Node.EventType.TOUCH_END,tFun,this);

//事件名註冊

// var tFun =function (event){

// console.log(“touchend event”);

// };

// this.node.on(“touchend”,tFun);

// this.node.on(“touchend”,function (event){

// console.log(“touchend event”);

// });

// this.node.on(“touchend”,function (event){

// console.log(“touchend event”);

// },this);

// this.node.on(“touchend”,function (event){

// console.log(“touchend event”);

// }.bind(this));

//— 一次性的事件監聽 once

// this.node.once(“touchend”,function (event){

// console.log(“touchend event”);

// });

//— 關閉監聽

this.node.off(“touchend”,tFun,this);

//— 發射事件(事件手動觸發)

this.node.on(“tEmitFun”,function (event){

console.log(“tEmitFun event:”+event.detail.himi+”|”+event.detail.say);

//– 事件中斷,如下函數阻止事件向當前父級進行事件傳遞

// event.stopPropagation();

});

this.node.emit(“tEmitFun”,{himi:27,say:”hello,cc!”});

//— 動作,類似c2dx api 基本無變化

var mTo = cc.moveBy(1,-100, -200);

var mAction = cc.repeatForever(cc.sequence(cc.moveBy(1,-100, -200),mTo.reverse(),cc.delayTime(0.5),cc.callFunc(function(action,data){

console.log(“action callback:”+data.himi);

},this,{tx:100,himi:”i’m action callback and bring data”})));

mySprite.node.runAction(mAction);

//暫停動作

mySprite.node.stopAction(mAction);

//— 計時器 (component)schedule (cc.Node 不包含計時器相關 API)

//參數: call funtion/interval/repeat times/delay time

//不延遲,永久重複

this.schedule(function(){

console.log(“schedule log…”);

},1);

//不延遲,有重複次數限定

// this.schedule(function(){

// console.log(“schedule log…”);

// },1,2);

//重複2次,重複間隔為1秒,延遲1秒進行

// this.schedule(function(){

// console.log(“schedule log…”);

// },1,2,1);

//一次性的計時器

var mySch =function(){ console.log(“schedule Once log…”); }

this.scheduleOnce(mySch);

//取消定時器

this.unschedule(mySch);

//— url raw資源獲取

var mSf = new cc.Node().addComponent(cc.Sprite);

mSf.spriteFrame = this.t_sprite;

mSf.spriteFrame.setTexture(this.t_url);

mSf.node.setPosition(400,0);

mSf.node.parent = this.node;

mSf.node.setScale(0.5);

//獲得 Raw Asset 的 url

var mUrl = cc.textureCache.addImage(cc.url.raw(“himi.png”));

console.log(“raw asset url:”+mUrl);

},

// called every frame

update: function (dt) {

// if (cc.isValid(this.label.node) ) {

// console.log(“有效存在,進行摧毀”);

// }else{

// console.log(“已摧毀”);

// }

},

});

testJs.js

1

2

3

4

5

6

7

8

9

t_global = {

tw:100,

th:200

};

module.exports= {

tme_pa1:”100″,

tme_pa2:333221

};

原創文章,作者:簡單一點,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/126352.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
簡單一點的頭像簡單一點
上一篇 2024-10-03 23:07
下一篇 2024-10-03 23:07

相關推薦

  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • 雲智直聘 源碼分析

    本文將會對雲智直聘的源碼進行分析,包括前端頁面和後端代碼,幫助讀者了解其架構、技術實現以及對一些常見的問題進行解決。通過本文的閱讀,讀者將會了解到雲智直聘的特點、優勢以及不足之處,…

    編程 2025-04-29
  • Python渲染HTML庫

    Python渲染HTML庫指的是能夠將Python中的數據自動轉換為HTML格式的Python庫。HTML(超文本標記語言)是用於創建網頁的標準標記語言。渲染HTML庫使得我們可以…

    編程 2025-04-29
  • 解析js base64並轉成unit

    本文將從多個方面詳細介紹js中如何解析base64編碼並轉成unit格式。 一、base64編碼解析 在JavaScript中解析base64編碼可以使用atob()函數,它會將b…

    編程 2025-04-29
  • Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的解決方法

    本文將解決Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的問題。同時,給出一些相關示例代碼,以幫助讀者更好的理解並處理這個問題。 一、問題解…

    編程 2025-04-29
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • Python網站源碼解析

    本文將從多個方面對Python網站源碼進行詳細解析,包括搭建網站、數據處理、安全性等內容。 一、搭建網站 Python是一種高級編程語言,適用於多種領域。它也可以用於搭建網站。最常…

    編程 2025-04-28
  • Python編程實戰:用Python做網頁與HTML

    Python語言是一種被廣泛應用的高級編程語言,也是一種非常適合於開發網頁和處理HTML的語言。在本文中,我們將從多個方面介紹如何用Python來編寫網頁和處理HTML。 一、Py…

    編程 2025-04-28
  • HTML sprite技術

    本文將從多個方面闡述HTML sprite技術,包含基本概念、使用示例、實現原理等。 一、基本概念 1、什麼是HTML sprite? HTML sprite,也稱CSS spri…

    編程 2025-04-28
  • 源碼是什麼

    源碼是一段計算機程序的原始代碼,它是程序員所編寫的可讀性高、理解性強的文本。在計算機中,源碼是指編寫的程序代碼,這些代碼按照一定規則排列,被計算機識別並執行。 一、源碼的組成 源碼…

    編程 2025-04-27

發表回復

登錄後才能評論