学习webpack系列之二 ---- (管理静态资源)
本文的项目代码是基于上一篇文章延续下来的。
在开始之前,让我们对项目做一个小的修改:
把dist/index.html里面的main.js改为bundle.js
把webpack.config.js里面的output改为bundle.js
这么做的目的只是为了使代码看起来更加符合语义一点,阅读起来比较舒服,没有什么特别的含义。
css、images、fonts都是项目的必备资源,所以webpack为了加载这些静态资源,是必须引入部分loaders的,这个就不用纠结为什么要引入这些loaders了的。
所以我们只需要学习如何使用loaders去加载一些我们自己后面项目里面添加的资源即可。
一、加载CSS
论在前端开发的过程中,但凡我们在框架内使用CSS,基本上都是使用import
来引入一个CSS文件的。
这里插一句,ES2015 中的 import 和 export 语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。
事实上,webpack 在幕后会将代码 “转译”,以便旧版本浏览器可以执行,而转译的过程中,运用的正是本文提及的loaders们。
标志性的有babel-loader,大家自行查阅官网,这里不再赘述。
为了import项目需要的CSS文件,我们需要安装style-loader
和 css-loader
,并在 module 配置 中添加这些 loader:
npm install --save-dev style-loader css-loader
webpack.config.js
写入依赖模块代码:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
// 链式调用,逆序执行,保证loaders的先后顺序,否则报错。
// 第一个 loader 将其结果(被转换后的资源)传递给下一个 loader,依此类推。
// 所以首先处理CSS文件的css-loader就放在最后,接着再是style-loader。
use: ['style-loader', 'css-loader']
},
],
},
};
添加完,测试一下新添加一个style.css
文件,观察有没有被编译,项目路径配置如下:
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
|- style.css
|- index.js
|- /node_modules
在style.css
键入以下代码:
.hello {
color: red;
}
在index.js
内补充以下代码:
import _ from 'lodash';
import './style.css';
function component() {
const element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
// 动态添加CSS样式
element.classList.add('hello');
return element;
}
document.body.appendChild(component());
这里补充一下,我们使用JavaScript为dom操作一些步骤的时候,都是动态操作的,所以一些资源在检查网页源代码的时候是无法查看的,这点应该不难理解。
现在可以使用我们上一篇文章配置好的npm script
对项目进行编译试试看,注意查看命令行的提示:
可以看到这里webpack引用了两个loaders,而且对style.css
文件成功的进行了编译,接下来查看一下网页效果,不出意外style应该是生效了,渲染为红色的字体:
二、加载images
编译图片类静态资源,我们只需要应用webpack内置的Asset Modules
loader即可,我们继续在webpack.config.js
里面添加loaders 的配置:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
...
// 新增处理图片类静态资源loader
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
// webpack内置asset module loader
type: 'asset/resource',
},
],
},
};
然后继续在style.css
里面添加关于图片的样式:
.hello {
color: red;
font-family: 'MyFont';
// 随便添加图片就行,跟此css文件保持同一目录
background: url('./timg.gif');
background-size: 100% 100%;
height: 500px;
}
接着同样执行npm run build
,观察命令行和网页的效果:
可以看到命令行里面只显示了编译结果,并没有显示使用了什么loader,因为我们引用的是内置loader,所以webpack并不需要将其纳入依赖关系图里面。
三、加载fonts
编译fonts类字体文件,跟编译图片类的流程差不多,都是使用webpack内置的Asset module loader
,并不需要去下载其他loader,很方便:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
...
// 此处新增处理fonts字体类文件loader
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
],
},
};
然后,我们去新增一个my-font.woff
字体文件测试一下,可以不填写内容,我们只需要看编译结果就可以了。项目配置如下:
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
|- my-font.woff
|- my-font.woff2
|- icon.png
|- style.css
|- index.js
|- /node_modules
接着,也是在style.css
文件里面,添加对应的引入:
@font-face {
font-family: 'MyFont';
src: url('./my-font.woff') format('woff'), url('./my-font.woff2') format('woff2');
font-weight: 600;
font-style: normal;
}
.hello {
color: red;
font-family: 'MyFont';
background: url('./timg.gif');
background-size: 100% 100%;
height: 400px;
}
最后,执行npm run build
编译项目,查看命令行和网页的效果:
大概就是酱紫。
可能到这一步会有小伙伴产生疑问,加入我新增文件之后,不引入的话,会有什么结果?
我们不妨动手来操作一下,打破砂锅问到底嘛!实践得出真理!
我们把style.css
文件内与fonts有关的内容全部删掉,执行npm run build
,看看有什么效果吧!让我们先删除fonts的相关代码:
执行npm run build
:
可以看到webpack
是完全没有编译跟fonts
有关的依赖的,因为webpack
是按需加载,根本不会把fonts
纳入依赖关系图之内。
四、实践、加载数据
经过以上3个loaders的介绍,我相信你现在已经对管理静态资源有了充分的了解了,所以这里我们趁热打铁,自己动手学习一下对其他类型文件要怎么编译处理吧!
新增data.xml
和data.csv
文件,项目配置如下:
|- package.json
|- webpack.config.js
|- /dist
|- bundle.js
|- index.html
|- /src
|- data.xml
|- data.csv
|- my-font.woff
|- my-font.woff2
|- icon.png
|- style.css
|- index.js
|- /node_modules
/src/data.xml
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Mary</to>
<from>John</from>
<heading>Reminder</heading>
<body>Call Cindy on Tuesday</body>
</note>
/src/data.csv
to,from,heading,body
Mary,John,Reminder,Call Cindy on Tuesday
Zoe,Bill,Reminder,Buy orange juice
Autumn,Lindsey,Letter,I miss you
对data.xml
和data.csv
进行引入:
import Data from './data.xml';
import Notes from './data.csv';
function component() {
console.log(Data);
console.log(Notes);
return element;
}
document.body.appendChild(component());
先执行npm run build
编译一下,看是什么结果:
很棒,报错了。谁让你没有引入loader
呢对吧?webpack
是识别不了这两种文件格式的。接下来添加loader
配置:
先安装对应的package
:
npm install --save-dev csv-loader xml-loader
添加loader
配置:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(csv|tsv)$/i,
use: ['csv-loader'],
},
{
test: /\.xml$/i,
use: ['xml-loader'],
}
],
},
};
再编译一下,看效果:
真的是,非常棒呢!
(md好鸡儿累,求求关注点赞叭大佬们~)