webpack v4 從dev到prd

目錄

  • 概述
  • Big changes
  • 加載loader方法總結
  • 開發必備的loader&plugins
  • 優化向prd進發
  • 未完待續

概述

本月迎來了 v4 正式版的發佈,本文用於學習新特性和總結開發必用plugin & loader,從dev到prd,走你~

Big changes

  • Environmentcss

    • Node.js 4 is no longer supported. Source Code was upgraded to a higher ecmascript version.
  • Usagehtml

    • You have to choose (mode or --mode) between two modes now: production or development
本次新版本中引入了 mode 配置項,開發者可在 none,development(開發 ) 以及 production(產品)三種模式間選擇。該配置項缺省狀況下默認使用 production 模式。
  • development 模式給你極致的開發體驗,包含瀏覽器調試相關工具,極快的增量編譯,豐富全面的報錯信息...
  • production 模式則包含大量發版優化,代碼壓縮,絲般潤滑的運行時優化,開發相關代碼的排除,易用,etc.
  • none 不使用預設,等於老版本中所有本身配置的原始狀態。

eg:node

webpack --mode development
  • Usagereact

    • Some Plugin options are now validated
    • CLI has been move to webpack-cli, you need to install webpack-cli to use the CLI
    • The ProgressPlugin (--progress) now displays plugin names

At least for plugins migrated to the new plugin systemwebpack

新版中將 webpack 命令行工具拆分到單獨的倉庫中,因此須要額外安裝 webpack-cli。
npm init -y //初始化項目
npm install webpack webpack-cli -D //安裝webpack webpack-cli 依賴
npx webpack --mode development // npx能夠直接運行node_modules/.bin目錄下面的命令

或者經過配置package.json的script build
"scripts": {
    "build": "webpack --mode development",
},

加載loader方法總結

  • use
module: {
    rules:[
        { 
            test: /\.css$/,
            use: ['style-loader','css-loader']
        }
    ]
}

css-loader用來解析處理CSS文件中的url路徑,web

要把CSS文件變成一個模塊
多個loader是有順序要求的,從右往左寫,由於轉換的時候是從右往左轉換ajax

此插件先用css-loader處理一下css文件,再用style-loader把CSS文件變成style標籤插入head中npm

  • loader
module: {
    rules:[
        {
            test: /\.css$/,
            loader: ["style-loader", "css-loader"]
        },
    ]
}
  • use+loader
module: {
    rules:[
        {
            test: /\.css$/,
            use:[
                { loader:"style-loader"},
                { 
                    loader: 'css-loader',
                    options: {sourceMap: true}
                }
            ]
        }
    ]
}
這三種loader的寫法,最後打包的結果相同

loader中的options配置項能夠用"?"跟在加載器後面json

eg:瀏覽器

{  
    test: /\.jpeg$/,  
    use: 'url-loader?limit=1024&name=[path][name].[ext]&outputPath=img/&publicPath=output/',  
}

爲如下配置的簡寫

{  
    test: /\.jpeg$/,  
    use: {
        loader:'url-loader',
        options:{
            limit:1024,
            name:[path][name].[ext],
            outputPath:img/
            publicPath:output/'
        }
    }
}

開發必備的loader&plugins

  • css-loader
  • babel-loader
講ES6代碼轉換爲ES5
{
    test: /\.js/,
    use: {
        loader: 'babel-loader',
        query: {
            presets: ["env", "stage-0", "react"]
        }
    }
},

babel-loader的預設能夠添加在query中,也能夠在項目根目錄添加 .babelrc 文件

.babelrc

{
    "presets": [
        "env",
        "stage-0",
        "react"
    ]
}
  • html-webpack-plugin

插件的基本做用就是生成html文件。原理很簡單:

將 webpack中 entry配置的相關入口thunk 和 extract-text-webpack-plugin抽取的css樣式 插入到該插件提供的 template或者 templateContent配置項指定的內容基礎上生成一個html文件,具體插入方式是將樣式 link插入到 head元素中, script插入到 head或者 body中。
const HtmlWebpackPlugin = require('html-webpack-plugin');

new HtmlWebpackPlugin({
    template: './src/index.html',//指定產的HTML模板
    filename: `index.html`,//產出的HTML文件名
    title: 'index',
    hash: true,// 會在引入的js里加入查詢字符串避免緩存,
    minify: {
        removeAttributeQuotes: true
    }
}),

能夠用 cnpm search html-webpack-plugin 查找想用loader的用法

  • less-loader sass-loader

優化向prd進發

  • 提取公共的css代碼
