在之前的系列文章中,我已经介绍了如何用webpack实现多页面应用的js,html,css的处理。今天就主要介绍如何处理静态资源,在web开发中最常见的静态资源就是图片。

图片的引用方式

而因为在web中,图片有两种主要的引入方式,第一种是<img src="...">,第二种是backgorund-image: url(...)。前者在html中使用,后者在css中使用。

web开发中的图片处理

图片常见的类型有jp(e)g,png,gif,包括现在普遍使用的svg以及webp。svg作为矢量图形,有一定的使用场景,而webp作为未来web开发的趋势,有一定的使用场景,比如:爱奇艺中的轮播图(carousel)中就是用webp,但其他的见到的不多。

现在,web开发中使用最多的还是jpg和png,处理他们,在构建工具中使用url-loaderfile-loader就好了,其中file-loader负责图片的拷贝和输出,并会给图片名添加一个hash值。

说到这里,很多人会想到字体图标。以前处理web页面中的图标(icon),使用图片来处理,这样会带来一个性能问题就是http请求的增多,这样会造成服务器的负载压力,同时会带来用户体验的问题,因为会出现页面的局部空白和页面重绘的问题,当然一种解决方案使雪碧图(sprite),但是如果图片过大怎么解决,如何对图片进行分解(大变小的问题),图片的拼接比较困难,最要命的是在引用雪碧图时要进行计算,除此之外就是如何对雪碧图的组成图片进行自定义的删减,而使用字体图标这些问题,都会得到一定程度的解决,当然在构建工具中可以使用webpack-spritesmith这个插件来处理组成雪碧图的图片。

当然,有些特殊的情况,需要使用base64,这里使用url-loader即可。

将图片处理为base64有使用场景,将图片转换为雪碧图亦有使用场景,单独的图片处理也有使用场景(这些使用场景的图片大小从左到右依次增大)。

这些场景在一个web项目中都会涉及到。

虽然使用字体图标可以替代雪碧图,因为字体图标有更小的尺寸,更自由的操作手法(如:图标颜色的自定义),但是一个DIY的web项目还是有些图标还是需要雪碧图。

但是,这里有一个问题,如何在一个项目中同时使用base64,雪碧图,字体图标,单独的图片。

在构建中如何使用多种图片处理方式

在构建多页面应用中,如何解决呢?

字体图标

处理字体图标很简单,如:iconfont(阿里巴巴字体图标库),就像引用css那么简单。

base64

base64的处理,使用url-loader

雪碧图

雪碧图的处理,可使用webpack-spritesmith这个插件

单独的图片

使用file-loader,它负责拷贝url-loader的处理结果,并输出。

上面就是我们常见的图片处理,如果要处理svg可以参考svg-url-loader,如果要处理webp可以参考webp-loader

如何对图片进行优化

对图片进行优化,会带来良好的用户体验。

熟悉图片优化的都知道渐进式(progressive),可参考nuwen.net

jp(e)g可以进行连续性处理,这样可保证图片数据请求回来多少,就渲染多少,是自上而下的渲染,也是有模糊到清晰的状态。

png可以进行交叉处理,这样也可保证图片数据请求回来多少,就渲染多少,它是整体的显示,而且是又模糊状态到清晰的状态。

gif图片一般使用小图,如果是大图会记号浏览器性能,还不如使用视频,或者用css动画来代替。我个人整理了一个css 动画集,有需要的可以看一下。

在构建多页面应用中,会使用到image-webpack-loader来做优化处理。

其中,配置项options中的mozjpeg 处理jp(e)g图片,pngquant处理png图片,gifsicle处理gif图片,webp处理webp图片。

多页面应用中的图片处理

首先,看一下多页面应用中的目录结构图:


