webpack4

webpack4筆記

快速了解幾個(gè)基本的概念

mode 模式

通過選擇 development, productionnone 之中的一個(gè)遏插,來設(shè)置 mode 參數(shù),你可以啟用 webpack 內(nèi)置在相應(yīng)環(huán)境下的優(yōu)化渤弛。其默認(rèn)值為 production。

  • development:開發(fā)模式,會(huì)將process.env.NODE_ENV 的值設(shè)為 development 甚带。啟用NamedChunksPlugin 和 NamedMoudulesPlugin她肯。
  • production:生產(chǎn)模式,會(huì)將process.env.NODE_ENV 的值設(shè)為 production 鹰贵。啟用FlagDependencyUsagePlugin辕宏,F(xiàn)lagIncludedChunksPlugin,ModuleConcatenationPlugin砾莱,NoEmitOnErrorsPlugin瑞筐,OccurrenceOrderPlugin,SideEffectsFlagPlugin 和UglifyJsPlugin
// webpack.config.js
module.exports = {
    mode: 'production',
}

入口文件(entry)

入口起點(diǎn)(entry point)指示 webpack 應(yīng)該使用哪個(gè)模塊,來作為構(gòu)建其內(nèi)部依賴圖的開始聚假。進(jìn)入入口起點(diǎn)后块蚌,webpack 會(huì)找出有哪些模塊和庫是入口起點(diǎn)(直接和間接)依賴的。

默認(rèn)值./src/index.js膘格,可以在 webpack 的配置文件中配置入口峭范,配置節(jié)點(diǎn)為: entry,當(dāng)然可以配置一個(gè)入口,也可以配置多個(gè)瘪贱。

// webpack.config.js
module.exports = {
+   entry: './src/index.js' //單入口
}
// webpack.config.js
module.exports = {
    entry: {    //多入口
        main: './src/index.js',
        other: './src/other.js'
    } 
}

輸出(output)

output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles纱控,以及如何命名這些文件。

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  }
};

loader

loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)菜秦。loader 可以將所有類型的文件轉(zhuǎn)換為 webpack 能夠處理的有效模塊甜害,然后你就可以利用 webpack 的打包能力,對(duì)它們進(jìn)行處理球昨。

插件(plugins)

loader 被用于轉(zhuǎn)換某些類型的模塊尔店,而插件則可以用于執(zhí)行范圍更廣的任務(wù)。插件的范圍包括主慰,從打包優(yōu)化和壓縮嚣州,一直到重新定義環(huán)境中的變量。插件接口功能極其強(qiáng)大共螺,可以用來處理各種各樣的任務(wù)该肴。

安裝webpack

使用webpack需要安裝node.js,可直接在node.js官網(wǎng)下載安裝

//查看node是否安裝成功
$ node -v   //查看node版本 顯示版本號(hào)表示安裝完成
$ npm -v        //查看npm版本 node內(nèi)置npm   
//創(chuàng)建項(xiàng)目文件
$ mkdir webpack-test && cd webpack-test //新建一個(gè)項(xiàng)目文件夾webpack-test
$ npm init -y   //創(chuàng)建一個(gè)默認(rèn)的package.json文件[在項(xiàng)目文件夾下執(zhí)行]

本地安裝

$ npm install webpack webpack-cli -D  //本地安裝

全局安裝【不推薦】

在全局狀態(tài)下安裝webpack

$ npm install webpack webpack-cli -g  //全局安裝【不推薦全局安裝

注意:不推薦全局安裝 webpack藐不。這會(huì)將你項(xiàng)目中的 webpack 鎖定到指定版本沙庐,并且在使用不同的 webpack 版本的項(xiàng)目中,可能會(huì)導(dǎo)致構(gòu)建失敗佳吞。

這里是使用npm來安裝的拱雏,也可以使用cnpm,yarn

簡單入門

項(xiàng)目結(jié)構(gòu)

  webpack-test
+ |- package.json
+ |- /dist
+   |- index.html
+ |- /src
+   |- index.js

webpack4支持 0 配置打包

項(xiàng)目根目錄執(zhí)行[npx] webpack會(huì)默認(rèn)將src/index.js打包到dist/main.js

默認(rèn)配置文件

webpack4默認(rèn)會(huì)在項(xiàng)目根目錄找webpack.config.js或者webpackfile.js作為配置文件
也可以通過--config指定配置文件,例如: webpack --config webpack.config.test.js

基礎(chǔ)配置

項(xiàng)目根目錄新建webpack.config.js文件

//webpack.config.js
const path = require('path')

module.exports = {
    //入口文件
    entry: './src/index.js',
    //開發(fā)模式 開發(fā):development, 生產(chǎn):production
    mode: 'development',
    //出口文件
    output: {
        //打包完的文件名
    filename: "bundle.js",
    //打包后的路徑
    path: path.resolve(__dirname,"dist"),
    //公共路徑
    publicPath: '/',
    },
    //配置loader
    // module: {},
    //配置插件
    // plugins: []
}
  • entry 入口文件
//多入口
entry: {
    main: './src/index.js',
    other: './src/other.js'
} 
  • mode 模式
    development:開發(fā)模式底扳,代碼不壓縮
    production:生產(chǎn)模式铸抑,會(huì)壓縮代碼

  • output 出口文件

//打包多入口文件,也可以通過[name]來生成不同的打包文件,
//[name]是entry中生成 通過[hash]可以生成hash戳
output: {
    filename: "bundle-[name].js",  //bundle-main.js  bundle-other.js
    path: path.resolve(__dirname,"dist"),  //修改path可以打包到對(duì)象的path文件夾下
}

通過上面webpack.config.js簡單配置執(zhí)行打包 [npx] webpack會(huì)將src/index.js打包到dist/bundle.js

webpack-dev-server

安裝yarn add webpack-dev-server -D
webpack-dev-server會(huì)通過express(node框架)啟動(dòng)一個(gè)http服務(wù)

配置devServer

//webpack.config.js
module.exports = {
    //開發(fā)服務(wù)器配置
    devServer: {
        port: 3000,//修改端口號(hào)
        progress: true,//進(jìn)度條
        contentBase: './dist',//默認(rèn)訪問目錄
        overlay: true,//是否在頁面展示錯(cuò)誤衷模,(創(chuàng)建腳手架一般都會(huì)開啟)
        hot: true, //熱更新
        // open: true,//自動(dòng)打開瀏覽器
    },
}

