详解JS: reduce方法实现 webpack多文件入口


Posted in Javascript onFebruary 14, 2017

1. reduce 方法介绍

1.1 简单场景

reduce 函数的设计意图就是方便进行叠加运算:

var arr = [0, 1, 2, 3];

// reduce 实现累加
var total = arr.reduce(function (pre, cur){
 return pre + cur;
}, 0);

console.log(total);  // 6

上述代码中,reduce 方法有两个参数,第一个参数是一个 callback,用于进行计算的函数;第二个参数则是累加计算的初始值: 0

reduce 以 0 作为初始值,从数组第 0 项开始累加,上述代码的计算过程如下:

total = 0;    // => 0
total = 0 + 0;  // => 0
total = 0 + 1;  // => 1
total = 1 + 2;  // => 3
total = 3 + 3;  // => 6

若不设置初始值 0,则 reduce 以数组第 0 项作为初始值,从第 1 项开始累加,其计算过程如下:

total = 0;    // => 0
total = 0 + 1;  // => 1
total = 1 + 2;  // => 3
total = 3 + 3;  // => 6

可以看出,reduce 函数根据初始值 0,不断进行叠加,完成最简单的数组累加。

1.2 两种简单的运用场景

第一个 demo,使用 reduce 函数进行二维数组的拼接:

var arr = [ [0], [1, 2], [3, 4, 5] ];

// reduce 实现数组拼接
var result = arr.reduce(function (pre, cur){
 return pre.concat(cur);
}, []);

console.log(result);  // [0, 1, 2, 3, 4, 5]

第二个 demo,使用 reduce 函数构造 JSON 数组:

// 此例演示:将所有员工的姓名进行拆分
var staff = ['Bob Dell', 'Johon Jobs', 'Maria July'];

// reduce 构造 JSON 数组
var result = staff.reduce(function (arr, full_name){
 arr.push({
  first_name: full_name.split(' ')[0],
  last_name: full_name.split(' ')[1]
 });

 return arr;
}, []);

console.log(JSON.stringify(result));
// [{"first_name":"Bob","last_name":"Dell"},{"first_name":"Johon","last_name":"Jobs"},{"first_name":"Maria","last_name":"July"}]

灵活使用 reduce 函数,能为我们节省不少中间变量和代码。

2. 用于实现 webpack 多文件入口配置

webpack 配置项中entry参数用于配置入口文件路径,通常对于只打包一个目录下的文件,只需要遍历该目录,构造一个如下的对象传递给entry即可:

// 注:index.js 为每个页面的入口文件,所有页面均在 ./fe/pages/ 目录下
var entry = {
 index: './fe/pages/home/index.js',
 list: './fe/pages/list/index.js'
};

通常,我们使用 reduce 方法来遍历同一目录下的入口:

var fs = require('fs');
var path = require('path');
...

// 定义入口路径
var entryPath = './fe/pages';

// 遍历路径下多文件入口
var entris = fs.readdirSync(entryPath).reduce(function (o, filename) {
 !/\./.test(filename) &&
 (o[filename] = './' + path.join(entryPath, filename, 'index.js'));
 return o;
}, {});

// entry = {
//  index: './fe/pages/home/index.js',
//  list: './fe/pages/list/index.js'
// }

对于多页面应用的开发场景,也许会需要构造类似于下面这样的一个对象:

// 多个入口,页面、公共组件并不一定在同一个目录下
var entry = {
 index: './fe/pages/home/index.js',
 list: './fe/pages/list/index.js',
 header: './fe/components/header/index.js',
 footer: './fe/components/footer/index.js'
};

可以发现,我们要打包的页面、公共组件不一定在同一个目录下,这时候就需要对原先的方法进行扩展,见代码:

var fs = require('fs');
var path = require('path');
...

// 定义入口路径
var entryPath = ['./fe/pages', './fe/components'];

// 遍历路径下多文件入口
var mkEntriesMap = function (entryPath){
 if (typeof(entryPath) == 'string') {  // 若 entryPath 为字符串,则直接遍历此目录
  var path_map = fs.readdirSync(entryPath).map(function (filename){
   return filename + '::./' + path.join(entryPath, filename, 'index.js');
  });
 } else if (typeof(entryPath) == 'object') {  // 若 entryPath 为数组,则进行两级遍历
  var path_map = entryPath.map(function (entry){
   return fs.readdirSync(entry).map(function (filename){
    return filename + '::./' + path.join(entry, filename, 'index.js');
   });
  }).reduce(function (preArr, curArr){
   return preArr.concat(curArr);
  }, []);
 } else {
  throw 'Type of config.entryPath is not valid.';
  return;
 }

 return path_map.reduce(function (o, file_map){
  var file_name = file_map.split('::')[0];
  var file_path = file_map.split('::')[1];

  if (!/\./.test(file_name)) {
   o[file_name] = file_path;
  }

  return o;
 }, {});
};

