Closed kitsonk closed 1 year ago
I'm strongly in favor of this proposal.
It seems like renaming from deno bundle
to deno pack
to tame expectations, and refactoring from SWC's custom bundler to SystemJS for less bugs, are unrelated changes. Is that correct? Doesn't matter if they're done at the same time regardless. It's just the latter isn't a breaking commitment (should be open to revisiting when module fragments eventually materialise).
They could be delivered separately. Changing the format is disruptive and will annoy some people. Deprecating deno bundle
allows us to change expectations and not touch the current code path. Nothing changes, including existing bug fixes. It is naïve to assume there won't be bugs/issues with deno pack
so trading out one set of bug for another and then renaming at some point in the future seems futile.
Yes, module fragments will make the whole thing much easier, and deno pack
could easily move to module fragments with likely little change in behaviour. Waiting for module fragments to land, versus cleaning up the mess that we currently have feels frustrating. There are those in the core team who would want to just remove the functionality all together, where I would rather go this approach, giving clear indication that things are changing (and that deno bundle
doesn't do what a lot of people assume it is intended to do).
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.
deno bundle was great
I see this issue was closed with the deprecation of deno bundle
. This original issue mentioned also introducing deno pack
at the same time, but I don't think that was done?
For those of us who rely on deno bundle
today, what path forward would the folks at deno recommend we take?
Context
The intention of
deno bundle
is to generate a single file redistributable of code for Deno which makes it easy run a Deno workload without having to fetch dependencies, transpile TypeScript, or usedeno compile
.There has been confusion in the community that
deno bundle
is a general purpose bundler, and people are then disappointed that it only does the thing it was designed to do.When
deno bundle
was introduced, it used the built in TypeScript compiler (tsc
) to emit a set of AMD modules where a minimalist AMD loader was prepended to the file to allow the modules to be loaded. This worked effectively, until top level await became a thing and AMD stating that they wouldn't ever be able to support that as part of the standard. This lead to a migration to SystemJS and again a minimalistic loader. During that period we adopted swc to start doing the emit of TypeScript in some situations and swc created bundler.We migrated to the swc bundler and had loads of issues where we work collaboratively with swc to resolve, but still bundling with swc has been a source of several issues, often hard to chase down, and hard to fix upstream, as well as a source of breaking changes in the Rust API which has caused needs for us to refactor. Using swc to transform and emit has not been as problematic, and been easy for us to stay current with releases.
That being said, merging ES modules into a single context, but trying to determine what symbols need to be renamed and changed while not affecting runtime behaviour is a daunting task, one that is really hard. So it is arguable that such an approach to "bundling" isn't such a good idea. The advantages of AMD and SystemJS is that the preserve the module scope. Specifically SystemJS was designed to be able to move an ES module into SystemJS and have its runtime behaviour preserved.
Proposal
We would deprecate
deno bundle
in the next minor release of Deno and remove it in the release after. We would introducedeno pack
in the same minor release.deno pack
would use swc to emit SystemJS modules into a single file, prepended with a minimalistic SystemJS loader, and support both inline and external source maps. While this doesn't provide features like tree shaking, it provides a far more reliable way to do what is intended, generate a single file JavaScript file with no external dependencies.We can investigate code minification at some point in the future to help reduce the size of the emitted file.
Alternatives considered
deno compile
- there are limitations to this, mainly that you have to not only redistribute the code, but you also have to redistribute the binary as the author plus also decide all my target architectures. It also precludes downstream derivative work as well, where people would pack one or more of their libraries and the composite them in a final script.eszip
bundles, which is the format thatdeno compile
uses and what Deno Deploy uses.eszip
was never designed to be "exposed" and always for internal consumption. It is not loadable by any runtime directly, and would require a lot of work to try to integrate an external file format seemlessly. Emitting somethings that is a pure ES module/file is desirable in this situation.deno vendor
- This is potentially fine for end users but doesn't make it easy to redistribute workloads.deno vendor
solves a different set of problems.esbuild
directly into Deno. This is probably overkill for a lot of people, as not everyone uses a general purpose web bundler, plus the need to provide configuration and options.esbuild
supports Deno as a runtime, and we should just continue to encourage people who need a general purpose web bundle/build tool to useesbuild
or other solutions.