这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
最近是实在太忙了,自己也陷入了一个怪圈,这个是笔者之前总结的关于webpack的基础入门知识。
1.webpack简介
1.1webpack是什么?
webpack是一种前端资源构建工具,一个静态模块打包器(module bundler)。在webpack看来,前端多有的资源文件(js/json/css/img/less/…)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源(bundle)。
1.2 webpack五个核心概念
-
Entry: 入口(entry)指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图。 -
Output: 输出指示webpack打包后的资源bundles输出到哪里去,以及如何命名。 -
Loader:Loader让webpack能够去处理那些非Javascript文件(webpack自身只理解Javascript)。 -
Plugins: 插件可以用于执行范围更广的任务,插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。 -
Mode:模式指示
webpack使用相应模式的配置。选项 描述 特点 development: 会将 DefinePlugin中process.env.NODE_ENV的值设置为development,启用NamedChunksPlugin和NamedModulesPlugin。能让代码本地调试的运行环境 production: 会将 DefinePlugin中process.env.NODE__ENV的值设置为production。启用FlagDependencyUsagePlugin,FlagIncludedChunksPluginModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和TerserPlugin。能让代码优化上线的运行环境
2.webpack打包初体验:
目录结构如下:
代码:
// index:webpack的入口起点文件
import data from "./test.json";
import test from "./test.css";
function add(x,y){
return x + y
}
console.log(add(1,2))
console.log("我是json",data);
//test.json
{
"key": "测试json文件打包"
}
// test.css
body{
background-color: #42b983;
height: 1000px;
width: 100%;
}
文件夹根目录下的index.html:
- 这里
script引入的是打包后的main.js文件 build为根目录下新建的文件夹
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="./src/test.css">
</head>
<body>
<script src="./build/main.js"></script>
</body>
</html>
安装以及打包操作:
安装:
- 全局下先安装:
npm i webpack webpack-cli -g - 项目中安装:
npm i webpack webpack-cli -D
打包:
- 开发环境:
- 命令:
webpack ./src/index.js -o ./build --mode=development(-o的意思就是output输出) - 作用:
webpack能够编译打包js和json文件,并且能够将es6的模块化语法转换成浏览器能识别的语法。
- 命令:
- 生产环境:
- 命令:
webpack ./src/index.js -o ./build --mode=production - 作用:在开发配置功能上多一个功能,压缩代码
- 命令:
问题:
在引入css文件后在打包,发现报错:
结论:
webpack能处理js和json文件,不能处理css/img等其他资源生成环境和开发环境将ES6模块化编译成浏览器能识别的module生产环境比开发环境多一个压缩js代码
3.webpack打包资源:
1.对于css和less的打包:
- 项目的根目录下创建一个
webpack.config.js文件,该文件的作用主要是用来告诉webpack---你要去干些啥 const {resolve} = require("path");:用来拼接绝对路径用的resolve(__dirname,"build"):__dirname表示的是当前的文件的目录绝对路径,是nodejs的一个变量
module中的rules是用来配置loader的test用来匹配文件use是来处理匹配文件的,use数组中的执行顺序是从下向上
- 打包
less文件的时候需要注意安装less和less-loader,less不用配置到use数组中
//告诉webpack的都干点啥
// 所有的构建工具都是基于nodejs平台运行的,模块化默认才用commonjs的语法
const {resolve} = require("path");
module.exports = {
// 入口
entry:"./src/index.js",
// 出口
output:{
//打包输出的文件名字
filename:"build.js",
//__dirname表示的是当前的文件的目录绝对路径,是nodejs的一个变量
path:resolve(__dirname,"build")
},
//loader的配置
module:{
rules:[
//详细的loader的配置
{
//test -- 匹配以.css文件结尾的
test:/\.css$/,
//use的意思是使用那些loader出处理,use数组中的执行顺序是从下到上
use:[
//将style标签以及js中的样式资源插入到head中生效
"style-loader",
//css-loader是将css文件转化为commonjs模块,加载到js中,里面的内容是样式字符串
"css-loader"
]
},
{
//test -- 匹配以.css文件结尾的
test:/\.less$/,
//use的意思是使用那些loader出处理,use数组中的执行顺序是从下到上
use:[
//将style标签以及js中的样式资源插入到head中生效
"style-loader",
//css-loader是将css文件转化为commonjs模块,加载到js中,里面的内容是样式字符串
"css-loader",
"less-loader",
]
}
]
},
// 插件
plugins:[
//插件的详细配置
],
//模式
mode:"development"
}
2.对于html的打包:
这里使用插件对html进行处理。
npm i html-webpack-plugin -D
webpack.config.js代码:
- 安装完了
html-webpack-plugin之后,使用时是需要引入的const HtmlWebpackPlugin = require("html-webpack-plugin");
template:就是一个模板嘛,复制"./src/index.html"文件资源,并自动引入打包输出所有的资源(js/css)
//webpack.config.js
const {resolve} = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports={
entry:"./src/index.js",
output:{
filename:"html.js",
path:resolve(__dirname,"build")
},
module:{
rules:[
]
},
plugins:[
// 默认创建一个空的html,自动引入打包输出所有的资源(js/css)
new HtmlWebpackPlugin({
//复制"./src/index.html"文件资源,并自动引入打包输出所有的资源(js/css)
template:"./src/index.html"
})
],
mode:"development"
}
打包结果:
会发现build文件夹下面多生成了一个index.html文件
3.对于图片资源的打包:
文件夹结构:
├─webpack.config.js
├─src
| ├─bbb.jpeg
| ├─index.html
| ├─index.js
| └index.less
webpack.config.js:
这里对于入口的index.js以及其他的内容就不做多余阐述了,和上面基本类似。直接来看下关于webpack.config.js的配置:
- 这里使用
url-loader对于图片做处理,但是url-loader依赖于file-loader,所以两个都是需要安装的(只引入一个) options中的limit:如下代码中注释部分
const {resolve} = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports={
entry:'./src/index.js',
output:{
filename:"build.js",
path:resolve(__dirname,"build")
},
module:{
rules:[
{
test:/\.less$/,
use:[
"style-loader",
"css-loader",
"less-loader",
]
},
{
test:/\.(jpg|png|gif|jpeg)$/,
//使用单个loader的书写形式
//需要下载两个包,url-loader和file-loader,因为url-loader依赖于file-loader去做事,所以需要下载两个
loader:"url-loader",
options:{
// 作用:图片大小小于8kb就还会被base64处理
// 优点:减少请求数量,减轻服务器压力
// 缺点:图片体积会更大(文件请求速度会稍微慢些)
limit:8 * 1024
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:"./src/index.html"
})
],
mode:"development"
}
新问题:
url-loader可以处理css中的图片,但是对于html中的图片,打包后build/index.html文件用浏览器打开后发现图片无法显示...
- 这个时候需要
html-loader url-loader和html-loader中的options的esModule都设置为了false- 原因:关闭
url-loader的es6module模块化,使用commonjs的模块化
- 原因:关闭
name:"[hash:10].[ext]":[hash:10]:取hash值的前10位[ext]:取文件的原来的后缀名
const {resolve} = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports={
entry:'./src/index.js',
output:{
filename:"build.js",
path:resolve(__dirname,"build")
},
module:{
rules:[
{
test:/\.less$/,
use:[
"style-loader",
"css-loader",
"less-loader",
]
},
{
test:/\.(jpg|png|gif|jpeg)$/,
//使用单个loader的书写形式
//需要下载两个包,url-loader和file-loader,因为url-loader依赖于file-loader去做事,所以需要下载两个
loader:"url-loader",
options:{
// 作用:图片大小小于8kb就还会被base64处理
// 优点:减少请求数量,减轻服务器压力
// 缺点:图片体积会更大(文件请求速度会稍微慢些)
limit:8 * 1024,
esModule:false,
//给图片进行重命名
name:"[hash:10].[ext]"
},
},
{
test:/\.html$/,
// html-loader 负责引入html中的图片,从而能被url-loader处理
loader: "html-loader",
options: {
esModule: false
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:"./src/index.html"
})
],
mode:"development"
}
4.对于其他资源的打包:
目录结构:
src
├─iconfont.css
├─iconfont.eot
├─iconfont.svg
├─iconfont.ttf
├─iconfont.woff
├─iconfont.woff2
├─index.html
└index.js
这里为了测试,使用了iconfont的资源
webpack.config.js
- 通过
rules中对象的exclude:/\.(css|js|html)$/排除这些后缀的文件,剩下的就是其他文件(这里指的是字体文件等) - 通过
file-loader来处理其他文件的加载
const {resolve} = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry:"./src/index.js",
output:{
filename:"build.js",
path:resolve(__dirname,"build")
},
module:{
rules:[
{
test:/\.css$/,
use:[
"style-loader",
"css-loader",
]
},
{
//使用exclude去排除这些后缀,那么剩下的就是其他资源
exclude:/\.(css|js|html)$/,
loader:"file-loader"
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:"./src/index.html"
})
],
mode:"development"
}
4.webpack-dev-server
修改src中的文件后需要手动编译,webpack-dev-server为其自动化提供了可能
直接上webpack.config.js文件:
contentBase:项目构建后的路径compress:是否开启gzip压缩port:端口号open:编译过后自动打开
const {resolve} = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry:"./src/index.js",
output:{
filename:"build.js",
path:resolve(__dirname,"build")
},
module:{
rules:[
{
test:/\.css$/,
use:[
"style-loader",
"css-loader",
]
},
{
//使用exclude去排除这些后缀,那么剩下的就是其他资源
exclude:/\.(css|js|html)$/,
loader:"file-loader"
}
]
},
plugins:[
new HtmlWebpackPlugin({
template:"./src/index.html"
})
],
mode:"development",
devServer:{
//项目构建后的路径
contentBase:resolve(__dirname,"build"),
//启动gzip压缩
compress:true,
// 端口号
port:3000,
// 编译后自动打开浏览器
open:true
}
}