03-webpack核心基礎(chǔ)-loader

什么是loader?


webapck的本質(zhì)是一個模塊打包工具, 所以webpack默認(rèn)只能處理JS文件,不能處理其他文件,
因為其他文件中沒有模塊的概念, 但是在企業(yè)開發(fā)中我們除了需要對JS進(jìn)行打包以外,
還有可能需要對圖片/CSS等進(jìn)行打包, 所以為了能夠讓webpack能夠?qū)ζ渌奈募愋瓦M(jìn)行打包,
在打包之前就必須將其它類型文件轉(zhuǎn)換為webpack能夠識別處理的模塊,
用于將其它類型文件轉(zhuǎn)換為webpack能夠識別處理模塊的工具我們就稱之為loader

如何使用loader


一般loader的使用方式分為三種:
1:在配置文件webpack.config.js中配置

module.exports = {
  // 單個 loader 的配置
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {}
          }
        ]
      }
    ]
  }
  // 多個 loader 的配置
  module: {
    rules: [
      {
        // 增加對 SCSS 文件的支持
        test: /\.scss/,
        // SCSS 文件的處理順序為先 sass-loader 再 css-loader 再 style-loader
        use: [
          'style-loader',
          {
            loader:'css-loader',
            // 給 css-loader 傳入配置項
            options:{
              minimize:true, 
            }
          },
          'sass-loader'],
      },
    ]
  }
}

2:通過命令行參數(shù)方式

webpack --module-bind 'txt=raw-loader'

3:通過內(nèi)聯(lián)使用

import txt from 'raw-loader!./file.txt';

webpack常用的loader


  • 樣式:style-loader、css-loader、less-loader拍鲤、sass-loader等
  • 文件:raw-loader腕铸、file-loader 、url-loader等
  • 編譯:babel-loader橡娄、coffee-loader 、ts-loader等
  • 校驗測試:mocha-loader、jshint-loader 盾似、eslint-loader等

file-loader


中文文檔

1. 安裝file-loader
npm install --save-dev file-loader
2. 在webpack.config.js中配置file-loader

webpack.config.js

module.exports = {
  // module: 告訴webpack如何處理webpack不能夠識別的文件
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {}
          }
        ]
      }
    ]
  }
}
3. 其他配置(options)
  1. 默認(rèn)情況下fileloader生成的圖片名就是文件內(nèi)容的 MD5 哈希值
    如何想打包后不修改圖片的名稱, 那么可以新增配置 name: "[name].[ext]"
    其它命名規(guī)則詳見: placeholders

  2. 默認(rèn)情況下fileloader會將生成的圖片放到dist根目錄下面
    如果想打包之后放到指定目錄下面, 那么可以新增配置 outputPath: "images/"

  3. 如果需要將圖片托管到其它服務(wù)器, 那么只需在打包之前配置 publicPath: "托管服務(wù)器地址"即可

例如:

module: {
        rules: [
            {
                test: /\.(png|jpg|gif)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: "[name].[ext]",
                            outputPath: "images/",
                            publicPath: "http://www.baidu.com/images/"
                        }
                    }
                ]
            }
        ]
    }

url-loader


中文文檔
url-loader 功能類似于 file-loader,
但是在文件大醒┍辍(單位 byte)低于指定的限制時零院,可以返回一個 DataURL

1. 安裝urlloader
npm install --save-dev url-loader
2. 配置urlloader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              // limit: 指定圖片限制的大小
              limit: 1024*100,
              // 指定打包后的文件名稱
              name: "[name].[ext]",
              // 指定打包后文件存放目錄
              outputPath: "images/"
            }
          }
        ]
      }
    ]
  }
}

【注意】
如果被打包的圖片超過了限制的大小, 就會將圖片保存為一個文件
如果被打包的圖片沒有超過限制的大小, 就會將圖片轉(zhuǎn)換成base64的字符串

對于比較小的圖片, 我們將圖片轉(zhuǎn)換成base64的字符串之后, 可以提升網(wǎng)頁的性能(因為減少了請求的次數(shù))
對于比較大的圖片, 哪怕我們將圖片轉(zhuǎn)換成了base64的字符串之后, 也不會提升網(wǎng)頁的性能, 還有可能降低網(wǎng)頁的性能(因為圖片如果比較大, 那么轉(zhuǎn)換之后的字符串也會比較多, 那么網(wǎng)頁的體積就會變大, 那么訪問的速度就會變慢)