配置script

每次通過[npx] webpack等命令比較麻煩鹊汛,可以配置script

//package.json
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",

  "scripts": {
    "build": "webpack --config webpack.config.js",
    "dev": "webpack-dev-server --config webpack.config.js"
  },

  "devDependencies": {
    "webpack": "^4.41.0",
    "webpack-cli": "^3.3.9",
    "webpack-dev-server": "^3.8.1"
  }
}

這樣就可以通過yarn build|devnpm run build|dev 執(zhí)行相應(yīng)的script

打包非js文件

打包html文件

安裝yarn add html-webpack-plugin -D
html-webpack-plugin可以將htm模板打包

//webpack.config.js
const path = require('path')
const HtmlWabpackPlugin = require('html-webpack-plugin')

module.exports = {
    //入口文件
    entry: './src/index.js',
    //打包環(huán)境 開發(fā):development, 生產(chǎn):production
    mode: 'development',
    //出口文件
    output: {
        filename: "bundle.js",//打包完的文件名
        path: path.resolve(__dirname,"dist"),//打包后的路徑
        publicPath: '/',//公共路徑
    },
    //配置loader
    // module: {},
    //配置插件
    plugins: [
        new HtmlWabpackPlugin({
            template: './src/index.html',//打包html模板文件 源
            filename: 'index.html',//打包的文件名
            minify: {
                // removeAttrbuteQuotes: true,//刪除雙引號(hào)
                collapseWhitespace: true,//壓縮成一行
            },
            // hash: true,//生成hash
        })
    ]
}

處理樣式

css-loader,style-loader

當(dāng)引入css文件阱冶,webpack是無法識(shí)別的刁憋,這就需要使用相應(yīng)的css插件|loader
安裝yarn css-loader style-loader -D
css-loader 使webpack能夠解析css @import 'xx.css'
style-loader 將css插入到html文件head標(biāo)簽中

//配置loader
module: {
    rules: [
        //loader解析是從右向左執(zhí)行
        //用法單一,一般一個(gè)loader處理一件事
        {
            test: /\.css$/,
            use: [
                {
                    loader: 'style-loader',//把css插入head標(biāo)簽中 【對(duì)象形式木蹬,可以添加參數(shù)】
                    options: {
                     // insertAt: 'top',//插入head位置 注:添加這個(gè)配置(還有wabpack文檔中介紹的個(gè)別其他屬性)報(bào)錯(cuò)至耻,不明所以
                   }
                },
                {
                    loader: 'css-loader'
                }
                // 'css-loader',//解析@import 【字符串形式】
            ]
        }
    ]
}

上面通過配置module的rules,通過正則匹配.css文件,陪通過use指定使用相應(yīng)的loader

loader大致分以下幾種

  • pre 前置loader //設(shè)置loader可以添加options:{enforce:'pre'}
  • normal 普通loader //默認(rèn)
  • 內(nèi)鏈loader //import from 'expose-loader?!jquery'
  • post 后置loader //設(shè)置loader可以添加options:{enforce:'postloader'}

loader解析是從右向左[從后往前]執(zhí)行尘颓,也可以設(shè)置options修改執(zhí)行順序(options:{enforce:'pre'}優(yōu)先執(zhí)行)
webpack需要先解析css走触,然后再插入到head標(biāo)中,所以應(yīng)該先配置style-laoder,再配置css-loader
使用sass,less樣式預(yù)處理疤苹,需要安裝相應(yīng)的loader(例如:sass-loader[看下面配置]互广,less類似),并配置在css-loader后面(需要先解析)

解析sass

配置sass-loader
安裝yarn add sass-loader node-sass -D

{
    test: /\.css$/,
    use: [
        {
            loader: 'style-loader',//把css插入head標(biāo)簽中 【對(duì)象形式,可以添加參數(shù)】
            options: {
             // insertAt: 'top',//插入head位置 注:添加這個(gè)配置(還有wabpack文檔中介紹的個(gè)別其他屬性)報(bào)錯(cuò)卧土,不明所以
           }
        },
        {
            loader: 'css-loader'
        }
    +   'sass-loader'
    ]
}

上面通過css-loader,style-loader可以將引入的css文件插入到html文件的head標(biāo)簽中,

抽離css到文件

還可以通過mini-css-extract-plugin插件將css抽離到文件中
安裝yarn add mini-css-extract-plugin -D

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

plugins: [
    ///***
    new MiniCssExtractPlugin({  //將樣式抽離到文件中
        filename: 'main.css'
    })
],
module: {
    rules: [
        //loader解析是從右向左執(zhí)行
        //用法單一惫皱,一般一個(gè)loader處理一件事
        {
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader   
                },
                {
                    loader: 'css-loader'
                }
                // 'css-loader',//解析@import 【字符串形式】
            ]
        }
    ]
}

css添加前綴

安裝yarn add postcss-loader autoprefixer -D
css-loader后面添加postcss-loader

module: {
    rules: [
        //loader解析是從右向左執(zhí)行
        //用法單一,一般一個(gè)loader處理一件事
        {
            test: /\.css$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader   
                },
                {
                    loader: 'css-loader'
                }
                {
                    loader: 'postcss-loader'
                }
            ]
        }
    ]
}

postcss-loader會(huì)在根目錄查找postcss.config.js作為配置
在根目錄新建postcss.config.js文件

//postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

打包圖片

安裝yarn add file-loader url-loader -D

  • js創(chuàng)建圖片
    file-loader 默認(rèn)會(huì)在內(nèi)部生成一張圖片尤莺,到build目錄下旅敷,返回圖片地址
import logo from './logo.png' //引入圖片,返回新的圖片地址

let img = new Image();
img.src = logo;
document.body.appendChild(img);
  • css中引入背景圖片 可以直接引入
    background: url('./logo.png')

  • img標(biāo)簽引入 使用html-withimg-loader
    安裝yarn add html-withimg-loader -D

//webpack.config.js
module: {
    rules: [
        {
            test: /\.html$/,
            use: 'html-withimg-loader'
        }
    ]
}