它會將全部的入口 chunk(entry chunks)中引用的 *.css,移動到獨立分離的 CSS 文件。所以,你的樣式將再也不內嵌到 JS bundle 中,而是會放到一個單獨的 CSS 文件(即 styles.css)當中。 若是你的樣式文件大小較大,這會作更快提早加載,由於 CSS bundle 會跟 JS bundle 並行加載。
npm i extract-text-webpack-plugin@next -D
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin({
    filename: 'css/css.css',
    allChunks: true
});
module:{
    rules:[
        {
            test: /\.css$/,//轉換文件的匹配正則
            loader: cssExtract.extract({
                use: ["css-loader?minimize"]
            })
        },
    ]
}
plugins:[
    ...... ,
    + cssExtract
]
  • 儘可能減小文件解析,用resolve配置文件解析路徑,include
rules: {
    test: /\.js$/,
    loader:'babel-loader',
    include: path.resolve(__dirname, 'src'),//只轉換或者編譯src 目錄 下的文件
    exclude: /node_modules/ //不要解析node_modules
}
  • resolve.mainFields
WebpackTest
|
|
| - src
|   | - index.js
|
| - lib
|   | - fetch
|       |
|       browser.js
|       node.js
|       package.json
|
| - webpack.config.js
當從 npm 包中導入模塊時(例如,引入lib下的庫),此選項將決定在 package.json 中使用哪一個字段導入模塊。根據 webpack 配置中指定的 target 不一樣,默認值也會有所不一樣。

package.json

lib文件夾下的package.json中配置相對應模塊的key

{
  "name": "fetch",
  "version": "1.0.0",
  "description": "",
  "node": "./node.js",
  "browser": "./browser.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

webpack.config.js

在resolve解析對象中,加入lib的路徑
resolve: {
    extensions: ['.js', '.json'],
    mainFields: ['main', 'browser', 'node'],
    modules: [path.resolve('node_modules'), path.resolve('lib')]
}

index.js

這樣在index.js中引用第三方庫時,會去查找modules下的路徑中是否配置了所需的文件,知道在package.json中找到mainFields中的key對應文件,中止。
let fetch = require('fetch');
console.log(fetch);

打包後 console.log出的對象

若是交換mainFields中的key順序

mainFields: ['main', 'node','browser']

打包後 console.log出的對象,由於找到了key=node對應的文件就中止了查找

  • DllReferencePlugin
這個插件是在 webpack 主配置文件中設置的, 這個插件把只有 dll 的 bundle(們)(dll-only-bundle(s)) 引用到須要的預編譯的依賴。

新建webpack.react.config.js

const path = require('path');
const webpack = require('webpack')
module.exports = {
    entry: {
        react: ['react', 'react-dom']
    },
    output: {
        path: path.join(__dirname, 'dist'),// 輸出動態鏈接庫的文件名稱
        filename: '[name]_dll.js',
        library: '_dll_[name]'//全局變量的名字,其它會今後變量上獲取到裏面的模塊
    },
    // manifest 表示一個描述文件
    plugins: [
        new webpack.DllPlugin({
            name: '_dll_[name]',
            path: path.join(__dirname, 'dist', 'manifest.json')//最後打包出來的文件目錄和名字
        })
    ]
}
在entry入口寫入要打包成dll的文件,這裏把體積較大的react和react-dom打包

output中的關鍵是library的全局變量名,下文詳細說明dll&manifest工做原理

打包dll文件

webpack --config webpack.react.config.js --mode development

打包出來的manifest.json節選

打包出來的react_dll.js節選

可見manifest.json中的 name值就是

output:{
    library:_dll_react
}

manifest.json就是借書證,_dll_react就像圖書館書籍的條形碼,爲咱們最終找到filename爲react_dll.js的參考書

使用「參考書」

在webpack.config.js中加入「借書證」

new webpack.DllReferencePlugin({
    manifest: path.join(__dirname, 'dist', 'manifest.json')
})

再運行

webpack --mode development

打包速度顯著變快

打包後的main.js中,react,react-dom.js也打包進來了,成功~

import React from 'react';\n//import ReactDOM from 'react-dom';
(function(module, exports, __webpack_require__) {

"use strict";
eval("\n\n//import name from './base';\n//import React from 'react';\n//import ReactDOM from 'react-dom';\n//import ajax from 'ajax';\n//let result = ajax('/ajax');\n\n//ReactDOM.render(<h1>{result}</h1>, document.getElementById('root'));\n// fetch fetch.js fetch.json fetch文件夾\n//let fetch = require('fetch');\n//console.log(fetch);\n//let get = require('../dist/bundle.js');\n//get.getName();\nconsole.log('hello');\n\nvar name = 'zfpx';\nconsole.log(name);\nif (true) {\n    var s = 'ssssssssssssssssssssssss';\n    console.log(s);\n    console.log(s);\n    console.log(s);\n    console.log(s);\n}\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ })

/******/ });

未完待續

  • webpack.ProvidePlugin
  • 拷貝靜態資源
  • 壓縮css(npm i -D purifycss-webpack purify-css)

以爲好玩就關注一下~歡迎你們收藏寫評論~~~

相關文章
相關標籤/搜索