優(yōu)勢:
圖片比較小的時候直接轉(zhuǎn)換成base64字符串圖片, 減少請求次數(shù)
圖片比較大的時候由于生成的base64字符串圖片也比較大, 就保持原有的圖片

html-withimg-loader


我們通過file-loader或者url-loader已經(jīng)可以將JS或者CSS中用到的圖片打包到指定目錄中了
但是file-loader或者url-loader并不能將HTML中用到的圖片打包到指定目錄中
所以此時我們就需要再借助一個名稱叫做"html-withimg-loader"的加載器來實現(xiàn)HTML中圖片的打包
參考文檔

1. 安裝html-withimg-loader
npm install html-withimg-loader --save
2. 配置html-withimg-loader

webpack.config.js

{
    test: /\.(htm|html)$/i,
    loader: 'html-withimg-loader'
}

image-webpack-loader 和 img-loader(壓縮圖片)


在開發(fā)中為了提升網(wǎng)頁的訪問速度, 我們除了會壓縮HTML/CSS/JS以外,還會對網(wǎng)頁上的圖片進(jìn)行壓縮汰聋, 壓縮可以減少網(wǎng)頁體積门粪。
image-webpack-loader 和 img-loader都可以壓縮打包之后的圖片, 這里我們選擇image-webpack-loader 演示
參考文檔: image-webpack-loaderimg-loader

1. 安裝image-webpack-loader
npm install image-webpack-loader --save-dev
2. 配置image-webpack-loader

webpack.config.js

rules: [{
  test: /\.(gif|png|jpe?g|svg)$/i,
  use: [
    'file-loader',
    {
      loader: 'image-webpack-loader',
      options: {
        mozjpeg: {
          progressive: true,
          quality: 65
        },
        // optipng.enabled: false will disable optipng
        optipng: {
          enabled: false,
        },
        pngquant: {
          quality: [0.65, 0.90],
          speed: 4
        },
        gifsicle: {
          interlaced: false,
        },
        // the webp option will enable WEBP
        webp: {
          quality: 75
        }
      }
    },
  ],
}]

postcss-sprites和webpack-spritesmith(合并圖片)


過去為了減少網(wǎng)頁請求的次數(shù), 我們需要"UI設(shè)計師"給我們提供精靈圖, 并且在使用時還需要手動的去設(shè)置每張圖片的位置烹困。但是有了webpack之后我們只需要讓"UI設(shè)計師"給我們提供切割好的圖片玄妈,我們可以自己合成精靈圖, 并且還不用手動去設(shè)置圖片的位置
postcss-sprites和webpack-spritesmith都可以合并圖片, 這里只介紹postcss-sprites
參考文檔: postcss-spriteswebpack-spritesmith

1. 安裝postcss-sprites
npm install --save-dev postcss
npm install --save-dev postcss-sprites
2. 配置postcss-sprites

postcss.config.js

module.exports = {
    plugins: {
        "postcss-sprites": {
            // 告訴webpack合并之后的圖片保存到什么地方
            spritePath: "./bundle/images",
            // 告訴webpack合并圖片的時候如何分組
            groupBy: function (image) {
                let path = image.url.substr(0, image.url.lastIndexOf('/'));
                let name = path.substr(path.lastIndexOf("/") + 1);
                return  Promise.resolve(name);
            },
            // 告訴webpack哪些圖片需要合并, 哪些圖片不需要合并
            filterBy: function (image) {
                let path = image.url;
                // 如果不是以png結(jié)尾的圖片就不合并
                // 這里的過濾規(guī)則可以自定義
                if (!/\.png$/.test(path)){
                    return Promise.reject();
                } 
                // 如果是以png結(jié)尾的圖片就合并
                return Promise.resolve();
            } 
        }
    }
};

iconfot-loader(打包字體圖標(biāo))


如何打包字體圖標(biāo)

字體圖標(biāo)中也用到了url用到了文件, 所以我們需要通過file-loader來處理字體圖標(biāo)文件
webpack.config.js

{
    test: /\.(eot|svg|ttf|woff|woff2)$/,
    use:[{
        loader: "file-loader",
        options: {
            name: "[name].[ext]",
            outputPath: "font/",
        }
    }]
}

css-loader


