Node入門教程(6)第五章:node 模塊化(上)模塊化演進(jìn)

node 模塊化

JS 誕生的時候,僅僅是為了實現(xiàn)網(wǎng)頁表單的本地校驗和簡單的 dom 操作處理。所以并沒有模塊化的規(guī)范設(shè)計邢隧。

項目小的時候痕慢,我們可以通過命名空間、局部作用域抑堡、自執(zhí)行函數(shù)等手段實現(xiàn)變量不沖突摆出。但是到了大一點的項目,各種組件首妖,各種第三方插件和各種 js 腳步融合的時候偎漫,就會發(fā)現(xiàn)這些技巧遠(yuǎn)遠(yuǎn)不夠。

模塊化的演變

為什么要有 JS 模塊化呢有缆?在瀏覽器中象踊,頂層作用域的變量是全局的,所以項目稍微復(fù)雜點棚壁,如果引用的 js 非常多的時候杯矩,很容易造成命名沖突,然后造成很大意想不到的結(jié)果灌曙。

為了避免全局污染菊碟,JS 前輩們想了很多辦法,也就是前端的模塊化的演變過程在刺,可以參考我的視頻:前端模塊化演變

模塊化演變過程:

  • 對象封裝

    • 所有的方法和屬性封裝到一個對象中
    • 所有的訪問通過對象來訪問逆害,只污染一個對象头镊,盡量避免污染其他。
var module = {
 star : 0,
  f1 : function ()
     //...
  },
 f2 : function (){
    //...
  }
 };
module.f1();
module.star = 1;
  • 命名空間(對象封裝的變種或者叫做升級)

    • 理論意義上減少了變量沖突
    • 缺點 1:暴露了模塊中所有的成員魄幕,內(nèi)部狀態(tài)可以被外部改寫相艇,不安全
    • 缺點 2:命名空間會越來越長
    var Shop = {}; // 頂層命名空間
    Shop.User = {}; // 電商的用戶模塊
    Shop.User.UserList = {}; //用戶列表頁面模塊。
    Shop.User.UserList.length = 19; // 用戶一共有19個纯陨。
    
  • 私有空間

    • 私有空間的變量和函數(shù)不會影響全局作用域
    • 公開公有方法坛芽,隱藏私有屬性
    // => 給單個文件里面定義的局部變量都 變成 局部作用域里面的變量。
    // 第二個嘗試:
    // a.js
    (function() {
      var a = 9;
    })();
    
    // b.js
    (function() {
      var a = 'ssss';
    })();
    
  • 模塊的維護(hù)和擴展

    • 開閉原則
    • 可維護(hù)性好
   // laoma.core.js
  (function(laoma, d1, d2) {
    laoma.Btn = {
      getVal: function() {
        console.log('val');
      },
      setVal: function(str) {
        console.log('setvale');
      }
    };
  })(window.laoma || {}, depend1, depend2);

  // laoma.animate.js
  // 動畫組件
  (function(laoma, d1, d2) {
    laoma.animate = {};
  })(window.laoma || {}, depend1, depend2);

  // laoma.form.js
  // 表單組件
  (function(laoma, d1, d2) {
    laoma.form = {};
  })(window.laoma || {}, depend1, depend2);
  • 圍觀jQuery的結(jié)構(gòu)
(function(window, undefined) {
    var jQuery = function() {}
    // ...
    window.jQuery = window.$ = jQuery;
})(window);

后續(xù)的演變就是翼抠,出現(xiàn)了 AMD咙轩、CMD、CommonJS 等模塊化標(biāo)準(zhǔn)阴颖,然后前端模塊化進(jìn)入大爆發(fā)時代活喊。

什么是 JS 模塊化

JS 模塊化就是指 JS 代碼分成不同的模塊,模塊內(nèi)部定義變量作用域只屬于模塊內(nèi)部量愧,模塊之間變量命名不會相互沖突钾菊。各個模塊相互獨立,而且又可以通過某種方式相互引用協(xié)作偎肃。

模塊化的標(biāo)準(zhǔn)

目前前端流行的幾個模塊化標(biāo)準(zhǔn):CommonJs標(biāo)準(zhǔn)(node 的方案)煞烫、AMDCMD累颂、ES6 模塊方案滞详。

未來的趨勢肯定是 ES6 的標(biāo)準(zhǔn)方案會逐漸統(tǒng)一。但是 AMD紊馏、CMD 標(biāo)準(zhǔn)跟 CommonJs 的標(biāo)準(zhǔn)相差不大茵宪,需要我們都研究一下。

requirejs 入門

