• webpack中的require.context


    在我们项目开发中,经常需要import或者export各种模块,那么有没有什么办法可以简化这种引入或者导出操作呢?答案是肯定的,下面就为大家介绍一下require.context

    我们会这样引入组件:

    import A from 'components/A'
    import B from 'components/B'
    import C from 'components/C'
    import D from 'components/D'
    // ...
    

    这样很蛋疼,因为每加一个组件,可能都要写这么一句,这样有规律的事,是否可以通过自动化完成?

    看下Webpack [Dependency Management | webpack]

    require.context

    require.context(directory, useSubdirectories, regExp)
    

      

    1. directory: 要查找的文件路径
    2. useSubdirectories: 是否查找子目录
    3. regExp: 要匹配文件的正则

    用法

    require.context('./components/', true, /.js$/)
    

      

    目录结构

    一个 context module 会导出一个(require)函数,此函数可以接收一个参数:request。

    此导出函数有三个属性:resolvekeysid

    • resolve 是一个函数,它返回 request 被解析后得到的模块 id。
    • keys 也是一个函数,它返回一个数组,由所有可能被此 context module 处理的请求(译者注:参考下面第二段代码中的 key)组成。

    上面调用方法,到底返回的是什么?

    var map = {
    	"./A.js": "./src/components/test/components/A.js",
    	"./B.js": "./src/components/test/components/B.js",
    	"./C.js": "./src/components/test/components/C.js",
    	"./D.js": "./src/components/test/components/D.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/components/test/components sync recursive \.js$"; 

    代码很简单,require.context执行后,返回一个方法webpackContext,这个方法又返回一个__webpack_require__,这个__webpack_require__就相当于require或者import。同时webpackContext还有二个静态方法keys与resolve,一个id属性。

    1. keys: 返回匹配成功模块的名字组成的数组
    2. resolve: 接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
    3. id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载

    看下keys是作用

    const ctx = require.context('./components/', true, /.js$/)
    console.log(ctx.keys())
    // ["./A.js", "./B.js", "./C.js", "./D.js"]
    

      

    其实就是

    var map = {
    	"./A.js": "./src/components/test/components/A.js",
    	"./B.js": "./src/components/test/components/B.js",
    	"./C.js": "./src/components/test/components/C.js",
    	"./D.js": "./src/components/test/components/D.js"
    };
    
    Object.keys(map)
    

      

    只不过map是模块内部变量,无法直接访问,所以通过其实提供的keys方法访问

    那么如何引入ABCD组件呢?

    const ctx = require.context('./components/', true, /.js$/)
    const map = {}
    for (const key of ctx.keys()) {
      map[key] = ctx(key)
    }
    console.log(map)
    

      

    看到了吧!成功import进来了,但'./A.js'这样的key有点不太好,自己可以处理字符串生成自己想要的key

     

    可以优化一下,生成一个公共的方法

    const importAll = context => {
      const map = {}
    
      for (const key of context.keys()) {
        const keyArr = key.split('/')
        keyArr.shift() // 移除.
        map[keyArr.join('.').replace(/.js$/g, '')] = context(key)
      }
    
      return map
    }
    
    export default importAll
    使用
    
    import importAll from '$common/importAll'
    export default importAll(require.context('./', true, /.js$/))
    

      

  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/ygunoil/p/15026060.html
Copyright © 2020-2023  润新知