和圖片一樣webpack默認(rèn)能不能處理CSS文件, 所以也需要借助loader將CSS文件轉(zhuǎn)換為webpack能夠處理的類型

1. 安裝css-oader
npm install --save-dev css-loader
2. 安裝style-loader
npm install style-loader --save-dev
3. 配置css-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ]
      }
    ]
  }
}

css-loader和style-loader作用

css-loader: 解析css文件中的@import依賴關(guān)系
style-loader: 將webpack處理之后的內(nèi)容插入到HTML的HEAD代碼中

css-loader模塊化


默認(rèn)情況下通過import "./xxx.css"導(dǎo)入的樣式是全局樣式, 也就是只要被導(dǎo)入, 在其它文件中也可以使用髓梅。如果想要導(dǎo)入的CSS文件只在導(dǎo)入的文件中有效, 那么就需要開啟CSS模塊化

目的:局部組件引入局部css樣式,實現(xiàn)css模塊化開發(fā); 減免全局污染

操作
  • 啟用css modules
    webpack.config.js
{
    loader: "css-loader",
    options: {
        modules: true // 開啟CSS模塊化
    }
}
  • 使用css modules
    導(dǎo)入的地方通過 import xxx from "./xxx.css"導(dǎo)入
    在使用的地方通過 xxx.className方式使用即可, "xxx"是一個對象
    例如:
import cssModule from "./index.css";

oImg.setAttribute("class", cssModule.size);

less-loader


將Less文件轉(zhuǎn)換為webpack能夠處理的類型

1. 安裝less-loader
npm install --save-dev less-loader less
2. 配置less-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [ 'style-loader', 'css-loader' , 'less-loader']
      }
    ]
  }
}

sass-loader


將SASS/SCSS文件轉(zhuǎn)換為webpack能夠處理的類型

1. 安裝sass-loader
npm install sass-loader node-sass webpack --save-dev

如果安裝的時候報錯, 可以嘗試執(zhí)行nrm use cnpm將npm源改為cnpm

2. 配置sass-loader

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(sass|scss)$/,
        use: [ 'style-loader', 'css-loader' , 'sass-loader']
      }
    ]
  }
}

postcss-loader


1. 什么是PostCSS?

官網(wǎng)
PostCSS 是目前流行的一個對 CSS 進(jìn)行處理的工具拟蜻。
PostCSS和sass/less不同, 它不是CSS預(yù)處理器, 它是一款使用插件去轉(zhuǎn)換CSS的工具,它負(fù)責(zé)進(jìn)一步處理 CSS 文件枯饿,比如自動補(bǔ)全瀏覽器前綴酝锅,自動把px代為轉(zhuǎn)換成rem 等。

PostCSS有許多非常好用的插件, PostCSS 依托其強(qiáng)大的插件體系為 CSS 處理增加了無窮的可能性奢方。

2. autoprefixer(自動補(bǔ)全瀏覽器前綴)
  • 安裝postcss-loader
npm i -D postcss-loader
  • 安裝autoprefixer插件
npm i -D autoprefixer
  • 配置postcss-loader
    在css-loader or less-loader or sass-loader之后添加postcss-loader
    webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
        ]
      }
    ]
  }
}
  • 創(chuàng)建并配置postcss-loader配置文件
    postcss.config.js
module.exports = {
    plugins: {
        "autoprefixer": {
            "overrideBrowserslist": [
                "ie >= 8", // 兼容IE7以上瀏覽器
                "Firefox >= 3.5", // 兼容火狐版本號大于3.5瀏覽器
                "chrome  >= 35", // 兼容谷歌版本號大于35瀏覽器,
                "opera >= 11.5", // 兼容歐朋版本號大于11.5瀏覽器,
            ]
        }
    }
};
3. postcss-pxtorem(自動把px代為轉(zhuǎn)換成rem)
  • 安裝postcss-loader
npm i -D postcss-loader
  • 安裝postcss-pxtorem
npm install postcss-pxtorem -D
  • 在配置文件中配置postcss-pxtorem
    postcss.config.js
module.exports = {
    plugins: {
        "postcss-pxtorem": {
            rootValue: 100, // 根元素字體大小
            // propList: ["*"]   // 可以從px更改到rem的屬性
            propList: ["height"]   
        }
    }
};