requirejs 的使用:

第一步:requirejs 下載

第二步: 把 requirejs 直接引入到 html

<script src="js/require.js"></script>

第三步: 設(shè)置當(dāng)前頁面的 js 入口文件

<script src="js/require.js" data-main="js/main"></script>

data-main 屬性的作用是瘦棋,指定網(wǎng)頁程序的主模塊。意思是當(dāng)前整個網(wǎng)頁的入口代碼暖哨。那么其他需要引用的 JS 文件呢赌朋?

第四步: 引用其他模塊的文件

主模塊依賴于其他模塊,這時就要使用 AMD 規(guī)范定義的的 require()函數(shù)篇裁。

// main.js
require(['moduleA', 'moduleB', 'moduleC'], function(moduleA, moduleB, moduleC) {
  // some code here
});

require()函數(shù)接受兩個參數(shù)沛慢。第一個參數(shù)是一個數(shù)組,表示所依賴的模塊达布,上例就是['moduleA', 'moduleB', 'moduleC']团甲,即主模塊依賴這三個模塊;第二個參數(shù)是一個回調(diào)函數(shù)黍聂,當(dāng)前面指定的模塊都加載成功后躺苦,它將被調(diào)用身腻。加載的模塊會以參數(shù)形式傳入該函數(shù),從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊匹厘。

require()異步加載 moduleA嘀趟,moduleB 和 moduleC,瀏覽器不會失去響應(yīng)愈诚;它指定的回調(diào)函數(shù)她按,只有前面的模塊都加載成功后,才會運行炕柔,解決了依賴性的問題酌泰。

實際應(yīng)用例子:

require(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
  // some code here
});

如果依賴的 JS 文件跟我們的 require.js 不在相同的目錄,那么需要我們單獨設(shè)置一下路徑映射關(guān)系匕累。

require.config({
  paths: {
    underscore: 'lib/underscore.min',
    backbone: 'lib/backbone.min'
  }
});

第五步:如何自定義 AMD 模塊(可選)

自定義的模塊還依賴其他模塊陵刹,那么 define()函數(shù)的第一個參數(shù),必須是一個數(shù)組哩罪,指明該模塊的依賴性

define(['myLib'], function(myLib) {
  function foo() {
    myLib.doSomething();
  }
  return {
    foo: foo
  };
});

CMD 與 Sea.js

[Sea.js]在推廣過程中逐漸形成了 CMD 的模塊定義標(biāo)準(zhǔn)授霸。具體詳情請參考

跟 AMD 比較類似际插,而且兼容 CommonJS 的模塊寫法碘耳。

CMD 推崇的是:依賴就近依賴,AMD 則默認(rèn)約束模塊一開始就聲明相關(guān)依賴框弛。其他定義方式及模塊相關(guān)的變量都很相似辛辨。

由于 Sea.js 官方文檔很詳細(xì),在此就不再贅述瑟枫。如何使用請參考官網(wǎng)斗搞。

Node 的模塊化

Node.js 有一個簡單的模塊加載系統(tǒng),遵循的是 CommonJS 的規(guī)范慷妙。 在 Node.js 中僻焚,文件和模塊是一一對應(yīng)的(每個文件被視為一個獨立的模塊)。

Node 在加載 JS 文件的時候膝擂,自動給 JS 文件包裝上定義模塊的頭部和尾部虑啤。

// nodejs 會自動給我們的js文件添加頭部,見下行
(function(exports, require, module, __filename, __dirname) {
  // 這里是你自己寫的js代碼文件
}); // 自定添加上尾部

見 NodeJs 的源碼截圖:


Node會自動給js文件模塊傳遞的5個參數(shù)架馋,每個模塊內(nèi)的代碼都可以直接用狞山。而且您也看到了,我們的代碼都會被包裝到一個函數(shù)中叉寂,所以我們的代碼的作用域都是在這個包裝的函數(shù)內(nèi)萍启,這點跟瀏覽器的window全局作用域是不同的。

模塊內(nèi)的參數(shù)說明:

  • __dirname: 當(dāng)前模塊的文件夾名稱
  • __filename: 當(dāng)前模塊的文件名稱---解析后的絕對路徑。
  • module: 當(dāng)前模塊的引用勘纯,通過此對象可以控制當(dāng)前模塊對外的行為和屬性等局服。
  • require:是一個函數(shù),幫助引入其他模塊.
  • exports:這是一個對于 module.exports 的更簡短的引用形式屡律,也就是當(dāng)前模塊對外輸出的引用腌逢。

如何加載模塊

在模塊內(nèi),我們可以通過require函數(shù)(此函數(shù)由nodejs自動傳入超埋,在模塊內(nèi)可以直接用)來加載js文件模塊搏讶、node內(nèi)置模塊等。require函數(shù)需要傳入要加載的模塊的名字或者是文件名或者目錄霍殴。

/*
假設(shè)開發(fā)目錄下有文件:
.
├── circle.js
└── main.js
*/

// circle.js
exports.pi = 3.1415926;  // 其他模塊引用當(dāng)前模塊時媒惕,可以直接通過模塊對象訪問到 pi屬性。

// 主文件main.js:
const circle = require('./circle.js'); // 加載circle.js文件的module.export 賦值給circle
console.log(circle.pi); // => 3.1415926

解釋:
require加載文件circle.js后来庭,此文件被node拼裝成模塊的代碼妒蔚,然后執(zhí)行文件里面的js代碼,并把模塊內(nèi)的module.exports做為模塊的對外接口返回給引用者月弛。

// circle.js 包裝后的代碼就是
// nodejs 會自動給我們的js文件添加頭部
(function(exports, require, module, __filename, __dirname) {
  exports.pi = 3.1415926;
  // exports  === modeule.exports
}); // 自定添加上尾部

// 主文件main.js:
const circle = require('./circle.js'); 
circle =>  circle.js中的module.exports 

加載策略

Node.js的模塊分為兩類肴盏,一類為原生(核心)模塊,一類為文件模塊帽衙。

  1. 模塊在第一次加載后會被緩存菜皂。 這也意味著如果每次調(diào)用 require('foo') 都解析到同一文件,則返回相同的對象厉萝。

  2. Node.js提供了一些底層的核心模塊恍飘,它們定義在 Node.js 源代碼的 lib/ 目錄下。這些原生模塊在Node.js源代碼編譯的時候編譯進(jìn)了二進(jìn)制執(zhí)行文件谴垫,加載的速度最快章母。開發(fā)人員自定義的js文件是動態(tài)加載的,加載速度比原生模塊慢翩剪,這個只是在第一次加載有區(qū)別乳怎,模塊加載完后都會被緩存,后續(xù)使用就不會被再次加載前弯。

  3. require() 總是會優(yōu)先加載核心模塊舞肆。 例如,require('http') 始終返回內(nèi)置的 HTTP 模塊博杖,即使有同名文件。

文件模塊中筷登,又分為3類模塊剃根。這三類文件模塊以后綴來區(qū)分,Node.js會根據(jù)后綴名來決定加載方法前方。

  • .js狈醉。通過fs模塊同步讀取js文件并編譯執(zhí)行廉油。
  • .node。通過C/C++進(jìn)行編寫的Addon苗傅。通過dlopen方法進(jìn)行加載抒线。
  • .json。讀取文件渣慕,調(diào)用JSON.parse解析加載嘶炭。

參考源碼:


模塊加載邏輯

require方法接受以下幾種參數(shù)的傳遞:

  • http、fs逊桦、path等眨猎,原生模塊。
  • ./mod或../mod强经,相對路徑的文件模塊睡陪。
  • /pathtomodule/mod,絕對路徑的文件模塊匿情。
  • mod兰迫,非原生模塊的文件模塊。

文件加載的邏輯還是比較復(fù)雜的炬称,而且考慮很多種情況汁果。

  • require加載文件模塊,直接找對應(yīng)完整文件名最快转砖,如果不給文件后綴名须鼎,node會自動嘗試添加 js\json\mod等后綴進(jìn)行嘗試。當(dāng)沒有以 '/'府蔗、'./' 或 '../' 開頭來表示文件時晋控,這個模塊必須是一個核心模塊或加載自 node_modules 目錄。如果給定的路徑不存在姓赤,則 require() 會拋出一個 code 屬性為 'MODULE_NOT_FOUND' 的 Error赡译。
  • 如果加載目錄,又分三種情況:
  1. 第一種方式是在根目錄下創(chuàng)建一個 package.json 文件不铆,并指定一個 main 模塊蝌焚。 例子,package.json 文件類似:
{ 
  "name" : "some-library",
  "main" : "./lib/some-library.js"
}

如果這是在 ./some-library 目錄中誓斥,則 require('./some-library') 會試圖加載 ./some-library/lib/some-library.js只洒。不存在也會報錯。

  1. 如果目錄里沒有 package.json 文件劳坑,則 Node.js 就會試圖加載目錄下的 index.js 或 index.node 文件毕谴。 例如,如果上面的例子中沒有 package.json 文件,則 require('./some-library') 會試圖加載:
./some-library/index.js
./some-library/index.node
  1. 其他的情況涝开,則從 node_modules 目錄加載循帐。 Node.js 會從當(dāng)前模塊的父目錄開始,嘗試從它的 /node_modules 目錄里加載模塊舀武。 Node.js 不會附加 node_modules 到一個已經(jīng)以 node_modules 結(jié)尾的路徑上拄养。

如果還是沒有找到,則移動到再上一層父目錄银舱,直到文件系統(tǒng)的根目錄瘪匿。

例子,如果在 '/home/ry/projects/foo.js' 文件里調(diào)用了 require('bar.js')纵朋,則 Node.js 會按以下順序查找:

/home/ry/projects/node_modules/bar.js
/home/ry/node_modules/bar.js
/home/node_modules/bar.js
/node_modules/bar.js

這使得程序本地化它們的依賴柿顶,避免它們產(chǎn)生沖突。

可以通過module.paths打印當(dāng)前node尋找模塊要搜索的所有路徑操软。

綜上邏輯嘁锯,看官網(wǎng)的加載邏輯偽代碼:

從 Y 路徑的模塊 require(X)
1. 如果 X 是一個核心模塊,
   a. 返回核心模塊
   b. 結(jié)束
2. 如果 X 是以 '/' 開頭
   a. 設(shè) Y 為文件系統(tǒng)根目錄
3. 如果 X 是以 './' 或 '/' 或 '../' 開頭
   a. 加載文件(Y + X)
   b. 加載目錄(Y + X)
4. 加載Node模塊(X, dirname(Y))
5. 拋出 "未找到"

加載文件(X)
1. 如果 X 是一個文件聂薪,加載 X 作為 JavaScript 文本家乘。結(jié)束
2. 如果 X.js 是一個文件,加載 X.js 作為 JavaScript 文本藏澳。結(jié)束
3. 如果 X.json 是一個文件仁锯,解析 X.json 成一個 JavaScript 對象。結(jié)束
4. 如果 X.node 是一個文件翔悠,加載 X.node 作為二進(jìn)制插件业崖。結(jié)束

加載目錄(X)
1. 如果 X/package.json 是一個文件,
   a. 解析 X/package.json蓄愁,查找 "main" 字段
   b. let M = X + (json main 字段)
   c. 加載文件(M)
   d. 加載索引(M)
2. 加載索引(X)

加載Node模塊(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. 加載文件(DIR/X)
   b. 加載目錄(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   b. DIR = path join(PARTS[0 .. I] + "node_modules")
   c. DIRS = DIRS + DIR
   d. let I = I - 1
5. return DIRS

總結(jié):

我們自己加載模塊的時候双炕,盡量的寫全點,盡量不要讓node去推斷撮抓,引用文件模塊直接把文件名寫全妇斤,文件

module 對象

如果想查看當(dāng)前模塊,可以直接使用console直接打印一下module對象丹拯。

console.dir(module);
// 打印結(jié)果:
Module {
  id: '.',
  exports: {},
  parent: null,
  filename: '/Users/flydragon/Desktop/work/gitdata/nodedemos/demos/02console.js',
  loaded: false,
  children: [],
  paths:
   [ '/Users/flydragon/Desktop/work/gitdata/nodedemos/demos/node_modules',
     '/Users/flydragon/Desktop/work/gitdata/nodedemos/node_modules',
     '/Users/flydragon/Desktop/work/gitdata/node_modules',
     '/Users/flydragon/Desktop/work/node_modules',
     '/Users/flydragon/Desktop/node_modules',
     '/Users/flydragon/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }

在每個模塊中站超,module 的自由變量是一個指向表示當(dāng)前模塊的對象的引用。 為了方便乖酬,module.exports 也可以通過全局模塊的 exports 對象訪問死相。

module.exports 與 exports區(qū)別,看Node中的源碼就知道了咬像。

// 模塊的構(gòu)造函數(shù)
function Module(id, parent) {
  this.id = id;
  this.exports = {};   // 模塊實例的exports屬性初始化O蔽场K簟!module.exports === exports
  this.parent = parent;
  updateChildren(parent, this, false);
  this.filename = null;
  this.loaded = false;
  this.children = [];
}

注意:exportsmodule.exports 的一個引用钮惠,就好比在每一個模塊定義最開始的地方寫了這么一句代碼:var exports = module.exports要注意的一點就是: 最終模塊會把module.exports作為對外的接口。所以七芭,module.exports的引用地址發(fā)生了改變素挽,在改變之前通過exports屬性設(shè)置的都會被遺棄。

module的其他屬性:

屬性 類型 屬性說明
module.filename string 模塊的完全解析后的文件名
module.id string 模塊的標(biāo)識符狸驳。 通常是完全解析后的文件名预明。
module.loaded boolean 模塊是否已經(jīng)加載完成,或正在加載
module.parent object 最先引用該模塊的模塊耙箍。
module.paths string 模塊的搜索路徑撰糠。
module.children object 被該模塊引用的模塊對象。

詳情請參考:中文Node文檔

es6的模塊

es6的模塊引入和導(dǎo)出跟以上都有點區(qū)別辩昆。不過肯定是未來的統(tǒng)一的模型阅酪。node目前版本位置并沒有es6的模塊api支持的很好,只是在實驗階段汁针。不過我們可以借助babel來轉(zhuǎn)換我們的js代碼术辐,可以放心的使用。

由于這塊內(nèi)容施无,請直接參考阮一峰老師的es6入門

總結(jié)

從客戶端到服務(wù)端我們都搞定了js的模塊化辉词,也就是說讓js走向了工程化,大型應(yīng)用的基礎(chǔ)被奠定了猾骡。當(dāng)然瑞躺,目前業(yè)界模塊化已經(jīng)走入深水區(qū),尤其是webpack已經(jīng)可以讓前端的大部分資源都模塊化使用兴想。

我們已經(jīng)搞定了幢哨,自己書寫模塊,已經(jīng)引用核心模塊襟企、自己寫的模塊嘱么,那么怎么引用第三方模塊,怎么使用package文件顽悼,好吧提前透露一下:npm解密(下一節(jié))


參考:

  1. NodeJs 官網(wǎng)文檔
  2. MDN 文檔
  3. Javascript 模塊化編程(二):AMD 規(guī)范
  4. Javascript 模塊化編程(三):require.js 的用法
  5. CMD 模塊定義規(guī)范

老馬免費視頻教程

返回教程列表首頁

github地址:https://github.com/malun666/aicoder_node

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曼振,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蔚龙,更是在濱河造成了極大的恐慌冰评,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件木羹,死亡現(xiàn)場離奇詭異甲雅,居然都是意外死亡解孙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門抛人,熙熙樓的掌柜王于貴愁眉苦臉地迎上來弛姜,“玉大人,你說我怎么就攤上這事妖枚⊥⒕剩” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵绝页,是天一觀的道長荠商。 經(jīng)常有香客問我,道長续誉,這世上最難降的妖魔是什么莱没? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮酷鸦,結(jié)果婚禮上饰躲,老公的妹妹穿的比我還像新娘。我一直安慰自己井佑,他們只是感情好属铁,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躬翁,像睡著了一般焦蘑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盒发,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天例嘱,我揣著相機與錄音,去河邊找鬼宁舰。 笑死拼卵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛮艰。 我是一名探鬼主播腋腮,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼壤蚜!你這毒婦竟也來了即寡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤袜刷,失蹤者是張志新(化名)和其女友劉穎聪富,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體著蟹,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡墩蔓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年梢莽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奸披。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡昏名,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阵面,到底是詐尸還是另有隱情葡粒,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布膜钓,位于F島的核電站,受9級特大地震影響卿嘲,放射性物質(zhì)發(fā)生泄漏颂斜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一拾枣、第九天 我趴在偏房一處隱蔽的房頂上張望沃疮。 院中可真熱鬧,春花似錦梅肤、人聲如沸司蔬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俊啼。三九已至,卻和暖如春左医,著一層夾襖步出監(jiān)牢的瞬間授帕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工浮梢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留跛十,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓秕硝,卻偏偏與公主長得像芥映,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子远豺,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,088評論 0 1
  • Node.js是目前非衬纹火熱的技術(shù),但是它的誕生經(jīng)歷卻很奇特憋飞。 眾所周知霎苗,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,617評論 2 41
  • 模塊 Node 有簡單的模塊加載系統(tǒng)。在 Node 里榛做,文件和模塊是一一對應(yīng)的唁盏。下面例子里内狸,foo.js加載同一個...
    保川閱讀 600評論 0 0
  • 模塊通常是指編程語言所提供的代碼組織機制,利用此機制可將程序拆解為獨立且通用的代碼單元厘擂。所謂模塊化主要是解決代碼分...
    MapleLeafFall閱讀 1,171評論 0 0
  • 檢查: 1.內(nèi)核版本 2.Device Mapper 安裝 1.ubuntu維護(hù)的版本 2.Docker維護(hù)的版本...
    AnyL8023閱讀 231評論 0 0