配置的功能包括
1.ES6/REACT/CSS/LESS/IMG解析
2.文件监听和热更新
3.HTML/CSS文件生成、代码压缩、资源清理
4.文件指纹
1.创建一个项目,安装webpack
前提:node环境,创建项目test-project,初始化package.json和webpack
desktop % mkdir test-project
test-project % cd test-project && npm init -y
test-project % npm i webpack webpack-cli -D
安装成功后看下webpack版本,目前笔者这边是4.44.1
test-project % ./node_modules/.bin/webpack --version
4.44.1
通过vscode打开项目,根目录下创建webpack.config.js、src/index.js、src/helloworld.js
webpack.config.js
"use strict";
const path = require("path");
module.exports = {
// 提供打包文件的入口
entry: "./src/index.js",
// 提供打包输出的目录
output: {
path: path.join(__dirname, "dist"), // 输出文件夹
filename: "boundle.js", // 输出文件名
},
// 提供打包环境:production、development、none
mode: "production",
// 提供loader插件用于解析JSX/ES6/CSS/LESS/IMG等(由于webpack只能识别JSON和JS文件)
module: {
rules: [],
},
// 提供一些插件配置,用于解析外的处理(打包、压缩、文件生成等)
plugins: [],
};
index.js
import { helloworld } from "./helloworld";
helloworld();
src/helloworld.js
export function helloworld() {
document.write("Hello world!");
}
配置package.js
的webpack打包命令执行npm run build
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
得到dist文件以及其内容
在dist创建
index.html
,引入打包后的js文件,浏览器打开页面上正常显示:Hello world!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World!</title>
</head>
<body>
<script type="text/javascript" src="boundle.js"></script>
</body>
</html>
2.ES6/REACT/CSS/LESS/IMG解析
loader插件:
ES6:babel-loader、@babel/core、@babel/preset-env
REACT:react、react-dom、@babel/preset-react
CSS/LESS:style-loader、css-loader、less-loader
IMG:file-loader
安装插件
test-project % npm i babel-loader @babel/core @babel/preset-env react react-dom @babel/preset-react style-loader css-loader less-loader file-loader -D
babel的使用需要.babelrc
文件的配置
{
"presets": [
"@babel/preset-env", // 支持解析ES6
"@babel/preset-react" // 支持解析REACT
]
}
修改webpack.config.js
文件中的loader配置,rules为一个数组,每个对象是一个loader配置,test是一个校验,匹配支持该校验的文件,use指的使用何种loader,多个时使用数组(由于webpack的解析是一个自下向上的树解析过程,所以配置多个loader时,最上解析的loader放最前面)
module: {
rules: [
{
test: /.js$/,
use: "babel-loader",
},
{
test: /.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /.less$/,
use: ["style-loader", "css-loader", "less-loader"],
},
{
test: /.(png|jpg|jpeg|gif)$/,
use: "file-loader",
},
],
},
创建src/test.js、src/test.css、src/test.less
文件
test.js
import React from "react";
import ReactDOM from "react-dom";
import Img from "./images/test.jpg";
import "./test.css";
import "./test.less";
class Test extends React.Component {
render() {
return (
<div className="test-box">
<span>hello react!</span>
<img src={Img} />
</div>
);
}
}
ReactDOM.render(<Test />, document.getElementById("root"));
test.css
.test-box {
font-size: 20px;
color : #00f
}
test.less
.test-box {
img {
width : 300px;
height: auto;
}
}
由于本次查看的是test.js,我们需要重新调整webpack入口配置,entry可配置多个,使用对象包裹,output调整输出的名字,使用占位符“[name]”
// 提供打包文件的入口
entry: {
index: "./src/index.js",
test: "./src/test.js",
},
// 提供打包输出的目录
output: {
path: path.join(__dirname, "dist"), // 输出文件夹
filename: "[name].js", // 输出文件名
},
执行打包命令npm run build,添加dist/test.html,浏览器查看正常显示样式和图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World!</title>
</head>
<body>
<!-- 添加react挂载根节点 -->
<div id="root"></div>
<script type="text/javascript" src="test.js"></script>
</body>
</html>
3.文件监听和热更新
在开发环境下,由于每次修改文件我们都需要打包查看,webpack提供了文件监听和热更新的功能
文件监听:配置package.json命令"watch": "webpack --watch"
,使用npm run watch,这时候webpack会将我们修改的文件缓存在磁盘,当文件进行修改每隔一段时间(300ms)会进行匹配替换,此时我们仍需要刷新浏览器才可以看到最新代码
热更新:需要添加plugins插件HMR(HotModuleReplacementPlugin),安装webpack-dev-server
,配置package.json命令"dev": "webpack-dev-server --open"
test-project % npm i webpack-dev-server -D
// 提供打包环境:production、development、none
mode: "development",
// 提供一些插件配置,用于解析外的处理(打包、压缩、文件生成等)
plugins: [
// 代码热更新插件
new HotModuleReplacementPlugin(),
],
devServer: {
contentBase: "./dist",
hot: true,
},
注:清除dist目录重新打包,创建index.html引用test.js,执行npm run dev,当我们修改test.js后浏览器会自动刷新更新为最新的代码
当我们使用热更新启动时,打包后的boundle文件在浏览器中是运行在localhost:8080服务端的,会与客户端浏览器建立websocket长连接,当文件发生改动,服务端会主动推送消息给浏览器,浏览器接收到后进行一个reload
4.HTML/CSS文件生成、代码压缩、资源清理
plugins插件:
HTML文件生成、代码压缩:html-webpack-plugin
CSS文件生成、代码压缩:mini-css-extract-plugin、optimize-css-assets-webpack-plugin、cssnano
资源清理:clean-webpack-plugin
安装插件
test-project % npm i html-webpack-plugin -D
test-project % npm i mini-css-extract-plugin -D
test-project % npm i optimize-css-assets-webpack-plugin cssnano -D
test-project % npm i clean-webpack-plugin -D
修改webpack配置
plugins: [
// 生成css文件插件
new MinCssExtractPlugin({
filename: "[name].css",
}),
// css文件代码压缩插件
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require("cssnano"),
}),
// html文件生成、代码压缩插件
new HtmlWebpackPlugin({
template: path.join(__dirname, "src/index.html"),
filename: "index.html",
chunks: ["index"],
inject: true,
minify: {
html5: true,
removeComments: false,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyJS: true,
minifyCSS: true,
},
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, "src/test.html"),
filename: "test.html",
chunks: ["test"],
inject: true,
minify: {
html5: true,
removeComments: false,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyJS: true,
minifyCSS: true,
},
}),
// 清理打包后的目录插件
new CleanWebpackPlugin(),
],
由于style-loader是将生成的样式插入到页面的header中,和MinCssExtractPlugin会有冲突,所以调整rules
rules: [
{
test: /.css$/,
use: [MinCssExtractPlugin.loader, "css-loader"],
},
{
test: /.less$/,
use: [MinCssExtractPlugin.loader, "css-loader", "less-loader"],
},
],
创建src/index.html、src/test.html
,执行npm run build查看
代码都进行了压缩,且生成了html和css文件,浏览器查看显示正常
5.文件指纹
由于浏览器对一些静态文件会做缓存,当文件发生更改我们编译后虽然内容发生了变化,但名字没变化导致浏览器没检测到,所以引入了文件指纹,给生成的文件名后添加hash值
js:chunkhash
css:contenthash
img:hash
配置webpack文件(:8表示取hash值的前8位数)
output: {
path: path.join(__dirname, "dist"),
filename: "[name]_[chunkhash:8].js",
},
module: {
rules: [
{
test: /.(png|jpg|jpeg|gif)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name]_[hash:8].[ext]",
},
},
],
},
],
},
plugins: [
// 生成css文件插件
new MinCssExtractPlugin({
filename: "[name]_[contenthash:8].css",
}),
]
再次执行npm run build,浏览器查看显示正常
尾语
至此,支持基本开发打包的项目配置就完成啦😄😄😄