目录
(2)在webpack.config.js中配置loader
(一)概念
webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。
当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
webpack的依赖图
- 根据指令或配置找到入口文件
- 从入口文件出发构建依赖关系图,这个关系图会包括项目中所需的所有模块(js、css、字体、图片等)
- 遍历图结构,依次打包每个模块(依靠loader完成)
webpack只能理解 JavaScript 和 JSON 文件,而对于其他类型文件:css、TypeScript等,需要依靠安装对应的 loader对其进行转换(后续会补充)。
(二)webpack的基本使用
1.初始化项目,生成package.json文件
npm init -y
2.安装webpack和webpack-cli包
npm i webpack webpack-cli -D
3.在package.json配置打包指令
"scripts": {
"build": "webpack"
},
4.在终端输入 npm run build 即可打包项目
(三)webpack的配置文件
webpack可以开箱即用,无需设置配置文件,但会将 src/index,js 文件作为入口文件,将 dist/main.js 作为输出文件。如果没有对应路径的入口文件,就会打包失败并报错。
如果需要对webpack进行更完善的配置,就需要创建webpack.config.js文件,webpack会自动使用它的配置内容
1.入口(entry)配置
可以配置一个或多个入口文件
javascript
module.exports = {
entry: './src/index.js'
}
2.输出(output)配置
通过配置
output
选项,告知 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个entry
起点,但只能指定一个output
配置。
通过如下配置打包后代码会生成在/dist/bundle.js中
javascript
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
(三)loader
loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
两种使用loader的方法:
- 配置法:在webpack配置文件中使用(推荐)
- 内嵌法:在需要解析的文件中引入对应loader(每个文件都需要单独引入,较繁琐)
loader有两个属性:
- test属性:用于识别文件类型
- use属性:用于进行转换时使用哪个loader
1.css文件处理
直接将css文件引入到入口文件进行打包会导致报错
javascript
import './components/css_test.css'
因此,需要依靠css-loader解析css文件,依靠style-loader将解析好的css插入DOM中
参考文档:
css-loader | webpack 中文文档 | webpack中文文档 | webpack中文网
style-loader | webpack 中文文档 | webpack中文文档 | webpack中文网
(1)安装css-loader和style-loader
npm i css-loader style-loader -D
(2)在webpack.config.js中配置loader
注意:loader 从前往后地取值(evaluate)/执行(execute) ,即先执行css-loader再执行style-loader
javascript
module: {
rules: [
{
/* 正则表达式 */
test: /\.css$/, // 识别.css后缀的文件
/* 使用对应loader解析,解析方向:从后往前 */
// 简写形式
use: ['style-loader', 'css-loader']
// 完整形式
// use: [
// { loader: 'style-loader' },
// { loader: 'css-loader' },
// ]
}
]
}
重新打包后,css就解析成功了,但是是通过页内样式添加进来的。后续css文件的单独抽取以及压缩等操作会在后面学习到。
2.less文件处理
参考文档:less-loader | webpack 中文文档 | webpack中文文档 | webpack中文网
(1)安装less和less-loader组件
npm i less less-loader -D
(2)配置webpack.config.js
javascript
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
3.postcss的使用
postcss是一个用 JavaScript 工具和插件转换 CSS 代码的工具,可以帮助我们进行一些CSS的转换和适配,比如自动添加浏览器前缀、css样式的重置
PostCSS - 是一个用 JavaScript 工具和插件来转换 CSS 代码的工具 | PostCSS中文网
postcss的postcss-preset-env 插件可以帮助我们将一些现代的 CSS 特性,转成大多数浏览器认识的 CSS,并且会根据目标浏览器或者运行时环境添加所需的 polyfill,已经内置了autoprefixer
(1)安装postcss和postcss-loader
npm i postcss postcss-loader -D
(2)安装postcss-preset-env插件
npm i poscss-preset-env -D
(3)配置webpack.config.js
javascript
{
test: /\.css$/, // 识别.css后缀的文件
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'postcss-loader',
options: {
/* 对postcss进行配置 */
postcssOptions: {
/* 配置插件 */
plugins: [
['postcss-preset-env',],
],
},
},
}
]
},
可以将postcss的具体配置写到postcss.config.js文件中,配置更简洁
javascript
在postcss.config.js文件中:
module.exports = {
plugins: [
'postcss-preset-env'
]
}
在webpack.config.js中:
{
test: /\.css$/, // 识别.css后缀的文件
use: [ 'style-loader','css-loader','postcss-loader']
},
再重新打包后,postcss就会根据样式自动添加浏览器前缀
4.图片文件处理
资源模块 | webpack 中文文档 | webpack中文文档 | webpack中文网
在webpack5之前,处理资源文件还需要用到相关的loader
在webpack5中,资源模块(asset module) 是一种模块类型,它允许使用资源文件(字体,图标等)而无需配置额外 loader
资源模块类型(asset module type),通过添加 4 种新的模块类型,来替换所有这些 loader:
- asset/resource:发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。
- asset/inline:导出一个资源的 data URI。之前通过使用 url-loader 实现。
- asset/source:导出资源的源代码 。之前通过使用 raw-loader 实现。(不常用)
- asset:在导出一个 data URI 和发送一个单独的文件之间自动选择 。之前通过使用 url-loader,并且配置资源体积限制 实现。(推荐)
示范代码准备:
用到两个文件大小不同的图片(后续解释原因),一个使用background-url链接到图片,一个使用img标签src链接到图片。
css
.image {
background-image: url(../images/p1.jpg);
}
javascript
import img2 from '../images/p2.jpg'
import '../style/img.css'
// 图片1 采用url()展示
const image1 = document.createElement('img')
image1.classList.add('image')
document.body.append(image1)
// 图片2 采用直接链接展示
const image2 = document.createElement('img')
image2.src = img2
document.body.append(image2)
接下来会分别展示asset/resource、asset/inline、asset这三种资源模块类型的区别
(1)asset/resource模块类型
在webpack配置文件中配置模块类型
javascript
{
test: /\.(png|jpe?g|gif|svg)$/, // 识别图片后缀的文件
type: 'asset/resource'
}
打包后,可以看到用到的图片资源都被复制到打包文件夹中,以哈希值进行重命名了
所有图片文件都将被发送到输出目录,并且其路径将被注入到 bundle 中,除此之外,你可以为它们自定义 outputPath 和 publicPath 属性。
自定义输出文件名
第一种方法:在配置文件的output里设置assetModuleFilename。
可以设置固定名称(不建议),也可以设置相关占位符,如
javascript
assetModuleFilename: 'images/[hash][ext][query]'
但是不建议在这里配置,资源文件除了图片还有可能是字体文件等资源,这样会导致混淆
**第二种方法:**在rules里进行配置generator
javascript
{
test: /\.(png|jpe?g|gif|svg)$/, // 识别图片后缀的文件
type: 'asset/resource',
/* 第二种:在这里设置输出资源路径和文件名 */
generator: {
/* 占位符:
name:文件原本的名字;
hash:webpack生成的哈希值;
ext:扩展名
*/
filename: 'image/[name]_[hash][ext]'
}
}
打包后图片资源文件都存储在image文件夹中,并以name和hash命名
(2)asset/inline模块类型
配置文件:
javascript
{
test: /\.(png|jpe?g|gif|svg)$/, // 识别图片后缀的文件
type: 'asset/inline', // 将图片转换为base64编码的data:uri数据存放在js文件中
}
打包后,图片资源不再以文件形式打包,而是转换为base64编码的数据存储到js文件中,这会导致js文件变大
(3)asset模块类型
以上两种模块类型都太过绝对,不是最优解
- 使用resource模块类型,图片过多会影响网络请求;
- 使用inline模块类型,图片过大会增加js文件体积,导致页面渲染缓慢 ;
使用asset类型进行自动选择
webpack 将按照默认条件,自动地在
resource
和inline
之间进行选择:小于 8kb 的文件,将会视为inline
模块类型,否则会被视为resource
模块类型。
可以根据自己的情况,在 webpack 配置的 module rule 层级中自定义使用inline类型的最大文件大小
javascript
{
test: /\.(png|jpe?g|gif|svg)$/, // 识别图片后缀的文件
type: 'asset',
/* 第二种:在这里设置输出资源路径和文件名 */
generator: {
/* 占位符:
name:文件原本的名字;
hash:webpack生成的哈希值;
ext:扩展名
*/
filename: 'image/[name]_[hash][ext]'
},
/* 自定义使用inline还是resource类型 */
parser: {
dataUrlCondition: {
maxSize: 200 * 1024 // 200kb 单位为byte
}
}
},
5.JS文件的babel处理
webpack对代码进行打包时,会将ES6+的代码原封不动的打包进文件,而一些低版本浏览器无法兼容,因此使用babel工具对代码进行转换,将ES6+转换为ES5代码
Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。
Babel 是什么? · Babel 中文文档 | Babel中文网
@babel/core:是babel的核心库,所有的核心Api都在这个库里,这些Api供babel-loader调用
预设(presets) :
Babel 的预设(preset)可以被看作是一组 Babel 插件和/或 options 配置的可共享模块
@babel/preset-env:用于将es6+转换为es5语法
**@babel/preset-typescript:**用于typescript语法转换
**@babel/preset-react:**用于react代码
高版本js代码转es5规范的配置如下:
下载对应组件和loader
npm install -D babel-loader @babel/core @babel/preset-env
配置webpack.config.js文件
javascript
rules: [
/* babel预设插件的使用 */
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
// 使用预设,将高版本js语法转换为es5语法
presets: ['@babel/preset-env']
}}}]
6.vue文件处理
通过vue-loader来编写单文件组件格式的vue文件
安装vue-loader 和 vue-template-compiler
npm install -D vue-loader vue-template-compiler
vue-template-compiler插件:用于编译template标签包裹的内容
准备入口文件main.js和vue文件
javascript
/* main.js */
import { createApp } from 'vue'
import App from './app.vue'
createApp(App).mount('#app')
/* app.vue*/
<template>
<div>
<h1 class="title">{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
msg: "7777777"
}
},
}
</script>
<style>
.title {
color: red;
}
</style>
在webpack.config.js中配置loader
javascript
const { VueLoaderPlugin } = require('vue-loader')
module: {
rules: [
/* vue文件的处理 */
{
test: /\.vue$/,
use: ['vue-loader']
},
{
test: /\.css$/, // 识别.css后缀的文件
use: ['vue-style-loader', 'css-loader',]
},
],
},
plugins: [
new VueLoaderPlugin()
]
VueLoaderPlugin插件作用:
将定义过的其它规则复制并应用到
.vue
文件里相应语言的块。例如,如果你有一条匹配/\.js$/
的规则,那么它会应用到.vue
文件里的<script>
块