./src
│  aboutUs.js
│  contactUs.js
│  css.js
│  index.js
│  recruitment.js
│
├─assets
│  │  favicon.jpg
│  │
│  ├─css
│  │  │  index.scss
│  │  │
│  │  ├─commons
│  │  │  ├─container
│  │  │  │      index.scss
│  │  │  │
│  │  │  ├─footer
│  │  │  │      index.scss
│  │  │  │
│  │  │  └─header
│  │  │          index.scss
│  │  │
│  │  ├─productus
│  │  │      index.scss
│  │  │      productus-sprite.scss
│  │  │
│  │  └─utils
│  │          btn.scss
│  │          form.scss
│  │          inital.scss
│  │          list.scss
│  │          modeal.scss
│  │          normalize.scss
│  │          pagination.scss
│  │          popover.scss
│  │          table.scss
│  │          text.scss
│  │          tooltip.scss
│  │
│  └─imgs
│      ├─base64
│      │      fe.jpg
│      │
│      ├─other
│      │      float.jpg
│      │      productus-sprite.png
│      │
│      └─sprites
│          └─productus
│                  product-us_01.png
│                  product-us_02.png
│                  product-us_03.png
│                  product-us_04.png
│                  product-us_05.png
│                  product-us_06.png
│                  product-us_07.png
│                  product-us_08.png
│                  product-us_09.png
│                  product-us_10.png
│                  product-us_11.png
│                  product-us_12.png
│
├─pages
│  │  recruitment.pug
│  │  template.pug
│  │
│  └─components
│      ├─commons
│      │  ├─container
│      │  │      index.pug
│      │  │
│      │  ├─footer
│      │  │      index.pug
│      │  │
│      │  └─header
│      │          index.pug
│      │
│      └─productus
│              index.pug
│
└─utilsload.js

跟以前的实例代码相比,这次的文件目录结构变化较大,这里将要处理的所有文件模块都放在了src目录下。

可能有人会问,为什么要要将目录分的这么细,下面我就说一下为什么这么分。

  • aboutUs.js, contactUs.js, index.js, recruitment.js是四个路由页面,要用到的js代码,css.js处理各个路由页面公用的css代码;
  • 静态资源目录(assets)下,存放web项目常用的静态资源;
  • 静态资源目录下的css目录统一存放整个web项目所用到的css样式。其中commons存放公用的css模块,每个公用模块有创建一个目录存放该公用模块可以使用到的css模块(提醒,不要分的过于细),而其他的如productus存放产品模块代码,根据开发的需要可以创建其他的模块目录,目录结构类似于commons中的header模块,其中utils放置自己总结的工具模块代码,如tableform等。然后,指定style-loader,css-loader等样式相关的loader处理css样式文件,这样可以减少遍历,缩短构建时间。
  • 静态资源目录下的imgs目录,用来存放整个项目中,用到的图片。在这里,分为base64spriteohter等,为什么要这样分?如果分的话file-loader这个webapck的loader会复制并导出imgs目下所有的图片,者在构建中并不是我们需要的,这样会增加构建的时间。如果让url-loader处理base64目录下的图片,file-loader处理ohter目录下的图片,webpack-spritesmith处理sprite目录下的图片,并将生成的图片放到ohter目录下,用file-loader进行二次处理。这样做,webpack处理更精确,可以减少不必要的遍历,极大地减少构建的时间,同样方便对图片的管理,特别是对于需要改变sprite的图片的管理。
  • imgs目录下创建base64目录,sprite目录,使用file-loader指定处理ohter目录,是为了避免file-loader将所有的图片都拷贝一份并导出到dist输出目录中,因为与base64相关的文件已经在css样式文件中了,再拷贝一份,已经没有意义,而sprite相关的文件会被webpack-spritesmith插件先处理生成一个文件,所以再拷贝它们也没有意义,还会让构建速度更慢。
  • page目录下,放置所有的html代码块(这里使用pug编译器生成相应的html代码块),它的目录分类和css相类似,它们是一一对应的关系。

注意:iamge-webpack-loader,要先对所有的图片进行优化处理,然后再用其他loader处理。loader的执行顺序,如果你是style-loader!css-loader!sass-loader"使用,它是从右到左方向先后执行,如果你是在配置文件中的rules: [...]数组中,它也是从右到左的方向执行,如果你将所有的loader规则有回车符号隔开,那么它就是自下而上的执行。

