详解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 相关文章推荐
破除网页鼠标右键被禁用的绝招大全
Dec 27 Javascript
在Z-Blog中运行代码[html][/html](纯JS版)
Mar 25 Javascript
一个JS小玩意 几个属性相加不能超过一个特定值.
Sep 29 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
Dec 13 Javascript
解决vue项目打包后提示图片文件路径错误的问题
Jul 04 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
Jul 20 Javascript
小程序清理本地缓存的方法
Aug 17 Javascript
微信小程序实现多选删除列表数据功能示例
Jan 15 Javascript
node app 打包工具pkg的具体使用
Jan 17 Javascript
vue组件文档(.md)中如何自动导入示例(.vue)详解
Jan 25 Javascript
Vue实现点击显示不同图片的效果
Aug 10 Javascript
小谈angular ng deploy的实现
Apr 07 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和js交互一例-PHP教程,PHP应用
2007/01/03 PHP
php程序之die调试法 快速解决错误
2009/09/17 PHP
php二维数组排序与默认自然排序的方法介绍
2013/04/27 PHP
php 启动报错如何解决
2014/01/17 PHP
ThinkPHP后台首页index使用frameset时的注意事项分析
2014/08/22 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
PHP读取XML格式文件的方法总结
2017/02/27 PHP
php解决安全问题的方法实例
2019/09/19 PHP
TP5框架请求响应参数实例分析
2019/10/17 PHP
js克隆对象、数组的常用方法介绍
2013/09/26 Javascript
JS动态调用方法名示例介绍
2013/12/18 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
简单的分页代码js实现
2016/05/17 Javascript
js 中文汉字转Unicode、Unicode转中文汉字、ASCII转换Unicode、Unicode转换ASCII、中文转换
2016/12/06 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
10个经典的网页鼠标特效代码
2018/01/09 Javascript
使用live-server快速搭建本地服务器+自动刷新的方法
2018/03/09 Javascript
Vue SPA单页应用首屏优化实践
2018/06/28 Javascript
jQuery实现仿京东防抖动菜单效果示例
2018/07/06 jQuery
JavaScript实现缓动动画
2020/11/25 Javascript
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
Python中使用HTMLParser解析html实例
2015/02/08 Python
python实现红包裂变算法
2016/02/16 Python
Python读写txt文本文件的操作方法全解析
2016/06/26 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
解决pyqt5中QToolButton无法使用的问题
2019/06/21 Python
详解pandas删除缺失数据(pd.dropna()方法)
2019/06/25 Python
Python银行系统实战源码
2019/10/25 Python
Python生成pdf目录书签的实例方法
2020/10/29 Python
python os.listdir()乱码解决方案
2021/01/31 Python
css3实现超立体3D图片侧翻倾斜效果
2014/04/16 HTML / CSS
.NET笔试题(20个问题)
2016/02/02 面试题
哈弗商学院毕业生求职信
2014/02/26 职场文书
诚信贷款承诺书
2014/05/30 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang