Deno: shebang script fails with "Unknown media type for <filename>..." for extension-less filename

Created on 27 Nov 2018  路  5Comments  路  Source: denoland/deno

I tried setting up a deno script with a shebang but it fails with the following error:

Error: Unknown media type for: "./deno-shebang-test" from "/private/var/folders/yv/j40dl1051zx47t3r9cwnf3580000gn/T/tmp.jmu81WscJR/".
    at assert (deno/js/util.ts:25:11)
    at DenoCompiler.resolveModule (deno/js/compiler.ts:581:5)
    at DenoCompiler.run (deno/js/compiler.ts:617:33)
    at denoMain (deno/js/main.ts:99:14)
    at deno_main.js:1:1

Let me know if I'm missing something.

Here's more info for context:

$ deno -v
deno: 0.2.0
v8: 7.1.302.4
typescript: 3.1.6
$ ls -l
-rwxr-xr-x 1 piet staff   48 Nov 27 16:30 deno-shebang-test
$ cat deno-shebang-test
#!/usr/bin/env deno

console.log('Hello world')

Most helpful comment

There was some discussion about it in #929. While it seems that the reasonable solution to handle extensionless filenames would be to assume TypeScript by default but then the question is that since deno can run JavaScript then how could we override the default to tell the interpretter that a particular file is actually in JavaScript. It quickly gets tricky when you consider anything more than the simplest case. I think that every executable script with a shebang shouldn't break when it's renamed or symlinked, at least I don't know of any other interpretter that interprets the executable script differently when renamed, and I think that it's reasonable to assume that no one will want to install command-line tools with extensions in their name, so this seems quite important in the long run.

All 5 comments

Adding a .ts extension makes it work fine.

This is a bit tricky as Deno internals rely on file extension to resolve MediaType.

@ry do you think that changing map_file_extension in deno_dir.rs to return TypeScript as default for extension-less files is a bad idea?

Other idea is to change this bit (in deno_dir.rs):

out.source_code = filter_shebang(out.source_code);

to something like that:

if has_shebang(out.source_code) {
    out.source_code = filter_shebang(out.source_code);
    if out.media_type == MediaType::Unkown {
       out.media_type = MediaType::TypeScript
    }
}

EDIT:
I tried that I get this:

DEBUG JS - compiler.setFileName { moduleSpecifier: "$asset$/lib.esnext.intl.d.ts", containingFile: "" }
DEBUG JS - getScriptVersion() $asset$/lib.esnext.intl.d.ts
DEBUG JS - getScriptKind() $asset$/lib.esnext.intl.d.ts
DEBUG JS - compiler.getGeneratedContents deno_main.js
Error: Could not find file: '/Users/biwanczuk/dev/deno/a'.
    at getValidSourceFile (<anonymous>)
    at Object.getEmitOutput (<anonymous>)
    at Compiler.compile (deno/js/compiler.ts:325:30)
    at Compiler.getOutput (deno/js/compiler.ts:440:17)
    at Runner._gatherDependencies (deno/js/runner.ts:91:37)
    at Runner.run (deno/js/runner.ts:179:12)
    at denoMain (deno/js/main.ts:100:12)
    at deno_main.js:1:1

Does TypeScript language service not like extension-less files?

There was some discussion about it in #929. While it seems that the reasonable solution to handle extensionless filenames would be to assume TypeScript by default but then the question is that since deno can run JavaScript then how could we override the default to tell the interpretter that a particular file is actually in JavaScript. It quickly gets tricky when you consider anything more than the simplest case. I think that every executable script with a shebang shouldn't break when it's renamed or symlinked, at least I don't know of any other interpretter that interprets the executable script differently when renamed, and I think that it's reasonable to assume that no one will want to install command-line tools with extensions in their name, so this seems quite important in the long run.

Yeah, I specifically mentioned that it wouldn't work in the PR.

I don't think we should have Rust lie about the file extension. We are in the processes of splitting the compiler into a seperate isolate, and once that it done, I think the best thing to do is have the compiler tell TypeScript that files that have the media type of TypeScript but don't end in .ts actually do end in .ts. Right now it would be a little complex because the compiler is keeping a lot more state and is indexing things based on the file name and so it is harder for it to "lie" to TypeScript.

This issue no longer occurs on v0.2.11.

CC @ry

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sh7dm picture sh7dm  路  3Comments

justjavac picture justjavac  路  3Comments

doutchnugget picture doutchnugget  路  3Comments

davidbarratt picture davidbarratt  路  3Comments

benjamingr picture benjamingr  路  3Comments