【webpack】指南

官網(wǎng)指南地址

管理資源&管理輸出

管理資源

webpack 最出色的功能之一就是,除了 JavaScript擂仍,還可以通過 loader 引入任何其他類型的文件webpack.config.js配置如下:

 const path = require('path');
 module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
        {
            test: /\.css$/,
            use: [
                'style-loader',
                'css-loader'
            ]
        },
        {
            test: /\.(png|svg|jpg|gif)$/,
            use: [
                'file-loader'
            ]
        },
        {
            test: /\.(woff|woff2|eot|ttf|otf)$/,
            use: [
                'file-loader'
            ]
        },
        {
            test: /\.(csv|tsv)$/,
            use: [
               'csv-loader'
            ]
        },
        {
            test: /\.xml$/,
            use: [
               'xml-loader'
            ]
        }
      ]
    }
};

管理輸出

配置HtmlWebpackPlugin插件自動生成index.html;配置CleanWebpackPlugin插件自動清理dist目錄轧拄;WebpackManifestPlugin插件可以提取manifest挥下。webpack.config.js配置如下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: {
        app: './src/index.js',
        print: './src/print.js'
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
        title: 'Output Management'
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

開發(fā)環(huán)境&生產(chǎn)環(huán)境

  • 開發(fā)環(huán)境(development)和生產(chǎn)環(huán)境(production)的構(gòu)建目標(biāo)差異很大揍魂。
  • 在開發(fā)環(huán)境中,我們需要具有強大的棚瘟、具有實時重新加載(live reloading)或熱模塊替換(hot module replacement)能力的 source maplocalhost server现斋。
  • 而在生產(chǎn)環(huán)境中,我們的目標(biāo)則轉(zhuǎn)向于關(guān)注更小的 bundle偎蘸,更輕量的 source map庄蹋,以及更優(yōu)化的資源,以改善加載時間迷雪。
  • 由于要遵循邏輯分離限书,我們通常建議為每個環(huán)境編寫彼此獨立的 webpack 配置。
  • 但是章咧,我們會遵循不重復(fù)原則倦西,保留一個“通用”配置。我們將使用一個名為 webpack-merge 的工具合并配置
npm install --save-dev webpack-merge
image

開發(fā)模式&模塊熱替換

image

生產(chǎn)環(huán)境

  1. 代碼壓縮:UglifyJSPlugin或其他工具
  2. source map用還是不用赁严?
  3. 許多 library 將通過與 process.env.NODE_ENV 環(huán)境變量關(guān)聯(lián)扰柠,以決定 library 中應(yīng)該引用哪些內(nèi)容
new webpack.DefinePlugin({
   'process.env.NODE_ENV': JSON.stringify('production')
})
  1. ExtractTextPlugin:將 CSS 分離成單獨的文件
  2. CLI 替代選項:原來用的一些插件現(xiàn)在可以替換成一些優(yōu)化配置項:例如,--optimize-minimize 標(biāo)記將在后臺引用 UglifyJSPlugin疼约。和以上描述的 DefinePlugin 實例相同卤档,--define process.env.NODE_ENV="'production'" 也會做同樣的事情。并且程剥,webpack -p 將自動地調(diào)用上述這些標(biāo)記劝枣,從而調(diào)用需要引入的插件。

構(gòu)建性能

  1. 保持版本最新webpack/node/npm
  2. 盡量少使用不同的工具loader/plugins;必要的話也用在盡量最少數(shù)的必要模塊中哨免;可以將非常消耗資源的 loaders 轉(zhuǎn)存到 worker pool
//使用 include 字段僅將 loader 模塊應(yīng)用在實際需要用其轉(zhuǎn)換的位置中:
{
  test: /\.js$/,
  include: path.resolve(__dirname, "src"),
  loader: "babel-loader"
}
  1. Dlls:使用 DllPlugin更改不頻繁的代碼進行單獨編譯茎活。這將改善引用程序的編譯速度,即使它增加了構(gòu)建過程的復(fù)雜性琢唾。
  2. Smaller = Faster:減少編譯的整體大小载荔,以提高構(gòu)建性能。盡量保持 chunks 小巧采桃。
  3. 使用 cache-loader 啟用持久化緩存懒熙。使用 package.json 中的 postinstall 清除緩存目錄。thread-loader 可以將非常消耗資源的 loaders 轉(zhuǎn)存到 worker pool
  4. 提高解析速度:
    • 盡量減少 resolve.modules, resolve.extensions, resolve.mainFiles, resolve.descriptionFiles 中類目的數(shù)量普办,因為他們會增加文件系統(tǒng)調(diào)用的次數(shù)工扎。
    • 如果你不使用 symlinks ,可以設(shè)置 resolve.symlinks: false衔蹲。
    • 如果你使用自定義解析 plugins 肢娘,并且沒有指定 context 信息,可以設(shè)置 resolve.cacheWithContext: false 舆驶。
  5. 開發(fā)環(huán)境中
    • 硬避免在生產(chǎn)環(huán)境下才會用到的工具:UglifyJsPlugin橱健、ExtractTextPlugin、[hash]/[chunkhash]沙廉、AggressiveSplittingPlugin拘荡、AggressiveMergingPlugin、ModuleConcatenationPlugin
    • 不同的 devtool 的設(shè)置撬陵,會導(dǎo)致不同的性能差異
    • 在內(nèi)存中進行代碼的編譯和資源的提供珊皿,但并不寫入磁盤來提高性能:webpack-dev-server
    • 盡量減少入口 chunk 的體積,以提高性能
  6. 其他

tree shaking

tree shaking 是一個術(shù)語巨税,通常用于描述移除 JavaScript 上下文中的未引用代碼(dead-code)蟋定。新的 webpack 4 正式版本,擴展了這個檢測能力垢夹,通過 package.jsonsideEffects 屬性作為標(biāo)記溢吻,向 compiler 提供提示,表明項目中的哪些文件是 pure(純的 ES2015 模塊)"果元,由此可以安全地刪除文件中未使用的部分促王。

  1. sideEffects:將文件標(biāo)記為無副作用
    如同上面提到的,如果所有代碼都不包含副作用而晒,我們就可以簡單地將該屬性標(biāo)記為 false蝇狼,來告知 webpack,它可以安全地刪除未用到的 export 導(dǎo)出倡怎。
{
  "name": "your-project",
  "sideEffects": false
}

如果你的代碼確實有一些副作用迅耘,那么可以改為提供一個數(shù)組:

{
  "name": "your-project",
  "sideEffects": [
    "./src/some-side-effectful-file.js"
  ]
}
  1. 壓縮輸出:通過如上方式贱枣,我們可以,找出那些需要刪除的“未使用代碼”颤专,然而纽哥,我們不只是要找出,還需要在 bundle 中刪除它們栖秕。為此春塌,我們將使用 -p(production) 這個 webpack 編譯標(biāo)記,來啟用 uglifyjs 壓縮插件簇捍。
    • 注意只壳,--optimize-minimize 標(biāo)記也會在 webpack 內(nèi)部調(diào)用 UglifyJsPlugin。)
    • webpack 4 開始暑塑,也可以通過 mode 配置選項輕松切換到壓縮輸出吼句,只需設(shè)置為 production
      image