postcss-pxtorem常用參數(shù)配置:

  • rootValue (Number) root 元素的字體大小搔扁。
  • unitPrecision (Number) 允許REM單位增長到的十進(jìn)制數(shù)。
  • propList ( array ) 可以從px更改到rem的屬性蟋字。
    值需要精確匹配稿蹲。
    使用通配符 * 啟用所有屬性。 示例:[ ' * ' ]
    在單詞的開頭或者結(jié)尾使用 鹊奖。 ( [ ' position ' ] 將匹配 background-position-y )
    使用 與屬性不匹配苛聘。! 示例:[' letter-spacing ']!
    將"非"前綴與其他前綴合并。 示例:['
    ', 'font*']!
  • selectorBlackList ( array ) 要忽略和離開的選擇器。
    如果值為字符串设哗,它將檢查選擇器是否包含字符串唱捣。
    ['body'] 將匹配 .body-class
    如果值為 regexp,它將檢查選擇器是否匹配正則表達(dá)式网梢。
    [/^body$/] 將匹配 body震缭,但不匹配 .body
  • replace (Boolean) 替代包含rems的規(guī)則,而不是添加回退澎粟。
  • mediaQuery (Boolean) 允許在媒體查詢中轉(zhuǎn)換 px蛀序。
  • minPixelValue (Number) 設(shè)置要替換的最小像素值。

eslint


ESLint 是一個插件化的 javascript 代碼檢測工具活烙,它可以用于檢查常見的 JavaScript 代碼錯誤徐裸,也可以進(jìn)行"代碼規(guī)范"檢查,在開發(fā)中項目負(fù)責(zé)人會定制一套 ESLint 規(guī)則啸盏,然后應(yīng)用到所編寫的項目上重贺,從而實現(xiàn)輔助編碼規(guī)范的執(zhí)行,有效控制項目代碼的質(zhì)量回懦。在編譯打包時如果語法有錯或者有不符合規(guī)范的語法就會報錯, 并且會提示相關(guān)錯誤信息
參考文檔: eslint-loader气笙、eslint中文文檔

  • 安裝對應(yīng)環(huán)境和loader
npm install eslint --save-dev
npm install eslint-loader --save-dev
  • 配置文件
    webpack.config.js
module.exports = {
  // ...
  module: {
    rules: [
      // 檢查編碼規(guī)范的規(guī)則
      {
        test: /\.js$/,
        // 讓當(dāng)前的loader在其他loader之前執(zhí)行
        enforce: pre,
        // 過濾 node_modules 文件夾
        exclude: /node_modules/,
        // 只檢查src目錄
        include: path.resolve(__dirname, "src"),
        loader: 'eslint-loader',
        options: {
          // 檢查代碼時發(fā)現(xiàn)不符合規(guī)范的代碼會自動修復(fù)
          fix: true
        },
      },
    ],
  },
  // ...
};
module.exports = {
  /*
  不重要,永遠(yuǎn)寫true
  * */
  root: true,
  parserOptions: {
    // parser: 'babel-eslint',
    /*
    默認(rèn)設(shè)置為 3,5(默認(rèn))怯晕, 你可以使用 6潜圃、7、8舟茶、9 或 10 來指定你想要使用的 ECMAScript 版本
    * */
    "ecmaVersion": 10,
    /*
    設(shè)置為 "script" (默認(rèn)) 或 "module"(如果你的代碼是 ECMAScript 模塊)谭期。
    * */
    "sourceType": "module",
    /*
    ecmaFeatures - 這是個對象,表示你想使用的額外的語言特性:
    globalReturn - 允許在全局作用域下使用 return 語句
    impliedStrict - 啟用全局 strict mode (如果 ecmaVersion 是 5 或更高)
    jsx - 啟用 JSX
    * */
    "ecmaFeatures": {}
  },
  // 指定代碼運行的宿主環(huán)境
  env: {
    browser: true, // 瀏覽器
    node: true, // node
    /*
    支持 ES6 語法并不意味著同時支持新的 ES6 全局變量或類型(比如 Set 等新類型)吧凉。
    對于 ES6 語法隧出,使用 { "parserOptions": { "ecmaVersion": 6 } }
    * */
    es6: true,
  },
  extends: [
      /*
      引入standard代碼規(guī)范
      * */
    // https://github.com/standard/standard/blob/master/docs/README-zhcn.md
    'standard'
  ],
  /*
  擴(kuò)展或覆蓋規(guī)則
  * */
  rules: {
    // 強(qiáng)制語句結(jié)束添加,分號
    semi: ["error", "always"],
    // 強(qiáng)制縮進(jìn)2個空格
    indent: ["error", 4],
    // 方法名和刮號之間不加空格
    'space-before-function-paren': ['error', 'never'],
    "no-unexpected-multiline": "off"
  }
};

如果要使用standard代碼規(guī)范, 還必須安裝它

npm install standard --save-dev
  • 如何自動修復(fù)不符合規(guī)范的代碼
  1. webpack.config.js配置文件的規(guī)則中新增fix: true
options: {
    // 檢查代碼時發(fā)現(xiàn)不符合規(guī)范的代碼會自動修復(fù)
    fix: true
},

弊端: 只能在打包的時候自動修復(fù)

  1. 借助webstorm
    可以在編寫代碼的時候修復(fù)不符合規(guī)范的代碼
    在webstorm的sitting中搜索eslint, 選中手動配置



    選中自己編寫的規(guī)則



    發(fā)現(xiàn)自己在編寫代碼的時候出現(xiàn)了紅線提示, 可以右鍵鼠標(biāo)選擇最后一個, 就會自動修改不符合規(guī)則的代碼

loader特點:


1. 單一原則, 一個loader只做一件事情
2. 多個loader會按照從右至左, 從下至上的順序執(zhí)行

例如: 從右至左

      [ 'style-loader', 'css-loader' ]

先執(zhí)行css-loader解析css文件關(guān)系拿到所有內(nèi)容,
再執(zhí)行style-loader將內(nèi)容插入到HTML的HEAD代碼中

例如: 從下至上

    [{
        loader: "style-loader"
    },{
        loader: "css-loader"
    }]

先執(zhí)行css-loader解析css文件關(guān)系拿到所有內(nèi)容,
再執(zhí)行style-loader將內(nèi)容插入到HTML的HEAD代碼中

如果一個源文件需要經(jīng)歷多步轉(zhuǎn)換才能正常使用阀捅,就通過多個 Loader 去轉(zhuǎn)換胀瞪。
在調(diào)用多個 Loader 去轉(zhuǎn)換一個文件時,每個 Loader 會鏈?zhǔn)降捻樞驁?zhí)行饲鄙,
第一個 Loader 將會拿到需處理的原內(nèi)容凄诞,上一個 Loader 處理后的結(jié)果會傳給下一個接著處理,最后的 Loader 將處理后的最終結(jié)果返回給 Webpack忍级。
所以帆谍,在你開發(fā)一個 Loader 時,請保持其職責(zé)的單一性颤练,你只需關(guān)心輸入和輸出。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嗦玖,隨后出現(xiàn)的幾起案子患雇,更是在濱河造成了極大的恐慌,老刑警劉巖宇挫,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件苛吱,死亡現(xiàn)場離奇詭異,居然都是意外死亡器瘪,警方通過查閱死者的電腦和手機(jī)翠储,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來橡疼,“玉大人援所,你說我怎么就攤上這事⌒莱” “怎么了住拭?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長历帚。 經(jīng)常有香客問我滔岳,道長,這世上最難降的妖魔是什么挽牢? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任谱煤,我火速辦了婚禮,結(jié)果婚禮上禽拔,老公的妹妹穿的比我還像新娘刘离。我一直安慰自己,他們只是感情好奏赘,可當(dāng)我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布寥闪。 她就那樣靜靜地躺著,像睡著了一般磨淌。 火紅的嫁衣襯著肌膚如雪疲憋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天梁只,我揣著相機(jī)與錄音缚柳,去河邊找鬼。 笑死搪锣,一個胖子當(dāng)著我的面吹牛秋忙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播构舟,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼灰追,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起弹澎,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朴下,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苦蒿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殴胧,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年佩迟,在試婚紗的時候發(fā)現(xiàn)自己被綠了团滥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡报强,死狀恐怖灸姊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躺涝,我是刑警寧澤厨钻,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坚嗜,受9級特大地震影響夯膀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苍蔬,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一诱建、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碟绑,春花似錦俺猿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凯肋,卻和暖如春谊惭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侮东。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工圈盔, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悄雅。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓驱敲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宽闲。 傳聞我的和親對象是個殘疾皇子众眨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,884評論 2 354

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