30分鐘快速過(guò)一遍Webpack4核心知識(shí)

1规个、webpack和webpack-dev-server區(qū)別

webpack 每次會(huì)生成一個(gè)bundle.js文件岭皂,webpack-dev-server不會(huì)存捺,只是將打包結(jié)果放在內(nèi)存中贼邓,并不會(huì)寫(xiě)入實(shí)際的bundle.js,在每次webpack-dev-server接收到請(qǐng)求時(shí)热鞍,都將內(nèi)存中的打包結(jié)果返回給瀏覽器葫慎。

2、webpack-cli安裝后可以直接在控制臺(tái)調(diào)用webpack命令

3薇宠、url-loader 和 file-loader

url-loaderfile-loader都可以用來(lái)作為打包圖片的loader

  • url-loader不會(huì)生成一個(gè)具體的圖片文件偷办,而是直接在需要這個(gè)圖片src地址的地方給出圖片的base64地址,這樣比較適合幾k大小的小圖澄港,減少http請(qǐng)求椒涯;url-loader有個(gè)limit設(shè)置一個(gè)numer,單位是bytes回梧,如果圖片大于這個(gè)limit值废岂,則默認(rèn)使用file-loader, 如果小于則使用url-loader
  • file-loader會(huì)生成一個(gè)圖片文件,適合大點(diǎn)的圖片

4狱意、style-loader作用主要是將css放到dom中

官方英文解釋很到位:Adds CSS to the DOM by injecting a <style> tag

如果配置style-loader/url湖苞,則會(huì)生成一個(gè)類(lèi)似<link rel="stylesheet" href="path/to/file.css">這樣的內(nèi)聯(lián)css。

5详囤、postcss-loader與Autoprefixer一起财骨,用來(lái)適配各大瀏覽器廠(chǎng)商css前綴

  • 需要配置postcss.config.js,和安裝autoprefixer

6藏姐、resolve配置

  • resolve.alias 設(shè)置別名來(lái)替換某個(gè)路徑隆箩,如:
resolve:{
  alias:{
    @: './src/components/'
  }
}

當(dāng)需要引入import './src/components/header'時(shí),可以寫(xiě)成import '@/header'

  • resolve.extensions 設(shè)置引入文件的擴(kuò)展格式羔杨,當(dāng)引入文件省略了后綴名時(shí)候捌臊,會(huì)按照設(shè)置的resolve.extensions去相應(yīng)路徑匹配對(duì)應(yīng)格式的文件,默認(rèn)是['js', 'json']问畅,如果是react項(xiàng)目可以設(shè)置:extensions: ['.jsx', '.js', '.json']

7娃属、模塊樣化處理

{
  loader: 'css-loader',
  options: {
    importLoaders: 2,
    modules: true,
  },
},

如上在配置css-loader時(shí)候,配置modules: true

但一般出路antd的樣式時(shí)候护姆,需要做兩手處理:

{
    test: /\.less$/,
    include: /node_modules\/antd/,
    use: [
        'style-loader',
        { loader: 'css-loader', options: {modules: false} },
        'less-loader'
    ]
},
{
    test: /\.less$/,
    exclude: /node_modules\/antd/,
    use: [
        'style-loader',
        { loader: 'css-loader', options: {modules: true} },
        'less-loader'
    ]
}

這樣避免了 css-modules 對(duì) antd 的樣式進(jìn)行處理矾端,否則會(huì)造成antd 的樣式的不匹配。

8卵皂、iconfont字體打包

{
    test: /\.(eot|ttf|svg|woff)$/,
     use: {
        loader: 'file-loader',
    },
}

如上示例秩铆,打包.eot, .ttf等字體文件

9、html-webpack-plugin

  • 會(huì)在打包完成后灯变,自動(dòng)生成一個(gè)html文件殴玛,并把打包生成的js自動(dòng)引入到這個(gè)html中
  • 如果希望打包出來(lái)的html是按照要求配置的,如加上<div id="root"></div>添祸,那么就可以在HtmlWebpackPlugin配置中加入template指定一個(gè)模板文件