懶加載(動態(tài)導(dǎo)入/按需加載)

vue單頁應(yīng)用中事格,當(dāng)項目不斷完善豐富時惕艳,即使使用webpack打包,文件依然是非常大的分蓖,影響頁面的加載尔艇。如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊尔许,當(dāng)路由被訪問時才加載對應(yīng)的組件(也就是按需加載)么鹤,這樣就更加高效了∥独龋——引自vue-router官方文檔

非動態(tài)加載時的打包情況如下圖:

image

如下案例中hello組件的加載方式改為路由懶加載[import()語法],在進行打包

// import Hello from '@/components/Hello'
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      // component: Hello,
      component: () => import('@/components/Hello')
    }
  ]
})
image
  • 很明顯的看到蒸甜,打包后有4個js文件,仔細的同學(xué)還發(fā)現(xiàn)余佛,app.js文件的大小加上新多出文件的大小柠新,約等于沒有分割打包的app的大小。
  • 這樣等于異步加載的組件辉巡,是單獨打包成了一個js恨憎,在頁面首次加載的時候不需要加載他,等到請求相應(yīng)的頁面的時候在去服務(wù)器請求它郊楣,減小了頁面首屏加載的時間憔恳。
  • webpack.prod.conf.js 中配置 output.chunkFilename 規(guī)定了打包異步文件的格式
