详解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 相关文章推荐
由document.body和document.documentElement想到的
Apr 13 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
Jun 24 Javascript
JS将制定内容复制到剪切板示例代码
Feb 11 Javascript
javascript轻量级模板引擎juicer使用指南
Jun 22 Javascript
js友好的时间返回函数
Aug 24 Javascript
微信小程序 富文本转文本实例详解
Oct 24 Javascript
JavaScript实现二分查找实例代码
Feb 22 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
Apr 12 Javascript
vue.js路由mode配置之去掉url上默认的#方法
Nov 01 Javascript
vue在线动态切换主题色方案
Mar 26 Javascript
Javascript call及apply应用场景及实例
Aug 26 Javascript
鸿蒙系统中的 JS 开发框架
Sep 18 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中文字符串截取函数
2013/11/12 PHP
php封装的表单验证类完整实例
2016/10/19 PHP
jQuery 性能优化指南(3)
2009/05/21 Javascript
javascript replace()正则替换实现代码
2010/02/26 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
2012/12/19 Javascript
jquery js 重置表单 reset()具体实现代码
2013/08/05 Javascript
用JS在浏览器中创建下载文件
2014/03/05 Javascript
使用AmplifyJS组件配合JavaScript进行编程的指南
2015/07/28 Javascript
js模拟淘宝网的多级选择菜单实现方法
2015/08/18 Javascript
详解javascript实现自定义事件
2016/01/19 Javascript
解析JavaScript面向对象概念中的Object类型与作用域
2016/05/10 Javascript
JavaScript对象创建模式实例汇总
2016/10/03 Javascript
Vue.js数据绑定之data属性
2017/07/07 Javascript
12条写出高质量JS代码的方法
2018/01/07 Javascript
vue.js在标签属性中插入变量参数的方法
2018/03/06 Javascript
jQuery实现监听下拉框选中内容发生改变操作示例
2018/07/13 jQuery
vue实现div可拖动位置也可改变盒子大小的原理
2020/09/16 Javascript
python编写网页爬虫脚本并实现APScheduler调度
2014/07/28 Python
python对指定目录下文件进行批量重命名的方法
2015/04/18 Python
python如何压缩新文件到已有ZIP文件
2018/03/14 Python
安装python及pycharm的教程图解
2019/10/10 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
python 按钮点击关闭窗口的实现
2020/03/04 Python
python入门之井字棋小游戏
2020/03/05 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
python利用文件时间批量重命名照片和视频
2021/02/09 Python
三星英国官网:Samsung英国
2018/09/25 全球购物
澳大利亚宠物食品和用品商店:PETstock
2020/01/02 全球购物
师范毕业生个人求职信
2013/12/09 职场文书
食品安全工作方案
2014/05/07 职场文书
2014年客服工作总结与计划
2014/12/09 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
2015年实习生工作总结报告
2015/04/28 职场文书
老乡会致辞
2015/07/28 职场文书
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
php双向队列实例讲解
2021/11/17 PHP