10滚粟、clean-webpack-plugin

  • 清除打包數(shù)據(jù)
  • clean-webpack-plugin v3.0以上版本,不需要添加額外配置項(xiàng)刃泌,默認(rèn)清除的文件是output.path指定的路徑文件夾內(nèi)容

11凡壤、output.publicPath

  • output中配置publicPath,如一個(gè)路徑或者一個(gè)cdn地址耙替,然后打包出來(lái)的資源會(huì)自動(dòng)加上這個(gè)publicPath前綴亚侠,如加上一個(gè)cdn的host后,打包出來(lái)的script的src會(huì)在文件名前加上這個(gè)cdn地址俗扇。

12硝烂、source-map

  • souce-map是源代碼和打包后的代碼的一個(gè)映射關(guān)系,對(duì)應(yīng)的webpack配置是devtool铜幽,可以快速定位錯(cuò)誤行代碼滞谢。
  • devtoolmode=development中一般配置,devtool:cheap-module-eval-source-map除抛,這樣既可以定位錯(cuò)誤正確的位置爹凹,同時(shí)打包速度也不會(huì)太受影響。
  • devtoolmode=production中一般配置镶殷,devtool:cheap-module-source-map禾酱。
  • devtool設(shè)置了source-map會(huì)生成一個(gè).map映射文件;
  • 設(shè)置了帶inline绘趋,則會(huì)將映射文件內(nèi)容放到打包文件里颤陶,不會(huì)單獨(dú)生成.map映射文件;
  • 設(shè)置了帶cheap的配置只會(huì)提示行不提示列錯(cuò)誤陷遮,同時(shí)只提示業(yè)務(wù)代碼滓走,不管loader的打包代碼;
  • 設(shè)置了帶module的是除了核心業(yè)務(wù)代碼帽馋,loader打包文件代碼也會(huì)提示錯(cuò)誤位置
  • 設(shè)置了帶eval的會(huì)提高打包速度搅方。

13比吭、devServer

  • 主要用于快速開(kāi)發(fā)應(yīng)用,提高開(kāi)發(fā)效率
  • 通過(guò)設(shè)置package.json中的stripts姨涡,"watch": "webpack --watch"衩藤,可以實(shí)現(xiàn)修改頁(yè)面代碼后自動(dòng)打包,但是沒(méi)法開(kāi)啟一個(gè)服務(wù)涛漂,這就不能滿(mǎn)足ajax(ajax必須在一個(gè)http服務(wù)里才能使用)調(diào)用服務(wù)等開(kāi)發(fā)需求了赏表,此時(shí)需要webpack-dev-server
  • webpack-dev-server打包出來(lái)的文件不會(huì)放到原先的dist或者配置好的output路徑,而是放到了本地電腦內(nèi)存中匈仗,這樣提升打包速度
  • 配置contentBase瓢剿,告訴服務(wù)器從哪個(gè)目錄中提供內(nèi)容,填寫(xiě)output的path就可以了
  • 配置open悠轩,設(shè)為true時(shí)devserver啟動(dòng)后自動(dòng)打開(kāi)瀏覽器
  • 配置port间狂,可以修改開(kāi)啟服務(wù)的端口號(hào)
  • 配置proxy,如果現(xiàn)在在http://localhost:3000上有服務(wù)端的話(huà)火架,可以設(shè)置proxy: {'/api': 'http://localhost:3000'}前标,這樣在本地的非3000端口host上請(qǐng)求/api/info接口,實(shí)際是請(qǐng)求了http://localhost:3000/api/info距潘,否則會(huì)報(bào)跨域錯(cuò)誤
  • 如果不用 webpack-dev-server炼列,可以通過(guò) webpack-dev-middleware 和express/koa2寫(xiě)一個(gè)server.js的服務(wù),然后啟動(dòng)這個(gè)服務(wù)音比,可以達(dá)到和 webpack-dev-server 一樣的修改后自動(dòng)更新等效果

14俭尖、hot-module-replacement

  • 當(dāng)添加了 webpack-dev-server 之后,那么每次有代碼修改時(shí)洞翩,就會(huì)重新請(qǐng)求頁(yè)面稽犁,然后刷新頁(yè)面,但這有個(gè)小問(wèn)題骚亿,就是即便一個(gè)css顏色值修改了已亥,頁(yè)面也會(huì)重新刷新,加入hot-module-replacement可以簡(jiǎn)化這個(gè)請(qǐng)求過(guò)程来屠。
  • 首先在devServer中加入 hot:true虑椎,然后在 plugins 中加入new webpack.HotModuleReplacementPlugin()配置,這樣僅僅只能做到css樣式的無(wú)刷新修改
  • 如果需要js也能無(wú)刷新修改俱笛,則需要在js中加入module.hot的判斷捆姜,判斷的對(duì)應(yīng)結(jié)果中需要更新代碼,使用 module.hot.accept 將其綁定到新的函數(shù)執(zhí)行中迎膜,詳見(jiàn)https://webpack.docschina.org/guides/hot-module-replacement/#%E5%90%AF%E7%94%A8-hmr
  • 具體針對(duì)前端不同框架泥技,社區(qū)有不同loader可以支持HMR,React Hot Loader磕仅,Vue loader

15珊豹、配置Babel

  • Babel主要是將es6+代碼轉(zhuǎn)換為es5代碼簸呈,讓低版本瀏覽器也能加載代碼
  • ① 最基本的設(shè)置是:

npm install --save-dev babel-loader @babel/core

webpack 設(shè)置:

module: {
  rules: [
    {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
    }
  ]
}

.babelrc 文件設(shè)置如下:

npm install @babel/preset-env --save-dev

{
    "presets": ["@babel/preset-env"]
}

但面對(duì)更低版本的瀏覽器的時(shí)候,像promise還需要轉(zhuǎn)化注入店茶,就需要引入babel/polyfill


  • npm install --save @babel/polyfill

在對(duì)應(yīng)業(yè)務(wù)js代碼文件開(kāi)頭引入polyfill import "@babel/polyfill";

但是這樣有個(gè)缺點(diǎn)蜕便,就是會(huì)把所有es6轉(zhuǎn)es5的需要的語(yǔ)法都給打包到對(duì)應(yīng)文件,造成打包文件過(guò)大忽妒。

如果需要按需去打包polyfill語(yǔ)法,根據(jù)代碼需要兼贸,可以設(shè)置文件 .babelrc

{
    "presets": [["@babel/preset-env", {
    "targets": {
        chrome: "67"
    },
    "useBuiltIns": "usage",
    }]],
}

上面配置中的 targets 中配置的瀏覽器版本段直,是指大于該版本的瀏覽器,根據(jù)該瀏覽器對(duì)es6的支持情況去有針對(duì)性的打包polyfill代碼溶诞,這樣可以讓打包文件變得更小一點(diǎn)鸯檬,比如如果chrome67以上的版本瀏覽器對(duì)promise支持很好,那么就不需要打包promise的語(yǔ)法了螺垢,更不需要對(duì)promise去轉(zhuǎn)碼喧务。

總的來(lái)說(shuō),polyfill修改了全局作用域枉圃,瀏覽器下是window功茴,node下是global。

babel-polyfill主要由兩部分組成孽亲,core-js和regenerator runtime坎穿。

core-js:提供了如ES5、ES6返劲、ES7等規(guī)范中 中新定義的各種對(duì)象玲昧、方法的模擬實(shí)現(xiàn)。
regenerator:提供generator支持篮绿,如果應(yīng)用代碼中用到generator孵延、async函數(shù)的話(huà)用到。

引入babel-polyfill全量包后文件會(huì)變得非常大亲配。

  • ③ 以上方式需要在對(duì)應(yīng)入口js文件開(kāi)頭引入polyfillimport "@babel/polyfill";
    這種方式會(huì)產(chǎn)生一些全局變量尘应,代碼量大了之后如寫(xiě)一個(gè)大型庫(kù)或者ui組件庫(kù)等全局變量會(huì)產(chǎn)生變量污染全局。這樣就需要用到 transform-runtime吼虎,它不會(huì)污染全局環(huán)境:

