Webpack 知識(shí)梳理

1. Webpack 簡(jiǎn)介及相關(guān)知識(shí)

Webpack —— JavaScript應(yīng)用模塊打包工具。

1.1 核心概念:

Webpack 有四個(gè)核心概念:

  • entry(入口)

    單入口——單頁(yè)面應(yīng)用

    多入口——多頁(yè)面應(yīng)用

  • output(輸出)

    path: 輸出路徑(必須是絕對(duì)路徑) path.resolve

    filename: 輸出文件名

  • loaders

    編譯文件

  • plugins(插件)

    webpack 功能擴(kuò)展

1.2 相關(guān)知識(shí)(Node.js & ES6 模塊化)

1.2.1 Node.js

Node.js 是 javascript的服務(wù)器版本,Webpack 在執(zhí)行打包壓縮時(shí)是依賴 Node.js 的。

1.2.2 ES6 模塊化

1.2.2.1 export 導(dǎo)出

//分別導(dǎo)出一個(gè)或幾個(gè)變量(函數(shù))
export let a = 1;
export const b = 2;
export function fn(){
    console.log('fn')
}

//導(dǎo)出一個(gè)對(duì)象
let a = 1;
const b = 2;
function fn(){
    console.log('fn')
}
export { a, b, fn };

//導(dǎo)出默認(rèn)成員——僅能導(dǎo)出一個(gè),默認(rèn)引入的就是這一個(gè)
export default let a = 1;

1.2.2.2 import 導(dǎo)入

//引入所有成員(as —— 給引入的值重命名)
import * as name from 'xxx'; 
//引入 default 成員
import a from 'xxx';   
//只引入:引入 css 或 函數(shù)
import 'xxx';
//異步引入
let a =import("./util");

2.開(kāi)始使用 Webpack —— 搭建項(xiàng)目

2.1 新建項(xiàng)目

npm init
npm i webpack webpack-cli --save-dev

初始化項(xiàng)目,并安裝 Webpack 依賴,安裝 webpack-cli 才能在命令行運(yùn)行 webpack 命令。

2.2 webpack 配置

創(chuàng)建并配置 webpack.config.js

  • 單入口 | 單輸出
    根目錄內(nèi)新建 src 文件夾,新建 index.js 文件。

index.js 文件:

console.log('index')

webpack.config.js 文件

const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.min.js'
  }
}
  • 多入口 | 多輸出
    根目錄內(nèi)新建 src 文件夾,新建 index.jshome.js 文件。

index.js 文件:

console.log('index')

home.js 文件:

console.log('home')

webpack.config.js 文件

const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  }
}

2.3 node 命令配置

配置 package.json 文件,驗(yàn)證基本配置

  • 修改 script 屬性:
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
},
  • 運(yùn)行 npm run build 執(zhí)行 webpack 命令,驗(yàn)證輸入輸出配置。
    根目錄內(nèi)會(huì)生成 dist 文件夾,里面有對(duì)應(yīng)的文件生成。
    多入口

2.4 文件引入

在 index.html 中引入打包好的 js 文件
方式一:手動(dòng)引入
新建 index.html,并直接手動(dòng)引入 js 文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script src='./dist/index.min.js'></script>
<script src='./dist/home.min.js'></script>
</html>

打開(kāi) index.html,即已成功引入編譯好的 index.min.js 及 home.min.js,執(zhí)行里面的代碼。

3.plugins —— 擴(kuò)展 webpack 功能

前面已經(jīng)可以使用 webpack ,但開(kāi)發(fā)過(guò)程中,每次都要手動(dòng)引用 js 文件,更改代碼后還要重新編譯是很麻煩的,所以我們接下來(lái)看下 webpack 的 plugins,來(lái)便于開(kāi)發(fā)。

3.1 自動(dòng)生成 html

可通過(guò)插件html-webpack-plugin,由指定的 html 模板生成新的 html 文件,并自動(dòng)引入所需 js 等內(nèi)容。

1)執(zhí)行 npm i html-webpack-plugin --save-dev 命令,安裝依賴。

2)新建 index.ejs 文件

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>

3)修改 webpack.config.js 的配置:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包輸出HTML
      title: 'New HTML',  //打包后生成 html 的 title
      minify: {
        // 壓縮 HTML 文件
        removeComments: true, // 移除 HTML 中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true // 壓縮內(nèi)聯(lián) css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
    })
  ]
}

4)重新運(yùn)行 npm run build,生成新的 dist 包,包內(nèi)會(huì)生成一個(gè)新的 index.html 文件,并自動(dòng)引入了 index.min.js 文件。

自動(dòng)引入

index.html 文件

<!DOCTYPE html><html><head><meta http-equiv="Content-type" content="text/html; charset=utf-8"><title>New HTML</title></head><body><div id="root"></div><script type="text/javascript" src="index.min.js"></script><script type="text/javascript" src="home.min.js"></script></body></html>

3.2 刪除舊文件

再次打包時(shí)需刪除舊文件

3.2.1 更改配置

修改 webpack.config.js ,將輸出的 index.html 文件名改為其他的,如 indexNew.html

image

運(yùn)行 npm run build ,生成的 dist 內(nèi)文件列表如下:
image

之前生成的無(wú)用文件 index.html 還在,這里可以使用插件 clean-webpack-plugin 來(lái)刪除 webpack.config.jsoutput.path 目錄中的所有文件。

3.2.2 安裝依賴

運(yùn)行 npm install clean-webpack-plugin --save-dev 安裝依賴。

3.2.3 驗(yàn)證

修改 webpack.config.js 配置。

image

再次運(yùn)行 npm run build ,生成的 dist 內(nèi)文件列表如下:
image

可見(jiàn)之前生成的 indexNew.html 文件已被刪除。

3.3 自動(dòng)打開(kāi)瀏覽器,支持熱更新

3.3.1 安裝依賴

npm i open-browser-webpack-plugin webpack-dev-server --save-dev

3.3.2 更改配置

修改 webpack.config.js 配置如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包輸出HTML
      title: 'New HTML', //打包后生成 html 的 title
      minify: {
        // 壓縮 HTML 文件
        removeComments: true, // 移除 HTML 中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true // 壓縮內(nèi)聯(lián) css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
    }),
    // 默認(rèn)情況下,此插件將刪除 webpack output.path目錄中的所有文件。
    new CleanWebpackPlugin(),
    new OpenBrowserPlugin({ url: 'http://localhost:8080' })
  ]
}

3.3.3 更改 node 命令

修改 package.json ,添加 start ,使得運(yùn)行 npm run start 可直接執(zhí)行 webpack-dev-server 命令。

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

3.3.4 測(cè)試

執(zhí)行 npm run start

1)瀏覽器會(huì)自動(dòng)打開(kāi) http://localhost:8080

2)修改 index.js 文件,保存文件,瀏覽器會(huì)自動(dòng)刷新,更新內(nèi)容。

3.4 代碼調(diào)試定位 —— sourcemap

代碼經(jīng)過(guò)編譯、打包后,與源代碼已有很大差異,不便于調(diào)試。

source-map 會(huì)解決這個(gè)問(wèn)題,生成 .map 文件,便于錯(cuò)誤定位調(diào)試。

開(kāi)啟方法:在 webpack.config.js 文件中添加一行配置:devtool: "source-map"

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包輸出HTML
      title: 'New HTML', //打包后生成 html 的 title
      minify: {
        // 壓縮 HTML 文件
        removeComments: true, // 移除 HTML 中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true // 壓縮內(nèi)聯(lián) css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
    }),
    // 默認(rèn)情況下,此插件將刪除 webpack output.path目錄中的所有文件。
    new CleanWebpackPlugin(),
    new OpenBrowserPlugin({ url: 'http://localhost:8080' })
  ],
  //編譯前文件調(diào)試
  devtool: "source-map"
}

如上,即可??赏ㄟ^(guò)打印等方式進(jìn)行測(cè)試。

4. loader

loader ——文件編譯。

4.1 ES6 & React 編譯 —— babel-loader

Babel 是一個(gè) JavaScript 編譯器,Webpack 使用 babel-loader 來(lái)編譯 ES6。
此處我們要?jiǎng)?chuàng)建一個(gè) React 項(xiàng)目,所以同時(shí)也要添加 React 的相關(guān)依賴即配置。

4.1.1 安裝依賴

yarn add babel babel-core babel-loader@7.1.2 babel-preset-env babel-preset-react
注: 現(xiàn)在直接安裝 babel-core 和 babel-loader,安裝的版本不對(duì)應(yīng)會(huì)報(bào)錯(cuò),所以我在安裝時(shí)指定了 babel-loader 的版本,避免這個(gè)問(wèn)題。

4.1.2 更改配置

修改 webpack.config.js 如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包輸出HTML
      title: 'New HTML', //打包后生成 html 的 title
      minify: {
        // 壓縮 HTML 文件
        removeComments: true, // 移除 HTML 中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true // 壓縮內(nèi)聯(lián) css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
    }),
    // 默認(rèn)情況下,此插件將刪除 webpack output.path目錄中的所有文件。
    new CleanWebpackPlugin(),
    new OpenBrowserPlugin({ url: 'http://localhost:8080' })
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        use: [{
          loader: "babel-loader",
          options: {
            presets: ["env", "react"],
          }
        }],
        exclude: /node_modules/
      }
    ]
  }
}

4.1.3 修改文件

修改 index.js 及 home.js 文件為 react 語(yǔ)法
home.js文件

import React, { Component } from 'react';

export default class Home extends Component {

  render() {
    return (
      <div style={{backgroundColor: '#0f0'}}>
        home page
      </div>
    );
  }
}

index.js文件

import React from 'react';
import { render } from 'react-dom';
import Home from './home';

render(<Home/>, document.getElementById('root'));

此時(shí),頁(yè)面效果如下:


image

如上,React 語(yǔ)法被成功編譯。

4.2 處理 CSS 文件 —— style-loader & css-loader

4.2.1 修改文件

創(chuàng)建 index.css 文件

.container {
    background-color: aquamarine
}

修改 home.js 文件如下:

import React, { Component } from "react";
import './index.css'

export default class Home extends Component {
  render() {
    return (
      <div className="container">
        home page
      </div>
    );
  }
}

npm run start 重新啟動(dòng)項(xiàng)目,項(xiàng)目會(huì)報(bào)錯(cuò)如下:

image

4.2.2 安裝依賴

npm i style-loader css-loader --save-dev

4.2.3 更改配置

修改 webpack.config.js 配置如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
  entry: {
    index: './src/index.js',
    home: './src/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].min.js' //name為對(duì)應(yīng)入口文件的文件名
  },
  plugins: [
    new HtmlWebpackPlugin({
      // 打包輸出HTML
      title: 'New HTML', //打包后生成 html 的 title
      minify: {
        // 壓縮 HTML 文件
        removeComments: true, // 移除 HTML 中的注釋
        collapseWhitespace: true, // 刪除空白符與換行符
        minifyCSS: true // 壓縮內(nèi)聯(lián) css
      },
      filename: 'index.html', // 生成后的文件名
      template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
    }),
    // 默認(rèn)情況下,此插件將刪除 webpack output.path目錄中的所有文件。
    new CleanWebpackPlugin(),
    new OpenBrowserPlugin({ url: 'http://localhost:8080' })
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        use: [{
          loader: "babel-loader",
          options: {
            presets: ["env", "react"],
          }
        }],
        exclude: /node_modules/
      },
      {
        test: /\.css$/i, // 針對(duì) .css 后綴的文件設(shè)置 loader
        use: ['style-loader', 'css-loader']
      }
    ]
  }
}

添加了針對(duì) .css 文件的 loader,來(lái)對(duì) .css 文件進(jìn)行處理。

image

注:

  • css-loader:讀取并編譯 js 中引入的 css 文件
  • style-loader: html 中創(chuàng)建一個(gè) <style></style> 標(biāo)簽,里面是 css-loader 解析出的 css 樣式。
  • webpack 配置中,style-loader 必須在 css-loader 之前,順序不可變,即必須先由 css-loader 處理,再由 style-loader 處理。

4.3 處理 LESS 文件 —— less-loader

4.3.1 更改文件

創(chuàng)建 index.less 文件如下:

.container {
    background-color: aquamarine
}

修改 home.js 文件如下:

import React, { Component } from "react";
import './index.less'

export default class Home extends Component {
  render() {
    return (
      <div className="container">
        home page
      </div>
    );
  }
}

4.3.2 安裝依賴

npm i less less-loader --save-dev

4.3.3 更改配置

修改 webpack.config.js 配置,module/rules 下添加對(duì)于 less 文件的解析:

