# webpack常用配置解析
Webpack可以看做是模块打包机:它做的事情是,分析你的项⽬结构,找到JavaScript模块以及其它的⼀些浏览器不能直接运⾏的拓展语⾔(less,sass,typeScript等),并将其打包为合适的格式以供浏览器使⽤。
# 安装
npm install webpack --save-dev // 不建议全局安装
webpack -v // 查看版本 确定安装成功
# 基本配置
打包默认配置文件是 webpack.config.js
npx webpack //执⾏命令后,webpack会找到默认的配置⽂件,并使⽤执⾏
不使用默认配置文件:webpackconfig.js
npx webpack --config webpackconfig.js //指定webpackconfig.js⽂件来作为配置⽂件并执⾏
修改 package.json scripts
字段, 使用 npm run build
方式执行打包
package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "npx webpack"
},
"keywords": [],
"author": "",
"license": "ISC"
}
npm run build
webpack.config.js
配置结构
module.exports = {
entry: './src/index.js', // 入口文件
output: './dist', // 输出位置
mode: 'none', // 打包环境 production development none
module: {
rules: [
//loader模块处理
{
test: /\.css$/,
use: "style-loader"
}
]
},
plugins: [] //插件配置
}
# 常用loader
当 webpack
处理到不认识的模块时,需要在 webpack
中的 module
处进⾏配置,当检测到是什么格式的模块,使⽤什么 loader
来处理。
- style-loader // 处理样式
- css-loader // 处理css
- less-loader // 处理less
- sass-loader // 处理sass
- ts-loader //将Ts转换成js
- babel-loader//转换ES6、7等js新特性语法
- file-loader//处理图⽚⼦图等静态资源模块
# 样式处理 css-loader,style-loader,less-loader
css-loader:分析 css
模块之间的关系,并合成⼀个 css
style-loader:style-loader
会把 css-loader
⽣成的内容,以 style
挂载到⻚⾯的head
部分,(文件里面看不到,浏览器才能看到,放到了 index.js
等执行完head
才有)
less-loader:webpack
将 Less
编译为 CSS
的 loader
。
post-loader:预处理css
的loader
autoprefixer:样式⾃动添加前缀
const htmlWebpackPlugin = require("html-webpack-plugin"); // 通过 npm 安装
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'index.js',
path: path.resolve(__dirname, './dist')
},
mode: 'development', // 打包环境 production development none
module: {
rules: [
{
test: /\.less$/, // 处理less文件 并插入到head
use: ["style-loader", "css-loader", "less-loader"]
},
{
test: /\.sass$/, // 处理sass文件 并插入到head
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
plugins: [
// 以模版自动生成HTML 且生成的js会自动引入
new htmlWebpackPlugin({
title: 'webpack demo',
template: path.join(__dirname, './src/index.html'),
filename:'index.html' //指定生成的页面名称
})
] //插件配置
}
# 文件处理
file-loader:处理静态资源模块,把打包⼊⼝中识别出的资源模块,移动到输出⽬录,并且返回⼀个地址名称
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: "file-loader",
// options额外的配置,⽐如资源名称
options: {
name: "[name]_[hash].[ext]",
//打包后的存放位置
outputPath: "images/"
}
}
}
]
}
url-loader:file-loader
加强版本,不同的是会把 <limit
限制的图⽚转换成base64
格式字符串并打包到js
⾥。
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: "url-loader",
// options额外的配置,⽐如资源名称
options: {
name: "[name]_[hash].[ext]",
//打包后的存放位置
outputPath: "images/",
//⼩于2048,才转换成base64
limit: 2048
}
}
}
]
}
# Babel处理ES6
npm i babel-loader @babel/core @babel/preset-env -D
//babel-loader是webpack 与 babel的通信桥梁,不会做把es6转成es5的⼯作。
// 这部分⼯作需要⽤到@babel/preset-env来做
//@babel/preset-env⾥包含了es6转es5的转换规则
webpack.config.js
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"]
}
}
}
# 安装 es6
新特性
# 全局引入方式(全部引入)把所有特性注⼊进来
npm install --save @babel/polyfill
//index.js 顶部
import "@babel/polyfill";
# 按需加载
webpack.config.js
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
},
corejs: 2,//新版本需要指定核⼼库版本
useBuiltIns: "usage"//按需注⼊
}
]
]
}
}
}
# 不污染全局
@babel/plugin-transform-runtime
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
"plugins": [
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
}
}
usage 的⾏为类似 babel-transform-runtime,不会造成全局污染,因此也会不会对类似
Array.prototype.includes()
进⾏ polyfill。
# .babelrc⽂件
options部分移入该文件
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}
# 插件Plugins
# HtmlWebpackPlugin
在打包结束后,自动生成一个html
文件,并把打包⽣成的js
模块引⼊到该html
中。
npm install html-webpack-plugin --save-dev
const htmlWebpackPlugin = require("html-webpack-plugin"); // 通过 npm 安装
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'index.js',
path: path.resolve(__dirname, './dist')
},
mode: 'development', // 打包环境 production development none
module: {
rules: [
{
test: /\.less$/, // 处理less文件 并插入到head
use: ["style-loader", "css-loader", "less-loader"]
},
{
test: /\.sass$/, // 处理sass文件 并插入到head
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
plugins: [
// 以模版自动生成HTML 且生成的js会自动引入
new htmlWebpackPlugin({
title: 'webpack demo', // 页面标题
template: path.join(__dirname, './src/index.html'), // 源html
filename:'index.html' //指定生成的页面名称
})
] //插件配置
}
title
会赋值到 htmlWebpackPlugin.options.title
,在html
页面中用ejs
语法指定title
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app">app</div>
</body>
</html>
# clean-webpack-plugin
输出前删除生成的文件夹
npm install clean-webpack-plugin --save-dev
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const htmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'index.js',
path: path.resolve(__dirname, './dist')
},
mode: 'development', // 打包环境 production development none
module: {
rules: [
{
test: /\.less$/, // 处理less文件 并插入到head
use: ["style-loader", "css-loader", "less-loader"]
}
]
},
plugins: [
new CleanWebpackPlugin(),
// 以模版自动生成HTML 且生成的js会自动引入
new htmlWebpackPlugin({
title: 'webpack demo', // 页面标题
template: path.join(__dirname, './src/index.html'), // 源html
filename:'index.html' //指定生成的页面名称
})
] //插件配置
}
# mini-css-extract-plugin
将css
提取为独立的文件的插件,对每个包含css
的js
文件都会创建一个css
文件。生成的文件会自动添加到index.html
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const htmlWebpackPlugin = require("html-webpack-plugin");
const miniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'index.js',
path: path.resolve(__dirname, './dist')
},
mode: 'development', // 打包环境 production development none
module: {
rules: [
{
test: /\.less$/, // 处理less文件 并插入到head
use: [miniCssExtractPlugin.loader, "css-loader", "less-loader"] // 用了这个style-loader就不能写了
}
]
},
plugins: [
new CleanWebpackPlugin(),
new miniCssExtractPlugin({
filename: "[name][chunkhash:8].css" // 单独生成指定css文件
}),
// 以模版自动生成HTML 且生成的js会自动引入
new htmlWebpackPlugin({
title: 'webpack demo', // 页面标题
template: path.join(__dirname, './src/index.html'), // 源html
filename:'index.html' //指定生成的页面名称
})
] //插件配置
}
# sourceMap
源代码与打包后的代码的映射关系,通过sourceMap定位到源代码。
devtool:"cheap-module-eval-source-map",// 开发环境配置
devtool:"cheap-module-source-map", // 线上⽣成配置
# WebpackDevServer
提升开发效率的利器
npm install webpack-dev-server -D
# 运行 webpack-dev-server
npx webpack-dev-server
或
配置 package.json
"scripts": {
"server": "webpack-dev-server"
}
npm run server
该操作会运行服务到 http://localhost:8080
# 配置自定义端口
devServer: {
contentBase: "./dist",
open: true,
port: 8081
}
# 跨域实现代理
devServer: {
contentBase: "./dist",
open: true,
port: 8081,
proxy: {
'/api': 'http://localhost:3000'
}
}
现在,对 /api/users
的请求会将请求代理到 http://localhost:3000/api/users
。
# Hot Module Replacement (HMR:热模块替换)
const webpack = require("webpack");
module.exports = {
devServer: {
contentBase: "./dist",
open: true,
hot:true // 启动hmr
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
注意启动HMR后,
css
抽离会不⽣效,需用style-loader
← 鉴权 loader和plugin怎么写 →