初始Webpack
1.webpack介绍
1-1. 什么是webpack?
- webpack是一个前端自动化构建工具。
- webpack可以都会前端的所有资源文件(js/json/css/img/less/...)都可以进行相对于的处理。
- 它将根据模块的依赖关系进行静态分析,生成对应的静态资源。
1-2. 五个核心概念
- Entry:入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始
- Output:出口,output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件
- Loader:loader 让 webpack 能够去处理那些非 JavaScript 文件
- Plugins:插件则可以用于执行范围更广的任务。例如:打包优化、压缩
- Mode:模式,有生产模式 production 和开发模式 development
1-3. 理解 Loader
- Webpack本身只能加载 JS/JSON 模块,如果要加载其他类型的文件(模块),就需要使用对应的 loader 进行转换/加载
- Loader 本身也是运行在 node.js 环境中的 JavaScript 模块
- 本身是一个函数,接受源文件作为参数,返回转换的结果
- loader 一般以 xxx-loader 的方式命名,xxx 代表了这个loader 要做的转换功能,比如 less-loader
1-4. 理解 plugins
- 插件可以完成一些 loader 不能完成的功能
- 插件的使用一般是在 webpack 的配置信息 plugins 选项中指定
1-5. Mode
- 模式(Mode)指示 webpack 使用相应模式的配置
1-6. 配置文件(默认)
- webpack.config.js:是一个 node 模块,返回一个json 格式的配置信息对象
2. 安装 webpack
- 全局安装(这一步暂时不需要做)
npm install webpack webpack-cli -g
- 局部安装(选这个)
npm init -y
npm install webpack webpack-cli -D
官方推荐使用『局部安装』
,这样可以避免因为版本不同而产生的 BUG
3.webpack 的初体验
1. 创建JS模块:src/index.js
import data from './data.json'
console.log(data);
const add = (x,y)=>{
return x + y
}
console.log(add(1,2));
2. 创建JSON模块:src/data.json
{
"name":"jack",
"age": 18
}
3. 创建CSS:src/index.css
html,
body{
height: 100%;
background-color: pink;
}
4. 安装
npm init -y
npm i webpack webpack-cli -D
5. 执行打包命令 『项目根目录下运行』
生产环境会把代码压缩为一行
// 开发环境打包
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 /build/built.js
整体打包环境,是开发环境
npx webpack --entry ./src/index.js --output-path ./build --output-filename build.js --mode development
// 生产环境打包
webpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js
整体打包环境,是生产环境
npx webpack --entry ./src/index.js --output-path ./build --output-filename build.js --mode production
- –entry 设置入口
- –output-path 设置输出目录
- –output-filename 设置输出文件名
- –mode 设置运行模式
区别 npm 与 npx ?
- 它们都是由Node提供的2个工具, 用来做工具包的相关处理
- npm (Node Package Manager) : 包管理器, 用来 下载工具包
- npx (Node Package Excuted) : 包扩展工具, 用来 运行工具包命令
- npx 查找工具包的顺序: 局部查找 ==> 全局查找 ==> 运行
注:当在index.js中引入css样式,会进行一个报错
import "./index.css" // 发生错误
结论:
1)webpack能处理js/json资源,不能处理css/img等其他资源
2)生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化~
3)生产环境比开发环境多一个压缩js代码。
4.使用配置文件打包
问题
:打包命令太复杂(需要指定打包的各种配置信息)
解决
:通过JS类型的配置文件来指定打包的配置信息
- 目的:在项目根目录定义配置文件,通过自定义配置文件,进行项目的构建处理
- 文件名称: webpack.config.js
- 文件内容:
/*
webpack.config.js webpack的配置文件
作用: 指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)
所有构建工具都是基于nodejs平台运行的~模块化默认采用commonjs。
*/
const {resolve} = require('path'); // path模块是Node内置的
// __dirname:当前配置文件所在的目录绝对路径
// resolve: 用来拼接路径的函数
// 暴露配置对象
module.exports = {
// 入口
entry: './src/index.js',
// 出口
output: {
path: resolve(__dirname, 'build'), // 打包文件所在的根目录
filename: 'js/build.js', // 打包生成的js文件名(可以带目录)
clean: true, // 打包时, 会先自动清空打包文件夹
},
// 模式
// mode: 'production',
mode: 'development',
}
- 运行指令:
npx webpack
5.打包样式
问题
:webpack本身只能打包 JS 文件和 JSON 文件, 不能打包CSS文件
解决
:利用css-loader & style-loader
& less-loader
对CSS进行打包处理
准备工作:
1. 创建css文件:./src/index.css
html,body{
height: 100%;
background-color: pink;
}
2. 创建less文件:./src/index.less
#title{
color: #fff;
}
3.在入口JS文件中引入这些资源:./src/index.js
import './index.less'
import './index.css'
5-1. 打包 css 文件
1. 安装loader
npm i style-loader css-loader -D
2. 修改 webpack.config.js 配置文件
module.exports = {
.
.
.
mode: 'development',
// 配置 loader
module: {
rules: [
// 配置 css 文件处理
{
test: /\.css$/, // 处理css文件
use: [
"style-loader", // 将 CSS 生成 style 标签插入 HTML 中
"css-loader" // 将 CSS 转为 CommonJS 的模块
]
}
]
},
}
3. 运行打包命令 『在项目的根目录下运行』
npx webpack
5-2. 打包 less 文件
1. 安装loader
npm i less less-loader -D
2. 修改 webpack.config.js 配置loader
module.exports = {
.
.
.
module: {
rules: [
.
.
.
// 配置 less 文件处理
{
test: /\.less$/, // 处理less文件
use: [
'style-loader', // 将 CSS 生成 style 标签插入 HTML 中
'css-loader', // 将 CSS 转为 CommonJS 的模块
'less-loader' // 将Less编译为CSS
]
},
]
}
}
3. 运行打包命令 『在项目的根目录下运行』
npx webpack
6. 打包 HTML
问题
: 在HTML中手动引入打包文件比较麻烦,且没有压缩处理
解决
: 使用html-webpack-plugin
打包HTML => 自动引入打包文件,压缩HTML
1. 删除HTML中引入的JS打包文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>hello html</h1>
</body>
</html>
2. 安装插件
npm install --save-dev html-webpack-plugin
3. 修改 webpack.config.js 配置文件
// 1. 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
.
.
.
plugins:[
// plugins的配置
// html-webpack-plugin
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
// 需求:需要有结构的
// 2. 配置打包HTML的插件
new HtmlWebpackPlugin({
template: "./src/index.html",// 指定html模板文件。
inject: "body",// 将打包生成的JS文件放置在body尾部
hash: true,// 在引入JS时增加hash后缀字符串,去除缓存。
filename:'test.html', //指定生成打包后的文件名
minify: {
removeAttributeQuotes: true,// 移除属性中的双引号
removeComments: true,// 移除注释
collapseWhitespace: true,// 去除空格与换行
}
})
]
}
4. 执行打包命令
npx webpack # 打包产生的页面自动引入js/json打包文件
5. 执行后,产生新的 html 文件在我们指定路径中查看
7. 打包图片
7-1.打包 CSS和JS 中的图片
问题
: 在CSS或JS中我们都有可能引入图片, 如何打包这些图片文件呢?
解决
: 我们可以用内置的资源加载器来处理参考文档:https://webpack.docschina.org/guides/asset-modules/
1. 在CSS中引入图片
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
拷贝图片1.jpg、2.jpg、3.jpg到src/img文件夹下
#box1 {
width: 100px;
height: 100px;
background-image: url('1.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
}
#box1 {
width: 100px;
height: 100px;
background-image: url('2.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
}
#box1 {
width: 100px;
height: 100px;
background-image: url('3.jpg');
background-repeat: no-repeat;
background-size: 100% 100%;
}
2. 修改 webpack.config.js
module.exports = {
.
.
.
mode: 'development',
module: {
rules: [
// 处理图片
{
test: /\.(jpg|png|gif)$/,
type: "asset",
// 解析器
parser: {
// 指定进行图片base64编码最大文件大小
dataUrlCondition: {
maxSize: 5 * 1024, // 5kb 默认8k
}
},
// 打包生成的文件
generator: {
filename: 'images/[hash:8][ext]',
},
},
]
}
}
3. 重新打包
npx webpack
图片base64编码:对要引入的小图片转换为特定字符串,显示时还是为原图片
好处:减少HTTP请求,加快图片显示
限制:只合适小图片,如果是大图也做base64处理,会导致css/html文件过大,不利用页面显示
7-2.打包 HTML 中的图片
问题
:内置的资源打包器不能打包处理html中 引入的图片
解决
:利用html-loader
打包html中引入的图片
1. HTML 结构中引入图片
拷贝图片 angular.png
到public/img
目录下
<img src="./img/angular.png" alt="">
2. 安装 loader
npm i html-loader -D
3. 配置 loader
module.exports = {
.
.
.
module: {
rules: [
// 配置 html 的 loader
{
test: /\.(html)$/,
use: {
loader: 'html-loader'
}
}
]
}
}
4. 执行打包
npx webpack
需要移除 public/index.html 中的 script 标签, 否则会再次导入 JS, 造成打包失败
8. 其他资源打包
问题
:项目中有可能引入字体图片文件来显示小图标, 如何打包字体图标呢?
解决
:我们也可以用内置的资源加载器来处理
首先先下载一个阿里图标库中的项目,然后按照如下流程操作:
1. 将字体文件复制到 src/fonts
目录下
iconfont.ttf / iconfont.woff / iconfont.woff2
2. 复制 CSS 代码到样式文件中,这里可以是 CSS 文件,也可以是 LESS 文件
@font-face {
font-family: 'iconfont';
src: url('../fonts/iconfont.woff2?t=1652078424644') format('woff2'),
url('../fonts/iconfont.woff?t=1652078424644') format('woff'),
url('../fonts/iconfont.ttf?t=1652078424644') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
3. HTML 结构中创建对应的 span 标签
<span class="iconfont"></span>
4. 修改 webpack.config.js 配置文件
module.exports = {
mode: 'development',
module: {
rules: [
// 打包字体图标
{
test: /\.(eot|svg|woff|woff2|ttf)$/,
type: 'asset/resource',
generator: {
filename: 'fonts/[hash:8][ext]',
},
},
]
},
}
5. 重新打包
npx webpack
9. devServer 的开启
目的:开发服务器 devServer的开启,用来浏览器的自动化处理,包括:自动编译,自动打开浏览器,自动刷新浏览器等
1. 修改 webpack.config.js
module.exports = {
.
.
.
mode: 'development',
// 开发服务器 devServer: 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
// 特点:只会在内存中编译打包,不会有任何输出
// 启动devServer指令为: npx webpack-dev-server
devServer: {
// 项目构建后路径
contentBase: resolve( dirname, "build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open:true
}
};
2. 运行
npx webpack-dev-server