// 构造对象
var entris = mkEntriesMap(entryPath);

// entry = {
//  index: './fe/pages/home/index.js',
//  list: './fe/pages/list/index.js',
//  header: './fe/components/header/index.js',
//  footer: './fe/components/footer/index.js'
// }

这样做的好处在于,只需配置一开始的entryPath就行了,同时支持单个或多个路径下的文件打包:

// entryPath 可以为一个字符串
var entryPath = './fe/pages';

// entryPath 也可以设为一个数组
var entryPath = ['./fe/pages', './fe/components'];

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
(function(){})()的用法与优点
Mar 11 Javascript
jquery渐隐渐显的图片幻灯闪烁切换实现方法
Feb 26 Javascript
JavaScript使用yield模拟多线程的方法
Mar 19 Javascript
基于jQuery实现动态数字展示效果
Aug 12 Javascript
js检测用户输入密码强度
Oct 22 Javascript
jQuery Mobile和HTML5开发App推广注册页
Nov 07 Javascript
jQ处理xml文件和xml字符串的方法(详解)
Nov 22 Javascript
轻松理解JavaScript之AJAX
Mar 15 Javascript
es6学习笔记之Async函数的使用示例
May 11 Javascript
vue-cli系列之vue-cli-service整体架构浅析
Jan 14 Javascript
详解关于html,css,js三者的加载顺序问题
Apr 10 Javascript
javascript执行上下文、变量对象实例分析
Apr 25 Javascript
如何快速上手Vuex
Feb 14 #Javascript
BootStrap框架中的data-[ ]自定义属性理解(推荐)
Feb 14 #Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
Feb 14 #Javascript
Vue组件开发初探
Feb 14 #Javascript
JavaScript Base64 作为文件上传的实例代码解析
Feb 14 #Javascript
JavaScript实现定时页面跳转功能示例
Feb 14 #Javascript
javaScript嗅探执行神器-sniffer.js
Feb 14 #Javascript
You might like
在PHP里得到前天和昨天的日期的代码
2007/08/16 PHP
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
Linux下快速搭建php开发环境
2017/03/13 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
JavaScript TO HTML 转换
2006/06/26 Javascript
ASP.NET jQuery 实例17 通过使用jQuery validation插件校验ListBox
2012/02/03 Javascript
JS实现一个按钮的方法
2015/02/05 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
2015/09/06 Javascript
初步使用Node连接Mysql数据库
2016/03/03 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
树结构之JavaScript
2017/01/24 Javascript
JS实现的五级联动菜单效果完整实例
2017/02/23 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
关于meta viewport中target-densitydpi属性详解(推荐)
2017/08/18 Javascript
微信小程序常见页面跳转操作简单示例
2019/05/01 Javascript
[38:44]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第二局
2016/02/25 DOTA
Python中统计函数运行耗时的方法
2015/05/05 Python
Python获取当前页面内所有链接的四种方法对比分析
2017/08/19 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
2018/05/09 Python
解决pandas .to_excel不覆盖已有sheet的问题
2018/12/10 Python
用python做游戏的细节详解
2019/06/25 Python
python读取.mat文件的数据及实例代码
2019/07/12 Python
Python如何通过Flask-Mail发送电子邮件
2020/01/29 Python
python使用turtle库绘制奥运五环
2020/02/24 Python
Python模块/包/库安装的六种方法及区别
2020/02/24 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
英国时尚女装购物网站:Missguided
2018/08/23 全球购物
德国家具、照明、家居用品网上商店:Wayfair.de
2020/02/13 全球购物
十佳班主任事迹材料
2014/01/18 职场文书
挖掘机司机岗位职责
2014/02/12 职场文书
党员干部对十八届四中全会的期盼
2014/10/17 职场文书
2015年护士节慰问信
2015/03/23 职场文书
python-for x in range的用法(注意要点、细节)
2021/05/10 Python
详解Redis在SpringBoot工程中的综合应用
2021/10/16 Redis