配置圖片相應(yīng)loader

module: {
    rules: [
        {
            test: /\.(png|jpg|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    limit: 10 * 1024,  //設(shè)置當(dāng)圖片小于10KB就轉(zhuǎn)為base64
                    outputPath: '/img/'  //圖片打包到img文件下
                }
            }
        },
    ]
}

開發(fā)相關(guān)輔助

babel轉(zhuǎn)碼js

雖然現(xiàn)代的瀏覽器已經(jīng)兼容了96%以上的ES6的語法了缝裁,但是為了兼容老式的瀏覽器,我們需要把最新的ES6的語法轉(zhuǎn)成ES5的足绅。這時(shí)就可以使用babel-loader

安裝yarn add babel-loader @babel/core @babel/preset-env -D

配置

    module: {
        rules: [
            {
                test: /\.js$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {  //使用babel-loader es6 -> es5
                            presets: [  //也可以在配置在外面[.babelrc文件中配置]
                                [
                                    "@babel/preset-env",
                                    {
                                      "targets": {
                                        "chrome": "58",
                                        "ie": "10"
                                      }
                                    }
                                ]
                            ]
                        }
                    }
                ]
            }
        ]
    }

targets配置的意思就是讓babel根據(jù)你寫入的兼容平臺(tái)來做代碼轉(zhuǎn)換捷绑。

使用@babel/polyfill

includes作為數(shù)組的實(shí)例方法,在某些瀏覽器其實(shí)是不支持的氢妈,babel默認(rèn)的轉(zhuǎn)換對(duì)于這種場(chǎng)景并不會(huì)做處理粹污,同樣不會(huì)處理的包括WeakMap, WeakSet, Promise等es6新引入的類,所以我們需要@babel/polyfill為我們這些實(shí)例方法等等打上補(bǔ)丁首量。
安裝yarn add @babel/polyfill
很多項(xiàng)目會(huì)在入口文件頂部引入@babel/polyfill壮吩,或者指定webpack的entry為數(shù)組,第一項(xiàng)引入@babel/polyfill加缘,這樣配置是可以達(dá)到目錄鸭叙,但可能我們只使用了少量polyfill的api,這時(shí)全局引入就不太劃算了拣宏,這時(shí)我們可以使用babel的useBuiltIns來配置。如下

//這里配置在.babelrc文件(項(xiàng)目根目錄中新建`.babelrc`文件)  
{
  "presets": [
    [
      "@babel/preset-env",
      {
            "useBuiltIns": "usage",
        "targets": {
          "chrome": "58",
          "ie": "10"
        }
      },
    ]
  ]
}

babel幫我們做好了代碼分析勋乾,在需要用到polyfill的地方引入這個(gè)單獨(dú)的補(bǔ)丁宋下,這樣就實(shí)現(xiàn)了按需引入

class支持

當(dāng)打包如下簡單代碼

class A{
    a = 1 //報(bào)錯(cuò)
}

這時(shí)可以安裝yarn add @babel/plugin-proposal-class-properties -D插件

//.babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "targets": {
          "chrome": "58",
          "ie": "10"
        }
      },
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ]
}

裝飾器@Decorator

當(dāng)處理以下代碼時(shí)也是會(huì)報(bào)錯(cuò)

@log  //報(bào)錯(cuò)
class A{
    a = 1 
}
function log(tag){
    console.log(tag)
}

安裝相關(guān)插件yarn add @babel/plugin-proposal-decorators -D
配置

//.babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "targets": {
          "chrome": "58",
          "ie": "10"
        }
      },
    ]
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }]
  ]
}

Babel優(yōu)化

babel-loader可以配置如下幾個(gè)options:

  • cacheDirectory:默認(rèn)值為 false。當(dāng)有設(shè)置時(shí)辑莫,指定的目錄將用來緩存 loader 的執(zhí)行結(jié)果涧尿。之后的 webpack 構(gòu)建否过,將會(huì)嘗試讀取緩存,來避免在每次執(zhí)行時(shí),可能產(chǎn)生的并鸵、高性能消耗的 Babel 重新編譯過程(recompilation process)刊咳。如果設(shè)置了一個(gè)空值 (loader: 'babel-loader?cacheDirectory') 或者 true (loader: babel-loader?cacheDirectory=true),loader 將使用默認(rèn)的緩存目錄 node_modules/.cache/babel-loader,如果在任何根目錄下都沒有找到 node_modules 目錄昭躺,將會(huì)降級(jí)回退到操作系統(tǒng)默認(rèn)的臨時(shí)文件目錄。

  • cacheIdentifier:默認(rèn)是一個(gè)由 babel-core 版本號(hào)伪嫁,babel-loader 版本號(hào)领炫,.babelrc 文件內(nèi)容(存在的情況下),環(huán)境變量 BABEL_ENV 的值(沒有時(shí)降級(jí)到 NODE_ENV)組成的字符串张咳〉酆椋可以設(shè)置為一個(gè)自定義的值,在 identifier 改變后脚猾,強(qiáng)制緩存失效葱峡。

  • forceEnv:默認(rèn)將解析 BABEL_ENV 然后是 NODE_ENV。允許你在 loader 級(jí)別上覆蓋 BABEL_ENV/NODE_ENV龙助。對(duì)有不同 babel 配置的砰奕,客戶端和服務(wù)端同構(gòu)應(yīng)用非常有用提鸟。

注意:sourceMap 選項(xiàng)是被忽略的胸哥。當(dāng) webpack 配置了 sourceMap 時(shí)(通過 devtool 配置選項(xiàng)),將會(huì)自動(dòng)生成 sourceMap赡鲜。

babel 在每個(gè)文件都插入了輔助代碼空厌,使代碼體積過大.babel 對(duì)一些公共方法使用了非常小的輔助代碼,比如 _extend银酬。 默認(rèn)情況下會(huì)被添加到每一個(gè)需要它的文件中嘲更。你可以引入 babel runtime 作為一個(gè)獨(dú)立模塊,來避免重復(fù)引入揩瞪。
安裝
yarn add @babel/plugin-transform-runtime -D
yarn add @babel/runtime

@babel/plugin-transform-runtime插件是幫我們把一些babel的輔助方法由直接寫入代碼專為按需引入模塊的方式引用

