webpack

一、 初試牛刀

1.簡(jiǎn)介

1) 為什么要使用webpack

現(xiàn)今的很多網(wǎng)頁(yè)其實(shí)可以看做是功能豐富的應(yīng)用,它們擁有著復(fù)雜的JavaScript代碼和一大堆依賴包。為了簡(jiǎn)化開發(fā)的復(fù)雜度,前端社區(qū)涌現(xiàn)出了很多好的實(shí)踐方法

? 模塊化,讓我們可以把復(fù)雜的程序細(xì)化為小的文件

? 類似于TypeScript這種在JavaScript基礎(chǔ)上拓展的開發(fā)語(yǔ)言:使我們能夠?qū)崿F(xiàn)目前版本的JavaScript不能直接使用的特性,并且之后還能轉(zhuǎn)換為JavaScript文件使瀏覽器可以識(shí)別

? Scss,less等CSS預(yù)處理器

? ES6 babel

這些改進(jìn)確實(shí)大大的提高了我們的開發(fā)效率,但是利用它們開發(fā)的文件往往需要進(jìn)行額外的處理才能讓瀏覽器識(shí)別,而手動(dòng)處理又是非常繁瑣的,這就為WebPack類的工具的出現(xiàn)提供了需求

2) 什么是webpack

WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語(yǔ)言(Scss,TypeScript等),并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用。將多個(gè)文件打包成一個(gè)文件或者對(duì)項(xiàng)目進(jìn)行優(yōu)化(打包,轉(zhuǎn)化和優(yōu)化)。

image.png

2.起步

1) 安裝

參考文獻(xiàn):
https://blog.csdn.net/xiaolinlife/article/details/85058160
https://www.cnblogs.com/aizai846/p/11497508.html

前提條件:在開始之前,請(qǐng)確保安裝了 Node.js 的最新版本。使用 Node.js 最新的長(zhǎng)期支持版本(LTS - Long Term Support),是理想的起步。使用舊版本,你可能遇到各種問題,因?yàn)樗鼈兛赡苋鄙?webpack 功能以及/或者缺少相關(guān) package 包。

要安裝最新版本或特定版本,請(qǐng)運(yùn)行以下命令之一

npm install --save-dev webpack或者npm i webpack --save-dev

npm install --save-dev webpack@<version>

如果你使用 webpack 4+ 版本,你還需要安裝 CLI

npm install --save-dev webpack-cli或者npm i webpack-cli -D

webpack與webpack-cli兩者結(jié)合簡(jiǎn)寫
npm i webpack webpack-cli -D

輸入如下命令,將在項(xiàng)目目錄中自動(dòng)生成package.json文件

npm init -y //不加-y為手動(dòng)生成

補(bǔ)充:

npm install name -save 簡(jiǎn)寫(npm install name -S) 自動(dòng)把模塊和版本號(hào)添加到dependencies

npm install name -save-dev 簡(jiǎn)寫(npm install name -D) 自動(dòng)把模塊和版本號(hào)添加到devdependencies

-D后,安裝包會(huì)在package中的 devDependencies對(duì)象中,簡(jiǎn)稱dev,dev是在開發(fā)環(huán)境中要用到的

-S后,安裝包會(huì)在package中的 dependencies 對(duì)象中,簡(jiǎn)稱dep,dep是在生產(chǎn)環(huán)境中要用到的

舉個(gè)例子:
構(gòu)建工具:gulp和webpack是用來(lái)壓縮代碼,打包等需要的工具,程序?qū)嶋H運(yùn)行的時(shí)候并不需要,就要放在dev中所以要用 -D
項(xiàng)目插件:例如element ui、echarts這種插件要在運(yùn)行中使用的,就要放在dep中所以就用 -S

對(duì)于大多數(shù)項(xiàng)目,我們建議本地安裝。這可以使我們?cè)谝肫茐氖阶兏?breaking change)的依賴時(shí),更容易分別升級(jí)項(xiàng)目。通常,webpack 通過運(yùn)行一個(gè)或多個(gè) npm scripts,會(huì)在本地 node_modules 目錄中查找安裝的 webpack

"scripts": {
    "start": "webpack --config webpack.config.js"
}

當(dāng)你在本地安裝 webpack 后,你能夠從 node_modules/.bin/webpack 訪問它的 bin 版本

2) 簡(jiǎn)單使用

image.png
const path = require('path')
module.exports = {
    mode: 'production',
    entry:'./src/js/index.js',
    output:{
        path:path.join(__dirname,'dist'),
        filename:"bundle.js"
    },
}

3.初識(shí)webpack

1) webpack打包一個(gè)文件

webpack  ./src/index.js --output dist/bundle.js

2) webpack配置文件

module.exports= {
    //入口
    entry:{},
    //出口
    output:{},
    //loader加載器
    module:{
        rules: [
            { test: /\.txt$/, use: 'raw-loader' }
        ]
    },
    //插件
    plugins:{},
    //開發(fā)服務(wù)器
    devServer:{}    
}

4) webpack的配置文件名

默認(rèn)的是webpack.config.js。但是不一定必須是這個(gè)

webpack --config config_file_name

5) 配置npm 命令

在package.json文件中具有一個(gè)scripts的設(shè)置項(xiàng)中可以設(shè)置npm的命令

例如:npm run build

“scripts”:{
    “build”:“webpack --config config_file_name”
 }

 "scripts": {
    "build": "./node_modules/.bin/webpack --config webpack.config.js"
  }

// webpack4.x
“scripts”:{
    “build”:“webpack”
 }

注意:編譯后的文件在“/”目錄下,在html里引入時(shí)路徑應(yīng)為"/indexbundle.js"

6) 模式

webpack  --mode develepment
webpack  --mode production

 "scripts": {
    "build": "./node_modules/.bin/webpack --config webpack.config.js --mode develepment"
  }

4.配置文件基本組成結(jié)構(gòu)

1) 入口

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

可以通過在 webpack 配置中配置 entry 屬性,來(lái)指定一個(gè)入口起點(diǎn)(或多個(gè)入口起點(diǎn))。默認(rèn)值為 ./src。

2) 出口

output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles,以及如何命名這些文件,默認(rèn)值為 ./dist。基本上,整個(gè)應(yīng)用程序結(jié)構(gòu),都會(huì)被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個(gè) output 字段,來(lái)配置這些處理過程:

3) 模式

通過選擇 development 或 production 之中的一個(gè),來(lái)設(shè)置 mode 參數(shù),你可以啟用相應(yīng)模式下的 webpack 內(nèi)置的優(yōu)化

4) loader

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

本質(zhì)上,webpack loader 將所有類型的文件,轉(zhuǎn)換為應(yīng)用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。

在更高層面,在 webpack 的配置中 loader 有兩個(gè)目標(biāo):

test 屬性,用于標(biāo)識(shí)出應(yīng)該被對(duì)應(yīng)的 loader 進(jìn)行轉(zhuǎn)換的某個(gè)或某些文件。

use 屬性,表示進(jìn)行轉(zhuǎn)換時(shí),應(yīng)該使用哪個(gè) loader。

5) 插件plugins

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

想要使用一個(gè)插件,你只需要 require() 它,然后把它添加到 plugins 數(shù)組中。多數(shù)插件可以通過選項(xiàng)(option)自定義。你也可以在一個(gè)配置文件中因?yàn)椴煌康亩啻问褂猛粋€(gè)插件,這時(shí)需要通過使用 new 操作符來(lái)創(chuàng)建它的一個(gè)實(shí)例。

二、 webpack深入

1.入口

1) 多入口單出口

entry:[‘i.js’,’2.js’]

2) 多入口多出口

entry:{
     name1: ‘1.js’,
     name2: ’2.js’
},
output:{
   path:path.join(__dirname,'dist/'),
   filename: ‘[name]bundle.js’
}

2.出口

注意:

1、出口的默認(rèn)路徑

2、出口是絕對(duì)路徑

3、出口的默認(rèn)文件名與main的關(guān)系

3.html-webpack-plugin插件

用于編譯 Webpack 項(xiàng)目中的 html 類型的文件,如果直接將 html 文件置于 ./src 目錄中,用 Webpack 打包時(shí)是不會(huì)編譯到生產(chǎn)環(huán)境中的。因?yàn)?Webpack 編譯任何文件都需要基于配置文件先行配置的。

插件 html-webpack-plugin 的詳解

1) 安裝

npm i html-webpack-plugin -D

2) 引入

const HtmlWebpackPlugin = require(‘html-webpack-plugin’);

3) 使用

plugins:[
   new  HtmlWebpackPlugin({
     title:’’,//頁(yè)面標(biāo)題
     template:’./src/index.html’ //指定你生成的文件所依賴哪一個(gè)html文件模板,模板類型可以是html、jade、ejs等
   });
]

title的使用
<%=htmlWebpackPlugin.options.title%>

注意:依賴 webpack 與webpack-cli

4) 消除緩存

plugins:[
   new  HtmlWebpackPlugin({
     hash:true,
     title:’’,//頁(yè)面標(biāo)題
     template:’./src/index.html’ //模板文件
  }),
]

5) 壓縮輸出

