Webpack代码分割与按需加载实战:require.ensure详解

作者:初晴

时间:2026-10-22

浏览:248

本文详解Webpack中代码分割与按需加载的实现原理。通过require.ensure方法,可将业务组件拆分为独立chunk文件进行异步加载。文章结合入口文件配置、组件JS逻辑及webpack.config.js输出规则,演示如何优化首屏加载性能并解决依赖重复打包问题。

文章目录

本文旨在通过具体实例,深入解析Webpack中的代码分割与按需加载技术,既作为学习记录,也供读者参考。

代码分割与按需加载的必要性

探讨为何在项目开发中需要引入代码分割与按需加载机制。

代码分割的核心在于依据实际业务场景将代码进行拆分,并在合适的时机将其加载至文档中,以优化加载性能。

以下通过一个简单场景进行说明:

1. HTML页面中包含一个触发按钮。

2. 点击该按钮后,动态显示一个包含图片的div元素。

3. 点击该div内的关闭按钮,图片隐藏消失。

Demo目录结构如下:

代码分割与按需加载的必要性

一、当用户未点击按钮时,浏览器仅加载入口文件打包后的JS资源。

代码分割与按需加载的必要性

二、点击按钮后,系统会对相关组件进行异步加载。

代码分割与按需加载的必要性

此处的chunk文件即为打包好的click组件,包含了相应的JS逻辑、HTML模板及CSS样式。

以下是示例源码的具体记录。

基于require.ensure的异步加载实现

1. 编辑入口文件。


window.onload=function(){
     var _cs=require('./index.css');
     var $=require('jquery');

     $('#_click').on('click',function(){
       require.ensure([],function(require){
         var _click=require('./_clickWindow.js');
         if(!_clickEvent){
           console.log(_click);
           var _clickEvent=_click._clicks;
         }
         new _clickEvent();
       },'cli')
     });
};

Webpack将CSS、JS、HTML、JSX等一切资源视为模块进行统一管理。


var _cs=require('./index.css');

引入对应的CSS模块,这需要安装css-loder和style-loader。

代码分割与按需加载的必要性 

使用–save -dev参数,旨在将依赖项写入package.json文件的devDependencies中。

点击按钮时,加载预定义的组件,并在加载完成后执行组件内部的方法。

首先需要掌握require.ensure方法的使用。

CommonJS规范中存在Modules/Async/A标准,其中定义了require.ensure语法。Webpack实现了该功能,作用是在打包阶段进行代码分片,并异步加载分片后的代码。具体用法如下:


require.ensure([], function(require){
  var list = require('./list');
  list.show();
});

在中括号内写入所需的依赖项。

此时,list.js会被打包成一个独立的chunk文件,其大致结构如下:

1. 文件名类似fb874860b35831bc96a8.js。

由于文件名可读性较差,此时需要引入第三个参数来指定名称。


require.ensure([], function(require){
  var list = require('./list');
  list.show();
}, 'list');

此时打包后的JS文件名为:

list.fb874860b35831bc96a8.js

也可以传入如”question/list”这样带有层级结构的名称,Webpack会据此创建对应的文件夹结构。


require.ensure([], function(require){
  var list = require('./list');
  list.show();
  var edit = require('./edit');
  edit.display();
}, 'list_and_edit');

若同时引入两个文件,Webpack会将这两个文件及写入的依赖项打包在一起;若不希望它们合并,需分别编写两个require.ensure来引用各自文件。


require.ensure([‘./a.js'], function(require){
  var list = require('./list');
  list.show();
});

require.ensure([‘./a.js'], function(require){
  var b = require('./b');
  b.show();
});

如果list和b都依赖a.js,则在打包时a.js会被重复打包两次。为解决此问题,可采取以下措施:


require.ensure([‘./a.js'], function(require){
  var list = require('./list');
  list.show();
},'list-b');

require.ensure([‘./a.js'], function(require){
  var b = require('./b');
  b.show();
},'list-b');

此时,这三个文件将被统一打包在一起。

组件JS与Webpack配置详解

2. 组件JS代码。


(function(){
  var _html=require('./_clickHtml.html');
  var $=require('jquery');

  function ClickWindow(){
   this.div=$('body').append(_html);
   $('#_tip').append('<img src="./timg.jpg">');
   this.init();
  }
  ClickWindow.prototype.init=function(){
   $('#_tip').append('<button>关闭</button>')
     .on('click',function(){
       $('img').animate({'width':0},300);
     });
  };

  module.exports._clicks=ClickWindow;
})();

引入已写好的HTML模板,同上需下载html-loader。

3. 配置文件设置。


var path=require('path');
module.exports={
 entry:__dirname+'/index.js',
 output:{
   path: __dirname,
   filename:'[name]bundle.js',
   chunkFilename:'[name]chunk.js'
 },
  module: {
      loaders: [  //加载器
       {test: /\.css$/, loader: "style!css" },
       {test: /\.html$/, loader: "html" },
       {test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}
      ]
  }
};

filename:'[name]bundle.js',

[name]指向入口文件的name属性。

chunkFilename:'[name]chunk.js'

[name]指向require.ensure定义的第三个参数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也欢迎大家继续支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章