webpack做爲現代前端技術的基石,相信絕大部分的前端開發者都據說或是在項目中使用過。可是因爲如今各類各樣cli工具的出現,可以掌握webpack基本配置和使用的人,可能就不那麼多了。javascript
最開始接觸webpack仍是在之前的angular.js項目中,以後從angular.js轉到react後一直使用的create-react-app進行項目初始化。須要改動webpack配置時也是在使用eject命令暴露出webpack config進行修改,一直沒有本身從零開始配置過。在這期間angular.js升級成爲Angular,jQuery逐漸被歷史淘汰,Vue也從一個後期之秀成爲如今的當紅前端框架。不得不說,前端技術的更新迭代速度真的能夠用飛速來形容了。在如此快速的更新速度下,做爲一個前端開發人員,必定要緊跟技術的步伐,時刻保持着學習狀態,才能保證本身在大潮流中不掉隊。這也是我寫這篇文章的初衷,用來記錄本身的學習成果。css
要注意的是,本文不會贅述現代前端開發中的一些基礎知識,如 npm依賴管理、模塊化等基礎知識。因此,若你並無據說過webpack,或不知道它是什麼,那麼建議你仍是先了解一下基礎知識。若對webpack已經瞭如指掌,那麼也大可沒必要看這篇文章。不過大佬如果願意指導一番,我也是很是開心的!!^_^html
webpack是什麼?前端
本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(static module bundler)。在 webpack 處理應用程序時,它會在內部建立一個依賴圖(dependency graph),用於映射到項目須要的每一個模塊,而後將全部這些依賴生成到一個或多個bundle。—— 來自 webpack 官方文檔java
簡單的說,webpack就是一個現代前端開發的打包機。現代前端很是流行使用模塊化的方式開發,webpack所作的就是將各個js模塊合理的打包成bundle或者chunk。在打包的過程當中,能夠經過loader的方式,將新的js語法、CSS預處理語言等轉換成更容易被瀏覽器支持的形式。node
webpack是基於nodejs的,在絕大部分時,在使用時須要爲它寫一個配置文件。這個配置文件的主要結構以下:react
module.exports = {
mode: 'development' // 模式配置
entry: '', // 入口文件
output: {}, // 出口文件
module: {}, // 處理對應模塊
plugins: [], // 對應的插件
devServer: {}, // 開發服務器配置(僅在開發中使用)
}
複製代碼
接下來,咱們就來一步步的完成這些配置。linux
在指定文件夾下執行 npm init
進行初始化。webpack
mkdir webpackDemo&&npm init
git
由於項目並非一個要發佈到npm的項目,因此執行npm init後只用一路回車便可。
安裝webpack和react的依賴:
npm install --save-dev webpack react react-dom
在webpack4以後的版本中,還須要安裝webpack-cli,具體方法同上。
在項目根目錄建立config文件夾,並在內建立webpack.config.js。
打開根目錄下的package.json 配置scripts
:
"scripts": {
"build": "webpack --mode production --config ./config/webpack.config.js",
}
複製代碼
配置scripts腳本是爲了後期在執行過程當中只用在命令行中輸入 npm '腳本中指定配置' 就可以完成命令行的輸入操做。好比輸入 npm build,就會自動執行 "webpack --mode production --config ./config/webpack.config.js" 這一長串的操做。
建立代碼文件夾和react的入口文件:
在項目根目錄中建立src文件夾,並在內建立index.js、App.js、index.css。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css'
ReactDOM.render(
<App />,
document.getElementById('root')
);
複製代碼
App.js
import React from 'react';
export default class App extends React.Component {
render() {
return <div>
<p className="text">動手搭建一個基於webpack4的react開發環境</p>
</div>
}
}
複製代碼
index.css
.text{
color:'red'
}
複製代碼
完成上述操做後,項目目錄結構應該像下面這樣
webpackDemo
│ node_modules
└───config
│ webpack.config.js
└───src
│ index.js
│ index.css
│ App.js
package.json
複製代碼
如今,咱們完成了簡單的初始化工做,下面開始瞭解webpack吧。
mode是webpack4中新增的概念,它有三個選項:development
、production
、none
,用來設置webpack的優化方式。
開發模式,該模式優化了開發速度,提供了詳細的錯誤機制和瀏覽器調試工具。而且關閉了代碼壓縮,使代碼可以更快的構建。
生產模式,該模式可以提供更小的代碼包,去除了只在開發階段運行的代碼。自動開啓了代碼混淆壓縮。
module.export = {
mode:'production' // 'development'||'production'||'none'
}
複製代碼
在這裏,能夠聲明一個應用的起點。入口能夠有一個或者多個。在單頁應用中,入口通常只有一個。不過也能夠將公共依賴配置成爲單頁應用的入口,這樣單頁應用也能夠有多個入口。而在多頁應用中,通常會有多個入口文件。
一個簡單的單頁應用入口以下:
module.export = {
mode:'production' // 'development'||'production'||'none',
entry:'./src/index.js',
}
複製代碼
output用來配置項目打包後的文件名稱、路徑。用來告訴webpack怎麼輸出、輸出到哪、叫什麼名字。
const path = require('path');
module.export = {
mode:'production' // 'development'||'production'||'none',
entry:'./src/index.js',
output: {
// 在bundle中引入註釋 注意:該選項不該該在生產模式中啓用
pathinfo:true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "[name].[hash].js"
}
}
複製代碼
這裏的filename並無給它一個實際的名稱,而是使用模板字符串去設置webpack生成後的文件名稱。這個設置中的[name]表明模塊名稱,在單入口文件中默認爲main。而[hash]則會生成一個模塊標識符的hash,默認是20位,能夠經過[hash:16]的方式指定它的位數。打包後的文件名稱就像這樣main.f236aaeca342dfb1f8dd.js
。在生成文件名稱後跟上hash有助於咱們在項目從新部署後因爲引用的文件名稱變了,瀏覽器會去下載新的文件,再也不繼續使用本地的緩存。
webpack的做用就是將前端開發中的各個模塊進行處理以及打包。而loader的做用就是處理webpack中的這些模塊。
webpack中模塊有不少種,常見的有:
模塊化的js文件
css/less/sass文件
圖片以及靜態文件
loader在module中配置:
// 示例
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = {
mode: 'development',
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/, // 用來指定針對的文件類型 支持正則
exclude: /node_modules/, // 用來指定須要排除的文件夾,優化打包速度
include: appSrc, // 指定所包含的文件夾 ,優化打包速度
loader: "babel-loader", // 針對指定文件使用的loader
}
]
}
};
複製代碼
要對這些模塊進行處理,就要使用到不一樣的loader。在此以前,先簡單的介紹一下須要使用到的loader。
babel是一個語法轉換器,可以讓你自由的使用JavaScript的最新語法。它可以將咱們所寫的新語法、jsx等轉換成瀏覽器可以友好支持的形式。
要使用babel-loader須要下列依賴,能夠經過執行npm install --save-dev babel-loader @babel/core @babel/preset-react @babel/preset-env
安裝它們。
babel-loader
@babel/core
babel的核心組件,裏面包含着babel的api。
@babel/preset-env
用來轉義JavaScript語法。
@babel/preset-react
用來轉義react。
配置babel-loader:
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = {
mode: 'development',
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
// 指定babel預處理轉義
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
]
}
}
複製代碼
完成上述配置後,還需配置一下babel,讓它可以轉換react和js的新語法。能夠像上面使用webpack配置中的option選項中的presets字段指定babel預處理的方式。
也能夠在項目的根目錄建立babel的配置文件.babelrc
。.babelrc
後綴rc來自linux中,使用過linux就知道linux中不少rc結尾的文件,好比.bashrc,rc是run command的縮寫,翻譯成中文就是運行時的命令,表示程序執行時就會來調用這個文件。
babel全部的操做基本都會來讀取這個配置文件,除了一些在回調函數中設置options參數的,若是沒有這個配置文件,會從package.json文件的babel屬性中讀取配置。
在.babelrc
中添加下列語句:
{
"presets": ["@babel/preset-env","@babel/preset-react"]
}
複製代碼
url-loader和file-loader的做用相似,都是使webpack可以打包靜態文件。url-loader相較於file-loader的功能更強大,它可以使用兩種方式進行打包。
url-loader有一個重要的參數 limit
,這個參數用來設置打包文件大小的限制。當文件小於指定參數時,它可以返回一個DataURL(base64)形勢的文件。當文件大於指定參數時,它將經過file-loader進行打包。
配置url-loader:
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = {
mode: 'development',
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
// 指定babel預處理轉義
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
// url-loader的配置
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
// 設置url-loader轉DataURL的文件大小上限
limit: 10000
}
}
]
}
}
複製代碼
url-loader還有兩個參數mimetype
和fallback
,這兩個參數使用的並很少,就不在這裏贅述了。
style-loader和css-loader都是用來處理css文件的,不過它們的做用並不相同。
css-loader:用來讀取css文件的內容,並進行處理 如:minimize。
style-loader:將經過import形式導入到js中的css文件插入到<style></style>
標籤內。
在webpack中的配置以下:
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = {
mode: 'development',
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
// 指定babel預處理轉義
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
// 設置url-loader轉DataURL的文件大小上限
limit: 10000
}
},
// 針對css文件配置style-loader和css-loader
{
test: /\.css$/,
include: appSrc,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// 能夠包含一些配置
modules:true|false, // 是否開啓css模塊化,開啓後引入的css文件僅針對當前頁面有效,不會做用到全局
minimize: true // 開發模式下應該設爲false,優化打包速度
}
}
]
}
]
}
}
複製代碼
如上所示,當咱們在針對同一類型的文件配置多個loader時。能夠將loader聲明在一個數組內,數組項能夠是一個對象,也能夠僅僅是一個字符串,這取決於你針對某個loader還有沒有特殊的設置。好比在配置css-loader時,還聲明瞭option選項,並在option選項內開啓了minimize選項。可是在配置style-loader時,僅僅寫了一個字符串。
須要注意的是,數組內loader的執行順序是從數組的最後一項依次向前執行。全部咱們將css-loader配置在了後面,它是先執行的。這更符合處理邏輯,先對css進行處理,再插入到html中。
插件是webpack的一個極其重要的功能,webpack提供了豐富的插件接口,使開發者可以自由的開發插件來拓展webpack的功能。
這裏咱們拿大名鼎鼎的 HtmlWebpackPlugin
來舉例。
設想一個場景,在打包時,須要手動的去建立一個html文件,而後在其中引入打包好的各類文件。即便建立好html文件後,因爲在config中設置了hash形式的打包文件名稱。咱們在每次打包後還須要根據hash名稱的變更去改變html內引入的文件名稱,這是很是低級的重複勞做。
HtmlWebpackPlugin
爲咱們解決了這個問題。HtmlWebpackPlugin
可以根據咱們提供的模板自動生成html文件,並引入打包後的內容。
下面介紹一下HtmlWebpackPlugin
的使用過程。
安裝:npm install --save-dev html-webpack-plugin
安裝完成後,先在項目的根目錄建立一個文件夾public
,在其中建立一個模板文件index.html
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
複製代碼
而後在webpack中配置插件:
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
// 引入html-webpack-plugin插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
// 指定babel預處理轉義
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
// 設置url-loader轉DataURL的文件大小上限
limit: 10000
}
},
// 針對css文件配置style-loader和css-loader
{
test: /\.css$/,
include: appSrc,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// 能夠包含一些配置
minimize: true // 開發模式下應該設爲false,優化打包速度
}
}
]
}
]
},
plugins: [
// HTML模板文件處理插件
new HtmlWebpackPlugin({
file: 'index.html', // 生成的文件名稱
template: 'public/index.html' // 指定模板文件
})
],
}
複製代碼
如今在命令行中執行npm build
,webpack將打包src目錄內的文件。並將在根目錄生成一個build文件,將打包的內容輸出在裏面。
這時候,咱們其實已經完成了webpack的基本配置。可是如今的配置是基於development模式進行打包的,沒有進行壓縮,很顯然這並不能作爲一個可發佈的版本。要修改成生產模式其實也很簡單,能夠經過兩種方式去實現。
修改配置文件中的mode選項,將development修改成production。
刪除配置中的mode選項,修改package.json scripts中的build項爲 webpack --mode production --config ./config/webpack.config.js
。
在配置2中,使用--mode 可以爲webpack-cli設置打包模式。修改後再次打包,這時候代碼通過webpack production模式的優化,進行了混淆壓縮,變成了發佈版本。
在平常的開發過程當中,確定不能每修改一點東西就從新build一次,這樣開發效率會受到很大的影響。這時須要啓動一個服務,來監聽文件的變更。當文件保存時就從新打包,同時幫咱們自動刷新瀏覽器,方便咱們及時觀察到更新。
要完成上述操做有幾種方式,這裏只介紹其中的一種,使用 webpack-dev-server
插件。
執行 npm install --save-dev webpack-dev-server
安裝插件,在module.explot中添加配置項 devServer
。
devServer的配置項有不少,這裏大概的介紹其中幾種經常使用的配置:
contentBase: '',告訴服務器從哪一個目錄中提供內容
https: true|false, 是否啓用https
compress: true|false, 是否啓用壓縮
host: '127.0.0.1', 指定host地址
port: 23333, 指定端口
overlay: true|false, 當出現編譯器錯誤或警告時,在瀏覽器中顯示全屏覆蓋層。
progress: true|false, 將運行進度輸出到控制檯。
將devServer添加到配置中:
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
// 引入html-webpack-plugin插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口
entry: './src/index.js',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
// 指定babel預處理轉義
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
// 設置url-loader轉DataURL的文件大小上限
limit: 10000
}
},
// 針對css文件配置style-loader和css-loader
{
test: /\.css$/,
include: appSrc,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// 能夠包含一些配置
minimize: true // 開發模式下應該設爲false,優化打包速度
}
}
]
}
]
},
devServer: {
// HOST
host: '127.0.0.1',
// 端口
port: 23333,
// 報錯提示在網頁遮罩層
overlay: true,
// 顯示運行進度
progress: true,
},
plugins: [
// HTML模板文件處理插件
new HtmlWebpackPlugin({
file: 'index.html', // 生成的文件名稱
template: 'public/index.html' // 指定模板文件
})
]
}
複製代碼
須要注意的時,devServer應當用在開發環境中,因此如今須要將以前的配置進行修改。
在配置中刪除mode項。
爲package.json的scripts中添加另外一個啓動命令 "start": "webpack-dev-server --open --mode development --config ./config/webpack.config.js"
將以前的build項改成 webpack --mode production --config ./config/webpack.config.js
。
如今,執行npm build,webpack將使用production模式進行打包。執行npm start時,將使用development模式進行打包,而且webpack-dev-server將啓動一個服務,監聽文件變動。
如今執行npm start,就能夠開始進行開發了!
在上面的配置中,咱們已經實現了一個react項目開發環境的基本配置。但這遠遠不夠,在實際的項目中,可能會用到不少的工具來優化開發速度。同時也須要針對不一樣的環境寫不一樣的配置,作不一樣的優化等。而且,可能還涉及到代碼分割、壓縮等配置。
下面,咱們來一步步完善webpack的配置。
webpack中devtool選項用來控制是否生成,以及如何生成 source map。
想要了解source map,能夠看一下這篇文章。簡單的說,source map就是幫助咱們定位到錯誤信息位置的文件。正確的配置source map,可以提升開發效率,更快的定位到錯誤位置。
webpack中devtool有不少種配置,咱們能夠在 這裏 瞭解它。
在開發環境中,更推薦使用cheap-module-eval-source-map
,它能幫助咱們準確的定位到錯誤源代碼位置的同時,也能提供更快的構建速度和構建性能。
而在生產環境中,能夠不啓動任何source map(不配置devtool項),也可使用source-map
。須要注意的是,不要將source map部署到生產服務器中。
通常狀況下,項目都會須要用到圖標。常見的圖標使用方式有不少種,如雪碧圖、字體圖標、svg等。雪碧圖和iconfont的使用方式不須要進行特殊的處理,這裏咱們就再也不贅述。下面介紹一個使用svg圖標的方法。
經過 svgr ,可以直接將svg圖標以react組件的形式引入項目中。
就像這樣:
import React from 'react';
import { ReactComponent as Icon } from './icon.svg';
export default class App extends React.Component {
render() {
return <div>
<Icon width={10} height={10} />
</div>
}
}
複製代碼
在react最新版本的cli create-react-app
,已近默認集成了svgr。在咱們本身的項目中使用也很簡單,只須要針對 .svg
添加loader便可。
{
test: /\.svg$/,
use: ['@svgr/webpack'],
}
複製代碼
svgr同時也支持node、react-native等處理方式,能夠經過 svgr文檔來了解。
在生產環境和開發環境的構建目標差別很大。好比在開發環境中,須要更快的構建速度和更強的錯誤提示。可是在生產環境中,則但願構建的代碼能更小,更輕,更側重於性能。因此,針對不一樣的環境,須要不一樣的配置文件。可是若是將配置徹底拆分開,兩個配置文件中可能會包含不少重複的代碼。這時咱們須要提出公共的配置,爲了將這些配置合併在一塊兒,可使用webpack-merge。
下面,咱們開始使用 webpack-merge 進行配置優化。
首先,使用npm安裝依賴 npm install --save-dev webpack-merge
而後,在config文件夾下建立 webpack.config.common.js 、 webpack.config.dev.js 、webpack.config.prod.js。顧名思義,這三個配置表明了通用、開發、生產模式的配置文件。
將以前配置中用到的公共配置提出到 webpack.config.common.js 內:
// webpack.config.common.js
// 打包HTML文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = {
// 入口
entry: './src/index.js',
module: {
rules: [
{
// 配置svg圖標loader,能夠在項目中經過組件的形式直接引入svg圖標
test: /\.svg$/,
include: appSrc,
use: ['@svgr/webpack']
}
]
},
plugins: [
// HTML模板文件處理插件
new HtmlWebpackPlugin({
file: 'index.html',
template: 'public/index.html'
})
]
}
複製代碼
開發環境下的配置:
const merge = require('webpack-merge');
// 引入公共配置文件
const common = require('./webpack.config.common.js');
const path = require('path');
const appSrc = path.resolve(__dirname, '../src')
module.exports = merge(common, {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
// 出口
output: {
pathinfo: true,
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
// chunk名稱配置
chunkFilename: '[name].chunk.js',
// 輸出的文件名配置
filename: "bundle.js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
// exclude: /node_modules/,
include: appSrc,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
// 針對靜態文件
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
limit: 8192,
name: 'static/[name].[hash:8].[ext]',
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
minimize: false
}
}
]
}
]
},
devServer: {
// HOST
host: '127.0.0.1',
// 端口
port: 23333,
// 報錯提示在網頁遮罩層
overlay: true,
// 顯示運行進度
progress: true,
}
})
複製代碼
生產環境配置文件:
const path = require('path');
const merge = require('webpack-merge');
const common = require('./webpack.config.common.js');
// 每次執行打包 先清除以前的打包文件
const CleanWebpackPlugin = require('clean-webpack-plugin');
const appSrc = path.resolve(__dirname,'../src')
module.exports = merge(common, {
mode: 'production',
// 出口
output: {
pathinfo: false,
chunkFilename: 'js/[name].chunk.js',
// 全部輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, './../build'),
filename: "js/[name].[chunkhash:8].js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: appSrc,
// exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
},
// 針對靜態文件
{
test: /\.(png|jpg|gif)$/,
loader: "url-loader",
options: {
limit: 10000,
name: 'static/[name].[hash:8].[ext]',
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
minimize: true
}
}
]
}
]
},
plugins: [
// 打包前清除以前的build目錄
new CleanWebpackPlugin(['build'], path.resolve(__dirname, '../'))
]
});
複製代碼
如今配置已經修改完成,咱們還須要修改一下package.json,讓啓動命令去引用不一樣的配置文件。
將開發模式的啓動配置修改成 "start": "webpack-dev-server --open --mode development --config ./config/webpack.config.dev.js"
。
生產模式的啓動配置修改成 "build": "webpack --mode production --config ./config/webpack.config.prod.js",
如今咱們使用npm start
命令啓動項目,運行的是webpack.config.dev.js文件,這是開發配置文件,咱們能夠在裏面作一些針對開發模式的優化。
使用npm build
命令啓動項目,運行的是webpack.config.prod.js文件,這是生產配置文件,咱們能夠在裏面作一些針對生產模式的優化。
執行build命令打包文件時,會在項目的根目錄下生成build目錄,並在其中生成打包文件。當執行屢次build後,會發現因爲項目名稱的hash值不一樣,build目錄下可能存在多個版本打包後的文件。要解決這個問題,可使用插件 clean-webpack-plugin
。
首先安裝插件 npm i clean-webpack-plugin --save-dev
配置以下:
const CleanWebpackPlugin = require('clean-webpack-plugin')
// webpack config
{
plugins: [
new CleanWebpackPlugin(['build'], path.resolve(__dirname, '../'))
]
}
複製代碼
配置完插件後,再執行npm build命令。會發現每次打包前,build目錄都會被刪除,而後從新建立。
注意,該插件只用於生產環境配置。
到這裏,咱們實現了webpack的基礎的配置,以及各類概念的掃盲。其實這隻能算是基礎用法,要實現一個真正完善的webpack配置確定遠遠不止這些。這篇文章的面向對象爲初學者,全部在這裏就不過多的介紹那些比較複雜的概念。
在掌握了上述基礎配置後,你們能夠嘗試着進行一些更深刻的學習,如optimization、tree shaking、生產環境下的構建速度優化等。