Open jordanbtucker opened 1 year ago
This is complicated and requires implementing something that could be built in, but it does prevent walking the entire import tree, so it's the most efficient.
This seems to cover your use case very well. Is there a compelling reason to make this behaviour built-in?
Can you explain your use-case a bit more? Maybe this is something that we can expect other people to need, but it is hard to tell until we know the why behind the use case.
There are two use cases here.
mod.ts
file that re-exports everything, that isn't the only way to do things. In fact, I think that's bad practice for browser modules because it forces the browser to fetch all dependencies even if they're not needed for the current task. I'd rather just give deno_emit one directory and have it transpile all files inside it.I suppose this could also apply to any project that has multiple entry points that rely on common code. For example, foo.ts
ultimately relies on common.ts
, and bar.ts
ultimately relies on common.ts
too. Both foo.ts
and bar.ts
are entry points, but since they both rely on common.ts
, common.ts
will get transpiled twice.
The behavior I'm proposing also mirrors tools like tsc
and babel
, which are transpilers, rather than webpack
and esbuild
, which are bundlers. In other words, it makes sense for deno_emit's bundle
to accept entry points and walk the tree, but it doesn't make sense to me to have transpile
walk the tree.
We also faced this issue in our project and implemented a transpileIsolated
function in our fork of deno_emit, which provides this exact functionality.
As an alternative, we also created a standalone TS transpiler based on deno_ast/deno_graph, that takes TS module code as an input and returns the transpiled JS code.
I just wanted to follow up on this to see if this is something that sounds worthwhile to implement. I also want to emphasize that this behavior would mirror other transpilers like TypeScript's tsc and Babel.js.
Chiming in again to say that I've been investigating Bun as an alternative since its Transpiler does not walk the tree.
Bun has Bun.build
for bundling, which walks the tree, and Bun.Transpiler
, which is a pure transpiler with the ability to replace and manipulate imports and exports.
What are the limitations of the third workaround you proposed? It seems like it only takes a few lines of code. Is there something I am not seeing?
I have a use case where I do not want deno_emit to walk the import tree when transpiling. When I tell it to transpile
index.ts
I only want it to give me the JS forindex.ts
, but not the JS for everythingindex.ts
imports recursively.My use case is that I don't want to have to specify which files are "roots" or "entry points" for transpiling. I want to say "transpile all TS files in this directory" so I can output them to another folder as modules rather than bundles.
Currently, I have three workarounds.
transpile
for each TS file, pick out the current file from the returned map. This has the unfortunate side-effect of performing many redundant transpilations.transpile
on the current TS file and add its results to the main map. This is more efficient, but it still walks the entire import tree.transpile
for each TS file, provide aload
function that returns{ kind: "module", specifier, content }
for imports that match the current entry and{ kind: "external", specifier }
for those that don't, which seems to exclude it from the map. This is complicated and requires implementing something that could be built in, but it does prevent walking the entire import tree, so it's the most efficient.