zoukankan      html  css  js  c++  java
  • 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$/))
    

      

  • 相关阅读:
    easyUI日期框,默认显示今天,今天以后的日期不能选
    vue实现下拉框全选和输入匹配
    【转载】CSS flex属性深入理解
    ES6学习之二
    Centos7(Firewall)防火墙命令
    DeDeCMS模板标签(2)
    DeDeCMS模板标签(1)
    常用js正则表达式大全
    linux yum 命令
    Linux软链接和硬链接
  • 原文地址:https://www.cnblogs.com/ygunoil/p/15026060.html
Copyright © 2011-2022 走看看