详解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 相关文章推荐
IE中jquery.form中ajax提交没反应解决方法分享
Sep 11 Javascript
js鼠标点击事件在各个浏览器中的写法及Event对象属性介绍
Jan 24 Javascript
js的[defer]和[async]属性
Nov 24 Javascript
15款jQuery分布引导插件分享
Feb 04 Javascript
DOM操作一些常用的属性汇总
Mar 13 Javascript
jQuery的end()方法使用详解
Jul 15 Javascript
VUEJS实战之利用laypage插件实现分页(3)
Jun 13 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
Aug 18 Javascript
node.js中axios使用心得总结
Nov 29 Javascript
JavaScript求一个数组中重复出现次数最多的元素及其下标位置示例
Jul 23 Javascript
微信小程序拖拽排序列表的示例代码
Jul 08 Javascript
node.js爬虫框架node-crawler初体验
Oct 29 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 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
thinkphp实现面包屑导航(当前位置)例子分享
2014/05/10 PHP
symfony表单与页面实现技巧
2015/01/26 PHP
CSS3画一个阴阳八卦图
2021/03/09 HTML / CSS
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
2013/05/07 Javascript
JavaScript中的this关键字使用方法总结
2015/03/13 Javascript
js关于getImageData跨域问题的解决方法
2016/10/14 Javascript
AngularJS中$http的交互问题
2017/03/29 Javascript
详解AngularJS controller调用factory
2017/05/19 Javascript
基于Vue实例生命周期(全面解析)
2017/08/16 Javascript
angular指令笔记ng-options的使用方法
2017/09/18 Javascript
vue2.0路由切换后页面滚动位置不变BUG的解决方法
2018/03/14 Javascript
详解如何用typescript开发koa2的二三事
2018/11/13 Javascript
JavaScript常见继承模式实例小结
2019/01/11 Javascript
bootstrap tooltips在 angularJS中的使用方法
2019/04/10 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
vue自定义指令和动态路由实现权限控制
2020/08/28 Javascript
解决基于 keep-alive 的后台多级路由缓存问题
2020/12/23 Javascript
vue打开新窗口并实现传参的图文实例
2021/03/04 Vue.js
Python中%是什么意思?python中百分号如何使用?
2018/03/20 Python
为什么str(float)在Python 3中比Python 2返回更多的数字
2018/10/16 Python
使用Pyinstaller转换.py文件为.exe可执行程序过程详解
2019/08/06 Python
Django项目基础配置和基本使用过程解析
2019/11/25 Python
Python读取二进制文件代码方法解析
2020/06/22 Python
CSS3美化表单控件全集
2016/06/29 HTML / CSS
Html5移动端div固定到底部实现底部导航条的几种方式
2021/03/09 HTML / CSS
表彰会主持词
2014/03/26 职场文书
意外伤害赔偿协议书范本
2014/09/28 职场文书
大学生个人学年总结
2015/02/15 职场文书
工程合作意向书范本
2015/05/09 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书
MySQL开启事务的方式
2021/06/26 MySQL
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
Python开发五子棋小游戏
2022/04/28 Python