//webpack.prod.conf.js:生產(chǎn)打包js
//utils.assetsPath是utils.js中封裝的一個路徑相關(guān)的方法
output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    /**
        本人在自己的工程中刪除或修改chunkFilename的配置,
        最后還是都按這個規(guī)則生產(chǎn)js文件了净蚤,
        Why?
    */
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 
},
  • 不需要刻意懶加載钥组。下面的案例中,代碼確實會在腳本運行的時候產(chǎn)生一個分離的代碼塊 lodash.bundle.js今瀑,在技術(shù)概念上“懶加載”它程梦。問題是加載這個包并不需要用戶的交互 -- 意思是每次加載頁面的時候都會請求它点把。這樣做并沒有對我們有很多幫助,還會對性能產(chǎn)生負面影響屿附。
//src/index.js
- import _ from 'lodash';
-
- function component() {
+ function getComponent() {
-   var element = document.createElement('div');
-
-   // Lodash, now imported by this script
-   element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   return import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {
+     var element = document.createElement('div');
+
+     element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+
+     return element;
+
+   }).catch(error => 'An error occurred while loading the component');
  }

- document.body.appendChild(component());
+ getComponent().then(component => {
+   document.body.appendChild(component);
+ })
  • 當(dāng)頁面有個按鈕點擊事件時郎逃,需要加載某個組件,這種用戶交互的情景下挺份,我們可以使用懶加載衣厘;當(dāng)然,路由也是交互的一種压恒。

緩存

客戶端(通常是瀏覽器)獲取資源是比較耗費時間的影暴。可以通過命中緩存探赫,以降低網(wǎng)絡(luò)流量型宙,使網(wǎng)站加載速度更快;然而伦吠,緩存的存在可能會使你獲取新代碼時比較棘手(文件名不變的話)妆兑。如何通過必要的配置,以確保 webpack 編譯生成的文件能夠被客戶端緩存毛仪,而在文件內(nèi)容變化后搁嗓,能夠請求到新的文件

  • 通過使用 output.filename 進行文件名替換
    image
  • 如果我們不做修改箱靴,然后再次運行構(gòu)建腺逛,我們以為文件名會保持不變。然而衡怀,如果我們真的運行棍矛,可能會發(fā)現(xiàn)情況并非如此(譯注:如果不做修改,文件名可能會變抛杨,也可能不會够委。
  • 這也是因為 webpack 在入口 chunk 中,包含了某些樣板(boilerplate)怖现,特別是 runtimemanifest茁帽。譯注:樣板(boilerplate)指 webpack 運行時的引導(dǎo)代碼
  • 即:如果 webpack 生成的 hash 發(fā)生改變,manifest 文件也會發(fā)生改變屈嗤。因此潘拨,vendor bundle 的內(nèi)容也會發(fā)生改變,并且失效恢共。所以战秋,我們需要將 manifest 文件提取出來。
  • CommonsChunkPluginmanifest提取出來
    image
  • webpack 里每個模塊都有一個 module id 讨韭,module id 是該模塊在模塊依賴關(guān)系圖里按順序分配的序號脂信,如果這個 module id 發(fā)生了變化癣蟋,那么他的 chunkhash 也會發(fā)生變化。
  • 這樣會導(dǎo)致:如果你引入一個新的模塊狰闪,會導(dǎo)致module id 整體發(fā)生改變疯搅,可能會導(dǎo)致所有文件的chunkhash發(fā)生變化,這顯然不是我們想要的
  • 這里需要用 HashedModuleIdsPlugin埋泵,根據(jù)模塊的相對路徑生成一個四位數(shù)的hash作為模塊id幔欧,這樣就算引入了新的模塊,也不會影響 module id 的值丽声,只要模塊的路徑不改變的話礁蔗。
new webpack.HashedModuleIdsPlugin()

創(chuàng)建library

除了打包應(yīng)用程序代碼,webpack 還可以用于打包 JavaScript library雁社;即我們平時npm install下來的那種依賴包

我的demo:element-ui表單的二次封裝

image

最后浴井,package.json中配置"main": "dist/ginna-form.js";我們從node_modules引入時就靠這個屬性來找到對應(yīng)的文件的哦。


shimming

webpack 編譯器(compiler)能夠識別遵循 ES2015 模塊語法霉撵、CommonJSAMD 規(guī)范編寫的模塊磺浙。然而,一些第三方的庫(library)可能會引用一些全局依賴(例如 jQuery 中的 $)徒坡。這些庫也可能創(chuàng)建一些需要被導(dǎo)出的全局變量撕氧。 這些“不符合規(guī)范的模塊”就是 shimming 發(fā)揮作用的地方

shim:一種庫(library)的抽象,這種庫能將一個新的 API 引入到一個舊的環(huán)境中喇完,而且僅靠舊的環(huán)境中已有的手段實現(xiàn)伦泥。polyfill 就是一個用在瀏覽器 API 上的 shim

1. 讓jQuery作為全局變量何暮,可以被別的組件引用

image

2. 將模塊中的this置為window

當(dāng)模塊運行在 CommonJS 環(huán)境下this會變成一個問題奄喂,也就是說此時的 this 指向的是 module.exports。在這個例子中海洼,你可以通過使用 imports-loader 覆寫 this

image

3. 某個庫(library)創(chuàng)建出一個全局變量,它期望用戶使用這個變量

  • 你可能從來沒有在自己的源碼中做過這些事情富腊,但是你也許遇到過一個老舊的庫(library)坏逢,和下面所展示的代碼類似。
  • 在下圖用例中赘被,我們可以使用exports-loader是整,將一個全局變量作為一個普通的模塊來導(dǎo)出。例如民假,為了將 file 導(dǎo)出為 file 以及將 helpers.parse 導(dǎo)出為 parse
    image

4. babel-polyfill 按需加載

  • Babel是一個廣泛使用的轉(zhuǎn)碼器浮入,可以將ES6代碼轉(zhuǎn)為ES5代碼,從而可以在現(xiàn)有環(huán)境執(zhí)行羊异,所以我們可以用ES6編寫事秀,而不用考慮環(huán)境支持的問題彤断。
  • Babel默認(rèn)只轉(zhuǎn)換新的JavaScript語法(syntax),如箭頭函數(shù)等易迹,而不轉(zhuǎn)換新的API宰衙,比如Iterator、Generator睹欲、Set供炼、Maps、Proxy、Reflect策精、Symbol膏燕、Promise等全局對象,以及一些定義在全局對象上的方法(比如Object.assign)都不會轉(zhuǎn)碼先嬉;因此我們需要polyfill
    image

5. 深度優(yōu)化包babel-preset-env

  • babel-preset-env 是一個新的preset楚堤,可以根據(jù)配置的目標(biāo)運行環(huán)境(environment)自動啟用需要的 babel 插件
  • 之前我們寫 javascript 代碼時疫蔓,需要使用 Npreset,比如:babel-preset-es2015身冬、babel-preset-es2016衅胀。es2015 可以把 ES6 代碼編譯為 ES5es2016可以把 ES2016 代碼編譯為 ES6酥筝。babel-preset-latest 可以編譯 stage 4 進度的 ECMAScript 代碼滚躯。
  • 問題是我們幾乎每個項目中都使用了非常多的preset,包括不必要的嘿歌。
  • babel-preset-env 的工作方式類似 babel-preset-latest掸掏,唯一不同的就是它會根據(jù)配置的 env 只編譯那些還不支持的特性。
  • 使用這個插件宙帝,你講再也不需要使用 es20xx presets 了丧凤。

6. 其他工具

  • 還有一些其他的工具能夠幫助我們處理這些老舊的模塊。
  • script-loader 會在全局上下文中對代碼進行取值步脓,類似于通過一個 script 標(biāo)簽引入腳本愿待。在這種模式下,每一個標(biāo)準(zhǔn)的庫(library)都應(yīng)該能正常運行
  • 這些老舊的模塊如果沒有 AMD/CommonJS 規(guī)范版本靴患,但你也想將他們加入 dist 文件仍侥,你可以使用 noParse 來標(biāo)識出這個模塊
noParse:這是module中的一個屬性,
作用:不去解析屬性值代表的庫的依賴

舉例:
我們一般引用jquery鸳君,可以如下引用:
import jq from 'jquery'

對于上面的解析規(guī)則:
當(dāng)解析jq的時候农渊,會去解析jq這個庫是否有依賴其他的包

我們對類似jq這類依賴庫,一般會認(rèn)為不會引用其他的包(特殊除外,自行判斷)或颊。
所以砸紊,對于這類不引用其他的包的庫传于,我們在打包的時候就沒有必要去解析,
這樣能夠增加打包速率批糟。
所以格了,可以在webpack的配置中增加noParse屬性
(以下代碼只需要看module的noParse屬性)

module.exports = {
    mode:'development',
    entry:'./src/index.js',
    output:{
        filename:'bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    module:{
        noParse:/jquery/,//不去解析jquery中的依賴庫
        rules:[ ]
    }
}

漸進式網(wǎng)絡(luò)應(yīng)用程序PWA

漸進式網(wǎng)絡(luò)應(yīng)用程序(Progressive Web Application - PWA),是一種可以提供類似于原生應(yīng)用程序(native app)體驗的網(wǎng)絡(luò)應(yīng)用程序(web app)徽鼎。PWA 可以用來做很多事盛末。其中最重要的是,在離線(offline)時應(yīng)用程序能夠繼續(xù)運行功能否淤。這是通過使用名為 Service Workers 的網(wǎng)絡(luò)技術(shù)來實現(xiàn)的悄但。

//print.js
export default function printMe() {
  console.log('I get called from print.js!');
}

//index.js
import printMe from './print.js';

if ('serviceWorker' in navigator) {
   window.addEventListener('load', () => {
     navigator.serviceWorker.register('./service-worker.js').then(registration => {
       console.log('SW registered: ', registration);
     }).catch(registrationError => {
       console.log('SW registration failed: ', registrationError);
     });
   });
}

function component() {
    var element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    var btn = document.createElement('button');
    btn.innerHTML = 'Click me and check the console!';
    btn.onclick = printMe;
    element.appendChild(btn);
    return element;
}
document.body.appendChild(component());

//webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');

module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    //3個插件都需要npm install --save-dev
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Output Management'
            title: 'Progressive Web Application'
        }),
        //添加 Workbox
        new WorkboxPlugin.GenerateSW({
            // 這些選項幫助 ServiceWorkers 快速啟用
            // 不允許遺留任何“舊的” ServiceWorkers
            clientsClaim: true,
            skipWaiting: true
        })
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

//package.json配置腳本
"scripts": {
    "build": "webpack",
    //使用一個簡易服務(wù)器,搭建出我們所需的離線體驗
    //npm install http-server --save-dev
    "start": "http-server dist"
  },
  • 有了 Workbox石抡,我們再看下執(zhí)行 npm run build 時會發(fā)生什么
clean-webpack-plugin: /mnt/c/Source/webpack-follow-along/dist has been removed.
Hash: 6588e31715d9be04be25
Version: webpack 3.10.0
Time: 782ms
                                                Asset       Size  Chunks                    Chunk Names
                                        app.bundle.js     545 kB    0, 1  [emitted]  [big]  app
                                      print.bundle.js    2.74 kB       1  [emitted]         print
                                           index.html  254 bytes          [emitted]
precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js  268 bytes          [emitted]
                                    service-worker.js       1 kB          [emitted]
   [0] ./src/print.js 87 bytes {0} {1} [built]
   [1] ./src/index.js 477 bytes {0} [built]
   [3] (webpack)/buildin/global.js 509 bytes {0} [built]
   [4] (webpack)/buildin/module.js 517 bytes {0} [built]
    + 1 hidden module
Child html-webpack-plugin for "index.html":
     1 asset
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 2 hidden modules
  • 現(xiàn)在你可以看到檐嚣,生成了 2 個額外的文件:service-worker.js(或sw.js) 和體積很大的 precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.jssw.jsService Worker 文件啰扛,precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.jssw.js 引用的文件嚎京,所以它也可以運行
  • 然后用 npm start 啟動服務(wù)。訪問 http://localhost:8080/index.html 并查看 console 控制臺隐解。在那里你應(yīng)該看到:
SW registered
  • 現(xiàn)在來進行測試鞍帝。停止服務(wù)器并刷新頁面。如果瀏覽器能夠支持 Service Worker煞茫,你應(yīng)該可以看到你的應(yīng)用程序還在正常運行帕涌。然而,服務(wù)器已經(jīng)停止了服務(wù)续徽,此刻是 Service Worker 在提供服務(wù)蚓曼。

TypeScript

準(zhǔn)備工作:ts-loader插件、tsconfig.json配置文件(和package.json同級)钦扭、ts文件中如何使用第三方庫(ts聲明文件*.d.ts

  1. webpack.config.js配置
    image
  2. tsconfig.json案例:
    image
  3. 使用第三方庫
    當(dāng)從 npm 安裝第三方庫時纫版,一定要牢記同時安裝這個庫的類型聲明文件。你可以從 TypeSearch 中找到并安裝這些第三方庫的類型聲明文件土全。舉個例子捎琐,如果想安裝 lodash 這個庫的類型聲明文件,我們可以運行下面的命令:npm install --save-dev @types/lodash
  4. TypeScript學(xué)習(xí)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末裹匙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子末秃,更是在濱河造成了極大的恐慌概页,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件练慕,死亡現(xiàn)場離奇詭異惰匙,居然都是意外死亡技掏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門项鬼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哑梳,“玉大人,你說我怎么就攤上這事绘盟○妫” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵龄毡,是天一觀的道長吠卷。 經(jīng)常有香客問我,道長沦零,這世上最難降的妖魔是什么祭隔? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮路操,結(jié)果婚禮上疾渴,老公的妹妹穿的比我還像新娘。我一直安慰自己屯仗,他們只是感情好搞坝,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著祭钉,像睡著了一般瞄沙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慌核,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天距境,我揣著相機與錄音,去河邊找鬼垮卓。 笑死垫桂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的粟按。 我是一名探鬼主播诬滩,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼灭将!你這毒婦竟也來了疼鸟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤庙曙,失蹤者是張志新(化名)和其女友劉穎空镜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡吴攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年张抄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洼怔。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡署惯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出镣隶,到底是詐尸還是另有隱情极谊,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布矾缓,位于F島的核電站怀酷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏嗜闻。R本人自食惡果不足惜蜕依,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望琉雳。 院中可真熱鬧样眠,春花似錦、人聲如沸翠肘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽束倍。三九已至被丧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绪妹,已是汗流浹背甥桂。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留邮旷,地道東北人黄选。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像婶肩,于是被迫代替她去往敵國和親办陷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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

  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,286評論 4 31
  • 作者:小 boy (滬江前端開發(fā)工程師)本文原創(chuàng),轉(zhuǎn)載請注明作者及出處险毁。原文地址:https://www.smas...
    iKcamp閱讀 2,758評論 0 18
  • 目錄第1章 webpack簡介 11.1 webpack是什么殃恒? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,735評論 0 1
  • 全局安裝webpack 全局安裝webpack會有個問題植旧,就是當(dāng)你有兩個項目依賴于不同版本的webpack辱揭,就會有...
    説好的妹紙呢閱讀 1,816評論 0 11
  • 今天上午去參加模擬面試离唐,兩個半小時,提了很多刁鉆的問題问窃,見識了很多人不同的答案亥鬓。總結(jié)就一個宗旨域庇,再有思想有調(diào)理的情...
    忽爾今至閱讀 144評論 2 0