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

Could not find file .png #223

Closed
oojacoboo opened this issue Oct 15, 2016 · 12 comments
Closed

Could not find file .png #223

oojacoboo opened this issue Oct 15, 2016 · 12 comments
Labels
question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.

Comments

@oojacoboo
Copy link

oojacoboo commented Oct 15, 2016

Getting the following error when running ts-node. I haven't been able to resolve an issue surrounding asset requires with ts-node. However, it seems to be working properly with tsc and the proper definition types.

Error: Could not find file: '/valid/path/to/actual/file/image.png'. at getValidSourceFile (~/node_modules/typescript/lib/typescript.js:73826:23)

I thought it might be a typescript version issue at first, but I've confirmed that 2.1.0-dev is being used.

When enabling the fast prop for the register config, I then get hundreds of the following errors:

/valid/path/to/actual/file/image.png (38,64): Invalid character. (1127)
/valid/path/to/actual/file/image.png (38,64): Argument expression expected. (1135)
/valid/path/to/actual/file/image.png (38,64): Unterminated string literal. (1002)

Basically it seems it's trying to interpret the file as .js. I've tried defining the gif module as well like the following to no avail.

src/@types/images/index.d.ts

declare module '*.png' {
  const png: any;
  export default png;
}

The only thing I can do to get it working is override the require.extensions assignment for each extension and silence it. Unfortunately, this is a pretty big hack IMO.

I'm not really sure what else to dig into here. Any thoughts?

@blakeembrey
Copy link
Member

This can't be ts-node, as ts-node never attaches to any extensions other than .js (with allowJs), .ts and .tsx. Can you share an example?

@blakeembrey
Copy link
Member

blakeembrey commented Oct 15, 2016

The only thing I can do to get it working is override the require.extensions assignment for each extension and silence it.

Wait, are you saying that this fixes it? Because the issue is obvious then. You've got allowJs enabled and misunderstand how node.js works. Node will always fallback to treating a file as JavaScript when it can't handle the extension.

@blakeembrey blakeembrey added the question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead. label Oct 15, 2016
@oojacoboo
Copy link
Author

I disabled the allowJs prop in the tsconfig, but now I get the following error:

