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

[4.9 breaking change] hostOrText.readFile is not a function #51644

Closed
jeremy-coleman opened this issue Nov 25, 2022 · 11 comments
Closed

[4.9 breaking change] hostOrText.readFile is not a function #51644

jeremy-coleman opened this issue Nov 25, 2022 · 11 comments
Labels
External Relates to another program, environment, or user action which we cannot control.

Comments

@jeremy-coleman
Copy link

jeremy-coleman commented Nov 25, 2022

Bug Report

🔎 Search Terms

hostOrText
hostOrText.readFile

🕗 Version & Regression Information

When did you start seeing this bug occur?

today, after upgrading a project

I tried both 4.9.3 and next versions, both have the error.

  • This is a crash
  • This changed between versions <= 4.8x and 4.9.3

💻 Code

this is the source of the calling function https://github.com/microsoft/TypeScript/blob/main/src/compiler/utilities.ts#L6418

my code doesn't call hostOrText.readFile . I'm using a modified copy of rollup plugin typescript v2. It has worked for years, without change. I can copy/paste it here if wanted, but i think it'd be more clutter rather than providing anything useful.

for a little context, here is the project layout. its super simple. the rollup.bundles.js is just configured to export an array of rollup configs using the local typescript plugin.
image

Just Brainstorming: Possibly related to the new file watcher? I've written several cli tools and have experienced similar problems where chokidar would swallow errors but fs watch recursive would throw and exit. Another thought is maybe there is some change in logic for looking up the closest tsconfig file in a monorepo.

🙁 Actual behavior

error output when running rollup via an npm script

[rollups] [!] (plugin typescript) TypeError: hostOrText.readFile is not a function
[rollups] TypeError: hostOrText.readFile is not a function
[rollups]     at readJsonOrUndefined (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:19519:74)
[rollups]     at Object.readJson (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:19528:16)
[rollups]     at getPackageJsonInfo (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:44767:41)
[rollups]     at loadModuleFromSpecificNodeModulesDirectory (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:45316:27)
[rollups]     at loadModuleFromImmediateNodeModulesDirectory (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:45296:58)
[rollups]     at C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:45286:39
[rollups]     at Object.forEachAncestorDirectory (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:8224:26)
[rollups]     at loadModuleFromNearestNodeModulesDirectoryWorker (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:45280:19)
[rollups]     at loadModuleFromNearestNodeModulesDirectory (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:45272:16)
[rollups]     at tryResolve (C:\Users\jerem\Desktop\App\omnify-monorepo-starterkit\node_modules\typescript\lib\typescript.js:44358:34)

🙂 Expected behavior

output after downgrading to typescript 4.8.x or any other version

[rollups]
[rollups] rollup v3.4.0
[rollups] bundles packages\common\src\index.ts → packages/common/lib/index.js...
[rollups] created packages/common/lib/index.js in 114ms
@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Dec 1, 2022
@sheetalkamat
Copy link
Member

can you please share project where i can repro this

@sheetalkamat
Copy link
Member

Sample project i created seems to work correctly

// /src/math/index.ts
export function add(x: number, y: number): number {
    return x + y;
  }
  
  export function substract(x: number, y: number): number {
    return x - y;
  }
// /src/app.ts
import { add, substract } from './math';

const x = 20;
const y = 10;

console.log(`${x} + ${y} = ${add(x, y)}`)
console.log(`${x} - ${y} = ${substract(x, y)}`);
// /tsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "node",                     
    "outDir": "output",
    "rootDir": "./",
    "composite": true
  }
  ,
  "include": ["./src/**/*.ts"]
}
// /rollup.config.js
import typescript from 'rollup-plugin-typescript2';

export default {
  input: 'src/app.ts',
  output: {
    dir: 'output',
    format: 'cjs',
  },
  plugins: [typescript()],
};
// /package.json
{
  "name": "typescript-rollup",
  "version": "1.0.0",
  "description": "",
  "main": "output/app.js",
  "type": "module",
  "scripts": {
    "build": " rollup -c rollup.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "rimraf": "^3.0.2",
    "rollup": "^3.5.1",
    "rollup-plugin-typescript2": "^0.34.1",
    "tslib": "^2.4.1",
    "typescript": "^4.9.3"
  }
}

Ran

npm run build

@sheetalkamat sheetalkamat added Needs More Info The issue still hasn't been fully clarified and removed Needs Investigation This issue needs a team member to investigate its status. labels Dec 2, 2022
@jeremy-coleman
Copy link
Author

@sheetalkamat
Copy link
Member

Looked into this and it seems like issue with the plugin. It is passing host that has missing readFile on ModuleResolutionHost. It is required method.
image

   var result = tsRuntime.nodeModuleNameResolver(
        importee,
        containingFile,
        compilerOptions,
        resolveHost
      );

@sheetalkamat sheetalkamat added External Relates to another program, environment, or user action which we cannot control. and removed Needs More Info The issue still hasn't been fully clarified labels Dec 3, 2022
@typescript-bot
Copy link
Collaborator

This issue has been marked as 'External' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@jeremy-coleman
Copy link
Author

jeremy-coleman commented Dec 5, 2022

closed over the weekend - harsh.

One last question @sheetalkamat and thank you for taking the time to investigate.

Was this a planned breaking change in the resolveHost? Like I mentioned in the post, this has worked for years.

@sheetalkamat
Copy link
Member

This is not breaking change per say... The API always used readFile as non optional property but had try and catch statement that caught all the errors from reading file (unintentionally) while it was intending to catch json parsing errors. With the recent change we use our own json parsing which is more error tolerant and doesnt throw so now its actually error that was suppressed before.

@jeremy-coleman
Copy link
Author

thank you!

@jeremy-coleman jeremy-coleman removed their assignment Dec 6, 2022
@jeremy-coleman
Copy link
Author

btw, for any future readers, a simple noop for readFile in the resolve host is all that is required.

var resolveHost = {
  directoryExists: function directoryExists(dirPath) {
    try {
      return fs.statSync(dirPath).isDirectory();
    } catch (err) {
      return false;
    }
  },
  fileExists: function fileExists(filePath) {
    try {
      return fs.statSync(filePath).isFile();
    } catch (err) {
      return false;
    }
  },
  readFile: () => {}
};

@nicolaschambrier
Copy link

btw, for any future readers, a simple noop for readFile in the resolve host is all that is required.

@jeremy-coleman thanks for the heads up, however I don't get where we're supposed to add this? I didn't correctly understand the root-cause here but I face the same issue when trying to add a custom project.json in a folder

@FishOrBear
Copy link

readFile("node_modules\\rollup-plugin-typescript\\dist\\rollup-plugin-typescript.cjs.js", "utf-8", (err, str) =>
{
    if (str.includes("readFile: () => { }")) return;
    str = str.replaceAll("var resolveHost = {", "var resolveHost = {\r\nreadFile: () => { },\r\n");
    writeFile("node_modules\\rollup-plugin-typescript\\dist\\rollup-plugin-typescript.cjs.js", str, err =>
    {
        if (err)
            console.log("hack ok");
        else
            console.log("hack error");
    });
});

readFile("node_modules\\rollup-plugin-typescript\\dist\\rollup-plugin-typescript.es.js", "utf-8", (err, str) =>
{
    if (str.includes("readFile: () => { }")) return;
    str = str.replaceAll("var resolveHost = {", "var resolveHost = {\r\nreadFile: () => { },\r\n");
    writeFile("node_modules\\rollup-plugin-typescript\\dist\\rollup-plugin-typescript.es.js", str, err =>
    {
        if (err)
            console.log("hack ok");
        else
            console.log("hack error");
    });
});

Modify the code of the plugin @nicolaschambrier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Relates to another program, environment, or user action which we cannot control.
Projects
None yet
Development

No branches or pull requests

6 participants