npm install --save-dev @babel/plugin-transform-runtime

npm install --save @babel/runtime @babel/runtime-corejs2

刪除對(duì)應(yīng)文件開(kāi)頭的引入 import "@babel/polyfill";

.babelrc 文件設(shè)置如下:

{
    "plugins": [["@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 2,
        "helpers": true,
        "regenerator": true,
        "useESModules": false,
      }]],
}

@babel/plugin-transform-runtime 會(huì)以閉包的形式

16菩收、Tree Shaking

  • Tree Shaking 用來(lái)檢測(cè)項(xiàng)目中沒(méi)有被引用的代碼(dead-code),Webpack會(huì)對(duì)這部分代碼進(jìn)行標(biāo)記鲸睛,然后在資源壓縮打包的時(shí)候娜饵,從打包出來(lái)的文件中去掉友绝,如下示例:
// outer.js

export const foo = () => {
  console.log('Fucked Up');
};

export const bar = () => {
  console.log('Beyond All Repair');
};

// index.js
import { foo } from './outer';

foo();

然后配置webpack.config.js文件橄唬,添加如下modeoptimization2個(gè)配置:

// webpack.config.js
mode: 'development',
optimization: {
    usedExports: true,
},

然后打包,打開(kāi)打包好的文件,可以看到如下部分:

/***/ "./src/outer.js":
/*!**********************!*\
  !*** ./src/outer.js ***!
  \**********************/
/*! exports provided: foo, bar */
/*! exports used: foo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return foo; });\n/* unused harmony export bar */\nvar foo = function foo() {\n  console.log('Fucked Up');\n};\nvar bar = function bar() {\n  console.log('Beyond All Repair');\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvb3V0ZXIuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvb3V0ZXIuanM/NGJlZiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgZm9vID0gKCkgPT4ge1xuICBjb25zb2xlLmxvZygnRnVja2VkIFVwJyk7XG59O1xuXG5leHBvcnQgY29uc3QgYmFyID0gKCkgPT4ge1xuICBjb25zb2xlLmxvZygnQmV5b25kIEFsbCBSZXBhaXInKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/outer.js\n");

/***/ })

其中有2行注釋說(shuō)明了:

/*! exports provided: foo, bar */
/*! exports used: foo */

就是打包文件中還是導(dǎo)出了foobar兩個(gè)方法铐然,但只用到了foo,這說(shuō)明在development中代碼的tree shaking只是找出來(lái)了并告知了羽峰,但并沒(méi)有真的去刪除這部分沒(méi)用到的代碼踊赠,webpack4新增了mode,將其設(shè)置為production后电湘,不用設(shè)置optimization隔节,就會(huì)真實(shí)執(zhí)行tree shaking

// webpack.config.js
mode: 'production',

因?yàn)樵O(shè)置了mode: 'production'后代碼被作了minify(壓縮)mangle(混淆破壞)foobar方法已經(jīng)搜不到了寂呛,但是方法體中的console內(nèi)容還是可以搜的怎诫,可以發(fā)現(xiàn),foo中的console內(nèi)容Fucked Up還可以搜到贷痪,而bar中的console內(nèi)容Beyond All Repair已經(jīng)搜不到了幻妓,因?yàn)橐呀?jīng)被刪除了。

