Webpack4 那點兒東西

What

近幾年,構建對於前端開發來講是一個很重要的名詞,它給前端開發注入了很大的活力,解放了不少生產力。而webpack在前端項目中起了不可小覷的做用,它能夠將咱們所用的各類瀏覽器不認識的代碼好比es6,es7,sass,less等轉換爲瀏覽器認識的語言,能夠對文件進行壓縮合並,代碼進行分割,模塊合併。。。css

Why

昨天翻看我司的項目,雖然各個項目用的都是webpack,可是哪一個版本的都有,webpack1,webpack2,webpack3應有具備。不少插件隨着版本的升級是會有問題或者是不能再用的,所以對於webpack的配置仍是要不斷更新,不斷學習的。因此我以爲有必要總結一下,正巧webpack於2018年2月25日正式發佈v4.0.0版本,代號legato,因此本文基於最新的webpack4.0進行講解常規用法。不過第一步,我以爲仍是有必要講下webpack4的Update Log中比較重要的幾條。html

Update

  1. 環境支持: 官方宣佈再也不支持Node 4, Node 6,使用的是v8 5.0版本,支持93%的ES6語法。由於webpack4使用了不少JS新的語法,它們在新版本的 v8 裏通過了優化。
  2. 0配置 受Parcel打包工具啓發,儘量的讓開發者運行項目的成本變低。webpack4再也不強制須要 webpack.config.js 做爲打包的入口配置文件了,它默認的入口爲'./src/'和默認出口'./dist',這對於小項目來講確實是一件不錯的事情。
  3. Mode webpack須要設置mode屬性,可選 development 或 production。
"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}
複製代碼

development模式特性:前端

a.瀏覽器調試工具
b.註釋、開發階段的詳細錯誤日誌和提示
c.快速和優化的增量構建機制
複製代碼

production模式特性:node

a.開啓全部的優化代碼
b.更小的bundle大小
c.去除掉只在開發階段運行的代碼
d.Scope hoisting和Tree-shaking
複製代碼
  1. 插件變化 webpack4刪除了CommonsChunkPlugin插件,它使用內置API optimization.splitChunks 和 optimization.runtimeChunk,即webpack會默認爲你生成共享的代碼塊。
  2. 開箱即用WebAssembly(筆者暫時未使用)

Use

  1. 配置項
  • Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。
  • Module:模塊,在 Webpack 裏一切皆模塊,一個模塊對應着一個文件。Webpack 會從配置的 Entry 開始遞歸找出全部依賴的模塊。
  • Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用於代碼合併與分割。
  • Loader:模塊轉換器,用於把模塊原內容按照需求轉換成新內容。
  • Plugin:擴展插件,在 Webpack 構建流程中的特定時機注入擴展邏輯來改變構建結果或作你想要的事情。
  • Output:輸出結果,在 Webpack 通過一系列處理並得出最終想要的代碼後輸出結果。
  1. 啓動命令 執行webpack --mode development 會去全局找webpack包,若是沒有安裝的話會告訴你 bash: webapck: command not found。解決方案:
  • 使用npx 即 npx webpack development( npm 5.2.0版本支持的一個工具)詳細介紹
  • 在package.json中配置scripts
"scripts": {
    "build": "webpack --mode development",
    "dev": "webpack-dev-server --open --mode development"
  },
複製代碼
  1. 上述在scripts咱們已經配好了webpack-dev-server,它是開發時的一個服務器,把打包的文件所有放入內存中,能夠熱更新,熱替換等方便咱們開發。
npm i webpack-dev-server ---save-dev
複製代碼

完整簡單配置:webpack

const path = require('path');
module.exports = {
    entry:path.resolve(__dirname,'src','index.js'),
    output:{
        path: path.resolve(__dirname,'dist'),
        filename:'bundle.js'
    },
    devServer:{//配置此靜態文件服務器,能夠用來預覽打包後項目
        contentBase:path.resolve(__dirname,'dist'),//開發服務運行時的文件根目錄
        host:'localhost',//主機地址
        port:9090,//端口號
        compress:true//開發服務器是否啓動gzip等壓縮
    }
}
複製代碼

4.css文件處理 css-loader用來解析處理CSS文件中的url路徑,要把CSS文件變成一個模塊,style-loader 能夠把CSS文件變成style標籤插入head中。執行順序從右向左依次執行,先走css-loader,再走style-loader.es6

npm i style-loader css-loader ---save-dev
rules: [
            {
                test:/\.css$/,
                loader:['style-loader','css-loader']
            }
        ]
複製代碼

5.產出htmlweb

npm i html-webpack-plugin ---save-dev
plugins:[
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname,'src','index.html'),//模板
            filename:'index.html',
            hash:true,//防止緩存
            minify:{
                removeAttributeQuotes:true//壓縮 去掉引號
            }
        })
],
複製代碼

6.提取css文件爲單獨文件,不是像上面直接打包進入js中,注意extract-text-webpack-plugin 必須下載next版本 否則不支持webpack4npm

