require.context实现引用全部js文件或svg文件

1. 引用一个目录下的所有js文件

modules下

home.js
me.js
productList.js
user.js

实现

import home from './modules/home'
import me from './modules/me'
import productList from './modules/productList'
import user from './modules/user';

const modules = {
    home,
    me,
    productList,
    user
}

得到modules这么一个效果。

因为modules下会有很多module,也会动态添加新的module,每次都import略显繁琐,使用require.context可以实现一次引用全部
代码如下:

const ctx = require.context('./modules/', true, /\.js$/)
const map = {}
for (const key of ctx.keys()) {
   let fileKey = key.replace(/\.\/|\.js/g,'');
   map[fileKey] = ctx(key).default
}

map就是想要得到的modules对象。

2. 引用一个目录下的所有svg文件

requireSvgs () {
    const requireAll = requireContext => requireContext.keys().map(requireContext)
    const req = require.context('./assets/svg', false, /\.svg$/)
    requireAll(req)
}

调用requireSvgs方法,可以一次性引入assets/svg目录下的所有.svg后缀的文件。

3. require.context的原理

require.context会被编译为__webpack__require__的方式,打包之后,和其他的模块引用完全一样,所有可以完成放心的在项目里使用。
无论,在web项目,还是nodejs项目里面,只要走webpack,都没有问题。比如上面modules下文件打包结果如下:

引用处:

var ctx = __webpack_require__("yhJU");
var map = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
    for (var _iterator = ctx.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var key = _step.value;

        var fileKey = key.replace(/\.\/|\.js/g, '');
        map[fileKey] = ctx(key).default;
    }
} catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
} finally {
    try {
        if (!_iteratorNormalCompletion && _iterator.return) {
            _iterator.return();
        }
    } finally {
        if (_didIteratorError) {
            throw _iteratorError;
        }
    }
}

console.log(map);

exports.default = new _vuex2.default.Store({
    actions: actions,
    getters: getters,
    modules: map
});

关键的ctx就是__webpack_require__("yhJU"),yhJU代码的模块如下:

/***/ "yhJU":
/***/ (function(module, exports, __webpack_require__) {

var map = {
    "./home.js": "vhd+",
    "./me.js": "Zqav",
    "./productList.js": "Gsy1",
    "./user.js": "6ssc"
};
function webpackContext(req) {
    return __webpack_require__(webpackContextResolve(req));
};
function webpackContextResolve(req) {
    var id = map[req];
    if(!(id + 1)) // check for number or string
        throw new Error("Cannot find module '" + req + "'.");
    return id;
};
webpackContext.keys = function webpackContextKeys() {
    return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "yhJU";

/***/ })

关键就是那个map对象,key是文件的相对路径,后面是各个具体模块的id,
webpack自动帮我们生成了一个包含所有模块的map结构,引用了各个具体的模块,与我们直接import效果一样

4. require.context函数说明

require.context函数接受三个参数 

  1. directory {String} -读取文件的路径
  2. useSubdirectories {Boolean} -是否遍历文件的子目录
  3. regExp {RegExp} -匹配文件的正则 

语法: require.context(directory, useSubdirectories = false, regExp = /^.//);

const ctx = require.context(...), ctx有3个方法

1. resolve {Function}  接收一个req参数,是模块文件相对于js执行文件的路径,返回模块相对于整个工程的相对路径

2. keys {Function} 返回匹配模块的key,一般是个相对路径,例如:./home.js

3. id {String}  包含map对象的模块id,如第3节中的map模块

posted @ 2020-04-27 01:00  全玉  阅读(5249)  评论(0编辑  收藏  举报