配置:

webpack.config.js

rules: [
  {
    test: /\.js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
    }
  }
]

修改.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "targets": {
          "chrome": "58",
          "ie": "10"
        }
      },
    ]
  ],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose" : true }],
    "@babel/plugin-transform-runtime"
  ]
}

此時(shí)哮内,webpack打包的時(shí)候,會(huì)自動(dòng)優(yōu)化重復(fù)引入公共方法的問題壮韭。

資源打包不同文件夾下

  • js
output: {
  filename: "js/[name].js",//打包完的文件名
  path: path.resolve(__dirname,"dist"),//打包后的路徑
  // publicPath: '',//公共路徑
},
  • css
//css打包到css文件夾下
plugins:[
    new MiniCssExtractPlugin({  //將樣式抽離到文件中
        filename: 'css/main.css'   //打包到css文件夾
    }),
]
  • img
module: {
    rules: [
        {
            test: /\.(png|jpg|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    limit: 10 * 1024,  //設(shè)置當(dāng)圖片小于10KB就轉(zhuǎn)為base64北发,否則用file-loader處理
                    outputPath: '/img/'  //打包到img文件夾
                }
            }
        },
    ]
}

module 配置補(bǔ)充

模塊(module): 這些選項(xiàng)決定了如何處理項(xiàng)目中的不同類型的模塊。

webpack 模塊可以支持如下:

  • ES2015 import 語句
  • CommonJS require() 語句
  • AMD define 和 require 語句
  • css/sass/less 文件中的 @import 語句喷屋。
  • 樣式(url(...))或 HTML 文件(<img src=...>)中的圖片鏈接(image url)

module.noParse

值的類型: RegExp | [RegExp] | function

防止 webpack 解析那些任何與給定正則表達(dá)式相匹配的文件琳拨。忽略的文件中不應(yīng)該含有 import, require, define 的調(diào)用,或任何其他導(dǎo)入機(jī)制屯曹。忽略大型的 library 可以提高構(gòu)建性能狱庇。

module.exports = {
  mode: 'devleopment',
  entry: './src/index.js',
  ...
  module: {
    noParse: /jquery|lodash/,
    // 從 webpack 3.0.0 開始,可以使用函數(shù)惊畏,如下所示
    // noParse: function(content) {
    //   return /jquery|lodash/.test(content);
    // }
  }
  ...
};

module.rules

創(chuàng)建模塊時(shí),匹配請(qǐng)求的規(guī)則數(shù)組密任。這些規(guī)則能夠修改模塊的創(chuàng)建方式颜启。這些規(guī)則能夠?qū)δK(module)應(yīng)用 loader,或者修改解析器(parser)浪讳。

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

module Rule

  • Rule 條件詳解
    • 字符串:匹配輸入必須以提供的字符串開始缰盏。是的。目錄絕對(duì)路徑或文件絕對(duì)路徑淹遵。
    • 正則表達(dá)式:test 輸入值口猜。
    • 函數(shù):調(diào)用輸入的函數(shù),必須返回一個(gè)真值(truthy value)以匹配透揣。
    • 條件數(shù)組:至少一個(gè)匹配條件济炎。
    • 對(duì)象:匹配所有屬性。每個(gè)屬性都有一個(gè)定義行為辐真。

Rule.test

  • { test: Condition }:匹配特定條件须尚。一般是提供一個(gè)正則表達(dá)式或正則表達(dá)式的數(shù)組,但這不是強(qiáng)制的侍咱。
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }
  ...
};

其他的條件比如:

  • { include: Condition }:匹配特定條件耐床。一般是提供一個(gè)字符串或者字符串?dāng)?shù)組,但這不是強(qiáng)制的放坏。
  • { exclude: Condition }:排除特定條件咙咽。一般是提供一個(gè)字符串或字符串?dāng)?shù)組老玛,但這不是強(qiáng)制的淤年。
  • { and: [Condition] }:必須匹配數(shù)組中的所有條件
  • { or: [Condition] }:匹配數(shù)組中任何一個(gè)條件
  • { not: [Condition] }:必須排除這個(gè)條件
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.css$/,
        include: [
          path.resolve(__dirname, "app/styles"),
          path.resolve(__dirname, "vendor/styles")
        ],
        use: ['style-loader', 'css-loader']
      }
    ]
  }
  ...
};

Rule.use

應(yīng)用于模塊指定使用一個(gè) loader。

Loaders can be chained by passing multiple loaders, which will be applied from right to left (last to first configured).

加載器可以鏈?zhǔn)絺鬟f蜡豹,從右向左進(jìn)行應(yīng)用到模塊上麸粮。

use: [
  'style-loader',
  {
    loader: 'css-loader'
  },
  {
    loader: 'less-loader',
    options: {
      noIeCompat: true
    }
  }
];

傳遞字符串(如:use: [ "style-loader" ])是 loader 屬性的簡寫方式(如:use: [ { loader: "style-loader "} ])。

清理 dist 目錄

每次構(gòu)建镜廉,我們的 /dist 文件夾都會(huì)保存生成的文件弄诲,然后就會(huì)非常雜亂。

通常娇唯,在每次構(gòu)建前清理 /dist 文件夾齐遵,是比較推薦的做法

clean-webpack-plugin 是一個(gè)比較普及的管理插件,讓我們安裝和配置下塔插。

yarn add clean-webpack-plugin -D

webpack.config.js

  const path = require('path');
  ....
+ const CleanWebpackPlugin = require('clean-webpack-plugin');

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

現(xiàn)在執(zhí)行 npm run build梗摇,再檢查 /dist 文件夾。如果一切順利想许,你現(xiàn)在應(yīng)該不會(huì)再看到舊的文件伶授,只有構(gòu)建后生成的文件断序!

由于最新版本變化@2.0.1之前的寫法已經(jīng)不能使用:new CleanWebpackPlugin(['/dist'])
官方文檔地址:https://www.npmjs.com/package/clean-webpack-plugin
可以直接設(shè)置一個(gè)對(duì)象參考:
new CleanWebpackPlugin({cleanOnceBeforeBuildPatterns: ['**/*', '!static-files*']})

壓縮代碼

