详解JS: reduce方法实现 webpack多文件入口
1.reduce方法介绍
1.1简单场景
reduce函数的设计意图就是方便进行叠加运算:
vararr=[0,1,2,3];
//reduce实现累加
vartotal=arr.reduce(function(pre,cur){
returnpre+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函数进行二维数组的拼接:
vararr=[[0],[1,2],[3,4,5]];
//reduce实现数组拼接
varresult=arr.reduce(function(pre,cur){
returnpre.concat(cur);
},[]);
console.log(result);//[0,1,2,3,4,5]
第二个demo,使用reduce函数构造JSON数组:
//此例演示:将所有员工的姓名进行拆分
varstaff=['BobDell','JohonJobs','MariaJuly'];
//reduce构造JSON数组
varresult=staff.reduce(function(arr,full_name){
arr.push({
first_name:full_name.split('')[0],
last_name:full_name.split('')[1]
});
returnarr;
},[]);
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/目录下
varentry={
index:'./fe/pages/home/index.js',
list:'./fe/pages/list/index.js'
};
通常,我们使用reduce方法来遍历同一目录下的入口:
varfs=require('fs');
varpath=require('path');
...
//定义入口路径
varentryPath='./fe/pages';
//遍历路径下多文件入口
varentris=fs.readdirSync(entryPath).reduce(function(o,filename){
!/\./.test(filename)&&
(o[filename]='./'+path.join(entryPath,filename,'index.js'));
returno;
},{});
//entry={
//index:'./fe/pages/home/index.js',
//list:'./fe/pages/list/index.js'
//}
对于多页面应用的开发场景,也许会需要构造类似于下面这样的一个对象:
//多个入口,页面、公共组件并不一定在同一个目录下
varentry={
index:'./fe/pages/home/index.js',
list:'./fe/pages/list/index.js',
header:'./fe/components/header/index.js',
footer:'./fe/components/footer/index.js'
};
可以发现,我们要打包的页面、公共组件不一定在同一个目录下,这时候就需要对原先的方法进行扩展,见代码:
varfs=require('fs');
varpath=require('path');
...
//定义入口路径
varentryPath=['./fe/pages','./fe/components'];
//遍历路径下多文件入口
varmkEntriesMap=function(entryPath){
if(typeof(entryPath)=='string'){//若entryPath为字符串,则直接遍历此目录
varpath_map=fs.readdirSync(entryPath).map(function(filename){
returnfilename+'::./'+path.join(entryPath,filename,'index.js');
});
}elseif(typeof(entryPath)=='object'){//若entryPath为数组,则进行两级遍历
varpath_map=entryPath.map(function(entry){
returnfs.readdirSync(entry).map(function(filename){
returnfilename+'::./'+path.join(entry,filename,'index.js');
});
}).reduce(function(preArr,curArr){
returnpreArr.concat(curArr);
},[]);
}else{
throw'Typeofconfig.entryPathisnotvalid.';
return;
}
returnpath_map.reduce(function(o,file_map){
varfile_name=file_map.split('::')[0];
varfile_path=file_map.split('::')[1];
if(!/\./.test(file_name)){
o[file_name]=file_path;
}
returno;
},{});
};
//构造对象
varentris=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可以为一个字符串 varentryPath='./fe/pages'; //entryPath也可以设为一个数组 varentryPath=['./fe/pages','./fe/components'];
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。