webpack中require.context的运用

概述

You can create your own context with the require.context() function.

It allows you to pass in a directory to search, a flag indicating whether subdirectories should be searched too, and a regular expression to match files against.

webpack parses for require.context() in the code while building.

webpack文档 – require.context

require.context是webpack中,用来建立本身的(模块)上下文;

webpack会在代码构建的时刻去剖析该函数

剖析

require.context(directory, useSubdirectories = false, regExp = /^\.\//);

该要领有3个参数:

  1. 须要搜刮的文件夹目次(必传)
  2. 是不是须要搜刮它的子孙目次,默以为false
  3. 婚配文件名的正则表达式

例子

// 示例
const test = require.context('./string', false, /\.js$/);

我的目次构造以下:

  • String

    • trim.js
    • trimLeft.js
    • trimRight.js
    • test

      • test1.js
    • *

这时候刻假如console.log(test),就会发明挪用require.context以后返回的是一个函数

webpackContext(req) {
  var id = webpackContextResolve(req);
  return __webpack_require__(id);
}

此次假如还须要深切就须要去webpack打包以后的文件中寻找了:

var map = {
    "./test/test1.js": "./src/string/test/test1.js",
    "./trim.js": "./src/string/trim.js",
    "./trimLeft.js": "./src/string/trimLeft.js",
    "./trimRight.js": "./src/string/trimRight.js"
};


function webpackContext(req) {
    var id = webpackContextResolve(req);
    return __webpack_require__(id);
}
function webpackContextResolve(req) {
    var id = map[req];
    if(!(id + 1)) { // check for number or string
        var e = new Error("Cannot find module '" + req + "'");
        e.code = 'MODULE_NOT_FOUND';
        throw e;
    }
    return id;
}
webpackContext.keys = function webpackContextKeys() {
    return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/string sync recursive \\.js$";

由上面的代码能够看出,在webpackContext定义了多个要领和属性

console.log(webpackContext.id) // "./src/string sync recursive \.js$"

console.log(webpackContext('./trim.js')) // "./src/string/trim.js"

console.log(webpackContext.keys()) // ["./test/test1.js", "./trim.js", "./trimLeft.js", "./trimRight.js"]

运用场景

vue中的基本组件的自动化全局注册

详细就不多说了,直接看文档
vue官方文档 – 基本组件的自动化全局注册

大型单页运用中,路由过量

当你的单页运用变成了大型运用后,路由也在逐步的增添

// rootRoute.js
const rootRoute = {
  childRoutes: [
    {
      path: "/",
      component: AppLayout,
      childRoutes: [
        {
          path: "shop", // 购置详情页
          component: ShopLayout,
          childRoutes: [
            {
              path: "foodDetail",
              component: FoodDetail
            },
            {
              path: "shoesDetail",
              component: ShoesDetail
            }
            // 其他
          ]
        },
        {
          path: "order", // 定单页
          component: Order,
          childRoutes: [
            {
              path: "remark", //定单备注
              component: Remark
            },
            {
              path: "invoice", //发票仰面
              component: Invoice
            },
            {
              path: "payment", //付款页面
              component: Payment
            },
            {
              path: "userValidation", //用户考证
              component: UserValidation
            },
            {
              path: "chooseAddress", //挑选地点
              component: ChooseAddress,
              childRoutes: [
                {
                  path: "addAddress", //增添地点
                  component: AddAddress,
                  childRoutes: [
                    {
                      path: "searchAddress", //搜刮地点
                      component: SearchAddress
                    }
                  ]
                }
              ]
            }
          ]
        }
        // ...
        // 大批新增路由
        // ...
      ]
    }
  ]
};

当路由变的越来越大,大到已难以保护时。我们根据react-router供应的思绪,对路由按营业模块举行拆分。

// rootRoute.js
const rootRoute = {
  childRoutes: [
    {
      path: '/',
      component: AppLayout,
      childRoutes: [
        require('./modules/shop/route'), //购置详情页
        require('./modules/order/route'), // 定单页
        require('./modules/login/route'), // 登录注册页
        require('./modules/service/route'), // 服务中间
        // ...
        // 其他大批新增路由
        // ...
      ]
    }
  ]
};

再进一步优化的话,就能够运用require.context

const rootRoute = {
  childRoutes: [
    {
      path: '/',
      component: AppLayout,
      childRoutes: (r => {
        return r.keys().map(key => r(key));
      })(require.context('./', true, /^\.\/modules\/((?!\/)[\s\S])+\/route\.js$/))
    }
  ]
};

自动援用目次下的文件

比方我如今想要造一个本身的东西库utils,那末跟着东西函数数目的增添,必将须要将代码分割得更小,以至细化到一个东西函数对应一个js文件。

这时候假如还须要在进口js文件中一个个手动援用,那末每增添一个js文件,就须要重新去修正进口js一次,工程量是非常大的。

这时候就能够运用到require.context了~

/**
 * @desc webpack打包进口文件  
 * @example 自动引入子目次下一切js文件
 */
let moduleExports = {};

const r = require.context('./', true, /^\.\/.+\/.+\.js$/);
r.keys().forEach(key => {
    let attr = key.substring(key.lastIndexOf('/') + 1, key.lastIndexOf('.'));
    moduleExports[attr] = r(key);
});

module.exports = moduleExports;

参考

  1. 分享:运用 webpack 的 require.context 完成路由“去中间化”治理
  2. webpack 之 require.context 用法
  3. vue的基本组件的自动化全局注册
  4. webpack官方文档 – require-context
    原文作者:an_l
    原文地址: https://segmentfault.com/a/1190000017160862
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