require.context详解
可以给这个函数传入三个参数:一个要搜索的目录,一个标记表示是否还搜索其子目录, 以及一个匹配文件的正则表达式。
示例
require.context('./test', false, /\.test\.js$/);
// (创建出)一个 context,其中文件来自 test 目录,request 以 `.test.js` 结尾。

require.context会返回一个webpack式的上下文环境,其实质是一个function,此导出函数有三个属性:resolve, keys, id。
- resolve 是一个函数,它返回 request 被解析后得到的模块 id。
- keys 也是一个函数,它返回一个数组,由所有可能被此 context module 处理的请求组成。
- id:上下文模块的id
优化vuex中的modules写法
store中的文件结构

原来的引入方式
这种写法每次添加一个module都要自己手动引入,module命名改动也比较麻烦,并且大型项目中module比较多了之后代码就会显得比较臃肿
import Vue from 'vue';
import Vuex from 'vuex';
import one from './one';
import two from './two';
import three from './three';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
one,
two,
three
}
});
改进后
这样操作之后,就能实现自动化加入module,无论有多少,或者module有改动的话,这部分文件都不用再次改动了
import Vue from 'vue';
import Vuex from 'vuex';
const modules = {};
// 只匹配子文件夹的index.js ./one/index.js
const files = require.context('./', true, /^\.\/(\w*\/)+index\.js$/);
files.keys().forEach(file => {
const moduleName = file.replace(/(^\.\/)|(\/index\.js$)/g, '');
modules[moduleName] = files(file).default || files(file);
});
Vue.use(Vuex);
export default new Vuex.Store({
modules
});
优化组件引入
原来的写法
import HelloWorld from "@/components/HelloWorld.vue";
import Second from "@/components/Second.vue";
import Third from "@/components/Third.vue";
export default {
name: "Home",
components: {
HelloWorld,
Second,
Third
}
};
改进后
const files = require.context("@/components", true, /\.vue$/);
let components = {};
files.keys().forEach(file => {
let componentName = files(file).default.name;
components[componentName] = files(file).default;
});
export default {
name: "About",
components
};
优化route
同样的,路由引入也可以进行类似的改造,实现智能化引入路由
目录结构

代码部分
import Vue from 'vue'
import Router from 'vue-router'
const files = require.context("./views", true, /^.\/(\w+\/)?\w+.vue$/, 'lazy');
const routerItem = (name, modules = {}) => {
let [dot, parent, child] = name.split('/');
parent = parent && parent.replace(/.vue$/, '');
child = child && child.replace(/.vue$/, '');
if(!modules[parent]) {
const finalName = child ? `./${parent}/index.vue` : `./${parent}.vue`;
modules[parent] = {
path: '/' + parent,
name: parent,
component: () => Vue.component(parent, files(finalName))
};
}
if(child && child !== 'index') {
const fullName = parent + child.charAt().toUpperCase() + child.slice(1);
(modules[parent].children || (modules[parent].children = [])).push({
path: "/" + fullName,
name: fullName,
component: () => Vue.component(fullName, files(name))
});
}
};
const modules = ( (modules) => {
files.keys().map(file => {
routerItem(file, modules);
});
return Object.keys(modules).map(item => modules[item]);
})({});
Vue.use(Router);
export default new Router({
mode: "history",
routes: [
...modules,
]
});
require.context真的非常香,逼格十足,还不赶快在你的vue项目中使用起来吗?