Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error during build: Cannot read property 'file' of undefined #2531

Closed
1 task done
eliot-akira opened this issue Jul 11, 2017 · 19 comments
Closed
1 task done

Error during build: Cannot read property 'file' of undefined #2531

eliot-akira opened this issue Jul 11, 2017 · 19 comments

Comments

@eliot-akira
Copy link
Contributor

eliot-akira commented Jul 11, 2017

I'm stuck on an odd error during build, where a certain source file is unable to be transpiled. The file in question just exports a named class: export class ...

The issue seems to be caused by styled-jsx and its moduleExportsVisitor. The file where the error occurs does not use React or styled-jsx.

Any advice/help would be appreciated. For now, I'm working around it by creating a separate build for that module without going through the Next build pipeline. Here's the stack trace:

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)
  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

The build task completes successfully.

Current Behavior

The build task fails with an error mentioned in summary.

Steps to Reproduce

Unknown

Your Environment

Tech Version
next @beta
@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 11, 2017

The exact place where the error is thrown is: babel-traverse/lib/path/introspection.js:193:20. This is what's there:

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

I'm not familiar enough with Babel to know why this.hub is undefined.

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 11, 2017

Following who called getSource() at: 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') is returning a this without this.hub. If I understand correctly, getSource expects to have this.node and this.hub - as well as this.hub.file, which is throwing the undefined error.

As a try, I added a check for path.hub at this line:

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

Now the build completes. OK, getting closer to a solution..

@timneutkens
Copy link
Member

@giuseppeg

@giuseppeg
Copy link
Contributor

@eliot-akira can I see an example of the source code that causes the failure? Or maybe can you submit a PR to styled-jsx with a failing test?

@eliot-akira
Copy link
Contributor Author

OK, I will see if I can create a failing test case for styled-jsx.

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

So I created a number of tests for styled-jsx, all of which passed. I tested named class export, importing a named class export, and also just the whole source file from the problematic build.

Then, going back to the Next build process, I started removing parts of the source file where the error is happening. Remove, test, remove, test..until I narrowed it down to the smallest chunk that still fails to build:

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

I also removed extraneous details like variable names and what the original function did. This chunk as a test for styled-jsx passes, and the transpiled snapshot looks good.

The multiple occurrences of => could mean something. I'll keep following up..

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

OK, I think I've found a way to reliably reproduce this error:

  • Start a new project: next init, yarn

  • Replace page/index.js with the following:

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

Strange thing about this chunk is that if I remove any one part of it, the build error is gone.

@giuseppeg
Copy link
Contributor

Odd, do you have a custom .babelrc or additional babel plugins?
Can you put together a sample Next.js app which fails on build?

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

It happens on a brand new project with no babel config.

As additional info, the build completes if I move the variable declaration outside the for loop:

let i

for (i=0; ...

@giuseppeg
Copy link
Contributor

page/index.js or pages?

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

Here's an example I put together: https://github.com/eliot-akira/next-build-debug

Edit: I meant pages.

@giuseppeg
Copy link
Contributor

giuseppeg commented Jul 12, 2017

@eliot-akira yeah thank you! My guess is that by the time we do the check

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

the ast has been transformed by another plugin already and since getSource works on the original source code probably it is trying to stringify the wrong path/node.

Instead of being lazy and checking for the source to be module.exports maybe we should do something like this in styled-jsx http://astexplorer.net/#/gist/2a0110cea332771706ebd10c7d6dab68/41f6f8d1a4b981d2f018b69445610777a7e1d7ec

want to give it a try and see if that fixes it?

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

I tried the MemberExpression visitor in place of ExportDefaultDeclaration visitor in babel-external.js. It results in: Cannot read property 'name' of undefined. I see that path.get('object') and path.get('property') are returning instances of NodePath without the expected .node property.

It seems the issue is further up the build pipeline, and styled-jsx is receiving "corrupted" syntax tree..? Here's the stack trace:

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)

@giuseppeg
Copy link
Contributor

You need to replace AssignmentExpression with MemberExpression in babel.js.
Also why in place of ExportDefaultDeclaration visitor?

@eliot-akira
Copy link
Contributor Author

eliot-akira commented Jul 12, 2017

Ah OK, I didn't know what I was doing there. So I did as you suggested: replace AssignmentExpression with MemberExpression in babel.js, and then modified moduleExportsVisitor in babel-external.js to the following:

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)
}

Yes, the build completes successfully. I also tried defining module.exports in the problematic snippet, and it recognizes it.

@eliot-akira
Copy link
Contributor Author

I tried the above changes in styled-jsx source, and it fails 4 tests with Cannot read property 'name' of undefined.

@giuseppeg
Copy link
Contributor

Awesome, thank you for your collaboration! I can put together a patch in the following days, but if that's urgent feel free to submit a PR to styled-jsx. One thing to check before using my proposed fix is that there aren't edge cases and my code doesn't break other kind of MemberExpressions or stuff in general.

btw defaultExports(path, path.get('right'), opts) should be parentPath not sure how it worked.

@eliot-akira
Copy link
Contributor Author

Yes I noticed that mistake.. It works when passing parentPath.

If I add if (!path.get('object').node) return then all tests pass except 1.

It's not urgent, as I found a workaround for now in the problematic source file - to declare the variable before the for loop - so it compiles.

Thank you for looking into it, I'm a big fan of Zeit and Next.js.

@timneutkens
Copy link
Member

Seems like this was fixed in styled-jsx

@lock lock bot locked as resolved and limited conversation to collaborators May 25, 2019
wroy7860 added a commit to wroy7860/styled-jsx-github-React-and-node that referenced this issue Sep 19, 2022
ericbrown2716 added a commit to ericbrown2716/styled-jsx-react-repo that referenced this issue Sep 29, 2022
renawolford6 pushed a commit to renawolford6/styled-jsx-development-react-and-node that referenced this issue Oct 6, 2022
johnfrench3 pushed a commit to johnfrench3/styled-jsx-Build-React that referenced this issue Nov 2, 2022
JiachenSmith pushed a commit to JiachenSmith/styled-jsx that referenced this issue Mar 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants