Skip to content

On Windows arm64 TS-based custom loader sometimes causes the process to exit silently when used with --experimental-strip-types #54645

Closed
@wojtekmaj

Description

@wojtekmaj

Version

22.7.0

Platform

Microsoft Windows NT 10.0.26100.0 x64

Subsystem

No response

What steps will reproduce the bug?

I was trying to run my TypeScript + node16 resolution app using --experimental-strip-types.

To cope with --experimental-strip-types not working when using .js extension in import paths, I've decided to use --import, so this is the command I came up with:

node --import=./register.ts --experimental-strip-types ./test.js

register.ts

import { register } from 'node:module';

register('./hooks.ts', import.meta.url);

hooks.ts

import path from 'node:path';

import type { ResolveHook } from 'node:module';

const jsExts = new Set(['.js', '.jsx', '.mjs', '.cjs']);
const tsExts = new Set(['.ts', '.tsx', '.mts', '.cts']);

export const resolve: ResolveHook = async function resolve(specifier, context, nextResolve) {
  const ext = path.extname(specifier);

  // If it's not a JS import, use default behavior
  if (!jsExts.has(ext)) {
    return nextResolve(specifier, context);
  }

  for (const tsExt of tsExts) {
    const specifierWithExtReplaced = specifier.replace(ext, tsExt);

    try {
      // Try and resolve file using each of TS extensions
      return await nextResolve(specifierWithExtReplaced, context);
    } catch {}
  }

  // If all else fails, fall back to default behavior
  return nextResolve(specifier, context);
};

test.ts

console.log('Hello, world!');

How often does it reproduce? Is there a required condition?

100% of the time, condition: Windows (I tested arm64, can't tell if that happens on other architectures as well).

What is the expected behavior? Why is that the expected behavior?

./test.ts to be executed

What do you see instead?

On macOS, this works flawlessly, executing ./test.ts file (mind the extension).

On Windows, however, this does not execute the file, and just silently exits after producing one ExperimentalWarning written with red text:

PS C:\server> node --import=./register.ts --experimental-strip-types ./test.js
(node:3112) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)

Additional information

Note 1

If I rename register.ts and hooks.ts files to .js and strip types manually, it works:

PS C:\server> node --import=./register.js --experimental-strip-types ./test.js
(node:1648) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:1648) ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Hello, world!

(side note: first ExperimentalWarning is in red, seconds one in white. I guess one would be enough? :D)

Note 2

In addition, the workaround I came up with (stripping types manually from register.ts and hooks.ts), does not work on a larger scale application for me. This, in turn, produces two ExperimentalWarning like above, but no code appears to be executed, so my guess is that resolution still fails at some point. When added logs, I observed that my resolution hook receives all specifiers it found in my app's entry file, but then stopped resolution altogether.

I logged that issue separately in #54665.

Metadata

Metadata

Assignees

No one assigned

    Labels

    armIssues and PRs related to the ARM platform.dependenciesPull requests that update a dependency file.strip-typesIssues or PRs related to strip-types supportwindowsIssues and PRs related to the Windows platform.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions