從搭建vue-腳手架到掌握webpack配置(三.多頁(yè)面構(gòu)建)

前言

上一期中我們通過(guò)引入了插件實(shí)現(xiàn)了不少功能——樣式抽離、公共模塊提取、代碼壓縮等等;本期開(kāi)始講講可能會(huì)用到的第三方編譯器的配置和多入口的優(yōu)化。

本期重點(diǎn):postcss和.babelrc配置多入口多頁(yè)面代碼提取優(yōu)化

往期鏈接:

從搭建vue-腳手架到掌握webpack配置(一.基礎(chǔ)配置)

從搭建vue-腳手架到掌握webpack配置(二.插件與提取)

小小題外話(huà)

本系列文章寫(xiě)到了第三篇,Jason我發(fā)現(xiàn)了這系列的文章有一個(gè)很大的缺陷,文章和前面的文章存在著耦合,可能會(huì)導(dǎo)致知識(shí)點(diǎn)存在線(xiàn)性的關(guān)聯(lián),對(duì)于有基礎(chǔ)的朋友來(lái)說(shuō),又要從第一期開(kāi)始閱讀的話(huà),比較不友好。
所以后面的文章開(kāi)始Jason會(huì)嘗試獨(dú)立知識(shí)點(diǎn),盡量回歸知識(shí)點(diǎn)的運(yùn)用上;在文章的開(kāi)頭也會(huì)說(shuō)明本期的主要內(nèi)容;當(dāng)然一些插件和loader的進(jìn)階使用還是要有基礎(chǔ)的,初學(xué)者還是建議從頭過(guò)一遍。

使用postcss

postcss介紹

postcss官方的GitHub上還有中文的介紹。

PostCSS 是一個(gè)允許使用 JS 插件轉(zhuǎn)換樣式的工具。 這些插件可以檢查(lint)你的 CSS,支持 CSS Variables 和 Mixins, 編譯尚未被瀏覽器廣泛支持的先進(jìn)的 CSS 語(yǔ)法,內(nèi)聯(lián)圖片,以及其它很多優(yōu)秀的功能。

簡(jiǎn)單來(lái)說(shuō)postcss就是一個(gè)css的轉(zhuǎn)換器,有了postcss或許你就不用再用less和sass了,通過(guò)在postcss上添加插件可以組裝出你需要的語(yǔ)法需求和功能(屬性變量,父子嵌套,版本兼容等),在postcss上通常會(huì)用的插件有cssnext、Autoprefixer、postcss-import。甚至可以在postcss上用less或sass編譯器

用法

這里就用添加Autoprefixer(自動(dòng)兼容瀏覽器)為例簡(jiǎn)單講講postcss的配置方法,有幾種配置方法

  • 使用配置文件配置 postcss.config.js或.postcssrc.js
  • 使用post-loader的時(shí)候通過(guò)options配置項(xiàng)配置

建議是使用配置文件進(jìn)行配置,這樣可以在所有調(diào)用到postcss-loader的地方使用同樣的配置

!值得一提的是其實(shí)vue-loader是默認(rèn)啟用了postcss-loader的,所以vue-loader的官方文檔里面有直接設(shè)置postcss配置項(xiàng)的選項(xiàng)。

所以在有vue-loader的項(xiàng)目里面其實(shí)是不用手動(dòng)安裝npm install -save-dev postcss-loader的,不是vue項(xiàng)目就裝吧。

只要在css的loaders里面添加vue-style-loader,就會(huì)自動(dòng)啟用postcss了,如下

{
    test:/\.less$/,
    use:[
        'vue-style-loader',
        'css-loader',
        'less-loader'
    ]
    })
},
{
    test:/\.vue$/,
    loader:'vue-loader',
    options:{
        loaders:{
            'css': [
                'vue-style-loader',
                'css-loader',
            ],
            'less': [
                'vue-style-loader',
                'css-loader',
                'less-loader'
            ]
        },
        //postcss:{}//vue-loader還自帶了這一選項(xiàng),但是建議用配置文件進(jìn)行配置
    }
}

