fromdeno / deno2node

Compile your Deno project to run on Node.js.
MIT License
117 stars 3 forks source link

Be a `tsc`. #20

Closed KnorpelSenf closed 2 years ago

KnorpelSenf commented 2 years ago

I would love deno2node to behave exactly like a tsc that is Deno-aware. I see this as the main advantage over dnt—instead of having some magic black box that somehow tries to do everything, it would be awesome to do just one thing, and do it really well: compiling Deno code for Node.

That way, we could use our existing Node workflows that are based around tsc, and use deno2node as a drop-in replacement once we move to Deno. As a result, all existing infra and Node tooling will keep on working. I cannot imagine how dnt is going to solve https://github.com/denoland/dnt/issues/60 in the foreseeable future, but deno2node already integrates seamlessly with Node workflows.

At the same time, it enables us to write Deno code most of the time. We can use all their tooling, hosting, docs, infra, and all other advantages. On the Node side, in contrast to dnt, we still remain in control of our own configs and setup. In a way, deno2node brings the best of both worlds, because we can target both platforms natively, and use the familiar tooling of both ecosystems.

Some points that would be amazing to see are the following.

KnorpelSenf commented 2 years ago

Related discussion started at https://t.me/fromdeno/13870

wojpawlik commented 2 years ago

I like the idea of deno2node --init, I'll draft PR src/init.ts soon-ish. I'm thinking it could generate

.gitignore
tsconfig.json
package.json
src/
  shim.node.ts

I don't see a point in mimicking tsc further.

KnorpelSenf commented 2 years ago

The point would be to make Deno code a first-class TypeScript complication source. If your project compiles, you can make it compatible with Deno and it'll still compile.

wojpawlik commented 2 years ago

One could re-use TypeScript's argv parser...

KnorpelSenf commented 2 years ago

That would indeed be pretty cool! I find feature parity with tsc a pretty compelling argument. It's amazing for complex projects that may rely on tsc a lot. It's also amazing for beginners because they're familiar with the interface of tsc so they can trust that the learning curve is flat.

KnorpelSenf commented 2 years ago

Rejected in https://github.com/fromdeno/deno2node/pull/21#issuecomment-1003060686.

wojpawlik commented 2 years ago

There's still an abundance of good ideas here:

KnorpelSenf commented 2 years ago

I understood by https://github.com/fromdeno/deno2node/pull/21#issuecomment-1003059239 that deno2node --init is not going to happen. I figured that supporting other arguments of tsc does not make sense if not even deno2node --init will become a reality. I seem to have misunderstood you at some point. Where would you like to take this project?

wojpawlik commented 2 years ago

Scaffolding is preferable to implicit config file, but I'm not sure what's the best way to implement it. npx download-cli --extract --out=. https://github.com/fromdeno/template/archive/refs/heads/main.tar.gz downloads the template, but directory name is ./template-main/ and cannot be changed.

wojpawlik commented 2 years ago

PowerShell has curl.exe, tar.exe and unzip.exe

wojpawlik commented 2 years ago

async-dl-github-repo can programmicaly download a directory from GitHub from Node, but not Deno

wojpawlik commented 2 years ago

git clone preserves .git, which is undesirable for scaffolding

wojpawlik commented 2 years ago

npm lacks a subcommand to download and extract a tarball, even tho it's literally its job

KnorpelSenf commented 2 years ago

I think I understand now why literally every other tool I've seen ships a few static files when performing scaffolding.

I suggest to:

  1. Ship a JSON config file that contains an array of file paths.
  2. Ship a directory that contains the files at the given paths.
  3. Let --init simply traverse the list of paths and copy over the files.
  4. Optionally, keep the files in a submodule for git such that you can maintain them in a dedicated repo.
  5. Optionally, instead of 4., add a version script that updates the shipped package.json file to bump the used deno2node version. (Note that you cannot use postversion because then then changes will not be included in the git commit.)
wojpawlik commented 2 years ago

Way too complex, I'm not interested in rolling my own scaffolding tool from scratch...

wojpawlik commented 2 years ago

...At least until deno2node is a drop-in tsc replacement

KnorpelSenf commented 2 years ago

Maybe we can think differently about handling the complexity. All of git, tsc, npm handle --init the same way, they generate all necessary data from code. None of them actually ship any files to be created.

What is the minimal setup that would work for d2n? For example, I can use a TS project by simply creating src.ts and putting some TS inside and then running tsc. It would be cool if the same was possible with d2n.

At the same time, tsc --init generates a single config file from the options it supports. Hence, when it starts supporting new options, tsc --init will automatically include them next time. Is there a thinkable setup where d2n also only needs a single config file? How would this look?

wojpawlik commented 2 years ago

Everything in https://github.com/fromdeno/template is useful to some degree:

KnorpelSenf commented 2 years ago
  • .editorconfig -- useful for text editors

Useful, not required. Drop.

  • .github/workflows/ci.yml -- useful for GitHub

Useful only on GitHub. Drop.

  • .gitignore -- required

Useful only in git. Drop, but print message if in git which folders to ignore.

  • .vscode/extensions.json -- useful for VSCode
  • .vscode/settings.json -- required by VSCode

Useful only with this editor. Drop.

  • package.json -- required by (p)npm

Generate. Values could be chosen dynamically. Do not store a static file.

  • src/mod.ts -- useful

No other tool defines entry points. Unexpected. Drop. Optionally, print link to getting started guide.

  • src/shim.node.ts -- required by tsconfig.json

Change config. Not all projects need this. (Example: grammY runner.) Drop.

  • tsconfig.json -- required by deno2node

Tap into tsc to generate dynamically. Then, add empty d2n config for illustration purposes.

wojpawlik commented 2 years ago
  • .gitignore -- required

Useful only in git. Drop, but print message if in git which folders to ignore.

Weird middle ground. At that point, might as well create it.

  • tsconfig.json -- required by deno2node

Tap into tsc to generate dynamically. Then, add empty d2n config for illustration purposes.

21 already modifies the deno2node's tsconfig.json so that it can be "copied" to the new project. Feel free to resurrect the PR.

wojpawlik commented 2 years ago

npx deno2node --init would be sweet

wojpawlik commented 2 years ago

Actually, I'll resurrect it today

KnorpelSenf commented 2 years ago

Reopening to keep track of the other ideas mentioned here

wojpawlik commented 2 years ago

Summarizing:

  1. I'm happy to merge PRs adding useful CLI flags. We already added --noEmit and --init.
  2. I'd be happy to see a (possibly breaking) PR switching to TypeScript's CLI parser, even tho I'm starting to like x/cliffy: image