Webpack 4 + React Part 4
前言
经过前三节的学习,我们已经大概能自己配出一个react脚手架了,但是仍有许多配置未完成,比如图片,字体图标的配置,Source Map的配置等,通过前面的学习,我相信你已经能够做到这些简单的配置了,实在还不是很清楚,那我们就往下看吧!
添加图片的loader
file-loader
可以对图片文件进行打包,但是 url-loader
可以实现 file-loader
的所有功能,且能在图片大小限制范围内打包成base64图片插入到js文件中,这样做的好处是什么呢?先一步一步走着!
安装url-loader
这里需要注意,url-loader依赖于file-loader,所有我们两个loder都要安装
npm install file-loader url-loader --save-dev
引入url-loader
在 webpack.common.config.js
中的rules中添加一个新的对象,并输入以下代码:
module: {
rules: [
//...
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
limit: 8192,
},
}
}
]
}
- 遇到以jpg,png,gif为后缀的文件,使用url-loader进行预处理;
- options中的[name].[ext]表示,输出的文件名为
原来的文件名.后缀
; - outputPath是输出到dist目录下的路径,即dist/images/... ;
- limit表示,如果你这个图片文件大于8192b,即8kb,那我url-loader就不用,转而去使用file-loader,把图片正常打包成一个单独的图片文件到设置的目录下,若是小于了8kb,那好,我就将图片打包成base64的图片格式插入到bundle.js文件中,这样做的好处是,减少了http请求,但是如果文件过大,js文件也会过大,得不偿失,这是为什么有limit的原因!
接下来就是测试下可以不可以用了,在 src
目录下新建一个文件夹: images
,并导入一个图片文件,名为 background.png
,图片文件点我下载。
然后在 app.js
中写如下代码:
import React from 'react';
import './app.less';
import background from './images/background.png';
function App() {
return (
<div className="app">
<h1 className="text">Hello Webpack</h1>
<img className="background" src={background} alt=""/>
</div>
);
}
export default App;
在 app.less
中写如下代码:
.app {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
.text {
font-size: 20px;
color: lightseagreen;
}
.background {
position: absolute;
width: 100%;
left: 0;
top: -124px;
z-index: -1;
}
}
执行 npm run build
,你去dist目录下看看是不是多了一个images/background.png,这是因为我们的文件有300多kb,远远超出了我们设定的8kb,如果你在limit设置为:819200,你再重新编译一次,你会发现这个图片文件没有被打包出来,因为它以base64格式图片导入到了bundle.js中。
你可以看看index.html是啥样子的!~~
添加字体图标loader
字体图标需要我们之前已经安装过的 file-loader
,配置非常简单,但是具体操作还是得给你讲明白一点
安装file-loader
如果你不确定自己是否安装,在package.json中看看有没有依赖项
引入file-loader
在 webpack.common.config.js
中添加以下代码:
module: {
rules: [
//...
{
test: /\.(eot|ttf|svg|woff|woff2)$/,
use: {
loader: 'file-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'font/'
}
}
}
]
}
将iconfon图标导入项目
我们先在 src
目录下新建一个文件夹: font
。
然后我们去iconfont官网找几个图标,(若没有注册,先注册再添加至新项目)比如我添加了一个 爱心 图标至我的webpack-demo项目,点击下载至本地:
找到该文件夹,把 eot\svg\ttf\woff\woff2
为后缀的文件全部剪切进我们新建的 font
文件夹中,把 iconfont.css
文件中的代码复制到我们的 app.less
中,但因为我们的几个字体文件放到了font文件夹,我们需要更改url:
@font-face {font-family: "iconfont";
src: url('./font/iconfont.eot?t=1571041571943'); /* IE9 */
src: url('./font/iconfont.eot?t=1571041571943#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALIAAsAAAAABnQAAAJ6AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAp8gREBNgIkAwgLBgAEIAWEbQcyG7kFyJ6aPIEICihKRGQ5DgwQD//t9799ZubdP980uSRtnk1XN2B1CJEEsVGaheKZ/P5vrf3FtfHmPeqdN9STytzuzIrPDe7JpBEKIRGKNdNGIpKpWPGkkqoy4HL8XwEFMg8ot7U2/aImBRhYGuhYgyIrk9Qbxi54gccJdJnkIZw0tHVCksIeF4h3qowhqZBUFFapQtOwtLUpfBavpo/pFsCn6PvxD0JRSVqZzTp/qpeg6ue5MyIvthcN5hVLy/nBVpGxDhTiurF4KlYwYayuYpxZcCx68PO8/R+4xVH/PNGwqT1gHCqfSeWpH5WaQEl654C9SVeShrJnCh57/Hb/PLnaKZWf3mwfCRdfG4Ktlo5THx5ePGjOhWEZp8W/G9KHwMwXLClCjqgd7WX1FB3skhz7Rz3ryKmpyQp/ov+sVgvdPUJ14pkqgPZC+csrBAQfHgfeRzLL/mpqAT+uK6bqYWFQdx4KflJNMwhA+c81djEVdFADydyksQldutAGFB3yOdU6ekfVUI3eV7jDRIasmieKYB0t3bbQqPbRZU3j6m7DmFhROrFqDSAMuETS5wuyAXdEEXygZcwvGgOR0eU2crfsthivKbWMYE4kFJlCqmhb1PXwlJjeTuQxA7O8JhJ1ExZVMyjoC5QrjcQibIkZ0XE5xDlFlNkmagCnEcOwkcNsjYjcp3DulPj9tOlNPtE2IcUxhsA4QoJETEFUIpuFBt25lMrn2xGyMQaMdTTV5bsRTJTaPxLkExhANBqtQU2P8krUOFkIx1EIxdhMSAMYRBgMNsRpHqQhRJyPMiHvKOF3OtGhRt/2ZvMHKlgbti2Fw8nqe9XCqu8AAAAAAA==') format('woff2'),
url('./font/iconfont.woff?t=1571041571943') format('woff'),
url('./font/iconfont.ttf?t=1571041571943') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('./font/iconfont.svg?t=1571041571943#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-xinaixin:before {
content: "\e69b";
}
.app {
height: 200px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
.text {
font-size: 20px;
color: lightseagreen;
}
.background {
position: absolute;
width: 100%;
left: 0;
top: -124px;
z-index: -1;
}
}
然后在 app.js
中使用:
import React from 'react';
import './app.less';
import background from './images/background.png';
function App() {
return (
<div className="app">
<h1 className="text">Hello Webpack<i className="iconfont"></i></h1>
<img className="background" src={background} alt=""/>
</div>
);
}
export default App;
这时候你再打包,回到页面看看是不是我们的图标正确显示了。 我的html文件内容如下:
配置source-map
source-map是干嘛用的?我们先来修改以下 app.js
中的代码,故意给它制造一个错误:
import React from 'react';
import './app.less';
import background from './images/background.png';
function App() {
return (
<div className="app">
<h1 className="text">Hello Webpack<i className="iconfont"></i></h1>
<img className="background" src={background} alt=""/>
{
consele.log("I cannot print to console!")
}
</div>
);
}
export default App;
我们增加了一个控制台打印输出语句,如果正常的话我们会在控制台中看到打印输出:I cannot print to console!
但是我们把console.log故意制造了语法错误,写成consele.log。这个时候我们去控制台查看:
它的错误提示是我们的打包文件bundle.js,这是打包之后的文件,我们想知道的是我们源码文件的错误地方,不然你还要通过查看打包文件的错误,回溯到我们源码的错误地方,特别麻烦,那有没有一个方法能让我们控制台直接提示的是源码错误出处呢?答案就是 source-map
它的配置非常简单,只需要在 webpack.common.config.js
中增加一个 devtool
属性即可!
module.exports = {
devtool: 'cheap-module-eval-source-map',
//...
}
这里为什么是 cheap-module-eval-source-map
,你可查阅这个文档:devtool
然后我们再打包一次,这次去控制台看看,它的错误提示是不是我们源码位置了:
ps:右边的错误提示不是再app.js是因为我们定义了两个入口文件,可能会有相互依赖的关系,这里我也不是很清楚,知道的同学可以交流下。
这一节结束,我们这系列文章就算是结束了,其实还有很多可以优化的手段,比如建立单独的配置文件,让我们不用手动去找webpack配置进行修改啦;比如懒加载(lazy-loading)啦。。。这些大家有兴趣可需求可自行了解,这个系列文章主要和大家一起进行一些简单的配置,快速上手。
结语:花了大概四天完成这个系列的文章,作为自己的一个记录,也希望能帮到像我一样的新手,webpack的学习还任重道远,与大家共勉!
>> 本博客分享自vortesnail/blog,供自学使用,非商用 <<