plugins:[
    new htmlWebpackPlugin({
        hash:true,
        minify:{
            collapseWhitespace:true, //去除空格
            removeComments //去除注釋
            minifyCSS
            minifyJS
        },
        template:'./src/index.html',        
    }),
]

minify 的配置:https://blog.csdn.net/lqlqlq007/article/details/84103859

6) 生成多個(gè)頁(yè)面

plugins:[
        new htmlWebpackPlugin({
            hash:true,
            minfy:{
                collapaseWhitespace:true,
            },
            template:'./src/index.html',
            filename: file1
        }),
        new htmlWebpackPlugin({
            hash:true,
            minfy:{
                collapaseWhitespace:true,
            },
            template:'./src/nav.html',
            filename: file2
        })
]

7)多頁(yè)面分離引入

入口文件
entry:{
        index:'./src/index.js',
        index2:'./src/index2.js'
    },
// 出口文件
output:{
    path:path.join(__dirname,'dist/'),
    filename:'[name]bundle.js'
},

插件配置
new htmlWebpackPlugin({
    hash:true,
    chunks:[“name1”,”name2”], // chunks主要用于多入口文件,當(dāng)你有多個(gè)入口文件,那就回編譯后生成多個(gè)打包后的文件,那么chunks 就能選擇你要使用那些js文件
    minfy:{
        collapaseWhitespace:true,
    },
    template:'./src/index.html',
    filename: file1
}),
new htmlWebpackPlugin({
    hash:true,
    chunks:[name2],
    minfy:{
        collapaseWhitespace:true,
    },
    template:'./src/index.html',
    filename: file2
})

4.clean-webpack-plugin

1) 下載

npm i clean-webpack-plugin -D

2) 引入

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

3) 使用

在html-webpack-plugin插件使用之前去除已經(jīng)產(chǎn)生的垃圾文件

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
    /*
    入口 多入口單出口使用數(shù)組 ['./public/src/js/index.js','./public/src/js/reindex.js',]
    entry:'./src/js/index.js',
    */ 
    /*多入口多出口*/
    entry:{
        index:'./src/js/index.js',
        reindex:'./src/js/reindex.js',
    },
    
    // 出口 默認(rèn)的出口目錄是dist
    output:{
        path:path.join(__dirname,'dist/'),
        // filename:'bundle.js',
        filename:'[name]bundle.js'
    },
    // 打包模式
    mode:'development',
    // 自動(dòng)引入插件
    plugins:[
        new CleanWebpackPlugin(), // 刪除文件 保留新文件
        new HtmlWebpackPlugin({
            hash:true, // 清除緩存
            chunks:['index','reindex'], // 在壓縮后的html里引入的bundle里的一部分壓縮代碼
            filename:'index.html', // ../html/index.html
            title:"lalala",
            template:'./index.html',
            minify:{
                collapseWhitespace:true // 去除空格
            }
        }),
        new HtmlWebpackPlugin({
            hash:true, // 清除緩存
            chunks:['reindex'],
            template:'./reindex.html',
            filename:'reindex.html'
        }),
    ]
}

5.webpack-devserver

一個(gè)輕量級(jí)的服務(wù)器,修改文件源碼后,自動(dòng)刷新頁(yè)面將修改同步到頁(yè)面上

1) 下載

npm i webpack-devserver webpack-dev-server -D

2) 配置

devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’)
}

3) 配置啟動(dòng)

npm run dev

“scripts”:{
    “dev”:“webpack-dev-server --config config_file_name”
 }

scripts:{
   “dev”:”webpack-dev-server --config webpack.config.js”
}

// webpack4.x
scripts:{
   “dev”:”webpack-dev-server”
}

4) 自動(dòng)打開

devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’),
      open:true
}

5) 熱更新

const webpack = require(“webpack”);
devServer:{
      host:localhost,
      port:8090,
      contentBase:path.join(__dirname,’dist’),
      open:true,
      hot:true
},
plugins:[
     new webpack.HotModuleReplacementPlugin()
]
image.png

三、 loader

加載器,轉(zhuǎn)化器

1.打包c(diǎn)ss

1) 安裝

css-loader

style-loader

npm i css-loader style-loader -D

2) 配置

module:{
    rules:[
        {
            test:/\.css$/, //匹配的文件類型
            use:['style-loader','css-loader'] //對(duì)應(yīng)要調(diào)用的loader
        }
    ]
}

關(guān)于使用loader的三種寫法:

use:['style-loader','css-loader']
loader:['style-loader','css-loader']
use:[
     {loader:style-loader },
     {loader:css-loader }
]

2.壓縮代碼(之前)uglifyjs

1) 下載

npm i uglifyjs-webpack-plugin -D

2) 引入

const uglify = require(‘uglifyjs-webpack-plugin’)

3) 使用

new uglify()

3.圖片

1) 下載

npm i file-loader url-loader -D

2) 使用

{
  test:/\.(png|jpg|gif|jpeg)/,
  use:['url-loader']
}

3) base64轉(zhuǎn)碼

use:[
  {
    loader:’url-loader’,
    options:{
      limit:50000 //指定圖片大小,小于limit轉(zhuǎn)為base64
      outputPath: 圖片放置目錄
      publicPath: 解決圖片路徑
    }
  }
]

4.分離css代碼 1(已被棄用)

1) 安裝

npm i extract-text-webpack-plugin -D

2) 引入

const extract = require('extract-text-webpack-plugin');

3) 使用

在plugins中添加:
new extract('css/index.css'),

在use中修改
use:extract.extract({
  use:'css-loader',
  fallback:'style-loader'
})

4) 注意:

npm run build 報(bào)錯(cuò)

image.png
npm i extract-text-webpack-plugin@next -D    為4.X

npm i extract-text-webpack-plugin -D   為3.x

5.分離css 2

安裝:

npm i mini-css-extract-plugin -D

使用:

// 在js中引入sass
require('../css/index.css')

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // you can specify a publicPath here
              // by default it uses publicPath in webpackOptions.output
              publicPath: '',
              // hmr: process.env.NODE_ENV === 'development',
            },
          },
          'css-loader',
        ],
      },
    ],
  },
};

6.打包less

安裝:

npm i less less-loader -D

使用:

// 在js中引入less
require('../less/index.less')

// 在config里進(jìn)行配置
new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
}),
{
    test:/\.less$/,
    // use:['style-loader','css-loader','less-loader']
   // 分離
    use:[
        {
            loader:MiniCssExtractPlugin.loader,
            options:{
                publicPath:'',
            }   
        },
        'css-loader','less-loader'              
    ]
}

7.打包sass

安裝:

npm i node-sass sass-loader -D

使用:

// 在js中引入sass
require('../sass/index.scss')

// 在config里進(jìn)行配置
new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
}),
{
    test:/\.(sass|scss)$/,
    // use:['style-loader','css-loader','sass-loader']
   // 分離
    use:[
        {
            loader:MiniCssExtractPlugin.loader,
            options:{
                publicPath:'',
            }   
        },
        'css-loader','sass-loader'              
    ]
}

8.postcss添加css前綴

1) 下載

npm i postcss-loader autofrefixer -D

2) 配置單獨(dú)的配置文件 postcss.config.js

module.exports={
  plugins:[
    require(‘a(chǎn)utoprefixer’)
  ]
}

3) 配置loader

use:[‘css-loader',‘postcss-loader’]

9.消除冗余

將項(xiàng)目中沒有用到的css代碼或js代碼過濾掉(注釋掉),不將其打包到文件中

1) 下載

npm i purifycss-webpack purify-css -D

npm i glob -D

2) 引入

const glob = require('glob');
const purify = require(‘purifycss-webpack’)

3) 使用

需要使用到一個(gè)掃描路徑的包 glob

new purify({
   paths:glob.sync(path.join(__dirname,’./src/*.html’))
})

10.調(diào)試

4.x

--mode production

3.x

devtool:’source-map’

11.babel

將js由ES5轉(zhuǎn)換成ES6的格式

官方文檔
webpack編譯ES6,ES7,babel-loader的使用

1) 安裝

npm i babel-core babel-loader babel-preset-env -D

2) 使用

{
      test: /\.(js|jsx)/,
      exclude: /(node_modules|bower_components)/,
      use:[ {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }]
}

12.react (jsx)

npm i babel-preset-react -D

npm i react react-dom -D

四、 雜項(xiàng)

1.模塊化的使用

遵循node模塊的引入與導(dǎo)出

2.在webpack中使用json

之前需要json-loader。但是4.x默認(rèn)可以引入json。

const name = require(‘xxx.json’)

3.靜態(tài)資源拷貝(圖片、文字、js等)

1) 下載

npm i copy-webpack-plugin -D

2) 引入

const CopyPlugin = require('copy-webpack-plugin');

3) 使用

new CopyWebpackPlugin([{
   from: path.join(__dirname,’src/image’),
   to:path.join(__dirname,’dist/image’)
}])

4.使用第三方庫(kù)

1) 下載

2) 引入

3) 使用

4) 第二種方式 (推介)

只有在內(nèi)部使用到模塊的時(shí)候才會(huì)打包

new webpack.providePlugin{{
    $:’jquery’,
    lodash: ‘lodash’
}}

5) 提取第三方庫(kù)

image.png

5.簡(jiǎn)單的打包發(fā)布

 "scripts": {
    "build": "webpack -p"
  }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容