【问题标题】:Using require.resolve in webpack config yields runtime error: "The provided value"..."is not an absolute path!"在 webpack 配置中使用 require.resolve 会产生运行时错误:“提供的值”...“不是绝对路径!”
【发布时间】:2019-03-11 14:47:57
【问题描述】:

我正在尝试将 exports-loader 与我的 webpack 配置一起使用,但在尝试配置它时遇到了问题。

webpack.config.js

module.exports = {
    module: {
        rules: [
            {
                test: require.resolve('./src/globals.js'),
                use: 'exports-loader?file,parse=helpers.parse'
            }
        ]
    }
};

./src/globals.js

var file = 'blah.txt'
var helpers = {
    test: function() { console.log('test something'); },
    parse: function() { console.log('parse something'); }
}

./src/index.js

import { file } from './globals.js'
console.log('the file', file);

我的应用程序构建良好,但是当我尝试运行它时,我得到:

WebpackOptionsValidationError:配置对象无效。 Webpack 已使用与 API 架构不匹配的配置对象进行初始化。

  • configuration.module.rules[0].test 应该是以下之一:
    • configuration.module.rules[0].test:提供的值“./src/globals.js”不是绝对路径!

为了完全清楚,我了解绝对路径和相对路径之间的区别,并且我知道我使用的值是相对路径。我的困惑有两个方面:

  1. require.resolve 允许相对路径,为什么我不能用 在这里?
  2. 如果我不能使用相对路径,我该如何引用该文件?

我尝试使用test 属性的绝对路径,如下所示:

test: require.resolve(path.join(__dirname, 'src/globals.js'))

但是当我尝试运行时出现此错误:

错误:找不到模块'/workspace/my-app/dist/src/globals.js

所以我被困住了。如何正确配置此加载程序以正确引用该文件?

【问题讨论】:

  • 你试过了吗:test: path.join(__dirname, 'src/globals.js') ?
  • 这允许我构建和运行,但 file 在我的 ./src/index.js console.log 语句中未定义。所以我仍然不确定它是否配置正确......
  • 据我所知,test 基本上需要一个正则表达式,所以任何具有有效文件路径的字符串都应该是可以的,所以你不需要明确地需要 require.resolve for test工作。现在,除此之外,我不知道为什么您的项目没有按预期捆绑。祝你好运!
  • 谢谢。发布新问题以跟进此问题的其余部分。
  • 您的问题中有一些我不清楚的地方:您只是想让webpack-exports-loader 在您的常规 .js 文件中工作?还是更多?

标签: javascript webpack exports-loader


【解决方案1】:

exports-loader 工作

Exports loader 是一个 webpack 加载器,它允许动态地将 exports 语句添加到加载它的 javascript 文件中。例如,您的globals.js 文件中没有任何export,只有filehelpers 变量,但使用exports-loader 它可以工作就像它有@987654331 @ 子句。

加载 webpack 加载器

基本上,要使用加载器,我们必须提供testuse 子句。 test 可以是正则表达式、数组或对象,基本上它决定哪些文件将使用某些加载器。

use 子句决定哪些加载器将应用于与test 正则表达式匹配的文件。

在这种情况下,我们应该——例如——指示 webpack 加载 globals.jsexports-loader

  module: {
    rules: [
      {
        test: /globals.js/,
        use: 'exports-loader',
      }
    ]
  }

这是-afaik- 最常用的加载器使用方式。然而,Webpack 有很多配置选项和不同的有效语法。

一旦我们这样做了,当 webpack 找到 requireimportglobals.js 文件时,它将使用 exports-loader

另一方面,exports-loader 通过修改require 调用来指示它如何提取所需文件中的变量。在他们的文档中:

file.js

const file = 'foo';

app.js

const file = require('exports-loader?file!./file.js');
console.log(file); // foo

所以,基本上你需要两件事才能让exports-loader 工作:

  1. 使用 requireimport 及其特殊语法。

  2. 像往常一样在webpack.config.js 中加载加载程序(他们在文档中跳过了这一点)。

相反,您尝试在webpack.config.js 文件中使用此特定的exports-loader 语法,然后将其与import 一起使用。

所以,坏消息是exports-loader 需要在每个requireimport 语句中使用一些特殊格式来发挥其魔力。您只是不能在您的配置文件中指定它,因为您正在尝试(或者,至少,我不知道如何)。

因此,要使其正常工作,您需要:

  • 如上所述修复您的webpack.config.js
  • 更改您的index.js 文件,使其使用exports-loader 魔法
import file from 'exports-loader?file!./deps.js'
console.log('the file', file);

【讨论】:

  • Sergeon,请参阅 Webpack 自己的 exports-loader 示例,该示例确实 使用了 webpack 配置文件:webpack.js.org/guides/shimming/#global-exports。但是,我无法让它工作,并在这里问了这个问题:stackoverflow.com/questions/55106256/…
  • 为了扩展我之前的评论,似乎有两种不同的方式来使用exports-loader:(1) 通过 webpack 配置文件 (webpack.config.js),以及 (2) “内联” ,通过您描述的import 方法。我确实能够通过从我的webpack.config.js 中删除 all exports-loader 配置并使用 only import file from 'exports-loader?file!./globals.js 来实现此功能。综上所述,使用插件内联似乎可以工作,而使用文件配置方法则不行。
  • 在他们的github页面中,没有任何关于全局配置方式的文档。如果你在那里打开一个问题,也许你可以让它工作,所以:1)他们改进了他们的文档 2)他们建议你如何做到这一点。我将探索是否可以让全局配置方式工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 2018-11-07
  • 1970-01-01
  • 1970-01-01
  • 2019-06-29
  • 2019-12-06
相关资源
最近更新 更多