详解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'];
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。