require.context
Webpack默认支持ES6,CommonJs,AMD等模块语法,所以你可以使用这些模块语句来编写你的项目。有关于这些模块对应的方法的使用,在这里不做阐述,在这里针对Webpack中require.context的使用进行简单介绍。
require.context方法会创建一个上下文,允许通过检索一个目录来引入对应的文件。其拥有三个参数,含义如下:
- directory:需要检索的目录
- useSubdirectories:是否检索子目录
- regExp: 匹配文件的正则表达式
require.context在需要引用同一种含义的文件的时候非常有用,比如React和Vue中经常使用该方法引入路由对应的组件。
在这里使用require.context方法来改造实战项目。之前实战项目路由切换的时候,对应显示的内容是存放在一个对象中的,如下所示:
// 要显示组件集合
const components = {
"home": "首页",
"news": "新闻页面",
"about": "关于我们",
}
// 监听路由改变,调整页面显示
historyDep.historychange((route) => {
document.getElementsByClassName(`${css["right-area"]}`)[0].innerHTML = components[route];
});
在对应组件逻辑和页面布局丰富起来的时候,这种方式就不再适用。在这里把路由对应显示的组件抽离出去放到一个文件夹下面,抽离以后修改上面代码如下:
// 引入路由显示的组件
import Home from '../views/Home';
import About from '../views/About';
import News from '../views/News';
// 要显示组件集合
const components = {
"home": Home,
"news": News,
"about": About,
}
// 监听路由改变,调整页面显示
historyDep.historychange((route) => {
document.getElementsByClassName(`${css["right-area"]}`)[0].innerHTML = components[route];
});
现在已经抽离了每一个组件,可以针对组件进行单独的维护,但是如果一旦有了新的路由,那么我们又要重新引入一个新的组件,就会又要修改这部分的代码。这个时候使用require.context就可以实现一劳永逸,只需要新建对应的路由组件即可,不用在修改组件引入部分的代码。如下所示:
const context = require.context('../views', true, /index\.js$/);
得到key以后,使用context(key)方法就可以得到组件的实例,改造的完整方法如下:
const keys = context.keys(); // ["./about/index.js", "./home/index.js", "./news/index.js"]
// 要显示组件集合
const components = keys.map(key => {
// 组件名称
const fileName = key.replace(/(\.\/|\/index.js)/g, '');
// 组件实例
const component = context(key).default;
return {
[fileName]: component
}
}).reduce((componentA, componentB) => {
const key = Object.keys(componentB)[0];
const value = Object.values(componentB)[0];
return (componentA[key] ? true : componentA[key] = value,
componentA);
}, {})
现在的components对象和之前的components对象都包含了路由名称和路由对应的组件。以后新增路由,只需要新增路由对应的组件即可,这里的代码会把路由对应的组件给引入。
本章节着重介绍了Node.js API和require.context,并围绕这两个知识点对实战就行了改造。其实Webpack中API远不止这些,至于在何时使用,则需要结合具体场景。更多webpack的API学习,请前往https://webpack.js.org/api/进行查阅。