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'];


Related articles: