Detailed explanation of JS: reduce method to realize webpack multi file entry
- 2021-07-21 06:51:37
- OfStack
1. Introduction of reduce method
1.1 Simple Scenarios
The reduce function is designed to facilitate superposition operations:
var arr = [0, 1, 2, 3];
// reduce Accumulation
var total = arr.reduce(function (pre, cur){
return pre + cur;
}, 0);
console.log(total); // 6
In the above code, the reduce method has two parameters, the first parameter is an callback, which is used to calculate the function; The second parameter is the initial value of the accumulation calculation: 0
reduce takes 0 as the initial value and accumulates from item 0 of the array. The calculation process of the above code is as follows:
total = 0; // => 0
total = 0 + 0; // => 0
total = 0 + 1; // => 1
total = 1 + 2; // => 3
total = 3 + 3; // => 6
If the initial value of 0 is not set, reduce takes item 0 of the array as the initial value and accumulates from item 1. Its calculation process is as follows:
total = 0; // => 0
total = 0 + 1; // => 1
total = 1 + 2; // => 3
total = 3 + 3; // => 6
It can be seen that the reduce function continuously superimposes according to the initial value of 0, and completes the simplest array accumulation.
1.2 Two Simple Application Scenarios
The first demo, using the reduce function to splice 2-dimensional arrays:
var arr = [ [0], [1, 2], [3, 4, 5] ];
// reduce Implement array splicing
var result = arr.reduce(function (pre, cur){
return pre.concat(cur);
}, []);
console.log(result); // [0, 1, 2, 3, 4, 5]
The second demo, using the reduce function to construct an JSON array:
// This example demonstrates splitting the names of all employees
var staff = ['Bob Dell', 'Johon Jobs', 'Maria July'];
// reduce Structure JSON Array
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"}]
Flexible use of reduce function can save us a lot of intermediate variables and code.
2. Used to implement webpack multi-file entry configuration
The entry parameter in the webpack configuration item is used to configure the entrance file path. Usually, for files that are only packaged in one directory, you only need to traverse the directory and construct the following object and pass it to entry:
// Note: index.js Entry file for each page, all pages are in ./fe/pages/ Directory
var entry = {
index: './fe/pages/home/index.js',
list: './fe/pages/list/index.js'
};
Typically, we use the reduce method to traverse entries in the same directory:
var fs = require('fs');
var path = require('path');
...
// Define the entrance path
var entryPath = './fe/pages';
// Multi-file entry under traversal path
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'
// }
For the development scenario of multi-page application, it may be necessary to construct an object similar to the following:
// Multiple portals, pages, and common components do not 1 Fixed at the same 1 Directory under
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'
};
It can be found that the common components of the page we want to package are not set in the same directory, so we need to extend the original method, as shown in the code:
var fs = require('fs');
var path = require('path');
...
// Define the entrance path
var entryPath = ['./fe/pages', './fe/components'];
// Multi-file entry under traversal path
var mkEntriesMap = function (entryPath){
if (typeof(entryPath) == 'string') { // If entryPath Is a string, the directory is traversed directly
var path_map = fs.readdirSync(entryPath).map(function (filename){
return filename + '::./' + path.join(entryPath, filename, 'index.js');
});
} else if (typeof(entryPath) == 'object') { // If entryPath Is an array, a two-level traversal is performed
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;
}, {});
};
// Construct object
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'
// }
The advantage of this is that you only need to configure entryPath starting with 1, and support file packaging under single or multiple paths:
// entryPath Can be 1 String
var entryPath = './fe/pages';
// entryPath It can also be set to 1 Array of numbers
var entryPath = ['./fe/pages', './fe/components'];