npm install --save-dev extract-text-webpack-plugin@next
 rules: [
            {
                test:/\.css$/,
                // loader:['style-loader','css-loader']
                use:ExtractTextWebapckPlugin.extract({
                    use:'css-loader'
                })//再也不須要style-loader

            }
        ]
new ExtractTextWebapckPlugin('css/index.css')
複製代碼
  1. sass less 文件處理
npm i less less-loader ---save-dev
npm i node-saas sass-loader ---save-dev
const lessExtract = new ExtractTextWebapckPlugin('css/less.css');
const sassExtract = new ExtractTextWebapckPlugin('css/sass.css');
 {
    test:/\.less$/,
    use:lessExtract.extract({
        use: ['css-loader','less-loader']
    })
},
{
    test:/\.scss$/,
    use: sassExtract.extract({
        use:['css-loader','sass-loader']
    })
}
複製代碼
  1. babel轉換js
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 --save-dev
{
    test: /\.js/,
    use: {
        loader: 'babel-loader',
        query: {
            presets: ["env", "stage-0"]
        }
}
複製代碼
  1. 經常使用的三種加載圖片的方式
  • css中引入
body{
    color: red;
    background: url(./images/002.jpg) no-repeat;
}
複製代碼
  • js動態引入
let imgSrc = require('./images/002.jpg');
let img = new Image();
img.src = imgSrc;
document.body.appendChild(img);
複製代碼
  • html img標籤
<img src="./images/002.jpg" alt="">
複製代碼

前兩種 使用 file-loader( 解決CSS等文件中的引入圖片路徑問題) url-loader(當圖片較小的時候會把圖片BASE64編碼,大於配置的limit參數的時候仍是使用file-loader 進行拷貝)json

npm i file-loader url-loader --save-dev
{
test:/\.(jpg|png|gif|svg)$/,
use:'url-loader',
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
複製代碼

第三種使用html-withimg-loader進行處理數組

npm i html-withimg-loader --save-dev
{
    test:/\.(html|htm)$/,
    use:'html-withimg-loader'
}
複製代碼
  1. 多入口問題 數組的模式並非多入口,一下入口最終只生成一個js
entry: [path.resolve(__dirname, 'src', 'index.js'),path.resolve(__dirname, 'src', 'base.js')],
複製代碼

多入口的正確寫法是對象的形式,如下入口會產出兩個js文件

entry:{
        index:'./src/index.js',
        base:'./src/base.js'
},
複製代碼

多入口對應的html加載模塊用chunk區分

new HtmlWebpackPlugin({
    template: path.resolve(__dirname,'src','index.html'),
    filename:'index.html',
    chunks:['index'],
    hash:true,//防止緩存
    minify:{
        removeAttributeQuotes:true//壓縮 去掉引號
    }
}),
new HtmlWebpackPlugin({
    template: path.resolve(__dirname,'src','index.html'),
    filename:'base.html',
    chunks:['base'],
    hash:true,//防止緩存
    minify:{
        removeAttributeQuotes:true//壓縮 去掉引號
    }
}),
複製代碼
  1. 加入兩個文件都須要引入一個第三方庫,好比lodash,這時候咱們再每一個模塊內部都須要引入一下,所以打包的時候每一個入庫都會把lodash打包進去,文件變得很大,這時候咱們能夠把lodash變成一個入口文件,而後經過webpack.ProvidePlugin暴露變量,在html中chunk中引用,具體以下:
entry:{
        index:'./src/index.js',
        base:'./src/base.js',
        vendor:'lodash'
} 
new webpack.ProvidePlugin({
            _:'lodash'
})
new HtmlWebpackPlugin({
    template: path.resolve(__dirname,'src','index.html'),
    filename:'base.html',
    chunks:['base','vendor'],
    hash:true,//防止緩存
    minify:{
        removeAttributeQuotes:true//壓縮 去掉引號
    }
}),
複製代碼

咱們也能夠經過expose-loader向全局暴露一個對象

let _=require('expose-loader?_!lodash');
複製代碼
  1. watch監聽文件打包變化,當文件變化時自動打包
watch: true,
watchOptions: {
    ignored: /node_modules/, //忽略不用監聽變動的目錄
    aggregateTimeout: 500, //防止重複保存頻繁從新編譯,500毫米內重複保存不打包
    poll:1000 //每秒詢問的文件變動的次數
},
複製代碼
  1. resolve解析(比較經常使用,能夠不寫文件後綴名)
resolve:{
    extensions: ["",".js",".css",".json"]
},
複製代碼

14.壓縮js,讓輸出的JS文件體積更小、加載更快、流量更省,還有混淆代碼的加密功能

npm i uglifyjs-webpack-plugin --save-dev
直接new一下便可
new UglifyjsWebpackPlugin()
複製代碼

小結

常見的基本用法大概就總結了這麼多,有興趣能夠接着閱讀Webpack4優化之路

相關文章
相關標籤/搜索