资讯专栏INFORMATION COLUMN

reduce 方法实现 webpack 多文件入口

Little_XM / 1890人阅读

摘要:这篇日志,在开始接触时候就该写了,现在发布也许对一些刚入此坑的童鞋能些许帮助。。。

这篇日志,在开始接触 webpack 时候就该写了,现在发布也许对一些刚入此坑的童鞋能些许帮助。。。
即使有点 low,重要的仍是分享

1. reduce 方法介绍 1.1 简单场景

reduce 函数的设计意图就是方便进行叠加运算:

var arr = [0, 1, 2, 3];

// reduce 实现累加
var total = arr.reduce(function (pre, cur){
  return pre + 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 函数进行二维数组的拼接:

var arr = [ [0], [1, 2], [3, 4, 5] ];

// reduce 实现数组拼接
var result = arr.reduce(function (pre, cur){
  return pre.concat(cur);
}, []);

console.log(result);    // [0, 1, 2, 3, 4, 5]

第二个 demo,使用 reduce 函数构造 JSON 数组:

// 此例演示:将所有员工的姓名进行拆分
var staff = ["Bob Dell", "Johon Jobs", "Maria July"];

// reduce 构造 JSON 数组
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 函数,能为我们节省不少中间变量和代码。

2. 用于实现 webpack 多文件入口配置

webpack 配置项中entry参数用于配置入口文件路径,通常对于只打包一个目录下的文件,只需要遍历该目录,构造一个如下的对象传递给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"
// }

对于多页面应用的开发场景,也许会需要构造类似于下面这样的一个对象:

// 多个入口,页面、公共组件并不一定在同一个目录下
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"
};

可以发现,我们要打包的页面、公共组件不一定在同一个目录下,这时候就需要对原先的方法进行扩展,见代码:

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 为数组,则进行两级遍历
    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;
  }, {});
};

// 构造对象
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 也可以设为一个数组
var entryPath = ["./fe/pages", "./fe/components"];

原创文章,转载请注明作者、出处

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82645.html

相关文章

  • 基于Redux架构的单页应用开发总结

    摘要:系统架构介绍本项目开发基于框架,利用进行模块化构建,前端编写语言是,利用进行转换。单页是为单页应用量身定做的你可以把拆成很多,这些由路由来加载。前者用来获取的状态,后者用来修改的状态。 系统架构介绍 本项目开发基于 React + Redux + React-Route 框架,利用 webpack 进行模块化构建,前端编写语言是 JavaScript ES6,利用 babel进行转换。...

    fish 评论0 收藏0
  • webpack4 中的最新 React全家桶实战使用配置指南!

    摘要:安装配置加载器配置配置文件配置支持自定义的预设或插件只有配置了这两个才能让生效,单独的安装是无意义的。 showImg(https://segmentfault.com/img/bVbjGNY?w=2847&h=1931); 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 最新React全家桶实战使用配置指南 这篇文档 是吕小明老师结合以往的项目经验 加上自己本身...

    Towers 评论0 收藏0
  • 微信小程序模块化开发实践

    摘要:前言省略准备了解微信小程序是什么微信小程序官方文档了解应用状态管理方案也是架构的具体实现了解打包工具了解代码转译工具原理大致是借助语法分析工具之类的将代码解析成抽象语法树再重写成最终的代码测试工具等等请根据需要选择微信小程序目前版本的实现需 前言: 省略... 准备 了解微信小程序是什么? 微信小程序官方文档 了解应用状态管理方案: Redux, 也是Flux架构的具体实现 了解Ja...

    luxixing 评论0 收藏0
  • todolist for react redux 学习总结

    摘要:为了提高自己的学习效率,避免做一些无用的工作,我也决定以后无论是工作还是学习一定要养成定时总结的习惯,而且也要用文字记录下来,这样可以时常复习,理清逻辑,加深印象。一种解决方法是将对象作为参数,传入容器组件。 前言 最近一直在学习react技术栈,相关的理论和概念基本都了解了,之前也用reactjs写了几个demo,切身体会到了函数式编程和组件化开发的强大之处,但因各种主客观原因,事后...

    anquan 评论0 收藏0
  • webpack工程化集成React技术栈(一)

    项目开始前,我们先聊一聊关于项目的一些说明。该项目起始于2017年初,当时公司主要技术栈为gulp+angular,鉴于react的火热的生态,在公司决定研发bss管理系统时选用react开发,目的也是为react native打下基础,以解决后期公司大前端技术栈的逐步成熟。(当时没有选择vue开发的主要原因是weex生态还不够特别成熟),既然决定换新,项目的构建也跟着一起换,从gulp转向火热的...

    tianhang 评论0 收藏0

发表评论

0条评论

Little_XM

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<