Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
vortesnail opened this issue Oct 14, 2019 · 8 comments
Open

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

vortesnail opened this issue Oct 14, 2019 · 8 comments
Labels

Comments

@vortesnail
Copy link
Owner

前言

经过前三节的学习,我们已经大概能自己配出一个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的学习还任重道远,与大家共勉!

@qingshanyici
Copy link

非常有用,谢谢

@h-cloud
Copy link

h-cloud commented Nov 24, 2019

详细到位 深入浅出 很感谢

@vortesnail
Copy link
Owner Author

详细到位 深入浅出 很感谢

很有幸帮助到了你

@WanQuanXie
Copy link

作者您好,我最近也在做脚手架这方面的总结,这四篇文章对我帮助很大,我想在我的总结系列前几篇中可能会比较大地参考您这几篇文章的内容,当然,我会在参考链接中标注您文章的,完成后我将我的 issue 链过来您帮看看怎么样:)

@vortesnail
Copy link
Owner Author

作者您好,我最近也在做脚手架这方面的总结,这四篇文章对我帮助很大,我想在我的总结系列前几篇中可能会比较大地参考您这几篇文章的内容,当然,我会在参考链接中标注您文章的,完成后我将我的 issue 链过来您帮看看怎么样:)

当然可以!这四篇文章算是对webpack有比较的基础理解,但其实还有很多要学习的。
之后我可能出更深入一点的,到时候你也可以关注下,另外,求个star~
欢迎关注我的掘金账号,发了文章你可以及时看到~
https://juejin.im/user/5da573d3f265da5b8a5168a6

@fsa2000
Copy link

fsa2000 commented Aug 12, 2020

非常好!!!尤其前2片文章对我帮助很大,下一步我要自己加入Antd了。

@Yzmx1995
Copy link

<div className="App"> <img src="./assets/images/test.jpg" alt=""/> </div>
大佬,我这样引入图片图片不展示,打包也被忽略掉,只有用file-loader再重新配一个才会展示 这是因为啥

@ytJoinNow
Copy link

点赞大佬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants