什么是`require.context`

时间:2019-01-06 06:26:21

标签: webpack

Webpack Docs

You can create your own context with the require.context() function.
大。什么是“上下文”?这实际上是做什么的?

It allows you to pass in a directory to search, a flag indicating whether subdirectories should be searched too, and a regular expression to match files against.
允许我“搜索”吗?搜索我假设的文件,然后呢?此功能最终会做什么?它是做什么用的?

2 个答案:

答案 0 :(得分:6)

webpack编译器的主要功能之一是从条目开始递归解析所有模块,通过分析require()require.context(),{{1 }}和import表达式。

webpack和Node.js中对“上下文”的通常解释是一些目录,用作解析模块路径的基础。例如,当前工作目录用作webpack的default context,以解析到import()入口模块的实际路径;请求index.js的上下文是require.resolve('../../../foo.js')

require.context是webpack编译器支持的特殊功能,它使您可以从某个基本目录开始获取所有匹配的模块。目的是告诉webpack在编译时将其转换为它可以解析的所有可能匹配模块请求的动态列表,然后将它们添加为构建依赖项,并允许您在运行时要求它们。

简而言之,您将在完全相同的情况下使用__dirname,而在运行时在Node.js中使用glob动态构建所需的模块路径列表。返回值是一个行为类似于require的可调用对象,其键包含必需的模块请求数据,可以将这些数据作为参数传递给require模块。

有几种使用方法,但是我认为两个最常见的用例要么自动需要一些众所周知的模块(例如,您只添加require.context测试模块,然后在某些模块中使用some.test.js动态发现所有测试,因此不必记录文档并记住每次添加新测试模块时都要手动进行操作)或将静态资产加载到存储库中以将文件发射到构建输出(新来自其他构建工具的webpack用户通常会惊讶于他们的图像,字体,音频文件和其他资产不会出现在输出中,除非某些模块要求使用它们。

答案 1 :(得分:6)

这是一个实际的例子,但请耐心等待。我将向您展示如何使用 Webpack require.context().

从文件夹中加载HTML片段并将其输出到页面上

如今,有许多方法可以使用模板和模板语言来构建网站:您拥有handlebars, mustache, markdown, jasmine, JSX,和大量静态生成器来处理它们,例如Eleventy, Hugo, Gatsby。更不用说选择普通HTML或某种框架,例如Vue

但是有时您只需要从某些文件中获取一些HTML并将其发布到页面上即可。还有一种方法可以使用 Webpack require.context().

从文件夹中加载HTML片段并将其输出到页面上
  

为什么要完全使用require.context或HTML片段?

如果您要建立一个网站甚至一个小型Web应用程序,那么可能会有更直接,可扩展的方法。

但是,最近,我一直在构建一个简单的组件UI库,并希望有一种快速的方法来简单地获取一些HTML并将其包含在最终页(或一系列页面)中,以显示实际运行的库版本

HTML文件不是完整的文档,而仅仅是HTML片段,这些片段封装了库中的特定组件以显示其标记。另外,我希望将它们分解为一个文件夹中的单独文件,以更好地进行项目组织。呈现的主要问题是找到一种可靠的方式来抓取所有文件,因为它们被分解成部分而不是整个HTML文档,并以逻辑顺序进行抓取,而不必拥有一个长期的文档。

我正在使用 Webpack 捆绑所有内容并处理CSS和JS处理,因此尝试找到一种简单的方法来使 Webpack 参与其中是很有意义的这些文件并进行处理。当然,还有其他选择,但并不是所有可行的选择。但是,在这里,我们集中讨论基于 Webpack 的解决方案

  

Webpack并需要require.context()进行救援!

然后,由于我们已经在使用 Webpack 来构建此东西,所以让我们利用Webpack的一项重要功能:require.context().

首先,配置html-loader处理我们的文件 首先,因为我们正在加载HTML文件,所以我们需要安装Webpack的html-loader;通过npm / yarn轻松实现壮举:

npm i -D html-loader or yarn add --dev html-loader

在这里,我们需要将html-loader配置添加到我们的webpack.config.js

module: {
        rules: 
        [
            {
                test: /\.html$/,
                exclude: /node_modules/,
                use: {
                    loader: 'html-loader'
                }
            },
            ...
            {
            //other rules here
            }
        ]
      }

现在,如果执行以下操作,Webpack可以为我们识别并处理HTML文件:

require('/path/to/html/file.html');

但这只是一个文件,我们需要加载一堆文件,这将是一个不断增长的列表–对于一次只添加一行是不切实际的。

现在我们可以加载HTML文件,我们可以设置使用require.context()来加载文件夹中的某些文件并处理其内容。

这就是我要做的:

// grab the element where we'll output the HTML to
const output = document.querySelector('#output');

// create a 'cache' where we can store our built up HTML from our fragments
let htmlFragmentCache = {};

// here, we're creating an anonymous function that loads up our HTML fragments
// then it adds them to our cache object
const importAll = requireContext => requireContext.keys().forEach(key => htmlFragmentCache[key] = requireContext(key));

// next, we call our importAll() function to load the files
// notice how this is where we call the require.context() function
// it uses our file path, whether to load subdirectories and what file type to get
importAll(require.context('./fragments', false, /.html$/));

// finally, we can loop over our cache's keys and add the HTML to our output element
Object.keys(htmlFragmentCache).forEach(key => output.innerHTML += htmlFragmentCache[key]);

就这么简单!当然,即使是很少的几行也可以压缩成匿名函数(实际上,一个Immediately Invoked Function Expression or IIFE)的示例可产生更清晰,更简洁的最终结果:

(context => {
    // need to clear out the current element's contents (just in case!)
    output.innerHTML = '';

    // now, load up the html fragments and add them to the page
    context.keys().forEach(key => output.innerHTML += context(key));
})(require.context('./fragments', false, /.html$/));

就在那里。使用JavaScript文件中的require.context(),使用Webpack进行加载,处理和捆绑的一种非常干净,简单的方式来加载文件夹中的一堆HTML文件。嘘!