Proposal the "as-ts" language server, a deno loader in userland?

October 23, 2022 (Syndicated From dev.to)

Currently if I wanted to how can I write this in any javascript runtime and execute it? This is an astro file from the astro framework.

// example.astro
---
console.log('hello world')
---
<div>hello world</div>

Currently you can’t really run this without the framework it lives in. There’s no astro run example.astro command. Why would you need this? I’m using astro as an example, of a type of file that compiles to TypeScript, there are dozens, vue, svelte, rescript, dart, the list goes on. The same way you can’t just run this astro file, you can’t really run most of the others, some are framework specific, and some are language flavors. Even if they include a mechanism for execution there’s not a lot of interoperability. There’s also not a whole not of options when it comes to the runtimes and the package managers those runtimes use (npm for node, url imports for deno).

The way vite + npm works is fundamentally different from how deno url imports work. When a package such as @reggi/astro-stuff has an astro file in its path example.astro vite has access to this static file from the file system and can access it. In vite + deno what I want is this:

https://deno.land/x/reggi@0.0.3/astro-stuff/example.astro

This is a astro file in a url import. Deno has no clue how to handle this type of file type, or the astro syntax. You can imagine that within the astro file, there may even be more deno imports and deno would need to know how to recursively get the dependencies.

The conversation on whether or not deno should handle this or userland should is active here.

Enter the ”as-ts language server”. In deno you can specify import maps.

{
  "imports": {
    "as-ts/": "https://localhost:3021/"
  }
}

Then when you import a module you can do this:

import 'as-ts/https://deno.land/x/reggi@0.0.3/astro-stuff/example.astro'
import 'as-ts/example.astro'

The language server would be setup to take incoming local file requests or url requests fetch the file, cache and convert them into ts files. Deno would only see the ts file and if there are more imports deno would fetch those as well only seeing the ts files.

The server would be able to detect different file types

import 'as-ts/example.svelte'
import 'as-ts/example.mdx'