引入 Autoprefixer :

  • 需要安裝 autoprefixer插件哦:npm install --save-dev autoprefixer
  • 新建.postcssrc.js文件在跟目錄下,內(nèi)容如下
module.exports = {
  "plugins": {
    //"postcss-import": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {}
  }
}

autoprefixer對(duì)應(yīng)的對(duì)象{},是該插件的配置項(xiàng),有需要可以查閱文檔進(jìn)行配置;postcss-import插件是@import是可以引本地的文件,如node_modules內(nèi)的文件,英文好的去看看該插件介紹。既然vue-cli用了postcss-import我們也這樣用吧,記得安裝npm install --save-dev postcss-import

autoprefixer會(huì)去檢查package.json里的browserslist 配置項(xiàng)作為兼容瀏覽器版本的范圍

//在package.json上添加這一項(xiàng)
"browserslist": [
    "> 5%",
    "last 2 versions",
    "not ie <= 8"
  ]

我們這里就簡(jiǎn)單的引入了autoprefixer,沒(méi)有做過(guò)多的配置,如果對(duì)postcss感興趣的話(huà)可以去看看下面文檔

.babelrc配置

在使用es6語(yǔ)法編寫(xiě)js的時(shí)候,我們都會(huì)在webpack上用babel-loader轉(zhuǎn)換js文件,而.bablrc就是babel編譯js時(shí)用的的規(guī)則和插件的配置規(guī)范

像postcss一樣在根目錄下創(chuàng)建名為.babelrc的文件(沒(méi)有.js后綴)

{
  "presets": [
    ["env", {
       "modules": false ,
       "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-3"
  ]
}

安裝依賴(lài):

npm install --save-dev babel-presets-env babel-presets-stage-0 

babel-preset-env,本依賴(lài)插件是設(shè)置編譯環(huán)境的插件,如果直接引入不設(shè)置規(guī)則那實(shí)際它和引入babel-preset-latest一樣,會(huì)囊括es2015、es2016、es2017。

'modules':false:設(shè)置模塊引用規(guī)則,可以設(shè)置成"amd" | "umd" | "systemjs" | "commonjs" | false, defaults to "commonjs",設(shè)置了false,就是用es6以上默認(rèn)的規(guī)則。

targets.browsers:設(shè)置兼容的瀏覽器范圍

tage-3依賴(lài),ES7不同階段語(yǔ)法提案的轉(zhuǎn)碼規(guī)則(共有4個(gè)階段),選裝一個(gè)

babel-presets-stage-0  babel-presets-stage-1
babel-presets-stage-2  babel-presets-stage-3
其他

還可以在里面添加插件實(shí)現(xiàn)更多的功能,如添加react的jsx編譯。像官方給出的示例代碼一樣

{
  "presets":["env"]
  "plugins": ["transform-react-jsx"],
  "ignore": [
    "foo.js",
    "bar/**/*.js"
  ]
}

畢竟這不是babelrc的教程,更高級(jí)的使用可以去以下的鏈接去深入學(xué)習(xí)。

鏈接

好了,整個(gè)個(gè)系列到目前為止常常會(huì)用到的webpack配置、loader、插件、編譯器都使用過(guò)了。

后面開(kāi)始就要按照需求,改進(jìn)我們的自動(dòng)化構(gòu)建配置了。

多頁(yè)面、多入口

很多用vue或者react工程環(huán)境都會(huì)默認(rèn)是spa(單頁(yè)應(yīng)用),但是業(yè)界上也有很多項(xiàng)目?jī)A向于使用vue等框架的組件化功能,但是并不引入router模塊,而是使用傳統(tǒng)的路由鏈接;尤其是視頻網(wǎng)站、購(gòu)物網(wǎng)站等pc端的網(wǎng)頁(yè)是不會(huì)做成spa的。所以在一個(gè)工程中編輯和生成多個(gè)頁(yè)面是必須的情況。

在src目錄下新建home.js文件(內(nèi)容和main.js一樣就行),在webpack的entry項(xiàng)設(shè)置多個(gè)入口是最方便快捷的方法。

entry:{
    app:'./src/main.js',
    home:'./src/home.js'
},
output:{
    path:path.resolve(__dirname,'./dist'),
    filename:"js/[name].js",
},

entry對(duì)應(yīng)不同的頁(yè)面設(shè)置不同的入口文件,output.filename要寫(xiě)成[name]以chunk名命名的形式

看似簡(jiǎn)單,但是我們之前用到公共代碼提取(CommonsChunkPlugin)和css抽離(ExtractTextPlugin)會(huì)把整個(gè)項(xiàng)目中的代碼打包到一起會(huì)影響頁(yè)面的加載。所以我們要改進(jìn)他的邏輯

css分頁(yè)面拆分

這個(gè)很簡(jiǎn)單,只要在實(shí)例化ExtractTextPlugin插件的同時(shí)添加一個(gè)allchunks:true參數(shù)就可以了,還有就是把輸出都指向一個(gè)css文件,用``[name]```區(qū)分chunk名

const ExtractVueCss = new ExtractTextPlugin({filename:'styles/[name]-style.css',allChunks:true});

按照我的習(xí)慣,先分出一份公共樣式(root.css),其他的按chunk的數(shù)量進(jìn)行分割,所以root.css的allchunks:false,其他的true

const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const ExtractRootCss = new ExtractTextPlugin({filename:'styles/[name]-root.css',allChunks:false});
const ExtractVueCss = new ExtractTextPlugin({filename:'styles/[name]-style.css',allChunks:true});

module.exports = {
    //other options...
    module:{
        rules:[
        //...
            {
                test:/\.css$/,
                //這里用的ExtractRootCss,輸出到root.css
                use:ExtractRootCss.extract({
                    fallback:'style-loader',
                    use:['css-loader']
                })
            },
            {
                test:/\.less$/,
                //這里用的ExtractRootCss,輸出到root.css
                use:ExtractRootCss.extract({
                    fallback:'style-loader',
                    use:[
                        'css-loader',
                        'less-loader'
                    ]
                })
            },
            {
                test:/\.vue$/,
                loader:'vue-loader',
                options:{
                    loaders:{
                        //這里用的ExtractVueCss
                        'css': ExtractVueCss.extract({
                            use: 'css-loader',
                            fallback: 'vue-style-loader' 
                          }),
                        //這里用的ExtractVueCss
                        'less':
                        ExtractVueCss.extract({
                            use:[
                                'css-loader',
                                'less-loader'
                            ],
                            fallback:'vue-style-loader'
                        })
                    },
                }
            },
        ]
    },
    plugins:[
        //填入插件實(shí)例,記得按順序填入
        ExtractRootCss,//root.css
        ExtractVueCss,//vue內(nèi)的css
        new webpack.HotModuleReplacementPlugin(),
    ]
}

多頁(yè)面公共提取

不懂commons-chunk-plugin,又不想看以前的文章的話(huà)看左邊鏈接

之前我們把node_modules內(nèi)的模塊抽取到了vender.js里面。

//抽取從node_modules引入的模塊,如vue,vue-router
new webpack.optimize.CommonsChunkPlugin({
    name: 'vender',
    minChunks:function(module,count){
        var sPath = module.resource;
        // console.log(sPath,count);
        //匹配 node_modules文件目錄
        return sPath &&
            /\.js$/.test(sPath) &&
            sPath.indexOf(
                path.join(__dirname, 'node_modules')
            ) === 0
    }
}),

上上面設(shè)置了多個(gè)入口chunk,而且output的時(shí)候也不是設(shè)置成唯一的文件名,這樣webpack打包的時(shí)候會(huì)自動(dòng)按照入口chunk的數(shù)量生成相應(yīng)數(shù)量的代碼包,按目前情況會(huì)有app.js和home.js。

但是問(wèn)題在于每個(gè)chunk都會(huì)把所有他們用到的模塊單獨(dú)打包起來(lái)。比如app和home用到一樣的header.vue模塊,webpack都會(huì)分別打包到app.js和home.js里面。多次復(fù)用的模塊最好是可以抽取出來(lái),在首頁(yè)加載過(guò)js文件之后得到了緩存,在詳情頁(yè)能馬上得到提升頁(yè)面加載速度。

為了解決以上問(wèn)題,我們?cè)偌右粋€(gè)公共代碼提取的實(shí)例

new webpack.optimize.CommonsChunkPlugin({
    name:'common'
    minChunks:2
}),

這樣每個(gè)頁(yè)面(入口chunk)中引入超過(guò)兩次的模塊就會(huì)打包到common.js文件下面。

minChunks2代表所有chunk中復(fù)用超過(guò)2以上的模塊會(huì)被提取。寫(xiě)成2粒度最小,你可以按自己需求修改。

(5.20更新) 實(shí)際項(xiàng)目上發(fā)現(xiàn),單一入口的時(shí)候,vendor.js并沒(méi)有被抽離,原因可能是單一入口時(shí)common沒(méi)被提前導(dǎo)致的(具體原因請(qǐng)大神指教),所以我們要再做一步入口數(shù)量判斷

Object.keys(config.page).length >= 2 
    ? new webpack.optimize.CommonsChunkPlugin({
            name: 'common',
            minChunks:2
        }):()=>{},
抽取webpack的運(yùn)行時(shí)邏輯

參考vue-cli,我們會(huì)認(rèn)為webpack的加載調(diào)度等運(yùn)行時(shí)(runtime)邏輯是不會(huì)頻繁修改的,所以我們把這部分抽離出來(lái)方面以后的頁(yè)面都調(diào)用它。這樣的話(huà)我們?cè)诩右粋€(gè)CommonsChunkPlugin實(shí)例,用于抽取這些邏輯。

new webpack.optimize.CommonsChunkPlugin({
    name:'common'
    minChunks:2
}),
new webpack.optimize.CommonsChunkPlugin({
    name: 'vender',
    minChunks:function(module,count){
        var sPath = module.resource;
        return sPath &&
            /\.js$/.test(sPath) &&
            sPath.indexOf(
                path.join(__dirname, 'node_modules')
            ) === 0
    }
}),
//將webpack runtime 和一些復(fù)用部分抽取出來(lái)
new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    minChunks:Infinity
}),

!注意!這里插件是有引入順序的,順序不對(duì)可能會(huì)導(dǎo)致操作被覆蓋。

minChunksInfinity什么chunk都不抽取出來(lái),只抽取webpack的runtime等邏輯。

抽取異步公共模塊

在開(kāi)發(fā)vue或者react的時(shí)候可能會(huì)用到異步加載模塊的能力(又叫懶加載),比如import()webpack require.ensure功能異步加載的模塊。vue項(xiàng)目通常是vue-router懶加載組件的時(shí)候用到。

雖然做多頁(yè)開(kāi)發(fā)的時(shí)候不一定會(huì)用到vue-router,但是我們讓構(gòu)建配置更健壯那就適配到spa的情況,把異步公共模塊的提取也加進(jìn)去

// 放到上面三個(gè)CommonsChunkPlugin的最后

new webpack.optimize.CommonsChunkPlugin({
    // names: ["app", "subPageA"]
    // (選擇 chunks,或者忽略該項(xiàng)設(shè)置以選擇全部 chunks)
    async: 'vendor-async',
    children: true,
    minChunks:2
}),

沒(méi)有給name的話(huà)就會(huì)默認(rèn)選擇所有入口chunk。

async:可以使true或者字符串,字符串的話(huà)就是生成的公共chunk的名字。(這個(gè)選項(xiàng)一直沒(méi)搞懂,直到看到了這文章Webpack 大法之 Code Splitting

children:選擇所有被選 chunks 的子 chunks

minChunks:大于等于兩個(gè)chunk復(fù)用的子模塊會(huì)提取到該公共chunk

中文文檔下面的示例有介紹 link

改寫(xiě)生成的html模板

同樣,懶得看上期文章,又不懂HtmlWebpackPlugin的同學(xué)點(diǎn)這里

HtmlWebpackPlugin插件在上一期中用到了,但是我們只是簡(jiǎn)單的設(shè)置了模板文件和出口文件。插件會(huì)默認(rèn)把所有輸出的chunk包和css文件都引入到生成的模板中。我們?nèi)缦滦薷囊幌虏寮呐渲?/p>

plugins:[
        new HtmlWebpackPlugin({
            filename:'index.html',
            title:'vue demo',
            // favicon:'./src/images/logo.png',
            template:'./index.html',
            chunks:['app','vender','manifest','common'],
            chunksSortMode: 'dependency'
        }),
        new HtmlWebpackPlugin({
            filename:'home.html',
            title:'vue home',
            template:'./index.html',
            chunks:['home','vender','manifest','common'],
            chunksSortMode: 'dependency'
        }),
    ]

filename:生成的文件名,區(qū)分頁(yè)面起對(duì)應(yīng)的名字

template:html模板來(lái)源,應(yīng)為是vue 項(xiàng)目所以用同樣的模板,你可以按自己的需要來(lái)設(shè)置

chunks:關(guān)鍵的來(lái)了,這個(gè)就是把本模板關(guān)聯(lián)的chunks列舉出來(lái)的參數(shù),我把各種的入口chunk和提取出來(lái)的公共chunk填入了。

chunksSortMode:chunk的引入順序,'dependency'按依賴(lài)關(guān)系映入

build一下

運(yùn)行npm run build,生成的dist文件目錄結(jié)構(gòu)如下

dist目錄

并沒(méi)有成產(chǎn)vendor-async.js異步公共模塊是因?yàn)轫?xiàng)目中還沒(méi)有用到異步加載的部分

到目前為止完整的webpack.config.js文件可以到這 下載

ps

Jason建議看別人的webpack配置時(shí)遇到不懂的插件多多查 npmjs 或者社區(qū)論壇,有時(shí)間看看去webpack官方介紹的插件或許里面有有你需要的

Jason水平有限,如果有什么地方的知識(shí)點(diǎn)有錯(cuò)誤請(qǐng)大家多多提點(diǎn),在評(píng)論中告訴我。

下期預(yù)告

上一期的webpack配置完后完全可以應(yīng)付單頁(yè)應(yīng)用的構(gòu)建,而這一期還適應(yīng)了多頁(yè)面的構(gòu)建需求,而且還學(xué)會(huì)了postcss和babelrc的基礎(chǔ)配置方法。是不是感覺(jué)越來(lái)越接近vue-cli創(chuàng)建的項(xiàng)目了呢?

引入了多頁(yè)面的構(gòu)建思想后,我們發(fā)現(xiàn)如果我們的頁(yè)面不斷的增加就要不斷的給webpack.config.js添加插件和邏輯。所以為了方便和易用性,下一期我們來(lái)嘗試寫(xiě)一些封裝邏輯把構(gòu)建配置封裝起來(lái),用一個(gè)文件整合常用的配置項(xiàng)統(tǒng)一對(duì)工程進(jìn)行配置。

下一期可能不會(huì)很快能更新,一方面因?yàn)槭稚嫌惺虑橐Γ硪环矫嬲?xiàng)目我還沒(méi)有封裝測(cè)試好(這也正是為什么一直沒(méi)有給出github的原因),所以請(qǐng)有關(guān)注本系列的同學(xué)可能要等等了,有需要的同學(xué)也可以關(guān)注我的賬號(hào)留意更新。

參考

https://github.com/postcss/postcss/blob/HEAD/README.cn.md

PostCSS配置指北.md

PostCSS 是個(gè)什么鬼東西?

html-webpack-plugin用法全解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,746評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,991評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,036評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,203評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,266評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,606評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,407評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評(píng)論 2 380