- 这章你将学习到使用图片,特殊字体等怎么在页面上进行显示,还有多个入口文件,怎么输出
在前面的两章中,我们每次打包,之前的打包文件还在,想要不在的话,需要我们手动进行删除,但是怎么让我们每次打包的时候,自动的将其前面打包过的文件自动清除
npm install clean-webpack-plugin -D
- kfc.config.js
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
....
plugins:[//todo 不同的插件,可以帮助我们处理不同的事
new HtmlWebpackPlugin({
template:'./src/index.html'
}),
new MiniCssExtractPlugin({
filename: "css/[name].css"
}),
new CleanWebpackPlugin()//直接加入这个就好啦
]
1、在js中使用dom添加图片,怎么在页面中显示
- 首先在我们的src下新加入一张图片bj.jpg
- 在index.js中加载一张图片,加载成功添加到app后面
import bgImg from './bj.jpg';
const img = new Image();
img.src = bgImg;
img.onload = ()=>{
app.append(img);
}
img.onerror = ()=>{
console.log('图片加载错误');
}
-
此时进行打包,文件还是延续之前的webpack入门一,二的那个文件
image.png -
此时显示的是乱码,该怎么办呢?
-
使用file-loader进行解析我们的图片格式
npm install file-loader -D
- 在kfc.config.js中进行配置
{
test:/\.(png|jpg|gif|jpeg|webp)$/,
use:{
loader:'file-loader',
options:{
name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
outputPath:'image',//* 输出的文件名
publicPath:'../image'//* 这是配置公共的路径,目前不需要
}
}
}
- 此时进行打包,就会在页面上显示我们加载的图片了,我们将index.js中加载的图片改为css的背景图片,进行打包,会发现它会将我们的图片都进行base64的转化,但是小的图片一般转成base64会好一点,但是大的图片也转换的话,那么生成的base64会很长而且也不利于我们页面的性能,此时我们使用iconfont中的特殊字体的话,也是加载不出来的,我们要进行使用另一个url-loader进行解析,这个loader是在file-loader的基础上进行的封装,他可以设置图片大于多少的时候不用进行base64转换,还可以解析特殊字体,下面让我们试一试吧
npm install url-loader -D
-
先打开iconfont官网选择特殊字体进行本地下载,之后将里面的文件放到src文件夹下
image.png -
在index.scss进行引入
@font-face {
font-family: 'webfont';
font-display: swap;
src: url('webfont.eot'); /* IE9 */
src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('webfont.woff2') format('woff2'),
url('webfont.woff') format('woff'), /* chrome、firefox */
url('webfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
url('webfont.svg#webfont') format('svg'); /* iOS 4.1- */
}
#app{
width: 400px;
height: 400px;
// background: orange;
font-family: 'webfont' !important;
background: url('./bj.jpg') 30% 20% no-repeat;
.head{
width: 40px;
height: 40px;
// background: red;
}
img{
width: 400px;
height: 300px;
}
}
- 在src/index.html
<div id="app">
<p class="head"></p>
<p>英雄不问出路,流氓不看岁数。</p>
</div>
- kfc.config.js中
{
test:/\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
use:{
loader:'url-loader',
options:{
limit:1020*100,//* 当图片大小超过这个指定的大小,不会再进行base64的转义
name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
outputPath:'image',//* 输出的文件名
publicPath:'../image'//* 这是配置公共的路径,目前不需要
}
}
}
-
进行打包,查看效果
image.png - 当前我使用的图片是96kb,1024是1kb,1024100是100kb,设置为102410就是10kb,大于10kb就不会进行base64转义
image.png
-
简单的说下占位符(指纹策略)
[name] 输入是什么名,输出就是什么名
[hash] 输出的就是有hash值的,这个是全局的,要是有多个入口文件的话,那么生成的hash值都是相同的,一个文件修改的话,所有文件的hash值都会进行变化,这样的话,区分不出来文件
[chunkhash] 就是一个入口文件就是一个chunks,他们的chunks不同可以根据这个进行区分,但是如果这个入口文件中引入了一个模块,那么模块更新的话,那这个chunkhash的值变不变化呢?答案是肯定会变化的,那么如果这个index.js文件进行修改,里面引入的模块会不会变呢,也是会变化的
[contenthash] 这个是内容hash,如果修改index.js,里面引入的模块,此时不会发生改变,如果模块变了,这个index.js肯定也是会变的,包含的关系
[hash:6] 意思是hash值截取前6位
2、如果有多个入口文件我们怎么操作呢?
-
这是目录结构
image.png -
在kfc.config.js中
image.png
image.png -
运行打包可以看到
image.png -
不同的文件只引入自己的文件,如index.html中不会将list.js文件进行引入,list.html中不会将index.html中引入的文件在引入自己的文件中
-
但是上面的写法都是我们手动完成的,要是有十个百个,我们难道要一个一个的进行手动的写吗,那肯定是不行的,有个glob插件,可以让我们读取到文件,然后动态的生成
npm install glob -D
-
图下方是核心代码,进行封装
image.png -
整体的kfc.config.js
/**
* ! 使用webpack中自带的loader以及插件
* ! 自定义的loader文件在kfc.config-1.js文件中
* ! html-webpack-plugin 通过HtmlWebpackPlugin这个插件,可以将index.html进行复制,打包后会将打包的js文件等自动的引入
* ! mini-css-extract-plugin 为每个引入css的js文件创建一个css文件
* ! 使用sass-loader,css-loader,style-loader进行.scss文件的格式化
* ! 使用URL-loader处理文件,字体,图片,在file-loader基础上进行了封装,可以限制多大的图片不用转base64格式
* ! 使用file-loader也可以处理文件,字体,图片,但是当有的图片可以进行转为base64格式,不可控制
* ! 使用clean-webpack-plugin,每次打包都会把之前打包的文件进行清除
* ! glob 读取文件
*/
const glob = require('glob');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require('path');
//todo 通过HtmlWebpackPlugin这个插件,可以将index.html进行复制,打包后会将打包的js文件等自动的引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
// todo 为每个引入css的js文件创建一个css文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const setMap = ()=>{
const entry = {};
const HtmlWebpackPlugin1 = [];
const entryFile = glob.sync(path.join(__dirname,'/src/*/index.js'));
entryFile.map(item=>{
const key = item.match(/src\/(.*)\/index\.js$/);
const pageName = key[1];
entry[pageName] = item;
console.log(entry);
HtmlWebpackPlugin1.push(new HtmlWebpackPlugin({
template:path.join(__dirname,`src/${pageName}/index.html`),
filename:`${pageName}/${pageName}.html`,
chunks:[pageName]
}))
})
console.log(entry);
console.log(HtmlWebpackPlugin1[0].options.chunks);
console.log(HtmlWebpackPlugin1[1].options.chunks);
return {
entry,
HtmlWebpackPlugin1
}
}
const { entry, HtmlWebpackPlugin1 } = setMap();
module.exports = {
entry,
// entry:'./src/index.js',//入口文件(单文件入口)
// entry:{//todo 多文件入口
// index:'./src/index/index.js',
// list:'./src/list/index.js'
// // main:'./src/main.js'
// },
output:{
path:path.resolve(__dirname,'./build'),//todo 打包后存放的文件名
filename:'[name]/[name]_[chunkhash:6].js'//todo 打包后的文件名,单文件'build.js'直接写,多文件[name],入口文件名是啥,打包后还是啥
},
//todo 当前的模式,none 不做任何的处理 development开发环境做了相应的处理,方便调试,production生产环境会启动相应的插件
mode:'development',
module:{//todo 模块,一般可以将我们的scss,less,.vue等进行loader解析,在输出
rules:[//todo 规则
{//todo 每个模块都是独立的
test:/\.css$/,//todo .css结尾的文件进行解析
use:['style-loader','css-loader']//todo 自后往前的顺序,不能写错了,还可以单独的配置loader
},
{//todo 每个模块都是独立的
test:/\.scss$/,//todo .css结尾的文件进行解析
use:[
// 'style-loader',// 将 JS 字符串生成为 style 节点
MiniCssExtractPlugin.loader,
'css-loader',// 将 CSS 转化成 CommonJS 模块
'postcss-loader',
'sass-loader'// 将 Sass 编译成 CSS,默认使用 Node Sass
]//todo 自后往前的顺序,不能写错了,还可以单独的配置loader
},
{
test:/\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/,
use:{
loader:'url-loader',
options:{
limit:1020*10,//* 当图片大小超过这个指定的大小,不会再进行base64的转义
name:'[name]_[hash:6].[ext]',//* hash:6 表示hash值截取前6位,ext表示图片结尾是.png输出就是.png,是.jpg输出就是.jpg
outputPath:'image',//* 输出的文件名
publicPath:'../image'//* 这是配置公共的路径,目前不需要
}
}
}
]
},
plugins:[//todo 不同的插件,可以帮助我们处理不同的事
...HtmlWebpackPlugin1,
// new HtmlWebpackPlugin({
// template:'./src/index/index.html',
// filename:'index/index.html',
// chunks:['index']//! 进行区分,不同的文件夹只能引入同文件夹中的文件,不能index.html中引入了,list.html中也进行引入了,所以要区分
// }),
// new HtmlWebpackPlugin({
// template:'./src/list/index.html',
// filename:'list/list.html',
// chunks:['list']
// }),
new MiniCssExtractPlugin({
filename: "css/[name].css"
}),
new CleanWebpackPlugin()
]
}
-
注意:要是没打包成功,一定要看报错的信息,可能是你的.scss文件中的特殊字体导致的错误或者是其他的,记得看报错信息进行排查
网友评论