[vercel/next.js]构建期间出错:无法读取未定义的属性“文件”

2024-05-15 373 views
4

我在构建过程中遇到了一个奇怪的错误,其中某个源文件无法转换。有问题的文件只是导出一个命名类:export class ...

该问题似乎是styled-jsx由其 moduleExportsVisitor 引起的。发生错误的文件没有使用React或styled-jsx。

任何建议/帮助将不胜感激。目前,我正在通过为该模块创建一个单独的构建来解决这个问题,而不需要通过下一个构建管道。这是堆栈跟踪:

Module build failed: TypeError: ~/dev/mooz/vex/src/accidental.js: Cannot read property 'file' of undefined
    at NodePath.getSource (~/dev/node_modules/babel-traverse/lib/path/introspection.js:193:20)
    at moduleExportsVisitor (~/dev/node_modules/styled-jsx/dist/babel-external.js:171:24)
    at callExternalVisitor (~/dev/node_modules/styled-jsx/dist/babel.js:346:3)
    at PluginPass.AssignmentExpression (~/dev/node_modules/styled-jsx/dist/babel.js:308:9)
    at newFn (~/dev/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (~/dev/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (~/dev/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (~/dev/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (~/dev/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle (~/dev/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit (~/dev/node_modules/babel-traverse/lib/context.js:192:19)
    at Function.traverse.node (~/dev/node_modules/babel-traverse/lib/index.js:114:17)
预期行为

构建任务成功完成。

目前的行为

构建任务失败并出现摘要中提到的错误。

重现步骤

未知

您的环境
科技 版本
下一个 @贝塔

回答

4

抛出错误的确切位置是:babel-traverse/lib/path/introspection.js:193:20。这就是那里的内容:

function getSource() {
  var node = this.node;
  if (node.end) {
    return this.hub.file.code.slice(node.start, node.end); // <-- *here*
  } else {
    return "";
  }
}

我对 Babel 不够熟悉,不知道为什么this.hub未定义。

2

以下谁打电话getSource()styled-jsx/dist/babel-external.js:171:24..

function moduleExportsVisitor(path, opts) {
  if (path.get('left').getSource() !== 'module.exports') { // <-- *here*
    return;
  }
  defaultExports(path, path.get('right'), opts);
};

path.get('left')正在返回一个thiswithout this.hub。如果我理解正确的话,getSource期望有this.nodeand this.hub- 以及this.hub.file,这会引发未定义的错误。

作为尝试,我path.hub在这一行添加了一个检查:

if (path.hub && path.get('left').getSource() !== 'module.exports') {

现在构建完成了。好的,越来越接近解决方案了..

7

@giuseppeg

3

@eliot-akira 我可以查看导致失败的源代码示例吗?或者您可以向 styled-jsx 提交一个测试失败的 PR 吗?

4

好的,我将看看是否可以为 styled-jsx 创建一个失败的测试用例。

2

所以我为 styled-jsx 创建了一些测试,全部通过了。我测试了命名类导出、导入命名类导出,以及有问题的构建中的整个源文件。

然后,回到下一个构建过程,我开始删除发生错误的源文件部分。删除,测试,删除,测试..直到我将其缩小到仍然无法构建的最小块:

export default function fn() {
  for (let i = 0; i < 1; i++) {
    const g = () => {}
    const b = () => g()
    i = 2
  }
}

我还删除了无关的细节,例如变量名称以及原始函数的作用。该块作为 styled-jsx 的测试通过了,并且转换后的快照看起来不错。

多次出现=>可能意味着某些事情。我会继续跟进..

7

好的,我想我已经找到了一种可靠地重现此错误的方法:

  • 开始一个新项目:next init,yarn

  • 替换page/index.js为以下内容:

    for (let i = 0; i < 1; i++) {
    const g = () => {}
    const b = () => g()
    i = 2
    }
  • 跑步next build

关于这一块的奇怪的事情是,如果我删除它的任何一部分,构建错误就会消失。

0

奇怪,你有自定义的.babelrc或额外的 babel 插件吗?您能否整理一个在构建时失败的示例 Next.js 应用程序?

1

它发生在一个没有 babel 配置的全新项目上。

作为附加信息,如果我将变量声明移到循环之外,则构建完成for

let i

for (i=0; ...
6

page/index.js或者pages

2

@eliot-akira 是的谢谢你!我的猜测是当我们进行检查时

if (path.get('left').getSource() !== 'module.exports')

ast 已经被另一个插件转换了,并且由于getSource在原始源代码上工作,它可能正在尝试字符串化错误的路径/节点。

我们不应该偷懒并检查源代码,也许我们应该在 styled-jsx http://astexplorer.net/#/gist/2a0110cea332771706ebd10c7d6dab68/41f6f8d1a4b981d2f018b69445610777a7e1d7ecmodule.exports中做类似的事情

想尝试一下看看是否能解决问题?

0

我尝试使用 MemberExpression 访问者代替 中的 ExportDefaultDeclaration 访问者babel-external.js。其结果是:Cannot read property 'name' of undefined。我看到了这一点,path.get('object')并且path.get('property')正在返回没有预期.node属性的 NodePath 实例。

看来问题出在构建管道的更上游,并且 styled-jsx 正在接收“损坏的”语法树..?这是堆栈跟踪:

Module build failed: TypeError: ~/build-test/pages/index.js?entry: Cannot read property 'name' of undefined
    at moduleExportsVisitor (~/build-test/node_modules/styled-jsx/dist/babel-external.js:171:31)
    at callExternalVisitor (~/build-test/node_modules/styled-jsx/dist/babel.js:346:3)
    at PluginPass.AssignmentExpression (~/build-test/node_modules/styled-jsx/dist/babel.js:308:9)
    at newFn (~/build-test/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (~/build-test/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (~/build-test/node_modules/babel-traverse/lib/path/context.js:48:17)
    at NodePath.visit (~/build-test/node_modules/babel-traverse/lib/path/context.js:105:12)
    at TraversalContext.visitQueue (~/build-test/node_modules/babel-traverse/lib/context.js:150:16)
    at TraversalContext.visitSingle (~/build-test/node_modules/babel-traverse/lib/context.js:108:19)
    at TraversalContext.visit (~/build-test/node_modules/babel-traverse/lib/context.js:192:19)
 @ multi ./pages?entry
    at ~/build-test/node_modules/next/dist/server/build/index.js:182:21
    at ~/build-test/node_modules/webpack/lib/Compiler.js:274:15
    at Compiler.emitRecords (~/build-test/node_modules/webpack/lib/Compiler.js:369:37)
    at ~/build-test/node_modules/webpack/lib/Compiler.js:267:12
    at ~/build-test/node_modules/webpack/lib/Compiler.js:362:11
    at next (~/build-test/node_modules/tapable/lib/Tapable.js:154:11)
    at Compiler.compiler.plugin (~/build-test/node_modules/webpack/lib/performance/SizeLimitsPlugin.js:99:4)
    at Compiler.applyPluginsAsyncSeries1 (~/build-test/node_modules/tapable/lib/Tapable.js:158:13)
    at Compiler.afterEmit (~/build-test/node_modules/webpack/lib/Compiler.js:359:8)
    at Compiler.<anonymous> (~/build-test/node_modules/webpack/lib/Compiler.js:354:14)
0

您需要替换AssignmentExpressionMemberExpressionin babel.js。又为什么要代替ExportDefaultDeclaration访客呢?

4

啊好吧,我不知道我在那里做什么。所以我按照你的建议做了:替换AssignmentExpressionMemberExpressionin babel.js,然后将moduleExportsVisitorin修改babel-external.js为以下内容:

function moduleExportsVisitor(path, opts) {
  if (path.get('object').node.name !== 'module') {
    return
  }
  if (path.get('property').node.name !== 'exports') {
    return
  }
  console.log('yep module export')
  const parentPath = path.parentPath
  defaultExports(path, parentPath, opts)
}

是的,构建成功完成。我还尝试module.exports在有问题的代码片段中进行定义,它可以识别它。

0

我在 styled-jsx 源代码中尝试了上述更改,但 4 次测试失败Cannot read property 'name' of undefined

1

太棒了,感谢您的合作!我可以在接下来的几天内制作补丁,但如果紧急,请随时向 styled-jsx 提交 PR。在使用我建议的修复之前要检查的一件事是,不存在边缘情况,并且我的代码一般不会破坏其他类型的MemberExpression或其他东西。

顺便说一句,defaultExports(path, path.get('right'), opts)应该parentPath不确定它是如何工作的。

9

是的,我注意到了这个错误。它在传递parentPath 时有效。

如果我添加,if (!path.get('object').node) return那么除了 1 之外所有测试都会通过。

这并不紧急,因为我现在在有问题的源文件中找到了解决方法 - 在循环之前声明变量for- 所以它可以编译。

感谢您的关注,我是 Zeit 和 Next.js 的忠实粉丝。

6

似乎这个问题已在 styled-jsx 中修复