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函数接受三个参数
- directory {String} -读取文件的路径
- useSubdirectories {Boolean} -是否遍历文件的子目录
- 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模块