question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Named export arrow function name inference

See original GitHub issue

Description

When a React component is defined as a named export arrow function, the name of it cannot be inferred correctly in jest coverage mode. (To be precise, it’s node that cannot infer it) It generates inconsistent result compared with the stored snapshots.

What’s a named export arrow function?

export const MyFancyComponent = props => <div {...props} />

Digging in

It turns out the above MyFancyComponent will be transpiled (proper babel-preset-env) into this:

var MyFancyComponent = exports.MyFancyComponent = (cov_15qdocbbym.s[0]++, props => {
  cov_15qdocbbym.f[0]++;
  cov_15qdocbbym.s[1]++;
  return <div {...props />;
});

where the instrument code is inserted along with the arrow function, generating a SequenceExpression. However, node (I’m using 8.2.1) cannot infer the name of the arrow function inside a sequence expression.

> const a = (1, () => 2);
undefined
> a.name
''
> const b = () => 3;
undefined
> b.name
'b'

A possible solution

Modify the insertCounter function in istanbul-lib-instrument/src/visitor.js as follows:

-            if (parent && (T.isProgram(parent.parentPath) || T.isBlockStatement(parent.parentPath))) {
+            if (parent && T.isExportNamedDeclaration(parent.parentPath)) {
+                parent.parentPath.insertBefore(T.expressionStatement(increment));
+            } else if (parent && (T.isProgram(parent.parentPath) || T.isBlockStatement(parent.parentPath))) {

Thus, the generated code would be something like:

cov_15qdocbbym.s[0]++;
var foo = exports.foo = props => {
  cov_15qdocbbym.f[0]++;
  cov_15qdocbbym.s[1]++;
  return 'bar';
};

Thus, node can infer foo now 😃

Questions

  • What’s the current policies for ES modules of istanbul projects?
  • Is it a good practice to make such changes for ES modules compatibility?
  • Would you accept a PR?

Repos

I put my changes of istanbul-lib-instrument into my forked repo:

I also published it as a scoped npm module under @tomchentw/istanbul-lib-instrument, hence I can forked babel-plugin-istanbul to add a failing case and fix it:

Related issues

#63 ……and maybe more.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
ljharbcommented, Aug 24, 2017

That’s because of issues with jest caching; it should be a separate issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does the Airbnb style guide say that relying on function ...
This is taken from the Airbnb react style guide. Can someone please explain why "relying on function name inference is discouraged"? Is it...
Read more >
Arrow Functions in JavaScript: Fat & Concise Syntax - SitePoint
Arrow functions are all anonymous functions:​​ As of ES6, variables and methods can infer the name of an anonymous function from its syntactic ......
Read more >
The names of functions in ES6 - 2ality
With regard to names, arrow functions are like anonymous function expressions: const func = () => {}; console.log(func.name); // func.
Read more >
TypeScript Arrow Functions - TutorialsTeacher
Learn what is an arrow function and how to define it in TypeScript.
Read more >
5 Best Practices to Write Quality Arrow Functions
Fortunately, the function name inference (a feature of ES2015) can detect the function name under certain conditions. The idea of name inference ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found