第二節(jié): 模塊化Module

NodeJs 采用模塊化方式,管理和組織代碼,NodeJS的所有功能都存在每個(gè)模塊中的


1. 模塊和模塊化開發(fā)的了解

1.1 什么是模塊

模塊: 一個(gè)具有特定功能的文件就是一個(gè)模塊

模塊的優(yōu)點(diǎn): 有了模塊,我們就可以非常方式使用這些模塊,因?yàn)槟K總是完成了特定的功能,如果要修改模塊中個(gè)功能,那么只需要修改這個(gè)自己的模塊文件即可,模塊獨(dú)立于每一個(gè)文件中,不影響其他模塊的代碼

模塊之間相互獨(dú)立,如果一個(gè)模塊引入另一模塊,要使用里面的值,我們就需要在被引入的模塊中暴露這些值.


1.2 什么是模塊化

模塊化: 將一個(gè)復(fù)雜的程序依據(jù)一定的規(guī)則(規(guī)范)封裝成幾個(gè)模塊(文件),并進(jìn)行組合在一起,每個(gè)模塊內(nèi)部數(shù)據(jù)實(shí)現(xiàn)私有的, 只是向外部暴露一些接口(方法)與外部其他模塊通信

按照模塊化思考開發(fā)的項(xiàng)目, 也被稱為模塊化開發(fā).

模塊化的進(jìn)化

// 全局開發(fā)模式
// 最早期所有的js代碼卸載一個(gè)js文件中
function foo(){}

function bar(){}

// 造成的問題,就是代碼量過大以后,Global全局被污染,很容易導(dǎo)致命名沖突

后來對(duì)代碼進(jìn)行簡(jiǎn)單的封裝

// 簡(jiǎn)單封裝: Namespac 模式, 就是我們俗稱的命名空間
var Namespac = {
    foo: function(){},
    bar: function(){}
}
// 減少Global上的變量數(shù)目
// 本質(zhì)就是對(duì)象,不太安全

因?yàn)楹?jiǎn)單封裝的不安全,又出現(xiàn)了IIFE模式

// 匿名閉包: IIFE模式
var Module = (function(){
    var foo = function(){
        
    }
    
    return {
        foo: foo
    }
})()

Module.foo()

// 函數(shù)是JavaScript 的Local Scope

有的時(shí)候,我一個(gè)模塊可能還需要依賴其他的模塊,我們就需要在升級(jí)一下,將依賴的模塊注入

// 增強(qiáng)封裝, 引入依賴
var Module = (function($){
    var $body = $(body);
    var foo = function(){
        
    }
    
    return {
        foo:foo
    }
})($)

// 這就是模塊模式,也是現(xiàn)代模塊實(shí)現(xiàn)的基石


1.3 為什么要模塊化
  1. 降低復(fù)雜度
  2. 提高解耦性
  3. 部署方便


1.4 模塊化的好處
  1. 避免命名沖突(減少命名空間的污染)
  2. 更好的分類,按需加載
  3. 更高的復(fù)用性
  4. 高可維護(hù)性


2. CommonJS 規(guī)范

CommonJS規(guī)范為JavaScript制定了一個(gè)美好的愿景-希望JavaScript能夠在任何地方運(yùn)行


2.1模塊規(guī)范分類:
  1. CommonJS(NodeJS)

  2. AMD

  3. CMD

  4. ESModule (ES模塊化)


2.2. CommenJS 規(guī)范了解

CommonJS規(guī)范涵蓋了模塊,二進(jìn)制,Buffer,字符集編碼,I/O流, 進(jìn)制環(huán)境, 文件系統(tǒng),單元測(cè)試,包管理等
NodeJS借鑒CommonJs的規(guī)范來實(shí)現(xiàn)了一套易用的模塊系統(tǒng).NPM對(duì)Package規(guī)范的完好支持是的Node應(yīng)用在開發(fā)過程中事半功倍.

CommonJS 規(guī)范 :不是一個(gè)語言,也不是一個(gè)平臺(tái),它只是一個(gè)標(biāo)準(zhǔn),主要是對(duì)原有的JavaScript標(biāo)準(zhǔn)API進(jìn)行了增強(qiáng).

生態(tài)系統(tǒng).jpg


3. CommonJS 模塊規(guī)范

CommonJS對(duì)模塊的定義十分簡(jiǎn)單,主要分為模塊的引用, 模塊的定義, 模塊的標(biāo)識(shí)3個(gè)部分


3.1 模塊的引用

在CommonJS規(guī)范中, 存在require()方法,這個(gè)方法接受模塊標(biāo)識(shí), 以此引用一個(gè)模塊的API到當(dāng)前上下文中

const math = require('math')

require(moduleId)函數(shù)用于在當(dāng)前模塊中加載和使用別的模塊,傳入一個(gè)模塊標(biāo)識(shí),返回一個(gè)模塊導(dǎo)出對(duì)象

'1':{ 
        [Function: require]
        resolve: { [Function: resolve] paths: [Function: paths] },
        main:
          Module {
              id: '.',
              exports: {},
              parent: null,
              filename: 'C:\\Users\\HiWin10\\Desktop\\study\\app.js',
              loaded: false,
              children: [Array],
              paths: [Array] },
              extensions:[Object: null prototype] { 
                  '.js': [Function], 
                  '.json': [Function], 
                  '.node': [Function] 
              },
              cache:[Object: null prototype] {
                 'C:\\Users\\HiWin10\\Desktop\\study\\app.js': [Module],
                 'C:\\Users\\HiWin10\\Desktop\\study\\wu.js': [Module] 
              } 
         },
}

./.表示當(dāng)前目錄,模塊文件路徑的js后綴可以省略

var foo = require('./foo'); // 當(dāng)前目錄下面的foo.js文件
var foo2 = require('./foo.js')

導(dǎo)入如果不加后綴名 ,會(huì)先找js文件,如果沒有js文件 會(huì)找json文件

注意:

  1. 引入模塊文件有語法錯(cuò)誤時(shí)會(huì)報(bào)錯(cuò)
  2. 引入模塊不存在時(shí)會(huì)報(bào)錯(cuò)
  3. 重復(fù)引入模塊只會(huì)執(zhí)行一次(返回值會(huì)被緩存起來)
  4. 所有的模塊如果沒有返回值,導(dǎo)入的模塊中將返回空對(duì)象
  5. 導(dǎo)入自定義模塊必須加'./' 因?yàn)樵趎ode.js中查找 模塊默認(rèn)是在node_modules目錄中查找的
  6. 如果引入第三方模塊,直接寫模塊的名字就可以了require("jquery")


3.1.1 主模塊main

require有一個(gè)屬性main來確定當(dāng)前模塊是不是主模塊,應(yīng)該應(yīng)用程序中, 通過node啟動(dòng)的模塊就是應(yīng)用模塊,也叫主模塊

console.log(module == require.main)  // true表示當(dāng)前模塊是主模塊, false表示當(dāng)前模塊不是主模塊


3.1.2 require.resolve() 方法獲取絕對(duì)路徑

require.resolve()方法 傳入一個(gè)相對(duì)路徑參數(shù),返回拼接后的絕對(duì)路徑

console.log(require.resolve("./module"))


3.1.3 require.cache 屬性

require.cache屬性值是一個(gè)對(duì)象,緩存了所有已經(jīng)被加載的模塊

console.log(require.cache)


3.1.4 require.extensions屬性

require.extensions屬性值是一個(gè)對(duì)象,用于引入路徑省略后綴名時(shí),按照extension標(biāo)識(shí)的后綴查找

console.log(require.extensions)


3.2 模塊的定義

在模塊上下文提供了exports對(duì)象用于導(dǎo)出當(dāng)前模塊的方法或者變量, 并且它是唯一導(dǎo)出出口, 在模塊中還存在一個(gè)module對(duì)象, 它代表模塊自身.而exports是module的屬性.

3.2.1 查看導(dǎo)出對(duì)象

在模塊中通過打印當(dāng)前模塊的信息來查看module對(duì)象與exports對(duì)象

console.log(arguments)
console.log(arguments.callee.toString); // 打印函數(shù)體

打印的arguments對(duì)象

[Arguments] {
    '0': {},
    '1':{ 
        [Function: require]
        resolve: { [Function: resolve] paths: [Function: paths] },
        main:
          Module {
              id: '.',
              exports: {},
              parent: null,
              filename: 'C:\\Users\\HiWin10\\Desktop\\study\\app.js',
              loaded: false,
              children: [Array],
              paths: [Array] },
              extensions:[Object: null prototype] { 
                  '.js': [Function], 
                  '.json': [Function], 
                  '.node': [Function] 
              },
              cache:[Object: null prototype] {
                 'C:\\Users\\HiWin10\\Desktop\\study\\app.js': [Module],
                 'C:\\Users\\HiWin10\\Desktop\\study\\wu.js': [Module] 
              } 
         },
    '2':
        Module {
            id: '.',
            exports: {},
            parent: null,
            filename: 'C:\\Users\\HiWin10\\Desktop\\study\\app.js',
            loaded: false,
            children: [ [Module] ],
            paths:[
                'C:\\Users\\HiWin10\\Desktop\\study\\node_modules',
                'C:\\Users\\HiWin10\\Desktop\\node_modules',
                'C:\\Users\\HiWin10\\node_modules',
                'C:\\Users\\node_modules',
                'C:\\node_modules' 
            ] 
        },
                                                          
      '3': 'C:\\Users\\HiWin10\\Desktop\\study\\app.js',
      '4': 'C:\\Users\\HiWin10\\Desktop\\study' 
}

打印的函數(shù)體

function (exports, require, module, __filename, __dirname) {    
    console.log(arguments.callee.toString())
}

所有用戶編寫的代碼都自動(dòng)封裝一個(gè)函數(shù)中,函數(shù)有五個(gè)參數(shù),我們就可以在函數(shù)內(nèi)部使用五個(gè)實(shí)參


模塊中的五個(gè)參數(shù)

  1. exports 暴露對(duì)象,可以將模塊中的數(shù)據(jù)暴露給引入的地方
  2. require 引入模塊的函數(shù),用于在一個(gè)模塊中引入另外一個(gè)模塊,并且將子模塊暴露的數(shù)據(jù) 賦值給變量
  3. module 模塊對(duì)象包含了模塊的所有信息(當(dāng)前模塊信息)
  4. __filename 當(dāng)前模塊的文件名
  5. __dirname 當(dāng)前模塊所在 的路徑


3.2.2 exports 導(dǎo)出對(duì)象

exports 對(duì)象是當(dāng)前模塊的導(dǎo)出對(duì)象,用于導(dǎo)出模塊共有的方法和屬性,別的模塊在通過require函數(shù)導(dǎo)入使用當(dāng)前模塊時(shí)就會(huì)獲得當(dāng)前模塊的exports 對(duì)象

ps:例子

exports.hello = function(){
    console.log("hello World")
}

注意事項(xiàng):

  1. exports 是module.exports對(duì)象的引用
  2. exports 不能改指向,只能添加屬性和方法

如果希望更改暴露指向,那么我 們就需要使用modeule.exports進(jìn)行暴露

var aa = function(){
    console.log(11)
}
module.exports = aa;


3.2.3 module 模塊對(duì)象(重中之重)
'2':
    Module {
        id: '.',    // 模塊的id ,模塊的名稱,  .代表主模塊(其他模塊,id就是模塊的文件路徑)
        exports: {},    // 當(dāng)前模塊導(dǎo)出的內(nèi)容(重點(diǎn),其他了解)
        parent: null,   // 引入當(dāng)前模塊的父模塊,
        path: '' ,   // 當(dāng)前文件夾的例子
        filename: 'C:\\Users\\HiWin10\\Desktop\\study\\app.js', //當(dāng)前模塊文件路徑
        loaded: false, 
        children: [ [Module] ],   // 子模塊
        paths:[      // 默認(rèn)模塊查找路徑,當(dāng)前目錄找不到,就當(dāng)上一層文件夾找
            'C:\\Users\\HiWin10\\Desktop\\study\\node_modules',
            'C:\\Users\\HiWin10\\Desktop\\node_modules',
            'C:\\Users\\HiWin10\\node_modules',
            'C:\\Users\\node_modules',
            'C:\\node_modules' 
        ] 
    },

module對(duì)象可以訪問到當(dāng)前模塊的一些相關(guān)信息,但最多的用途是替換當(dāng)前模塊導(dǎo)出的對(duì)象

module.exports = {}

例如默認(rèn)的導(dǎo)出對(duì)象是一個(gè)對(duì)象,我們可以改變,讓導(dǎo)出對(duì)象為普通的函數(shù)或其他數(shù)據(jù)類型的值

module.exports = function(){
    console.log('hello world')
}

module.exports 真正的暴露對(duì)象,exports只是對(duì)module.exports的引用


3.3 模塊標(biāo)識(shí)

模塊標(biāo)識(shí)其實(shí)就是傳遞給require()方法的參數(shù).它必須是符合小駝峰命名的字符串, 或者以.,.. 開頭的相對(duì)路徑,或者絕對(duì)路徑


4. CommonJS模塊分類

4.1 模塊的分類
  1. 系統(tǒng)模塊
    NodeJS開發(fā) 團(tuán)隊(duì)已經(jīng)開發(fā)了很多功能模塊,不需要安裝,直接 引入就可以使用
  2. 第三方模塊
    第三模塊必須先安裝在使用
    使用包管理工具npm進(jìn)行安裝
    第三方模塊在npmjs.org中搜素
  3. 自定義模塊
    自己寫的一個(gè)js文件就是一個(gè)模塊



