這篇日志尘应,在開始接觸 webpack 時候就該寫了比庄,現(xiàn)在發(fā)布也許對一些剛?cè)氪丝拥耐苄┰S幫助寇漫。嘴瓤。斋竞。
即使有點 low益眉,重要的仍是分享
1. reduce 方法介紹
1.1 簡單場景
reduce 函數(shù)的設(shè)計意圖就是方便進行疊加運算:
var arr = [0, 1, 2, 3];
// reduce 實現(xiàn)累加
var total = arr.reduce(function (pre, cur){
return pre + cur;
}, 0);
console.log(total); // 6
上述代碼中陕壹,reduce 方法有兩個參數(shù)应狱,第一個參數(shù)是一個 callback共郭,用于進行計算的函數(shù);第二個參數(shù)則是累加計算的初始值: 0
reduce 以 0 作為初始值,從數(shù)組第 0 項開始累加除嘹,上述代碼的計算過程如下:
total = 0; // => 0
total = 0 + 0; // => 0
total = 0 + 1; // => 1
total = 1 + 2; // => 3
total = 3 + 3; // => 6
若不設(shè)置初始值 0写半,則 reduce 以數(shù)組第 0 項作為初始值,從第 1 項開始累加尉咕,其計算過程如下:
total = 0; // => 0
total = 0 + 1; // => 1
total = 1 + 2; // => 3
total = 3 + 3; // => 6
可以看出叠蝇,reduce 函數(shù)根據(jù)初始值 0,不斷進行疊加年缎,完成最簡單的數(shù)組累加悔捶。
1.2 兩種簡單的運用場景
第一個 demo,使用 reduce 函數(shù)進行二維數(shù)組的拼接:
var arr = [ [0], [1, 2], [3, 4, 5] ];
// reduce 實現(xiàn)數(shù)組拼接
var result = arr.reduce(function (pre, cur){
return pre.concat(cur);
}, []);
console.log(result); // [0, 1, 2, 3, 4, 5]
第二個 demo单芜,使用 reduce 函數(shù)構(gòu)造 JSON 數(shù)組:
// 此例演示:將所有員工的姓名進行拆分
var staff = ['Bob Dell', 'Johon Jobs', 'Maria July'];
// reduce 構(gòu)造 JSON 數(shù)組
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 函數(shù)炎功,能為我們節(jié)省不少中間變量和代碼。
2. 用于實現(xiàn) webpack 多文件入口配置
webpack 配置項中entry
參數(shù)用于配置入口文件路徑缓溅,通常對于只打包一個目錄下的文件蛇损,只需要遍歷該目錄,構(gòu)造一個如下的對象傳遞給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'
// }
對于多頁面應(yīng)用的開發(fā)場景袜匿,也許會需要構(gòu)造類似于下面這樣的一個對象:
// 多個入口,頁面居灯、公共組件并不一定在同一個目錄下
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'
};
可以發(fā)現(xiàn)祭务,我們要打包的頁面怪嫌、公共組件不一定在同一個目錄下,這時候就需要對原先的方法進行擴展岩灭,見代碼:
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 為數(shù)組噪径,則進行兩級遍歷
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;
}, {});
};
// 構(gòu)造對象
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 也可以設(shè)為一個數(shù)組
var entryPath = ['./fe/pages', './fe/components'];