css使用optimize-css-assets-webpack-plugin插件糜烹,
js使用uglifyjs-webpack-plugin插件
安裝yarn add optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D
配置

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
    optimization: { //配置優(yōu)化項(xiàng)
        minimizer: [
            new OptimizeCssAssetsWebpackPlugin(),
            new UglifyjsWebpackPlugin()
        ]
    }
    //也可以配置插件
    //plugins: [
    //  new OptimizeCssAssetsWebpackPlugin(),
    //  new UglifyjsWebpackPlugin()
    //]
}

定義環(huán)境變量

使用webpack.DefinePlugin插件可以定義變量
例如:

//webpack.config.js
plugins: [
    new webpack.DefinePlugin({
        DEV: JSON.stringify('dev'),    //定義字符串時(shí)违诗,不能直接使用'dev',取結(jié)果:dev
    })
]

//index.js
if(DEV){
    ***
}

webpack-merge合并配置文件

可以為不同環(huán)境配置不同的配置文件疮蹦,比如有
webpack.base.js //基礎(chǔ)配置文件
webpack.dev.js //開發(fā)環(huán)境配置
webpack.prod.js //生產(chǎn)環(huán)境配置

//webpack.dev.js
let { smart } = reqiure('webpack-merge')
let base = require('./webpack.base.js')

module.exports = smart(base,{
    mode: 'development',
    //其他配置
})
//webpack.prod.js
let { smart } = reqiure('webpack-merge')
let base = require('./webpack.base.js')

module.exports = smart(base,{
    mode: 'production',
    //其他配置
})

全局變量

當(dāng)我們引入第三方模塊時(shí)诸迟,該模塊作用域只在當(dāng)前模塊中。當(dāng)需要設(shè)置全局時(shí)挚币,可以添加loader處理
yarn add expose-loader -D

import $ from 'jquery'
console.log(window.$)  // -> underfine   【全局訪問不到】
import $ from 'expose-loader?$!jquery'  //通過expose-loader將jquery導(dǎo)出為全局($)
console.log(window.$) // ? ( selector, context ) { *** }    【全局變量】

//或者配置webpack.config.js
module: {
    rules: [
        {
            test: require.reslove('jqeury'),
            use: 'expose-loader?$'
        }
    ]
}

另外還可以通過webpack.ProvidePlugin插件亮蒋,讓每個(gè)模塊都插入某變量|模塊

//webpack.config.js
const webpack = require('webpack')

plugins: [
    new webpack.ProvidePlugin({
        $: 'jquery'         //在每個(gè)模塊都注入$(jquery)
    })
]

webpack跨域

  • 代理
devServer: {
    proxy: {
        '/api':{
            target: 'http:localhost:8081', 
            pathRewrite: {
                '/api': ''  //重寫路徑
            }
        }
    }
}
//接口:http:localhost:8081/user
//webpack服務(wù)http:localhost:8080
//以上配置,當(dāng)請(qǐng)求'/api/user',直接轉(zhuǎn)化了到http:localhost:8081/user
  • mock數(shù)據(jù)
devServer: {
    before(app){
        app.get('/user',(req,res) => {
            res.json({code: 200,msg: '成功'})
        })
    }
}
  • 使用webpack-dev-middleware
    安裝yarn add webpack-dev-middleware
//server.js
let express = require('express')
let app = express();
let webpack = require('webpack')

//中間件
let middle = require('webpack-dev-middle')
//引入配置文件
let config = require('./webpack.config.js')
//處理配置文件
let compiler = webpack(config)
//使用中間件妆毕,當(dāng)開啟服務(wù)的時(shí)候慎玖,將webpack服務(wù)也一并開啟
app.use(middle(compiler))


app.get('/user',(req,res) => {
    res.json({code: 200,msg: '成功'})
})

app.listen(300)

devtool映射文件

通過配置devtool可以配置映射文件

  • source-map
    單獨(dú)生成source-map文件,出錯(cuò)顯示行和列
    devtool: 'source-map'

  • eval-source-map
    不會(huì)生成單獨(dú)的文件笛粘,出錯(cuò)會(huì)顯示行和列
    devtool: 'eval-source-map'

  • cheap-module-source-map
    不產(chǎn)生列趁怔,但是一個(gè)單獨(dú)映射文件(和文件沒有關(guān)聯(lián))⌒角埃可以保存起來調(diào)試使用
    devtool: 'cheap-module-source-map'

  • cheap-module-eval-source-map
    不生成文件润努,集成到打包后的文件中,不顯示列
    devtool: 'cheap-module-eval-source-map'

watch監(jiān)聽(熱更新)

當(dāng)代碼修改時(shí)示括,可以時(shí)時(shí)打包铺浇。
devServer也可以實(shí)現(xiàn)重新打包,但感覺有點(diǎn)慢

module.exports = {
    devServer: {
        hot: true, //熱更新
    }
}

配置watch

module.exports = {
    watch: true,
    watchOptions: {  //監(jiān)控選項(xiàng)
        poll: 1000,//1分鐘詢問1000次
        aggregateTimeout: 500,//防抖 輸入停止后500ms后打包文件
        ignored: /node_module/, //不監(jiān)控的文件
    }
}

解析(resolve)

配置模塊如何解析垛膝。比如: import _ from 'lodash' ,其實(shí)是加載解析了lodash.js文件鳍侣。此配置就是設(shè)置加載和解析的方式。

  • resolve.alias

創(chuàng)建 import 或 require 的別名吼拥,來確保模塊引入變得更簡單倚聚。例如,一些位于 src/ 文件夾下的常用模塊:

// webpack.config.js
module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'main.[hash].js',
    path: path.resolve(__dirname, './dist')
  },
+ resolve: {
+   alias: {
+     vue$: path.resolve(__dirname, 'src/lib/vue/dist/vue.esm.js'),
+     '@': path.resolve(__dirname, 'src/')
+   }
+ }
  ...
}

// index.js
// 在我們的index.js文件中凿可,就可以直接import
import vue from 'vue';
// 等價(jià)于
import vue from  'src/lib/vue/dist/vue.esm.js';

  • resolve.extensions的應(yīng)用

自動(dòng)解析確定的擴(kuò)展惑折。