(function (exports, require, module, __filename, __dirname) { �PNG
                                                              ^
SyntaxError: Invalid or unexpected token

This isn't the actual files, it's the require statements. But yes, overriding the require.extensions['.png'] = function(){} will stop the error and allow everything to continue running as expected, without any issues. So, it seems fairly evident to me that TS is trying to compile the png require asset.

There is a registerExtension function within the ts-node/dist/index.js. I haven't been able to really dig into that to see what it's doing, but looked potentially related.

@blakeembrey
Copy link
Member

@oojacoboo Again, this is how node works. What you're seeing is either one runtime error or the other, and 100% expected.

@blakeembrey
Copy link
Member

Also, TypeScript is not trying to compile the asset. Node.js is trying to compile the asset. When in doubt, please run your code without TypeScript and you'll see the same result. Node.js doesn't typically enable arbitrary requires like that unless you add a "loader" (assuming you're coming from Webpack, no one else requires images except Webpack users 😛) like ts-node (which is how you can require .ts files without it blowing up).

@oojacoboo
Copy link
Author

Sorry, that's doesn't seem to be accurate or correct. It seems pretty clear based on this error that TS is trying to compile the asset and throwing the errors as a result.

~/node_modules/ts-node/src/index.ts:233
        throw new TSError(diagnosticList)
              ^
TSError: ⨯ Unable to compile TypeScript
/valid/path/to/actual/file/image.png (1,1): Invalid character. (1127)
/valid/path/to/actual/file/image.png (2,1): Invalid character. (1127)
/valid/path/to/actual/file/image.png (3,1): Invalid character. (1127)
/valid/path/to/actual/file/image.png (3,2): Invalid character. (1127)
/valid/path/to/actual/file/image.png (3,3): Invalid character. (1127)
/valid/path/to/actual/file/image.png (4,5): Invalid character. (1127)
/valid/path/to/actual/file/image.png (4,6): Invalid character. (1127)
/valid/path/to/actual/file/image.png (4,7): Invalid character. (1127)
...

@TypeStrong TypeStrong locked and limited conversation to collaborators Oct 15, 2016
@blakeembrey
Copy link
Member

blakeembrey commented Oct 15, 2016

I tried my best to explain the issue to you. I've given you multiple steps and explained how you can re-produce it in node.js only. This is not a TypeScript or ts-node issue. Like I said in #223 (comment) and #223 (comment), TypeScript is not compiling the asset. When allowJs is enable, TypeScript is used to compile JavaScript assets. By default, node.js falls back to .js compilation when it can't understand an extension. That's exactly what happened here, the result is that TypeScript is the fallback because you're using allowJs. I've released a breaking change to try and appease you so TypeScript won't touch it anymore - 380ab99 - but I just remembered breaks backward compatibility too because some people are actually using ts-node like this (E.g. for bin/ scripts).

@blakeembrey
Copy link
Member

blakeembrey commented Oct 15, 2016

Now, if you update to the latest ts-node, you won't see any more TypeScript errors. Only the node.js error you got above. Hopefully that makes it better for you, but it doesn't change anything about the issue as node.js operates how I stated above. Just because you said something in the type system, it doesn't make the runtime true.

@blakeembrey
Copy link
Member

blakeembrey commented Oct 15, 2016

I'm actually really disappointed I merged this hack so the TypeScript compiler is skipped and will likely revert it at later date. I think the previous behaviour was the expected behaviour, you just didn't understand how node.js worked and wouldn't accept the explanation. If you're using allowJs, and the behaviour of node.js is to fallback to .js for compiling, why wouldn't you expect TypeScript (with allowJs) to be compiling it then? I'm going to unlock the conversation in case someone else runs into this behaviour and finds it confusing that TypeScript isn't running when it should.

@TypeStrong TypeStrong unlocked this conversation Oct 15, 2016
@oojacoboo
Copy link
Author

oojacoboo commented Oct 15, 2016

@blakeembrey sorry for the frustration - not my intent. I do find this behavior quite frustrating. That said, I completely see what you're saying here. Thanks for explaining that in further detail. I wasn't aware of the Node.js fallback, although that makes perfect sense.

I was under the impression that TS, through the declare module construct, could assign a type to a particular require/module even being an image/scss file, etc. Granted, that may not prevent TS from trying to compile that as js - unsure there.

This was discussed here:
microsoft/TypeScript#6615

I do know I was able to compile with tsc without any errors.

@blakeembrey
Copy link
Member

blakeembrey commented Oct 16, 2016

@oojacoboo Right. The behaviour works like this - TypeScript is the compiler and node is the runtime. Technically you're seeing the same behaviour in ts-node, it's just two steps have been merged into one big step and it's harder to see the details.

The declare module works, because the .ts files importing the .png file is successfully compiled. However, then the node.js kicks in and it actually does the require of the .png file. This is where the error you're seeing comes in - at runtime. It's why I suggested trying it with plain node and also without allowJs - so you could see how node.js treats files, and you saw it tried to execute them. Compilation is definitely successful, but the runtime is failing - these things aren't intrinsically tied together in TypeScript as you can tell the compiler one thing, when the runtime is really something else. That's what happened - you told the compile declare module "*.png" (these files are handled like this) but you never implemented the runtime side for it (until you added require.extensions, which is the node.js runtime for it - the Webpack runtime for it looks like a loader, etc).

In summary, the compilation and TypeScript is 100% correct based on what you told it. However, the runtime doesn't match up with what you told the compiler is true. I've reverted the PR I did above and tried an initial write-up in the README instead - see https://github.com/TypeStrong/ts-node#how-it-works.

(Note that this sort of runtime/compiler mismatch is quite common - the most common example is adding .d.ts files).

@andyb1979
Copy link

Stumbled upon this old thread, having the same error when

ts-node somefile.ts

where somefile.ts is a simple script to pre-process some resources. This references jpg files and I'm getting the error

C:\...\node_modules\ts-node\src\index.ts:434
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
.../exampleInfo.tsx:8:26 - error TS2307: Cannot find module './your-file.jpg' or its corresponding type declarations.

8 import exampleImage from "./your-file.jpg";

Now I tried putting this at the very top of the file:

require.extensions[".jpg"] = (module, filename) => {
    console.log(`requiring jpg at ${filename}`);
    return filename;
}

I'm happy with a workaround this is just a pre-processing script. However it doesn't solve the issue? Still same error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Support requests. We tend not to answer these on Github. Nowadays I convert to Discussion instead.
Projects
None yet
Development

No branches or pull requests

3 participants