{
    test: /\.less$/, // 針對(duì) .less 后綴的文件設(shè)置 loader
    use: ['style-loader', 'css-loader', 'less-loader']
}

4.3.4 驗(yàn)證

重新啟動(dòng)項(xiàng)目,less 文件生效,頁(yè)面效果如下:


image

4.4 添加瀏覽器前綴 —— postcss-loader & autoprefixer

autoprefixer 按照瀏覽器使用量決定需要添加哪些瀏覽器前綴,postcss-loader 按照 autoprefixer 的結(jié)果來(lái)添加瀏覽器前綴。

4.4.1 更改文件

修改 index.less 文件如下:

.container {
    background-color: aquamarine;
    transform: rotate(0deg);
    transition-duration: 1000ms;
}
.container:hover {
    background-color: aquamarine;
    transform: rotate(360deg)
}

4.4.2 安裝依賴

npm i less postcss-loader autoprefixer --save-dev

4.4.3 更改配置

修改 webpack.config.js 配置,給 css、less 文件添加 postcss-loader 的解析,
有兩種方式:

1)在 webpack.config.js 的 modele/rules 內(nèi)指定 postcss-loader 的配置

{
    test: /\.css$/, // 針對(duì) .css 后綴的文件設(shè)置 loader
    use: ['style-loader', 'css-loader', {
        loader: 'postcss-loader',
        options: {
        plugins: [require('autoprefixer')]
        }
    }]
},
{
    test: /\.(less|css)$/, // 針對(duì) .less 后綴的文件設(shè)置 loader
    use: ['style-loader', 'css-loader', 'less-loader', {
      loader: 'postcss-loader',
      options: {
        plugins: [require('autoprefixer')]
      }
    }]
}

2)修改 webpack.config.js,并單獨(dú)創(chuàng)建 postcss.config.js ,進(jìn)行配置
修改webpack.config.js 文件,modele/rules 添加如下配置:

{
    test: /\.css$/, // 針對(duì) .css 后綴的文件設(shè)置 loader
    use: ['style-loader', 'css-loader', 'postcss-loader']
},
{
    test: /\.(less|css)$/, // 針對(duì) .less 后綴的文件設(shè)置 loader
    use: ['style-loader', 'css-loader', 'less-loader', 'postcss-loader']
}

postcss.config.js 文件

module.exports = {
    plugins: [require('autoprefixer')]
}

相對(duì)比而言,我更傾向于第一種,以免創(chuàng)建太多的配置文件,造成混亂。

4.4.4 驗(yàn)證

重新啟動(dòng)項(xiàng)目,查看瀏覽器元素,樣式前綴已添加成功。

image

注: 如有需要,可以自己進(jìn)行支持的瀏覽器版本配置,有兩種方式:

1)添加 .broserslistrc 文件,進(jìn)行配置

last 3 version  //支持每個(gè)版本的最近三個(gè)版本
>2%   //大于百分之二的用戶使用

2)無(wú)需創(chuàng)建新文件,直接在 package.json 文件內(nèi)添加屬性進(jìn)行配置

  "browserslist": [
    "last 5 version",
    " >1%"
  ]

重新啟動(dòng),效果如下:


image

按照設(shè)置的規(guī)則重新對(duì)我們的 css 樣式添加了前綴。

4.5 處理圖片 —— file-loader & url-loader

4.5.1 引入圖片

src 文件夾下創(chuàng)建 images 文件夾,并添加 bg.png 圖片

image

修改 index.less 文件如下:

.container {
    width: 100%;
    height: 600px;
    background: url('./images/bg.png');
    background-size: 100%;
    background-repeat: no-repeat;
}

重新啟動(dòng)項(xiàng)目,會(huì)報(bào)錯(cuò)如下:

image

4.5.2 安裝依賴 —— file-loader

如上,需要配置對(duì)應(yīng)的 loader 來(lái)解析圖片。

執(zhí)行npm i file-loader --save-dev,安裝依賴。

4.5.3 更改配置 —— file-loader

修改 webpack.config.js 配置, modole/rule 下添加配置如下:

{
    test: /\.(png|jpg|jpeg|gif)$/i, // 針對(duì) .png|.jpg|.jpeg | .gif 后綴的圖片設(shè)置 loader
    use: [{
      loader: 'file-loader',
      options: {
        outputPath: 'imgs/', //相對(duì)于 output.path 的輸出目錄
      }
    }]
}