// webpack.config.js
module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'main.[hash].js',
    path: path.resolve(__dirname, './dist')
  },
  resolve: {
    alias: {
      vue$: path.resolve(__dirname, 'src/lib/vue/dist/vue.esm.js'),
      '@': path.resolve(__dirname, 'src/')
    },
+   extensions: [".js", ".vue",".json"]   // 默認(rèn)值: [".js",".json"]
  }
  ...
}

給定對(duì)象的鍵后的末尾添加 $,以表示精準(zhǔn)匹配

  • resolve一般配置
//webpack.config.js
module.exports = {
    resolve: { //解析第三方包
        modules: [
            path.resolve('node_modules'),   //在當(dāng)前node_modules文件查找包
        ],
        mainFields: [ //查找字段 
            'style',
            'main'
        ],
        mainfiles: [  //入口文件名字
            'index.js'
        ],
        alias: { //別名
            bootstrap: 'bootstrap/dist/css/bootstrap.css'
        },
        extensions: [ //添加后綴  當(dāng)import xx from './xx'
            '.js',   //先找xx.js
            '.css'   //沒找到再找xx.css
        ]
    }
}

外部擴(kuò)展(externals)

externals 配置選項(xiàng)提供了「從輸出的 bundle 中排除依賴」的方法枯跑。 文檔

例如惨驶,從 CDN 引入 jQuery,而不是把它打包:

index.html

<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous">
</script>

webpack.config.js

// webpack.config.js
module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'main.[hash].js',
    path: path.resolve(__dirname, './dist')
  },
  alias: {
    extensions: [".js", ".vue",".json"]   // 默認(rèn)值: [".js",".json"]
    vue$: path.resolve(__dirname, 'src/lib/vue/dist/vue.esm.js'),
    '@': path.resolve(__dirname, 'src/')
  },
+ externals: {
+   jquery: 'jQuery'
+ },
  ...
}

這樣就剝離了那些不需要改動(dòng)的依賴模塊敛助,換句話粗卜,下面展示的代碼還可以正常運(yùn)行:

import $ from 'jquery';

$('.my-element').animate(...);

具有外部依賴(external dependency)的 bundle 可以在各種模塊上下文(module context)中使用,例如 CommonJS, AMD, 全局變量和 ES2015 模塊辜腺。外部 library 可能是以下任何一種形式:

  • root:可以通過一個(gè)全局變量訪問 library(例如休建,通過 script 標(biāo)簽)乍恐。
  • commonjs:可以將 library 作為一個(gè) CommonJS 模塊訪問。
  • commonjs2:和上面的類似测砂,但導(dǎo)出的是 module.exports.default.
  • amd:類似于 commonjs茵烈,但使用 AMD 模塊系統(tǒng)。

不同的配置方式:

externals : {
  react: 'react'
}

// 或者

externals : {
  lodash : {
    commonjs: "lodash",
    amd: "lodash",
    root: "_" // 指向全局變量
  }
}

// 或者

externals : {
  subtract : {
    root: ["math", "subtract"]   // 相當(dāng)于: window.math.substract
  }
}

構(gòu)建目標(biāo)(targets)

webpack 能夠?yàn)槎喾N環(huán)境或 target 構(gòu)建編譯砌些。想要理解什么是 target 的詳細(xì)信息呜投,請(qǐng)閱讀 target 概念頁面。

target: 告知 webpack 為目標(biāo)(target)指定一個(gè)環(huán)境存璃。

可以支持以下字符串值:

選項(xiàng) 描述
async-node 編譯為類 Node.js 環(huán)境可用(使用 fs 和 vm 異步加載分塊)
electron-main 編譯為 Electron 主進(jìn)程仑荐。
electron-renderer 編譯為 Electron 渲染進(jìn)程,使用 JsonpTemplatePlugin, FunctionModulePlugin 來為瀏覽器環(huán)境提供目標(biāo)纵东,使用 NodeTargetPlugin 和 ExternalsPlugin 為 CommonJS 和 Electron 內(nèi)置模塊提供目標(biāo)粘招。
node 編譯為類 Node.js 環(huán)境可用(使用 Node.js require 加載 chunk)
node-webkit 編譯為 Webkit 可用,并且使用 jsonp 去加載分塊偎球。支持 Node.js 內(nèi)置模塊和 nw.gui 導(dǎo)入(實(shí)驗(yàn)性質(zhì))
web 編譯為類瀏覽器環(huán)境里可用(默認(rèn))
webworker 編譯成一個(gè) WebWorker

例如洒扎,當(dāng) target 設(shè)置為 "electron",webpack 引入多個(gè) electron 特定的變量.

webpack.config.js

// webpack.config.js
module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'main.[hash].js',
    path: path.resolve(__dirname, './dist')
  },
  alias: {
    extensions: [".js", ".vue",".json"]   // 默認(rèn)值: [".js",".json"]
    vue$: path.resolve(__dirname, 'src/lib/vue/dist/vue.esm.js'),
    '@': path.resolve(__dirname, 'src/')
  },
  externals: {
    jquery: 'jQuery'
  },
+ target: 'node'
  ...
}

相關(guān)的loader列表

webpack 可以使用 loader 來預(yù)處理文件衰絮。這允許你打包除 JavaScript 之外的任何靜態(tài)資源袍冷。你可以使用 Node.js 來很簡單地編寫自己的 loader。

文件

  • raw-loader 加載文件原始內(nèi)容(utf-8)
  • val-loader 將代碼作為模塊執(zhí)行猫牡,并將 exports 轉(zhuǎn)為 JS 代碼
  • url-loader 像 file loader 一樣工作胡诗,但如果文件小于限制,可以返回 data URL
  • file-loader 將文件發(fā)送到輸出文件夾淌友,并返回(相對(duì))URL

JSON

  • json-loader 加載 JSON 文件(默認(rèn)包含)
  • json5-loader 加載和轉(zhuǎn)譯 JSON 5 文件
  • cson-loader 加載和轉(zhuǎn)譯 CSON 文件