webpack4新增了一個(gè)例外處理的口子劫拢,就是在package.json中配置一個(gè)sideEffects屬性肉津,來(lái)設(shè)置哪些文件是永遠(yuǎn)都不會(huì)被刪除掉的,如果設(shè)置了sideEffects: false舱沧,那么則會(huì)正常的刪除未被用到的代碼妹沙。如果設(shè)置了sideEffects: ["@babel/polly-fill"]則表明,即便@babel/polly-fill沒(méi)被直接應(yīng)用熟吏,但還是會(huì)在打包時(shí)初烘,將它打包進(jìn)來(lái)。

  • Tree Shaking的注意事項(xiàng)(來(lái)至官網(wǎng)):
    • 使用 ES2015 模塊語(yǔ)法(即 import 和 export)分俯。
    • 確保沒(méi)有 compiler 將 ES2015 模塊語(yǔ)法轉(zhuǎn)換為 CommonJS 模塊(這也是流行的 Babel preset 中 @babel/preset-env 的默認(rèn)行為)肾筐。
    • 在項(xiàng)目 package.json 文件中,添加一個(gè) "sideEffects" 屬性缸剪。
    • 通過(guò)將 mode 選項(xiàng)設(shè)置為 production 吗铐,啟用 minification (代碼壓縮) 和 tree shaking

17杏节、Mode: development/production

wenpack4新增了mode配置:

  • 設(shè)置mode: 'development'
    • 會(huì)將 process.env.NODE_ENV 的值設(shè)為 development
    • 啟用 NamedChunksPluginNamedModulesPlugin唬渗。
  • 設(shè)置mode: 'production'
    • 會(huì)將 process.env.NODE_ENV 的值設(shè)為 production
    • 啟用 FlagDependencyUsagePlugin
    • FlagIncludedChunksPlugin
    • ModuleConcatenationPlugin
    • NoEmitOnErrorsPlugin
    • OccurrenceOrderPlugin
    • SideEffectsFlagPlugin
    • UglifyJsPlugin
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市奋渔,隨后出現(xiàn)的幾起案子镊逝,更是在濱河造成了極大的恐慌,老刑警劉巖嫉鲸,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撑蒜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)座菠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)狸眼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人浴滴,你說(shuō)我怎么就攤上這事拓萌。” “怎么了升略?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵微王,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我品嚣,道長(zhǎng)炕倘,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任腰根,我火速辦了婚禮激才,結(jié)果婚禮上拓型,老公的妹妹穿的比我還像新娘额嘿。我一直安慰自己,他們只是感情好劣挫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布册养。 她就那樣靜靜地躺著,像睡著了一般压固。 火紅的嫁衣襯著肌膚如雪球拦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天帐我,我揣著相機(jī)與錄音坎炼,去河邊找鬼。 笑死拦键,一個(gè)胖子當(dāng)著我的面吹牛谣光,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芬为,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼萄金,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了媚朦?” 一聲冷哼從身側(cè)響起氧敢,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎询张,沒(méi)想到半個(gè)月后孙乖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年的圆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鼓拧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡越妈,死狀恐怖季俩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梅掠,我是刑警寧澤酌住,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站阎抒,受9級(jí)特大地震影響酪我,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜且叁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一都哭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逞带,春花似錦欺矫、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至遇汞,卻和暖如春未妹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背空入。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工络它, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歪赢。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓化戳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親轨淌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子迂烁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 如有好文, 請(qǐng)到此issue里提交文章,或者直接發(fā)pull request. ??webpack入門(mén) ??webpac...
    Creoa閱讀 2,233評(píng)論 0 30
  • webpack 優(yōu)秀中文文章 轉(zhuǎn)載 如有好文, 請(qǐng)到此issue里提交文章递鹉,或者直接發(fā)pull request. ...
    果汁密碼閱讀 1,046評(píng)論 0 6
  • 目錄第1章 webpack簡(jiǎn)介 11.1 webpack是什么盟步? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,731評(píng)論 0 1
  • 搜羅一切webpack的好文章好工具 Webpack webpack 優(yōu)秀中文文章如有好文, 請(qǐng)到此issue里提...
    Lefter閱讀 1,475評(píng)論 0 29
  • 有人動(dòng)不動(dòng)就拿老祖宗的話(huà)說(shuō)事,今天就遇到了一位黄橘。 其實(shí)老祖宗經(jīng)常是黑白不分的兆览,有人偏偏學(xué)會(huì)了這套把戲,我倒是覺(jué)得老...
    高手如林閱讀 593評(píng)論 0 3