一类特殊的图片引用

针对<img src="...">的图片使用,ul-loader是不会处理html中的img引用,现在处理这样情况的loader或插件,也并没有一个比较出名的。现在通用的做法就是将图片拷贝一份到生成目录中,copy-webpack-plugin。参考配置代码如下:


new CopyWebpackPlugin([{from: path.resolve(__dirname, 'assets/imgs/other/'),to: path.resolve(__dirname, 'dist/assets/imgs/other/'),ignore: ['.*']}
]),

但这样,会带来另一个问题就是图片的优化问题,如何使用 image-webpack-loader?本来的目的是对项目中使用到的所有的图片进行优化,而现在只能对base64sprite目录下的图片进行优化处理。不过,不要慌,可以通过创建一个新的npm脚本命令(本是里使用的是npm run img)来对图片进行压缩处理,新建了一个目录static用来保存优化前的图片,ohter用来保存优化后的图片。

首先,需要安装imagemin, imagemin-mozjpeg, imagemin-optipng, imagemin-gifsicle :


yarn add imagemin imagemin-mozjpeg imagemin-optipng imagemin-gifsicle --dev

然后,在项目的根目录添加一个优化图片的文件optzing-img.js,代码如下:


const path = require('path')
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminOptipng = require('imagemin-optipng');
const imageminGifsicle = require('imagemin-gifsicle');(async () =&gt; {await imagemin([path.resolve(__dirname, 'src/assets/imgs/static/*.jpg'),path.resolve(__dirname, 'src/assets/imgs/static/*.png'),path.resolve(__dirname, 'src/assets/imgs/static/*.gif')],path.resolve(__dirname, 'src/assets/imgs/other/'),{use: [imageminMozjpeg(),imageminOptipng(),imageminGifsicle()]});console.log('图片优化完成!');
})();

最后,在package.json文件中添加如下的npm命令:


...
"scripts": {..."img": "node optzing-img.js"},
...

在控制输入npm run img,然后按下回车键就可以得到你所需要的。

注:既然重新定义了图片优化的npm脚本命令,那么,是否需要去掉之前在webpack.config.js中的image-webpakc-loader,当然不需要。主要有两个原因,一个是sprite雪碧图它是用几张小图片合成了一张大图片,这张合成的图片还需要优化;另一个是因为本项目对于存放图片的目录进行了细化。

字体

在web开发中,自定义的字体也是比较常见的,在webpack中它的处理和图片类似,都是使用的 url-loaderfile-loader。参考代码如下:


...
{include: path.resolve(__dirname, 'assets/fonts/'),test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,use: [{loader: 'url-loader',options: {limit: 10000,name:  isDev ? '[name].[ext]' : '[name].[hash].[ext]',outputPath: 'assets/fonts/'}}]
},
...

新创建了一个fonts目录又来存放项目开发过程中使用的字体。

源代码

webpack4.x multi-page

此后,webpack构建多页面应用系列文章的源代码,都在这个github项目中,webpack3.x multi-page不再维护。

构建多页面应用系列文章

  • 构建多页面应用
  • 构建多页面应用——单个页面的处理
  • 构建多页面应用——模板
  • 构建多页面应用——静态资源

来源:https://segmentfault.com/a/1190000017579965

转载于:https://www.cnblogs.com/qixidi/p/10224698.html

