详解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 相关文章推荐
如果文字过长,则将过长的部分变成省略号显示
Jun 26 Javascript
JavaScript实用技巧(一)
Aug 16 Javascript
jQuery实现下拉框左右选择的简单实例
Feb 22 Javascript
wap浏览自动跳转到wap页面的js代码
May 17 Javascript
jquery常用操作小结
Jul 21 Javascript
js实现点击图片将图片地址复制到粘贴板的方法
Feb 16 Javascript
跟我学习javascript解决异步编程异常方案
Nov 23 Javascript
JS延时提示框实现方法详解
Nov 26 Javascript
JavaScript学习笔记整理_关于表达式和语句
Sep 19 Javascript
js HTML5多媒体影音播放
Oct 17 Javascript
Vue中的transition封装组件的实现方法
Aug 13 Javascript
Vue Extends 扩展选项用法完整实例
Sep 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函数
2008/10/03 PHP
php中常用字符串处理代码片段整理
2011/11/07 PHP
php使用for语句输出三角形的方法
2015/06/09 PHP
PHP中的表达式简述
2016/05/29 PHP
Zend Framework入门教程之Zend_Session会话操作详解
2016/12/08 PHP
tp5(thinkPHP5)框架连接数据库的方法示例
2018/12/24 PHP
JavaScript iframe的相互操作浅析
2009/10/14 Javascript
改写一个简单的菜单 弹性大小
2010/12/02 Javascript
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
2012/01/21 Javascript
在javascript中关于节点内容加强
2013/04/11 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
javascript如何判断输入的url是否正确
2014/04/11 Javascript
jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
2015/10/10 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
移动web开发之touch事件实例详解
2018/01/17 Javascript
vue mint-ui tabbar变组件使用
2018/05/04 Javascript
webpack项目轻松混用css module的方法
2018/06/12 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
Vue移动端项目实现使用手机预览调试操作
2020/07/18 Javascript
Vue基本指令实例图文讲解
2021/02/25 Vue.js
Python 实现子类获取父类的类成员方法
2019/01/11 Python
Python3 关于pycharm自动导入包快捷设置的方法
2019/01/16 Python
python 函数中的内置函数及用法详解
2019/07/02 Python
Python代码使用 Pyftpdlib实现FTP服务器功能
2019/07/22 Python
在django中使用post方法时,需要增加csrftoken的例子
2020/03/13 Python
美国顶尖折扣时尚购物网:Bluefly
2016/08/28 全球购物
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
营业员演讲稿
2013/12/30 职场文书
应届毕业生应聘自荐信范文
2014/02/26 职场文书
洗发露广告词
2014/03/14 职场文书
公立医院改革实施方案
2014/03/14 职场文书
爱国演讲稿400字
2014/05/07 职场文书
2015元旦节寄语
2014/12/08 职场文书
2015年个人现实表现材料
2014/12/10 职场文书
Java实现贪吃蛇游戏的示例代码
2022/09/23 Java/Android
Redis实战之Lettuce的使用技巧详解
2022/12/24 Redis