zoukankan      html  css  js  c++  java
  • 基于webpack的前端工程化开发解决方案探索(二):代码分割与图片加载

    1. require.ensure

      在上一章我们已经知道通过require引入的资源,可以通过插件让webpack将其独立成为单独的文件,然后向HTML中自动写入路径。那对于require.ensure情况又会是怎样的情况呢?

      我们都知道webpack通过require.ensure来对我们的代码进行分割,将按需加载的代码单独放在的块文件chunk中,然后在合适的时候异步加载进入文档中。

      在webpack中引入的提取文件插件,是否影响这一功能呢?

      

       同样的,这次我们对上次的项目进行了改动,具体代码可以查看: https://github.com/xiaoyunchen/webpack

      

       首先,我们在JS下新增了一个components文件夹,用于存放自定义的组件,然后定义了一个dialog组件(dialog的实现请参考之前的文章,本章将对本部分进行简化处理)。

      

      在dialog组件中我们定义了dialog所需的HTML模板,CSS样式文件,以及入口文件Index.js(如果模块逻辑层次很复杂的话,这里还可以再新建两个关于模板和样式的子目录)

      我们稍微看下index.js的内容:

    复制代码
     1 (function(){
     2     //加载模块CSS
     3     require('./dialog.css');
     4     //加载模板
     5     var html=require('./dialog.html');
     6     
     7     module.exports=function(text){
     8         $('body').append(html);
     9         $('.dialog:last-child').html(text);
    10     };
    11     
    12 })();
    复制代码

      这里只是出于演示使用,所以实现的功能与逻辑比较简单。就是引入了所需的模板和样式文件,然后导出一个方法,改方法将会向body插入一个元素。

      OK,我们再来看下page目录下index.js这个入口文件的变动:

    复制代码
     1 //引入CSS
     2 require("../../css/lib/reset.css");
     3 require("../../css/common/global.css");
     4 require("../../css/page/index.css");
     5 
     6 //增加事件
     7 $('#btn').click(function(){
     8     require.ensure(['../components/dialog/index.js'],function(require){
     9         var Dialog=require('../components/dialog/index.js');
    10         new Dialog(new Date()-0);
    11     });
    12 });
    复制代码

      第7行,为页面的一个按钮添加了点击事件,点击后加载dialog组件,然后生成一个dialog实例。

      

      再来看看webpack配置中添加了什么内容:

      

      可以看出配置文件并没有太大的变化,这里主要是:

      18行:增加了HTML加载器,用于加载HTML模板

      22行:引入全局jq,方便其他JS调用

      

      在项目根目录下运行 webpack 打包命令后,可以看到dist/js下多了1.chunk.js文件。其实看到这里大家也就放心了,webpack的确正确处理了这种按需加载的关系。

      

      然后运行dist/view/index.html,打开控制台观察资源加载。

      一开始并没有加载dialog组件,点击按钮后,浏览器开始异步加载dialog组件,然后生成对应的HTML.

      

      这里有个问题需要单独说明下,require.ensure 被webpack编译后在执行的时候会自动判断该模块已经下载,如果已经下载就不会再重复请求。

      2. 图片加载

      借助于url-loader这个加载器,在webpack中我们可以比较优雅的处理图片加载的问题。所谓的比较优雅,是指:

      1. webpack可以将所用到的图片自动拷贝到输出目录下,同样可以为其添加hash版本号

      2. 对于比较文件比较小的图片,webpack可以将其自动转换了BASE64字符串进行存储,减少一次HTTP请求

      接下来我们来做下演示:

         

      我们在dialog组件目录下增加一张图片(图片大小15k左右),然后修改了dialog组件的模板,在其中引入了该张图片。这样每次我们点击按钮的时候,浏览器都会显示这张图。

      

      另外我们在 global.css进行修改,为body添加一张背景图片,由于这个图很小(1KB),所以我们将背景图设置为重复。

    1 body{
    2     font: "微软雅黑";
    3     background: url(../../img/mask.png) repeat scroll 0 0;
    4 }

      最后,我们在webpack配置文件中,为图片引入url-loader加载器,同时为其指定存放路径和文件名:

    复制代码
    1 module: {
    2         loaders: [    //加载器
    3             {test: /.css$/, loader:ExtractTextPlugin.extract("style", "css") },
    4             {test: /.html$/, loader: "html" },
    5             {test: /.(png|jpg)$/, loader: 'url-loader?limit=8192&name=./img/[hash].[ext]'}
    6         ]
    7     }
    复制代码

      生成的图片存放在dist/img下,然后为了混淆,我们将图片文件名设置为其hash值。

      同时我们配置了limit参数,当图片大小小于这个值的时候,webpack都将会转换为base64字符串进行存储。

      然后在项目根目录下运行 webpack 命令进行打包,然后运行生成index.html文件:

      

      点击ADD按钮后浏览器才发起异步请求,加载了dialog组件以及我们所引入的图片资源,同时图片名称已经被设置为hash值。

      再来看看样式中引入的图片:

      

        可以看到这个背景图已经转换成BASE64字符串写入css文件中,所以这里就减少了一次图片请求。这是一种比较常用的优化页面性能的方式。

      

        上面说到webpack的这种处理方式是一种比较优雅的处理方式,那又有哪些地方不够完善呢?

        1. 上面写入模板中的图片webpack可以帮我们处理,但是src/view目录下的用于生成最终HTML的模板,webpack并不会对其中所引入的图片进行提取处理,导致图片路径不对。

        2. 这里只是对图片进行了提取,其实并未对图片进行任何优化处理,比如合并小图标,限制图片质量避免图片过大等。

    转博客园小侠

  • 相关阅读:
    javascript 数字格式化
    spring-cloud blogs
    rabbitmq python
    centos7下 安装mysql
    hue install
    d3 document
    elastichq 离线安装
    elasticsearch agg
    elastichq auto connect
    Go Hello World!
  • 原文地址:https://www.cnblogs.com/hsp-blog/p/5872114.html
Copyright © 2011-2022 走看看