webpack使用入門(設定loader:style、css、url、file、babel;plugin:html-webpack、mini-css-extract、clean-webpack)

2021-05-26 07:00:28

目錄

webpack介紹

使用方法

解決webpack-cli和webpack-dev-server版本衝突問題

構建基本框架

不使用webpack.dev.js檔案打包

使用webpack.dev.js檔案打包

簡化webpack命令列

引入jquery模組

通過html-webpack-plugin外掛生成html(自動引入js程式碼)

loader匯入css檔案

分離css檔案

loader匯入less檔案

載入圖片

清除dist目錄外掛

es6向下相容es5

生產環境打包檔案

提取公共模組設定

使用他人的檔案

plugin連結

loader連結


webpack介紹

一個前端資源載入/打包工具。它將根據模組的依賴關係進行靜態分析,然後將這些模組按照指定的規則生成對應的靜態資源(把一堆的css檔案和js檔案放在一個總的入口檔案,通過require引入,剩下的事情webpack會處理,包括所有模組的前後依賴關係,打包、壓縮、合併成一個js檔案,公共程式碼抽離成一個js檔案、某些自己指定的js單獨打包,模組可以是css/js/imsge/font等等)。
下面是webpack包含的一些模組。

使用方法

首先使用命令列全域性安裝webpack、webpack-cli、webpack-dev-server,其中webpack-cli需要指定版本號,因為預設安裝的最新是4點幾的版本和webpack-dev-server最新3點幾的版本衝突。以下命令列程式碼都是在當前資料夾下執行-D表示下載為本地專案依賴和-save-dev相同,然後npm installyarn add相同都是下載檔案

命令列:npm install webpack webpack-cli@3.3.12 webpack-dev-server -g安裝全域性webpack命令。

已安裝了最新版本的可以通過下面方法解決。

解決webpack-cli和webpack-dev-server版本衝突問題

  1. npm i webpack-cli@3.3.12 -D
  2. 將webpack.config.js中"start"修改如下:

     "scripts": {

            "build": "node_modules/.bin/webpack --config webpack.config.js",

            "start": "webpack serve --config webpack.config.js --open "

        }

構建基本框架

在專案資料夾(取名不要為webpack)下建立src、dist、config資料夾,然後通過npm init -y建立package.js檔案。然後在dist資料夾下建立index.html(主網頁程式碼),在src資料夾下建立index.js檔案,再次安裝npm install webpack webpack-cli@3.3.12 webpack-dev-server -D(因為組態檔需要使用到require等語句匯入webpack中的模組)。

不使用webpack.dev.js檔案打包

webpack4點幾提供的新打包命令,當需要載入css、圖片(載入外掛和使用loaders等)等時還是需要使用webpack.dev.js打包

在命令列中輸入webpack --mode=development (打包模式為開發者環境)或webpack --mode=production(打包模式為生產者環境,經過壓縮了,不會打包一些未使用的程式碼),最後在dist的資料夾下會生成main.js檔案。

使用webpack.dev.js檔案打包

緊接構建基本框架後,並在src資料夾下建立main.js,在config檔案下建立webpack.dev.js。編輯webpack.dev.js檔案如下圖,引數含義如下:

其中entry為入口通過陣列包裹多個入口檔名(此時會將陣列中的多個檔案打包成一個檔案,要想打包成輸出多個檔案,可給entry物件新增屬性index:['./src/main.js'],這時便會多生成一個打包檔案index-bundle.js),mode為模式可以為development和production,output為出口只能有一個出口,filename代表出口檔名[name]代表入口檔案的main,生成的檔名為main-bundle.js(該檔案包含所有js檔案,在index.html中便只需要匯入該檔案),path為路徑path.resolve()會返回路徑名(將引數進行拼接後的路徑名,若字元以 / 開頭,不會拼接到前面的路徑;若以 ../ 開頭,拼接前面一個引數的路徑,該引數不含最後一節路徑;若以 ./ 開頭或者沒有符號 則拼接前面路徑),__dirname代表當前檔案的絕對路徑(不包含檔名),程式碼中的意思是返回dist檔案的絕對路徑。publicPath為設定當前的路徑名,例如'/'時,在index.html中引入main-bundle.js就需要通過'/main-bundle.js'或'main-bundle.js';而為'/js'時,就需要通過'/js/main-bundle.js'引入。devServer代表本地伺服器,contentBase代表設定http://localhost:8080/存取的基礎路勁為dist檔案即直接存取indexl.html(未設定的話http://localhost:8080/會開啟專案的目錄),overlay讓錯誤資訊可以在網頁中顯示,port代表原生的埠預設為8080,open為是否自動開啟網頁。

const path = require('path')
module.exports = {
    entry: {
        main: ['./src/main.js','./src/index.js']
    },
    mode: 'development',
    output: {
        filename: '[name]-bundle.js',
        path: path.resolve(__dirname, '../dist'),
        publicPath:'/'
    },
    devServer:{
        contentBase: 'dist',
        overlay: true,
        port:8080,
        open:true
    },
    // module:{
    //     rules:[
    //         {
    //             test:/\.css$/,
    //             use:[
    //                 {
    //                     loader:'style-loader'
    //                 },
    //                 {
    //                     loader:'css-loader'
    //                 }
    //             ]
    //         }
    //     ]
    // }
}

命令列中執行webpack --config=config/webpack.dev.js(按照webpack.dev.js中的設定打包檔案)然後會在dist資料夾下生成main-bundle.js,最後輸入webpack-dev-server --config=config/webpack.dev.js(按照webpack.dev.js中的設定把專案佈置到本地伺服器上,可以不用生成main-bundle.js即可以在上一個命令前執行),便可以在網頁上開啟http://localhost:8080/存取到index.html檔案,而index.html檔案便可以通過引入main-bundle.js引入index.js和main.js。

簡化webpack命令列

修改package.json中的script標籤,如下圖新增start和build。這時npm start命令便等於webpack-dev-server --config=config/webpack.dev.js。

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start":"webpack-dev-server --config=config/webpack.dev.js",
    "build":"webpack --config=config/webpack.dev.js"
  }

引入jquery模組

在命令列輸入npm install jquery -D,然後在main.js中通過const $=require('jquery'),之後再main.js中便可以通過$符號來使用jQery函數。

通過html-webpack-plugin外掛生成html(自動引入js程式碼)

將index.html移入src資料夾下,執行命令列npm install html-webpack-plugin -D安裝外掛,設定webpack.dev.js中寫入const HtmlWebpackPlugin = require('html-webpack-plugin')用於引入自動生成html的外掛,給module.export指向的物件新增屬性plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],其中template指定的模板便是移入src資料夾下的index.html的路徑,這裡需要注意雖然我的webpack.dev.js檔案是在config資料夾下,但是這裡的相對路勁./依然指的是專案路徑即config的上層路徑。最後執行webpack --config=config/webpack.dev.js後會在dist檔案上生成一個index.js檔案,該檔案中會自動引入main-bundle.js即打包後的出口檔案(不需要手動引入了)。

loader匯入css檔案

在src資料夾下建立main.css在main.js中通過require('./main.css')引入,命令列輸入npm install style-loader css-loader -D安裝css-loader(能識別CSS並載入,支援模組化、壓縮、檔案匯入等特性)和style-loader(通過動態建立style標籤的方式,讓解析後的css內容能夠作用到頁面中)。然後將webpack.dev.js圖中註釋內容開啟即可(test是通過正規表示式匹配檔案,use中為使用的loader),再次執行webpack-dev-server --config=config/webpack.dev.js便可以在http://localhost:8080/中看到新增了css的index.html檔案。在devServer中新增屬性overlay:true可以使錯誤資訊不僅在命令列中顯示,還會在頁面中顯示。

分離css檔案

命令列輸入npm install mini-css-extract-plugin -D安裝分離外掛,在webpack.dev.js中輸入const MiniCssExtractPlugin = require('mini-css-extract-plugin'),將之前設定style-loader的物件替換為{loader:MiniCssExtractPlugin.loader},最後在plugins的陣列中新增new MiniCssExtractPlugin({filename:'./index.css'})即可,filename代表分離出來的css名字和地址,這裡注意./表示的位置是dist資料夾下。