重啟項(xiàng)目,則引入圖片成功,效果如下:

image

file-loader 可以解析項(xiàng)目中的圖片引入,根據(jù)配置,將圖片輸出到相應(yīng)路徑,并修改打包后文件中的引用路徑,使其指向打包后的文件。

4.5.4 安裝依賴 —— url-loader

針對(duì)圖片引用,url-loader 封裝了 file-loader。
增加了 limit 屬性,文件大小大于 limit 值,會(huì)調(diào)用 file-loader 進(jìn)行處理;
文件大小小于 limit 值,會(huì)將文件轉(zhuǎn)為 base64 格式,以減少文件請(qǐng)求次數(shù)。
安裝 url-loader 依賴

npm i url-loader --save-dev

4.5.5 更改配置 —— url-loader

修改 webpack.config.js 配置, modole/rule 下添加配置如下:

{
        test: /\.(png|jpg|jpeg|gif)$/i, // 針對(duì) .png|.jpg|.jpeg | .gif 后綴的圖片設(shè)置 loader
        use: [{
          loader: 'url-loader',
          options: {
            outputPath: 'imgs/', //相對(duì)于 output.path 的輸出目錄
            limit: 8*1024 //大于此數(shù)值依舊用 file-loader處理,打包到 imgs 里面,小于此數(shù)值的轉(zhuǎn)為 base64,以減少文件請(qǐng)求次數(shù)
          }
        }]
      }

重啟項(xiàng)目,圖片引用成功,執(zhí)行 npm run build,可發(fā)現(xiàn),大于 8k 的圖片會(huì)被打包到 dist/imgs 文件夾內(nèi),小于 8k 的則不會(huì)被打包輸出,而是轉(zhuǎn)為 base64 。

image

4.6 處理文字 —— file-loader & url-loader

4.6.1 引入字體

src 文件夾下一個(gè)字體文件——difital-7.ttf,這是一個(gè)液晶字體文件,修改 index.less 文件如下:

image
@font-face{
    font-family: "digital";
    src: url(./digital-7.ttf);
}
.container {
    width: 100%;
    height: 600px;
    background: url('./images/bgimg.jpg');
    background-size: 100%;
    background-repeat: no-repeat;
    font-family: "digital"
}

保存項(xiàng)目編譯后,會(huì)報(bào)錯(cuò)如下:

image

4.6.2 更改配置

同圖片,需要配置對(duì)應(yīng)的 url-loader 來(lái)解文字片,修改 webpack.config.js 配置, modole/rule 下添加配置如下:

{
    test: /\.(eot|svg|ttf|woff|woff2)$/i, // 針對(duì) eot|svg|ttf|woff|woff2 后綴的字體設(shè)置 loader
    use: [{
        loader: 'url-loader',
        options: {
        outputPath: 'fonts/', //相對(duì)于 output.path 的輸出目錄
        limit: 4*1024 //大于此數(shù)值依舊用 file-loader處理,打包到 fonts 里面,小于此數(shù)值的轉(zhuǎn)為 base64,以減少文件請(qǐng)求次數(shù)
        }
    }]
}

重新啟動(dòng)項(xiàng)目,則字體引用成功,效果如下:

image

通過(guò)修改 limit 值,重新打包,可測(cè)試 limit 值設(shè)置是否有效。

5. 開(kāi)發(fā)/生產(chǎn)模式

5.1 開(kāi)發(fā)/生產(chǎn)模式的區(qū)別

  • 開(kāi)發(fā)模式需要進(jìn)行調(diào)試,需要自動(dòng)打開(kāi)瀏覽器,而生產(chǎn)模式不需要
  • 生產(chǎn)模式需要設(shè)置打包文件目錄,需要啟用壓縮,忽略錯(cuò)誤。

上述區(qū)別需要通過(guò)兩個(gè)設(shè)置來(lái)實(shí)現(xiàn)。

5.1.1 設(shè)置 process.env.NODE_ENV

在 webpack.config.js 中通過(guò)判斷 env 的值,來(lái)進(jìn)行不同的配置

修改 package.json 來(lái)設(shè)置 process.env.NODE_ENV:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --env.development",
    "build": "webpack --env.production",
    "eslint": "eslint --init"
  },

根目錄下新建 config 文件夾,并在下面新建 webpack.production.config 和 webpack.development.config 文件。