也有將模塊分成兩種的

  1. 核心模塊(系統(tǒng)模塊)
  2. 文件模塊,(包括第三方模塊和自定義模塊)


還有按照模塊功能按照關(guān)系劃分為以下兩類

  1. 主模塊
    主模塊就是被node執(zhí)行的入口模塊,通常喜歡命名app.js main.js index.js
    一個(gè)項(xiàng)目只能有一個(gè)主模塊(也叫入口文件,就是整個(gè)項(xiàng)目的啟動(dòng)模塊)
  2. 依賴模塊


4.2 內(nèi)置模塊

NodeJs中的內(nèi)置了很多模塊,可以直接使用require來進(jìn)行引用.國(guó)際慣例,你接受的名字最好和模塊的名字一樣

const http = reqire('http')

如果特別長(zhǎng)可以簡(jiǎn)寫

const qs = require('querystring')

內(nèi)置模塊的引用是無條件的,無路徑的


4.3 自定義模塊

自定義模塊就是自己寫的一個(gè)模塊文件

每一個(gè)js文件都是一個(gè)模塊,Node.js使用commonjs規(guī)范

定義a模塊

// a.js
var str = '這個(gè)是一個(gè)字符串'
exports.str = str;   // exports 是導(dǎo)出(也可以叫暴露)對(duì)象

定義b模塊導(dǎo)入a模塊

// b.js
var aa = require('./a.js');
// 此時(shí)aa是a模塊中暴露對(duì)象,如果要使用暴露的字符串str,
console.log(aa.str)

然后通過node執(zhí)行b.js

node b.js

會(huì)發(fā)現(xiàn)require()誰,就會(huì)執(zhí)行誰,會(huì)讓a.js文件執(zhí)行

注意點(diǎn):

  1. 會(huì)發(fā)現(xiàn)require()誰,就會(huì)執(zhí)行誰,會(huì)讓a.js文件執(zhí)行
  2. require()引入的模塊如果有異步語句,不會(huì)死等,會(huì)將所有的同步執(zhí)行完畢后在執(zhí)行異步語句
  3. 如果是多層引用會(huì)先把引入文件里的引入執(zhí)行干凈了
  4. 如果循環(huán)引用.A引用B,B引入A,Node會(huì)很智能的組織好第二次引入


注意: 每一個(gè)模塊中的js代碼盡在模塊第一次使用時(shí)執(zhí)行一次,并在執(zhí)行過程中初始化模塊的導(dǎo)出對(duì)象,之后,會(huì)將導(dǎo)出對(duì)象緩存起來,被重復(fù)利用


5. NodeJS 作用域

5.1. 作用域

作用域: 規(guī)定一個(gè)變量和函數(shù)可以使用的范圍,作用域分為兩種,全局作用域和局部作用域

在Node中,每一個(gè)js文件都是單獨(dú)的作用域,因?yàn)閚ode的模塊化會(huì)將每一個(gè)文件中的代碼封裝在一個(gè)函數(shù)內(nèi)部,這和瀏覽器開發(fā)不同,瀏覽器中,var a,此時(shí)a會(huì)自動(dòng)成為window的屬性,此時(shí)js文件和js文件共享作用域,但是Node.js中,每個(gè)js文件是獨(dú)立的作用域不共享,所以Node中每一個(gè)文件中的變量都是私有的.

比如我們編寫一下代碼

var num = 10

NodeJS會(huì)在執(zhí)行之前,編譯這個(gè)模塊為

function (exports,require,module,__filename,__dirname){
    var num = 10
}


5.2. 暴露(導(dǎo)出)

所以,如果讓其他作用域使用本作用域中的值呢.我們采用暴露的方式將值拋出去: 也就是暴露共享的數(shù)據(jù)

暴露數(shù)據(jù)

module.exports = { num: 10}

使用exports暴露

// test.js
var a = 100;
exports.a = a;
// exports是一個(gè)對(duì)象,給這個(gè)對(duì)象添加了一個(gè)屬性a,a的值就是本作用域的變量值

此時(shí)當(dāng)我們通過require引入test.js的時(shí)候,就可以拿到這個(gè)屬性啊的值

// b.js
var test = require('./test.js');
// 此時(shí)text是引入的對(duì)象,就是exports對(duì)象,所以如果要獲取a的值應(yīng)該用
// test.a
console.log(test.a)

