从零配置webpack 4+react脚手架(四)

2,853 阅读4分钟

前言

可前往我的Github/blog进行阅读,若有帮助,赏个star😊

经过前三节的学习,我们已经大概能自己配出一个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项目,点击下载至本地:

image.png
找到该文件夹,把 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">&#xe69b;</i></h1>
      <img className="background" src={background} alt=""/>
    </div>
  );
}

export default App;

这时候你再打包,回到页面看看是不是我们的图标正确显示了。 我的html文件内容如下:

image.png

配置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">&#xe69b;</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。这个时候我们去控制台查看:

image.png
它的错误提示是我们的打包文件bundle.js,这是打包之后的文件,我们想知道的是我们源码文件的错误地方,不然你还要通过查看打包文件的错误,回溯到我们源码的错误地方,特别麻烦,那有没有一个方法能让我们控制台直接提示的是源码错误出处呢?答案就是 source-map

它的配置非常简单,只需要在 webpack.common.config.js 中增加一个 devtool 属性即可!

module.exports = {
  devtool: 'cheap-module-eval-source-map',
	//...
}

这里为什么是 cheap-module-eval-source-map ,你可查阅这个文档:devtool

然后我们再打包一次,这次去控制台看看,它的错误提示是不是我们源码位置了:

image.png

ps:右边的错误提示不是再app.js是因为我们定义了两个入口文件,可能会有相互依赖的关系,这里我也不是很清楚,知道的同学可以交流下。

这一节结束,我们这系列文章就算是结束了,其实还有很多可以优化的手段,比如建立单独的配置文件,让我们不用手动去找webpack配置进行修改啦;比如懒加载(lazy-loading)啦。。。这些大家有兴趣可需求可自行了解,这个系列文章主要和大家一起进行一些简单的配置,快速上手。

结语:花了大概四天完成这个系列的文章,作为自己的一个记录,也希望能帮到像我一样的新手,webpack的学习还任重道远,与大家共勉!