node test TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".png" in Preact app

260 views Asked by At

I'm importing a PNG file in my TypeScript component:

import MyImage from "./MyImage.png";

export default function () {
  return <img src={MyImage} width="16" height="16" />;
}

The component renders fine in Storybook (using Vite), however when I run my tests with this command:

tsx --test --test-reporter=spec $(glob '**/*.test.ts')

I get the error:

ℹ node:internal/errors:490
ℹ     ErrorCaptureStackTrace(err);
ℹ     ^
ℹ
ℹ TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".png" for /Users/me/src/templates/MyImage.png
ℹ     at __node_internal_captureLargerStackTrace (node:internal/errors:490:5)
ℹ     at new NodeError (node:internal/errors:399:5)
ℹ     at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:79:11)
ℹ     at defaultGetFormat (node:internal/modules/esm/get_format:121:38)
ℹ     at defaultLoad (node:internal/modules/esm/load:81:20)
ℹ     at nextLoad (node:internal/modules/esm/loader:163:28)
ℹ     at V (file:///Users/me/src/templates/node_modules/.pnpm/[email protected]/node_modules/tsx/dist/loaders-deprecated-261ba186.mjs:12:1703)
ℹ     at nextLoad (node:internal/modules/esm/loader:163:28)
ℹ     at ESMLoader.load (node:internal/modules/esm/loader:605:26)
ℹ     at ESMLoader.moduleProvider (node:internal/modules/esm/loader:457:22)
ℹ     at new ModuleJob (node:internal/modules/esm/module_job:64:26)
ℹ     at #createModuleJob (node:internal/modules/esm/loader:480:17)
ℹ     at ESMLoader.getModuleJob (node:internal/modules/esm/loader:434:34)
ℹ     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
ℹ     at async ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:79:21) {
ℹ   code: 'ERR_UNKNOWN_FILE_EXTENSION'
ℹ }
ℹ
ℹ Node.js v18.15.0

I get the same error about a .css file if I try and include one of those.

My tsconfig.json:

{
  "extends": "@tsconfig/strictest/tsconfig",
  "compilerOptions": {
    "lib": ["es2023"],
    "target": "es2022",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "noEmit": true,
    "jsx": "react-jsx",
    "resolveJsonModule": true,
    "jsxImportSource": "preact",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "baseUrl": "./",
    "paths": {
      "react": ["./node_modules/preact/compat/"],
      "react-dom": ["./node_modules/preact/compat/"]
    }
  },
  "exclude": ["node_modules"]
}

Any idea how to fix this error?

Thanks in advance.

1

There are 1 answers

0
rschristian On

This is the correct behavior.

Per the spec, you cannot import PNGs, CSS files, or any other asset types into JS (though we're almost at a point where JSON can be imported) -- this is technically invalid code that bundlers work around in order to support.

The issue that you're running into is that tsx is not equipped to handle this, from what I can tell. You'll need a test runner that is capable of stripping out bundler-specific behavior, or, you should migrate to use web standards instead, using string references instead of imports, i.e.,

<img src="./MyImage.png" />