详解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 相关文章推荐
表单的一些基本用法与技巧
Jul 15 Javascript
js当一个变量为函数时 应该注意的一点细节小结
Dec 29 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
May 30 Javascript
javascript快速排序算法详解
Sep 17 Javascript
为什么Node.js会这么火呢?Node.js流行的原因
Dec 01 Javascript
javascript简单比较日期大小的方法
Jan 05 Javascript
BootStrap响应式导航条实例介绍
May 06 Javascript
关于jquery form表单序列化的注意事项详解
Aug 01 jQuery
详解AngularJS跨页面传值(ui-router)
Aug 23 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
Sep 01 Javascript
JS实现方形抽奖效果
Aug 27 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
Apr 17 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中防止恶意刷新页面的代码小结
2012/10/31 PHP
PHP实现通过Luhn算法校验信用卡卡号是否有效
2015/03/23 PHP
CodeIgniter配置之database.php用法实例分析
2016/01/20 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
Laravel 解决composer相关操作提示php相关异常的问题
2019/10/23 PHP
PHP如何通过带尾指针的链表实现'队列'
2020/10/22 PHP
为指定元素增加样式的js代码
2009/12/09 Javascript
jQuery 常见开发使用技巧总结
2009/12/26 Javascript
JQuery实现倒计时按钮的实现代码
2012/03/23 Javascript
javascript实现手机震动API代码
2015/08/05 Javascript
JavaScript实战之带收放动画效果的导航菜单
2016/08/16 Javascript
AngularJs  Using $location详解及示例代码
2016/09/02 Javascript
JavaScript SHA-256加密算法详细代码
2016/10/06 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
React学习笔记之条件渲染(一)
2017/07/02 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
微信小程序实战篇之购物车的实现代码示例
2017/11/30 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
利用js-cookie实现前端设置缓存数据定时失效
2019/06/18 Javascript
Python实现单词翻译功能
2017/06/06 Python
Python 私有函数的实例详解
2017/09/11 Python
python进程间通信Queue工作过程详解
2019/11/01 Python
Python 线性回归分析以及评价指标详解
2020/04/02 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
详解Python 中的 defaultdict 数据类型
2021/02/22 Python
CSS3 清除浮动的方法示例
2018/06/01 HTML / CSS
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
DogBuddy荷兰:找到你最完美的狗保姆
2019/04/17 全球购物
给水工程专业毕业生自荐信
2014/01/28 职场文书
乡下人家教学反思
2014/02/01 职场文书
教师开学感言
2014/02/14 职场文书
心理健康日活动总结
2014/05/08 职场文书
入党积极分子学习党的纲领思想汇报
2014/09/13 职场文书
2014年旅游局法制宣传日活动总结
2014/11/01 职场文书
公司副总经理岗位职责
2015/04/08 职场文书
MySql新手入门的基本操作汇总
2021/05/13 MySQL