注意,模塊叫test文件,定義接受的變量名也叫test.其他名字不會(huì)報(bào)錯(cuò),但是我們不會(huì)這么做

使用module.exports 暴露數(shù)據(jù)

剛才我們使用了exports像外暴露一些值,但是很不方便,這個(gè)東西還必須是exports的屬性,require()導(dǎo)入的時(shí)候,返回的是一個(gè)對(duì)象我們還得去對(duì)象里那屬性和方法,如果僅僅只能暴露一個(gè)東西,我希望向外暴露一個(gè)類,此時(shí)就很不方便

// 到處類 Person.js
function Person(name,age,sex){
  this.name = name;
  this.age = age;
  this.sex = sex;
}
exports.Person = Person;

導(dǎo)入

var Person = require(./Person.js);
// 此時(shí)的Person是exports對(duì)象,如果想使用這個(gè)類,得Person.Person()使用
var xiaoming = new Person.Person('小明',12,'男')

此時(shí)就會(huì)發(fā)現(xiàn)使用很不方便

如果js里僅僅只暴露一個(gè)東西,我們可以使用module.exports來暴露

這樣module.export暴露的是什么,那么require()導(dǎo)入返回的就是什么

module.exports暴露一個(gè)東西,exports暴露多個(gè)東西

// 到處類 Person.js
function Person(name,age,sex){
  this.name = name;
  this.age = age;
  this.sex = sex;
}
module.exports = Person;

導(dǎo)入

var Person = require(./Person.js);
// 如果采用抵module.exports暴露的,這里Person就是暴露的那個(gè)類,所以餓哦們可以直接使用
var xiaoming = new Person('小明',12,'男')

這樣在使用的時(shí)候就方便很多


5.3. 定義為全局變量

在模塊中通過global全局對(duì)象定義全局?jǐn)?shù)據(jù)

var username = 'wuwei
global.name = username

使用時(shí)可以不寫global

    console.log(name)


6. 模塊的共性

所有的模塊化都有一個(gè)共性,模塊的功能都是把代碼放到一個(gè)獨(dú)立的函數(shù)中

  1. 模塊中使用的var 定義變量都是局部變量
  2. 模塊中定義的函數(shù)也是局部的
  3. 模塊有一個(gè)模塊對(duì)象,包含moduleName(模塊名),exports(導(dǎo)出對(duì)象)
  4. 如果模塊中需要 暴露方法或者屬性給外部使用,那么就是像exports對(duì)象上添加
  5. 導(dǎo)入一個(gè)模塊使用require('moduleName'),改方法返回的是模塊對(duì)象的exports對(duì)象
var aa = require('./a.js')


7. 關(guān)于路徑與后綴名情況

/ 表示絕對(duì)路徑

./ 表示當(dāng)前路徑

如果在引入模塊是不傳入后綴名, 會(huì)按照.js, .json, .node后綴名順序查找, 都找不到就報(bào)錯(cuò)

如果不寫路徑則認(rèn)為是內(nèi)置模塊或各級(jí)node_modules文件夾中的第三方模塊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市待德,隨后出現(xiàn)的幾起案子兄世,更是在濱河造成了極大的恐慌围详,老刑警劉巖七蜘,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異花履,居然都是意外死亡鸽粉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門聋呢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苗踪,“玉大人,你說我怎么就攤上這事削锰⊥ú” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵器贩,是天一觀的道長(zhǎng)颅夺。 經(jīng)常有香客問我,道長(zhǎng)蛹稍,這世上最難降的妖魔是什么碗啄? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮稳摄,結(jié)果婚禮上稚字,老公的妹妹穿的比我還像新娘。我一直安慰自己厦酬,他們只是感情好胆描,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仗阅,像睡著了一般昌讲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上减噪,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天短绸,我揣著相機(jī)與錄音,去河邊找鬼筹裕。 笑死醋闭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朝卒。 我是一名探鬼主播证逻,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼抗斤!你這毒婦竟也來了囚企?” 一聲冷哼從身側(cè)響起丈咐,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎龙宏,沒想到半個(gè)月后棵逊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡银酗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年辆影,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片花吟。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秸歧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衅澈,到底是詐尸還是另有隱情键菱,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布今布,位于F島的核電站经备,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏部默。R本人自食惡果不足惜侵蒙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望傅蹂。 院中可真熱鬧纷闺,春花似錦、人聲如沸份蝴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婚夫。三九已至浸卦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間案糙,已是汗流浹背限嫌。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留时捌,地道東北人怒医。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像匣椰,于是被迫代替她去往敵國(guó)和親裆熙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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