构建多页面应用——静态资源的处理相关推荐

  1. 如何在React Native中构建项目并管理静态资源

    by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...

  2. 利用 JS 判断页面图片静态资源链接是否有效是否加载完成

    文章目录 一.功能说明 二.动图效果展示 三.完整源代码 一.功能说明 利用原生 JS 实现对图片静态资源链接是否有效进行判断: 如果资源链接有效,直接渲染: 如果资源链接失效,3秒后替换新的链接,进 ...

  3. 基于Nginx构建七牛云CDN静态资源加速

    创建七牛云账号[七牛云] 进入管理控制台创建对象存储 3. 配置nginx[使用nginx rewrite 的重定向功能进行转发到七牛云] server {listen 80;server_name ...

  4. Hexo瞎折腾系列(5) - 使用hexo-neat插件压缩页面静态资源

    为什么要压缩页面静态资源 对于个人博客来说,优化页面的访问速度是很有必要的,如果打开你的个人站点,加载个首页就要十几秒,页面长时间处于空白状态,想必没什么人能够忍受得了吧.我个人觉得,如果能把页面的加 ...

  5. webpack静态资源地址注入html,Webpack4+ 多入口程序构建

    欢迎关注富途web开发团队,缺人从众 其实,说实话这篇文章的由来也是有很多的原因在里面的.在这之前,我也做过不少的项目.有新的项目,也有旧的项目.通过对旧项目的不断研究,改进.再结合自己的理解,将新的 ...

  6. Hexo文件压缩:使用hexo-neat插件压缩页面静态资源

    目录 为什么要压缩页面静态资源 hexo的压缩静态资源插件 如何使用hexo-neat 在站点根目录下安装hexo-neat 为站点配置文件添加相关配置 hexo-neat插件踩坑记录 跳过压缩文件的 ...

  7. 前端静态资源缓存最优解以及max-age的陷阱

    原文地址:点这里 合理的使用缓存可以极大地提高网站资源的利用率,还可以节约带宽从而降低服务器成本.但是很多站点针对缓存的策略并不合理,甚至是完全无作为,如果是这样,就完全没有发挥出缓存的优势,而不合理 ...

  8. SpringBoot 直接访问静态资源

    一般现在都前后端分离方式,SpringBoot主要提供接口服务,但有时候有一些小项目就希望一个jar前后端都搞定,因此一些页面等静态资源都放入SpringBoot中. 这里记录一下静态资源访问方式和引 ...

  9. springboot2.0+拦截器后 , 静态资源被拦截问题

    1.先弄懂第一件事: springboot默认的静态资源访问路径是:META-INF/resources > resources > static > public (访问优先级也是 ...

最新文章

  1. anacodna/python 安装 tensorflow
  2. python扫描端口脚本_python扫描端口脚本
  3. 链表排序---迭代版本归并算法 + [leetcode]148. 排序链表
  4. 简单的U盘病毒清理工具 v0.5
  5. C#调用天气预报接口
  6. 城镇污水处理厂工艺概述及提标改造路线
  7. 使用IMS搭建LMS系统(Logistics Management System 物流管理信息系统)
  8. python两个表格相同数据筛选_python筛选出两个文件中重复行的方法
  9. 阿里云现代农业园区解决方案,智慧园区大数据、产品管理、物联网、企业管理平台解决方案
  10. c语言中:=和==的区别是什么?
  11. 二维蒙特卡洛模拟居里温度_蒙特卡罗方法计算居里温度(上)
  12. ArrayDeque(双端队列的线性实现)详解
  13. linux资源查看命令详解大全[top|vmstat|free]
  14. 【步兵 经验篇】组件模式的特点
  15. 关于xxxxxxRepository.search()方法一个分页的小陷阱
  16. 重磅推荐 | 朱嘉明:元宇宙——创意、思想、意识协作的下一代网络
  17. ubuntu修改DNS重启网络服务
  18. 城市动能转换_动能转换 驱动发展
  19. 低轨互联网产业发展探究
  20. 如何制作“虚拟主播”?小灰一分钟教给大家!

热门文章

  1. bat 判断copy是否执行成功
  2. css三角的做法及其案例
  3. One PUNCH Man——支持向量机
  4. uniapp的input标签 type=“number“在移动端打开键盘不能输入小数点问题
  5. 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed
  6. 关于CAD软件按颜色选对象
  7. html转word出现小插插,记录利用phpword插件实现word文档转html的方法示例
  8. PS 图像特效算法— —渐变
  9. h5页面嵌入微信进行语音识别和分享功能注意问题
  10. Java面试之Mysql