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')
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
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.