webpack.config.js 文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')

module.exports = function(env, argv) {
  console.log('env', env)
  env = env || { development: true }

  return {
    entry: {
      index: './src/index.js',
    },
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/i,
          use: [{
            loader: "babel-loader",
            options: {
              presets: ["env", "react"],
            }
          }],
          exclude: /node_modules/
        },
        {
          test: /\.css$/i, // 針對(duì) .css 后綴的文件設(shè)置 loader
          use: ['style-loader', 'css-loader', {
            loader: 'postcss-loader',
            options: {
              plugins: [require('autoprefixer')]
            }
          }]
        },
        {
          test: /\.(less|css)$/i, // 針對(duì) .less 后綴的文件設(shè)置 loader
          use: ['style-loader', 'css-loader', 'less-loader', {
            loader: 'postcss-loader',
            options: {
              plugins: [require('autoprefixer')]
            }
          }]
        },
        {
          test: /\.(png|jpg|jpeg|gif)$/i, // 針對(duì) .png|.jpg|.jpeg | .gif 后綴的圖片設(shè)置 loader
          use: [{
            loader: 'url-loader',
            options: {
              outputPath: 'imgs/', //相對(duì)于 output.path 的輸出目錄
              limit: 8*1024 //大于此數(shù)值依舊用 file-loader處理,打包到 imgs 里面,小于此數(shù)值的轉(zhuǎn)為 base64,以減少文件請(qǐng)求次數(shù)
            }
          }]
        },
        {
          test: /\.(eot|svg|ttf|woff|woff2)$/i, // 針對(duì) eot|svg|ttf|woff|woff2 后綴的字體設(shè)置 loader
          use: [{
            loader: 'url-loader',
            options: {
              outputPath: 'fonts/', //相對(duì)于 output.path 的輸出目錄
              limit: 4*1024 //大于此數(shù)值依舊用 file-loader處理,打包到 fonts 里面,小于此數(shù)值的轉(zhuǎn)為 base64,以減少文件請(qǐng)求次數(shù)
            }
          }]
        }
      ]
    },
    ...env.production ? require('./config/webpack.production.config') : require('./config/webpack.development.config')
  }
}

5.1.2 設(shè)置 webpack 的 mode ,來(lái)決定 webpack 的優(yōu)化級(jí)別。

mode 有三種模式:

  • none: 不優(yōu)化
  • development: 輸出調(diào)試信息
  • production: 最高優(yōu)化,啟用壓縮,忽略錯(cuò)誤

webpack.production.config 文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin')
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
    mode: 'production',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.min.js' //name為對(duì)應(yīng)入口文件的文件名
    },
    plugins: [
        new HtmlWebpackPlugin({
        // 打包輸出HTML
        title: 'New HTML', //打包后生成 html 的 title html模板時(shí)不生效
        minify: {
            // 壓縮 HTML 文件
            removeComments: true, // 移除 HTML 中的注釋
            collapseWhitespace: true, // 刪除空白符與換行符
            minifyCSS: true // 壓縮內(nèi)聯(lián) css
        },
        filename: 'index.html', // 生成后的文件名
        template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
        }),
        // 默認(rèn)情況下,此插件將刪除 webpack output.path目錄中的所有文件。
        new CleanWebpackPlugin()
    ]
}

webpack.development.config 文件

const HtmlWebpackPlugin = require('html-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin') //自動(dòng)打開(kāi)瀏覽器
const path = require('path')
module.exports = {
    mode: 'development',
    output: {
      filename: 'main.js' //name為對(duì)應(yīng)入口文件的文件名
    },
    //編譯前文件調(diào)試
    devtool: "source-map",
    plugins: [
      new HtmlWebpackPlugin({
        // 打包輸出HTML
        title: 'New HTML', //打包后生成 html 的 title
        minify: {
          // 壓縮 HTML 文件
          removeComments: true, // 移除 HTML 中的注釋
          collapseWhitespace: true, // 刪除空白符與換行符
          minifyCSS: true // 壓縮內(nèi)聯(lián) css
        },
        filename: 'index.html', // 生成后的文件名
        template: 'index.ejs' // 根據(jù)此模版生成 HTML 文件
      }),
      new OpenBrowserPlugin({ url: 'http://localhost:8080' })
    ],
}
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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