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
,FlagIncludedChunksPlugin
ModuleConcatenationPlugin
,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
}
}