loader匯入less檔案

less是css預處理檔案,引入了變數函數等是css處理更靈活。首先命令列輸入npm install less less-loader -D,然後在src資料夾下建立iheader.less檔案,在main.js中寫入require('./header.less'),然後設定ebpack.dev.js,在rules陣列中新增{test: /\.less$/i,use: ["style-loader","css-loader","less-loader",],},注意這裡還是會生成style標籤插入,想要分離出來,把"style-loader"替換為{loader:MiniCssExtractPlugin.loader},這時less檔案也會被分離到index.css中

載入圖片

命令列輸入npm install url-loader file-loader -D,設定webpack.dev.js檔案,在rules陣列中新增物件{test: /\.(png|jpg|gif)$/i,use: [{loader: 'url-loader',options: {limit: 8192,name:'[name].[ext]',publicPath:'images/',outputPath:'images/'}}]}即可,這時可以在css和less檔案中使用圖片,(這裡的圖片會被預設轉換為base64字串格式,好處是瀏覽器不用傳送請求了,直接可以讀取,壞處是圖片如果太大,會導致轉換後體積增大30%,所以這裡設定了大小限制limit,表示當大於8kb時,在dist資料夾中建立images資料夾,在該資料夾下生成圖片,通過連結匯入,小於時才會base64轉換),注意css和less檔案中使用圖片的地址是src下的圖片和檔案的相對地址,而html中img標籤使用的地址是publicPath(靜態資源的參照路徑)

清除dist目錄外掛

命令列輸入npm install clean-webpack-plugin -D,在webpack.dev.js中輸入const { CleanWebpackPlugin } = require('clean-webpack-plugin'),然後在plugins陣列中新增new CleanWebpackPlugin()即可,這時我們每次輸入命令列webpack --config=config/webpack.dev.js後都會先清空dist資料夾,然後在生成打包的檔案。

es6向下相容es5

命令列輸入npm install -D babel-loader @babel/core @babel/preset-env,在webpack.dev.js中rules陣列下新增物件{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use:{ loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},此時如果在main.js寫了es6的語法會被轉換成es5(在最後的輸出檔案main-bundle.js可以檢視)。

生產環境打包檔案

命令列輸入npm install webpack-merge -D,在config資料夾下新建檔案webpack.pro.js(生產環境設定)和webpack.base.js(公用設定),之前的webpack.dev.js是開發環境的設定。設定webpack.base.js,將之前webpack.dev.js的內容全部複製過去,去除devServer和mode屬性,然後在重新設定webpack.dev.js為下圖程式碼,接著設定webpack.pro.js同樣為下圖,不同在於去除devServer屬性並將mode改為'production'即可(下圖中引數其中meige()中可以傳入多個物件,會將多個引數合併成一個物件,如果有重複屬性名,後面的物件屬性會覆蓋前面的)。

const base = require('./webpack.base');
const {merge} = require('webpack-merge');
module.exports = merge(base, {
    mode: 'development',
    devServer: {
        contentBase: 'dist',
        overlay: true,
        port: 8080,
        open: true
    }
})

此時可以通過webpack --config=config/webpack.dev.js打包為開發環境的,通過webpack --config=config/webpack.pro.js打包為生產者環境。

提取公共模組設定

當有多入口檔案生成多個打包檔案時,如果入口檔案中都用到jQuery,需要都引入,這時打包檔案會重複打包jquery,需要重新設定在webpack.base的module.exports物件中新增屬性optimization: {splitChunks: {chunks: 'all'}},這時便會提取公共模組設定。不會重複打包重複的模組。

使用他人的檔案

需要config檔案,src檔案,pack.json檔案,然後進入到專案檔案中命令列輸入yarn即可安裝他人所有區域性依賴,這樣便可以通過之前命令打包和佈置本地伺服器上使用。

plugin連結

https://v4.webpack.js.org/plugins/

loader連結

https://v4.webpack.js.org/loaders/