microsoft / microsoft/tslib

__importStar can result in undefined imports when importing cyclical dependencies

Open
#114 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.3k
Forks
145
PR merge metrics
No merged PRs in 30d

Description

I've run across what appears to be a bug with __importStar when cyclical dependencies are involved.

I've replicated the issue this sandbox:
https://codesandbox.io/s/eloquent-khayyam-nn14o?file=/src/tsFile.ts

Which contains 3 key files:

index.js

const jsFile = require("./jsFile");
jsFile.doMainThingInJsFile();
console.log("All is good!");

tsFile.ts

//this fails
import * as jsFile from "./jsFile";

//this works
// import jsFile = require("./jsFile");

export function doSomethingInTsFile() {
  console.log("tsFile.doSomethingInTsFile()");
  jsFile.doSomethingInJsFile2();
}

jsFile.js

const tsFile = require("./tsFile");

function doMainThingInJsFile() {
  console.log("jsFile: in doMainThingInJsFile()");
  tsFile.doSomethingInTsFile();
}
exports.doMainThingInJsFile = doMainThingInJsFile;
exports.doSomethingInJsFile2 = function() {
  console.log("jsFile.doSomethingInJsFile2()");
};

tsFile.ts and jsFile.js are cyclical dependencies.

When the 'fail' version of the code runs, doSomethingInTsFile() inside of tsFile.ts is undefined.

Looking at the source code for __importStar it becomes clear what is happening: the reference returned from require(...) is replaced with a new container object. It is unclear to me why this occurs and instead the original isn't used, but I suspect its related to emitting code that will ultimately work with other code that goes looking for a 'default' export in that output.

I would chalk this up to me misusing import * or other settings being incorrect, but if the cyclical dependency is removed, then the module imports just fine with an import *. It's this differing behaviour that leads me to think there is a bug here. We encountered this in our project when some code that rarely ran failed at runtime because a cyclical dependency had been added elsewhere that ultimately caused the member functions of the imported library (old commonjs code) to be undefined.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked CodeSandbox and its index.js, tsFile.ts, and jsFile.js files, then inspect the __importStar implementation and the import-versus-require behavior in the shown cycle. Done means the cyclical CommonJS import no longer produces an undefined member, with a regression test covering the demonstrated case.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.