轉(zhuǎn)換編譯(Transpiling)

  • script-loader 在全局上下文中執(zhí)行一次 JavaScript 文件(如在 script 標(biāo)簽)煌恢,不需要解析
  • babel-loader 加載 ES2015+ 代碼,然后使用 Babel 轉(zhuǎn)譯為 ES5
  • buble-loader 使用 Bublé 加載 ES2015+ 代碼亩进,并且將代碼轉(zhuǎn)譯為 ES5
  • traceur-loader 加載 ES2015+ 代碼症虑,然后使用 Traceur 轉(zhuǎn)譯為 ES5
  • ts-loaderawesome-typescript-loader 像 JavaScript 一樣加載 TypeScript 2.0+
  • coffee-loader 像 JavaScript 一樣加載 CoffeeScript

模板(Templating)

  • html-loader 導(dǎo)出 HTML 為字符串缩歪,需要引用靜態(tài)資源
  • pug-loader 加載 Pug 模板并返回一個(gè)函數(shù)
  • jade-loader 加載 Jade 模板并返回一個(gè)函數(shù)
  • markdown-loader 將 Markdown 轉(zhuǎn)譯為 HTML
  • react-markdown-loader 使用 markdown-parse parser(解析器) 將 Markdown 編譯為 React 組件
  • posthtml-loader 使用 PostHTML 加載并轉(zhuǎn)換 HTML 文件
  • handlebars-loader 將 Handlebars 轉(zhuǎn)移為 HTML
  • markup-inline-loader 將內(nèi)聯(lián)的 SVG/MathML 文件轉(zhuǎn)換為 HTML归薛。在應(yīng)用于圖標(biāo)字體,或?qū)?CSS 動(dòng)畫應(yīng)用于 SVG 時(shí)非常有用匪蝙。

樣式

  • style-loader 將模塊的導(dǎo)出作為樣式添加到 DOM 中
  • css-loader 解析 CSS 文件后主籍,使用 import 加載,并且返回 CSS 代碼
  • less-loader 加載和轉(zhuǎn)譯 LESS 文件
  • sass-loader 加載和轉(zhuǎn)譯 SASS/SCSS 文件
  • postcss-loader 使用 PostCSS 加載和轉(zhuǎn)譯 CSS/SSS 文件
  • stylus-loader 加載和轉(zhuǎn)譯 Stylus 文件

清理和測(cè)試(Linting && Testing)

  • mocha-loader 使用 mocha 測(cè)試(瀏覽器/NodeJS)
  • eslint-loader PreLoader逛球,使用 ESLint 清理代碼
  • jshint-loader PreLoader千元,使用 JSHint 清理代碼
  • jscs-loader PreLoader,使用 JSCS 檢查代碼樣式
  • coverjs-loader PreLoader颤绕,使用 CoverJS 確定測(cè)試覆蓋率

框架(Frameworks)

  • vue-loader 加載和轉(zhuǎn)譯 Vue 組件
  • polymer-loader 使用選擇預(yù)處理器(preprocessor)處理幸海,并且 require() 類似一等模塊(first-class)的 Web 組件
  • angular2-template-loader 加載和轉(zhuǎn)譯 Angular 組件
  • Awesome 更多第三方 loader祟身,查看 awesome-webpack 列表

其他小插件

  • cleanWebpackPlugin
    每次打包會(huì)先刪除文件
let CleanWebpackPlugin = require('clean-webpack-pulgin')
plugins: [
    new CleanWebpackPlugin('./dist'), //每次打包會(huì)先刪除dist文件夾物独,可以傳數(shù)組['./dist','./assets']
]
  • copyWebpackPlugin
    拷貝插件
let CopyWebpackPlugin = require('copy-webpack-pulgin')
plugins: [
    new CopyWebpackPlugin([
        {from: 'md',to:''},// 將md文件夾的內(nèi)容拷貝到打包目錄下
    ]),
]
  • bannerPlugin //webpack內(nèi)置插件
    版權(quán)申明插件
let webpack = require('webpack')
plugins: [
    new webpack.BannerPlugin('make by 2020 Echo'), //打包出來的每個(gè)js文件頭部都會(huì)插入 /*make by 2020 Echo*/
]

打包分析

webpack-bundle-analyzer插件可以幫助我們分析打包后的圖形化的報(bào)表袜硫。

僅僅在開發(fā)環(huán)境使用。

安裝yarn add webpack-bundle-analyzer -D

+ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  module.exports = {
    plugins: [
+     new BundleAnalyzerPlugin()
    ]
  }

自動(dòng)生成一個(gè)網(wǎng)頁報(bào)表挡篓,如下所示:
[圖片上傳失敗...(image-33e3e3-1586335983662)]

優(yōu)化

webpack自帶優(yōu)化

  • tree_shaking

使用import語法導(dǎo)入模塊婉陷,只會(huì)打包用了的方法(刪除掉沒使用的代碼)

例如:

//test.js
let fun1 = () => {}
let fun2 = () => {}
module.exports = {fun1,fun2}

//index.js
import test from './test.js'

test.fun1();//這里只用了fun1方法我碟,當(dāng)使用import導(dǎo)入瞬内,生產(chǎn)環(huán)境打包時(shí)fun2函數(shù)(沒使用)并不會(huì)打包

使用es6(require)導(dǎo)入會(huì)把結(jié)果放到default

let test = require('./test.js')  
test.default.fun1()  
  • 省略無用代碼
let a = 1,b = 2;  
console.log(a+b);
打包后:console.log(3)

動(dòng)態(tài)鏈接庫

使用webpack內(nèi)置插件dllPulgin

當(dāng)引入react,react-dom,打包會(huì)將其一起打包到一個(gè)文件夾漆羔,這樣文件會(huì)比較大戏羽。
我們可以將react,react-dom打包到單獨(dú)文件担神,或稱為動(dòng)態(tài)連接庫,并在html文件中引入該文件

//新建webpack.react.js配置文件始花,用于打包react,react-dom
let path = require('path')
let webpack = require('webpack')

module.exports = {
    entry: {
        react: ['react','react-dom']
    },
    output: {
        filename: '_dll_[name].js', 
        path: path.resolve(__dirname,'dist'), 
        library: '_dll_[name]',   //打包的js前面添加 var _dll_react = (原先打包內(nèi)容)
        // libraryTarget: 'var', //添加方式 var: var dll = ***; commmonjs: exports(dll) = ***; ...
    },
    mode: 'development',
    devServer: {
        port:3000,
        contentBase: './dist',
    },
    plugins: [
        new webpack.DllPlugin({
            name: '_dll_[name]',
            path: path.resolve(__dirname,'dist','manifest.json')
        })
    ]
}

打包完dist文件下生成_dll_react.jsmanifest.json兩文件
然后在html文件中引入_dll_react.js

//項(xiàng)目文件
import React from 'react'
import { render } from 'react-dom'

項(xiàng)目中引入的react,react-dom還是會(huì)打包杏瞻,所以需要添加配置,告知到動(dòng)態(tài)連接庫中查找

//項(xiàng)目正式配置文件webpack.config.js
let path = require('path')
let HtmlWebpackPulgin = require('html-webpack-plugin')
let webpack = require('webpack')
module.exports = {
    //配置多入口
    entry: {
        main: './src/react.js'
        // other: './src/other.js'
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname,'dist')
    },
    mode: 'production',
    devServer: {
        port:3000,
        contentBase: './dist'
    },
    plugins: [
        new webpack.DllReferencePlugin({
            manifest: path.resolve(__dirname,'dist','manifest.json')
        }),
        new HtmlWebpackPulgin({
            template: './src/index.html',
            filename: 'index.html',
        })
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            '@babel/preset-env',
                            '@babel/preset-react'
                        ]
                    }
                },
                include: /src/,
                exclude: /node_modules/
            }
        ]
    }
}

還有前面提到的externals可以設(shè)置不打包的模塊衙荐,CDN引入捞挥。

happypack多線程打包

安裝yarn add happypack -D

//webpack.config.js
let Happypack = require('happypack')
module.exports = {

    module: {
        rules: [
            {
                test: /\.js$/,
                use: 'Happypack/loader?id=js'
            },
            {
                test: /\.css$/,
                use: 'Happypack/loader?id=css'
            }
        ]
    },
    plugins: [
        new Happypack({
            id: 'js',
            use: [
                {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            '@babel/preset-env',
                            '@babel/preset-react'
                        ]
                    }
                }
            ]
        }),
        new Happypack({
            id: 'css',
            use: [
                MiniCssExtractPlugin.loader, 
                "css-loader", 
                "postcss-loader"
            ]
        })
    ]
}

抽離公共模塊

//webpack.config.js
module.exports = {
    optimization: {
        splitChunks: {  //分割代碼塊
            cacheGroups: {  //緩存組
                common: {   //公共模塊
                    chunks: 'initial', //入口處開始
                    minSize: 0, //大于0的公用代碼塊
                    minChunks: 2,   //公用了2次以上
                }
                vendor: {  //第三方
                    priority: 1, //優(yōu)先抽離
                    test: /node_modules/,
                    chunks: 'initial', //入口處開始
                    minSize: 0, //大于0的公用代碼塊
                    minChunks: 2
                }
            }

        }
    }
}

更過optimization配置請(qǐng)看webpack文檔

最后

到此,筆記結(jié)束忧吟。如有錯(cuò)誤砌函,歡迎在指出。


如果覺得可以溜族,幫忙點(diǎn)個(gè)贊讹俊。如有不對(duì)還忘指出,謝謝煌抒。
傳送門git筆記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仍劈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子寡壮,更是在濱河造成了極大的恐慌贩疙,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件况既,死亡現(xiàn)場(chǎng)離奇詭異这溅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)棒仍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門悲靴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人莫其,你說我怎么就攤上這事癞尚∷嗜” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵浇揩,是天一觀的道長吕晌。 經(jīng)常有香客問我,道長临燃,這世上最難降的妖魔是什么睛驳? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮膜廊,結(jié)果婚禮上乏沸,老公的妹妹穿的比我還像新娘。我一直安慰自己爪瓜,他們只是感情好蹬跃,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铆铆,像睡著了一般蝶缀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上薄货,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天翁都,我揣著相機(jī)與錄音,去河邊找鬼谅猾。 笑死柄慰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的税娜。 我是一名探鬼主播坐搔,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼敬矩!你這毒婦竟也來了概行?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤弧岳,失蹤者是張志新(化名)和其女友劉穎凳忙,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缩筛,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡消略,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年堡称,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞎抛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡却紧,死狀恐怖桐臊,靈堂內(nèi)的尸體忽然破棺而出胎撤,到底是詐尸還是另有隱情,我是刑警寧澤断凶,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布伤提,位于F島的核電站,受9級(jí)特大地震影響认烁,放射性物質(zhì)發(fā)生泄漏肿男。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一却嗡、第九天 我趴在偏房一處隱蔽的房頂上張望舶沛。 院中可真熱鬧,春花似錦窗价、人聲如沸如庭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坪它。三九已至,卻和暖如春帝牡,著一層夾襖步出監(jiān)牢的瞬間往毡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工靶溜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卖擅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓墨技,卻偏偏與公主長得像惩阶,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扣汪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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

  • 前言 本文主要從webpack4.x入手断楷,會(huì)對(duì)平時(shí)常用的Webpack配置一一講解,各個(gè)功能點(diǎn)都有對(duì)應(yīng)的詳細(xì)例子崭别,...
    BetterChen閱讀 1,948評(píng)論 0 3
  • 一冬筒、入坑初探 1. 設(shè)置項(xiàng)目為私有 我們只需要在package.json文件中配置,因?yàn)槭撬接许?xiàng)目不需要向外部暴露...
    zxhnext閱讀 2,039評(píng)論 0 15
  • 一茅主、使用webpack的原因 原生瀏覽器舞痰,不能很好的識(shí)別 ES6 以及更高版本中 ES moudule 模塊引入方...
    小a你好閱讀 790評(píng)論 3 3
  • 斷斷續(xù)續(xù),病了一陣子诀姚。 健康的時(shí)候總是太貪心响牛,這也舍不得,那也舍不得。 只有病了的時(shí)候呀打,可以心安理得地早早休息矢赁。 ...
    早安5點(diǎn)55閱讀 269評(píng)論 0 0
  • 至于原因,我想也許太忙碌了贬丛,或者給自己找了借口撩银,還好我沒放棄。但是本來簡書只是我解壓的一個(gè)工具豺憔,我不想自己有太多的...
    向日葵孔小姐閱讀 475評(píng)論 6 9