Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate "deno bundle" #11073

Closed
ry opened this issue Jun 21, 2021 · 82 comments
Closed

Deprecate "deno bundle" #11073

ry opened this issue Jun 21, 2021 · 82 comments
Labels
suggestion suggestions for new features (yet to be agreed) swc related to swc (bundling/transpiling)
Milestone

Comments

@ry
Copy link
Member

ry commented Jun 21, 2021

JS bundlers have a lot of complexity and we do not want to take on all that complexity in Deno. We believe this can be done effectively in "user space" - that is, it doesn't need to be built into the Deno executable. Packup is an example of a Deno program which utilizes esbuild-wasm to provide complex bundling abilities.

Ultimately we'd like to remove swc_bundler dependency completely completely from Deno.

@ry ry added the swc related to swc (bundling/transpiling) label Jun 21, 2021
@bartlomieju
Copy link
Member

If we were to do that, then deno compile couldn't work (or would require significant changes to keep the functionality working).

@MierenManz
Copy link

MierenManz commented Jun 21, 2021

I can see why it is done because there are alot of bundler's that already provide the same or more than deno bundle

Other than that, I'm fine with deprecating it and eventually removing it eventho it feels a bit weird to remove a handy utility like this with the only reason being "it can be done effectively in user space"

@LionC
Copy link

LionC commented Jun 21, 2021

I personally will always vote for making deno more of a pit of success for things that will predictably be needed by a huge percentage of apps. Keeping out parts of a toolchain that is needed for a lot of projects makes people spend time on choices that will likely not generate a lot of value, making project setup more complex and the whole space more fragmented.

At least how I see it, deno tries to solve exactly that go style by having one toolchain to do things and let people write applications instead of tooling setup.

@lucacasonato lucacasonato added the suggestion suggestions for new features (yet to be agreed) label Jun 21, 2021
@ry
Copy link
Member Author

ry commented Jun 21, 2021

If we were to do that, then deno compile couldn't work (or would require significant changes to keep the functionality working).

@bartlomieju To clarify (for other people) "deno bundle" can be deprecated and removed without effecting "deno compile", but in order to remove the swc_bundler dependency, we'd need to do some work to "deno compile" maybe to use something like the eszip json file format instead.

@caspervonb
Copy link
Contributor

JS bundlers have a lot of complexity and we do not want to take on all that complexity in Deno. We believe this can be done effectively in "user space" - that is, it doesn't need to be built into the Deno executable.

While true, that can be said for nearly all of our subcommands.

I'm against just because we're taking away a useful (albeit, needs some tic) feature from our promise of being a one stop toolchain.

@sebastienfilion
Copy link
Contributor

My first reaction was “no”. Then I thought about it a little bit and still “no”.
From where I stand, one of the big promise of Deno was the out-of-box toolchain. If we start removing every tools because there might be another option in user land, what’s the argument to not remove everything?
I think that we’re better off with a “not as great” bundler than no bundler; at least a “not so great” bundler can be fixed or improved. 🤔

@dsherret
Copy link
Member

JS bundlers have a lot of complexity and we do not want to take on all that complexity in Deno. We believe this can be done effectively in "user space" - that is, it doesn't need to be built into the Deno executable.

While true, that can be said for nearly all of our subcommands.

I'm against just because we're taking away a useful (albeit, needs some tic) feature from our promise of being a one stop toolchain.

If we start removing every tools because there might be another option in user land, what’s the argument to not remove everything?

I think the main difference here is that deno fmt & deno lint are used to help with the development of JS/TS that gets executed by deno. deno bundle however is mostly used for packaging up a single script for using it in the browser, to help target other runtimes, and perhaps as a way to distribute a library for Deno as well (less files, so less requests, though that's more of a nice to have).

On the note about complexity, I believe userland already has and will be able to provide better versioned APIs that aren't tied to the deno executable in order to solve this problem. They'll be able to provide features like code splitting, transforms, and such that would be unreasonable to add to deno bundle.

@LionC
Copy link

LionC commented Jun 21, 2021

I think the main difference here is that deno fmt & deno lint are used to help with the development of JS/TS that gets executed by deno. deno bundle however is mostly used for packaging up a single script for using it in the browser

But Deno explicitly invests work to be as browser compatible as possible, so I do not see how it does not fit - I see more potential to standardize an almost required part of the toolchain that people spend a ridiculous amount of time on right now (choosing one of 6 tools and 6273 meta frameworks that configure them) without writing actual code to solve their actual problem.

On the note about complexity, I believe userland already has and will be able to provide better versioned APIs that aren't tied to the deno executable in order to solve this problem.

Deno's philosophy is to have a one stop toolchain - that does not prevent people from writing userland alternatives but I still do not see how the option of alternatives defeats the purpose of a central standardized toolchain that will see a lot of use because it is convenient.

They'll be able to provide features like code splitting, transforms, and such that would be unreasonable to add to deno bundle.

Why are they unreasonable?

@dsherret
Copy link
Member

dsherret commented Jun 21, 2021

I'm just saying there's a difference between deno bundle and the other sub commands.

They'll be able to provide features like code splitting, transforms, and such that would be unreasonable to add to deno bundle.

Why are they unreasonable?

For example, implementing transforms would expose a huge amount of API that rapidly changes under the hood. People would be relying on what's available in the deno executable rather than a semantically versioned API. Using a versioned imported module would provide more stability and likely work no matter what version of the deno executable is used (since they're not tied together). For code splitting and more advanced bundler features it would require config or to expand the complexity of Deno.emit (in which case, once the complexity becomes too great I believe it's more appropriate to rely on a versioned imported module so that breaking changes can easily be made by the maintainers).

@wperron
Copy link
Contributor

wperron commented Jun 21, 2021

I'm mixed on this. On the one hand, bundlers are a rabbit hole that doesn't seem to ever end. deno bundle sort of opens the door to endless user requests to support this and that feature. On the other hand, I also agree that one of the selling points of Deno is that it is a one-stop-shop toolchain for the whole developer workflow, and it would be a shame to lose that feature.

We're in an interesting place right now since we're bundling swc in the runtime itself, so while esbuild and swc compiled to wasm are probably fast enough, a truly native solution is most likely faster. I think a sensible course of action would be to remove the deno bundle subcommand but keep Deno.emit in the runtime and keep working on its capabilities. The idea here would be to leave the implementation of the bundling, chunking, code splitting, whatever to userland, but provider the low-level API to access swc directly under the hood so that these tools can be written in JavaScript yet benefit from the native speed.

@mreinstein
Copy link
Contributor

This is really a fascinating discussion! There are a lot of things that come to mind:

  • bundlers are a rabbit hole of functionality because they tend to be very general purpose, providing a plugin interface so teams can use whatever tech they want in their build process (pug? sass? babel? 8million other things?)
  • I can understand the apprehension around this thing staying in core; it will inevitably balloon in size if we wanted to support all the things.
  • I really like that Deno skews torwards minimalistic opinions on several things (you don't need npm, deps.js will suffice mostly, etc.)
  • I think Deno's first bundle command attempt stays consistent with this minimalism ethos. <opinion>I'm actively trying to drop all this over-engineered stuff like babel, etc. and get back to a sane, minimal prod build pipeline</opinion>
  • from an adoption perspective, I get why Deno would want it's bundler to keep this flexibility. It enables more teams to adopt. (I'm internally debating this at work right now in fact. We have an over-engineered slow build system based on node and I want to move to Deno but we haven't stripped out enough stuff to make that viable yet.)

If Deno is able to articulate a bundling vision much the way it has for other aspects of itself, It may make sense to leave it in core.

To me that would look like taking a minimal stance and saying "sorry, we don't think you should be running 4 different html/css/js transpilers in your build system, etc." We have an ecosystem that has gorged itself on tools. Enough is enough. :)

@kitsonk
Copy link
Contributor

kitsonk commented Jun 21, 2021

I remember standing on a stage with you Ry at TSConf and stating that "Deno CLI will be the only tool you need" and now you are suggesting backing away from that.

I am not supportive, as it fundamently goes against what I thought we were trying to accomplish. Changing the infrastructure so that there are less issues with deno bundle is one thing, deprecating it is just cruel. Next thing you know, we will be requiring people to load tsc or some other type stripper themselves to use TypeScript with Deno because it makes maintaining Deno easier.

@ry
Copy link
Member Author

ry commented Jun 21, 2021

I remember standing on a stage with you Ry at TSConf and stating that "Deno CLI will be the only tool you need" and now you are suggesting backing away from that.

@kitsonk Deno CLI is still the only tool you need to do bundling, even if you remove deno bundle. Packup is a good proof of concept:

deno run -A --unstable https://deno.land/x/[email protected]/cli.ts build index.html

The alternative is that deno bundle starts competing with systems like webpack, esbuild. This is likely a deep rabbit hole of options.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 21, 2021

@kitsonk Deno CLI is still the only tool you need to do bundling, even if you remove deno bundle. Packup is a good proof of concept:

deno run -A --unstable https://deno.land/x/[email protected]/cli.ts build index.html

So are we deprecating deno lint, deno doc, deno info, deno test as well since all those can be done in user land. What about TypeScript transpiling all together? Again can be done in userland.

The alternative is that deno bundle starts competing with systems like webpack, esbuild. This is likely a deep rabbit hole of options.

As we talked earlier, we should be talking in use cases of problems we are trying to solve. deno bundle was always solving one problem in my mind, how do I take an arbitrary set of modules that run under Deno and create a single file that can be redistributed to run under Deno. It never has nor in my opinion never should be a competition for other arbitrary bundlers.

Drawing a line around what you do is one thing, deprecating core functionality because it is hard is another.

@lucacasonato
Copy link
Member

I completely agree with @kitsonk here. deno bundle is a tool for bundling program code for use in Deno. I don't think it should be deprecated or removed. It is incredibly useful and explicitly not meant as a general purpose web bundler.

In relation to Deno.emit, I could understand the argument that that could be done in userland, and that we should prevent scope creep. But I don't think we should discuss the future of Deno.emit in the same issue as discussing deno bundle. They must not be confused. They are distinctly different, even if they build on the same infrastructure.

@mreinstein
Copy link
Contributor

The alternative is that deno bundle starts competing with systems like webpack, esbuild.
This is likely a deep rabbit hole of options.

That's definitely true, but I'm thinking about it an inverted way; If my project can't be bundled with deno, it's on me to drop all the stupid crap that today's bundlers do and pare down to a reasonable bundle capability that deno already provides.

I'm trying to align my project to work with Deno's vision of a minimalistic modern js runtime. I don't know if I want deno to adopt these other unhealthy practices, even though it's very practical to do so today. If I want a bunch of bloated bundling logic including bits for commonjs plugins etc., why don't I just use node?

@ry
Copy link
Member Author

ry commented Jun 21, 2021

It is incredibly useful and explicitly not meant as a general purpose web bundler.

@lucacasonato is it incredibly useful? How are people using it?

It seem odd to me that Deno claims to be web compatible, but "deno bundle" explicitly does not produce bundles for browser.

But I don't think we should discuss the future of Deno.emit in the same issue as discussing deno bundle. They must not be confused. They are distinctly different, even if they build on the same infrastructure.

I agree - I'm conflating the problems here...

@mreinstein
Copy link
Contributor

mreinstein commented Jun 21, 2021

It seem odd to me that Deno claims to be web compatible, but "deno bundle" explicitly does not produce bundles for browser.

that's a really interesting point. Maybe it makes sense to specifically (re-?)define the purpose of deno bundle to explicitly produce bundles that run in the browser. I'm assuming that is the main use case 99% of the time (avoiding loading dozens or hundreds of modules is still not great, even when assuming http2 or even http3 capabilities.)

If we were to define that as the specific purpose, could we declare the bundle command as done, and just shrug off the infinite bundling feature requests?

@lucacasonato
Copy link
Member

How are people using it?

Bundling Deno programs for deployment to a server. The bundle is then just a single file you can plop onto a VPS or into a Docker image. Startup is greatly improved because no downloads or emits have to happen at startup.

It seem odd to me that Deno claims to be web compatible, but "deno bundle" explicitly does not produce bundles for browser.

It does not explicitly not create bundles for the browser (quite the opposite, they work fine there), it just is not it's primary focus as far as I can tell. The intension is to use deno bundle to produce bundles that will be loaded in Deno.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 21, 2021

is it incredibly useful? How are people using it?

Yes. Creating dependency-less bundles of Deno code qt a specific version, sometimes to have a single distributable with Node.js or a browser as a "library". Effectively a build step. There are other comments in this thread where people have uses which you seem to be ignoring.

It seem odd to me that Deno claims to be web compatible, but "deno bundle" explicitly does not produce bundles for browser.

Now you are changing your previous statements again. We always said that Deno would adopt web platform APIs where suitable, so that it is easier to move code between Deno and the Web, not to be headless Chrome.

@dsherret
Copy link
Member

dsherret commented Jun 21, 2021

Bundling Deno programs for deployment to a server. The bundle is then just a single file you can plop onto a VPS or into a Docker image. Startup is greatly improved because no downloads or emits have to happen at startup.

I think this is the most compelling use case though I think deno compile also covers this need.

is it incredibly useful? How are people using it?

Yes. Creating dependency-less bundles of Deno code at a specific version, sometimes to have a single distributable with Node.js or a browser as a "library". Effectively a build step. There are other comments in this thread where people have uses which you seem to be ignoring.

This is where I think there are userland tools that are better or have the potential to better meet this need. For example, something that even transpiles the Deno object to something Node compatible.

@MierenManz
Copy link

I think this is the most compelling use case though I think deno compile also covers this need.

It is alot slower to use compiling in a JavaScript tool chain. Plus you would have to install a 75 MB binary each time your project has an update.
While a bundle would likely be less than 15 mb's in filesize. So for deploying code I feel like the bundle subcommand is a really handy feature that the compile subcommand is not usable for.

@dev-nicolaos
Copy link
Contributor

dev-nicolaos commented Jun 21, 2021

@lucacasonato is it incredibly useful? How are people using it?

From the stated goals as listed in the Deno manual...

  • Ship as just a single executable (deno).
  • Be browser-compatible.
    • The subset of Deno programs which are written completely in JavaScript and do not use the global Deno namespace (or feature test for it), ought to also be able to be run in a modern web browser without change.
  • Provide built-in tooling to improve developer experience.

I'm primarily a front end web developer. I can say from personal experience I hate the high levels of complexity, configuration, language-manipulation magic involved with the node bundling ecosystem. One of the core things that attracted me to Deno was that it was going to be straightforward and follow the language implementations of the browser.

The goal stated above, (which deno bundle's current implementation totally lines up with) unlocks more or less my ideal workstream:

  1. Write code that adheres to the browser specs (optionally in TS).
    • Browser support for powerful JS features has come sooooo far in the last 10 years that a tool like Babel's ability to let me "use new features before they're implemented" really isn't that appealing. Plus TS support means that I can get some of that anyway.
  2. Run deno bundle to produce a single file (or a few files) to improve JS loading performance, while still being able to enjoy all the goodness of code organized into ES modules.

And that's it. No complex tool chains or plugins or configuration needed. Not to say there aren't use cases that are more demanding, but I don't see why they couldn't build on top of or just be separate from the basic functionality Deno provides. I don't need to import my CSS into my JS. I can use other tools purpose built to be a dev server (the snowpack mentality, non-bundled es modules are great in dev environments). I don't mind (at all) writing file extensions in my import statements. I just want to be able to take a whole bunch of TS/JS files and smash them into one. deno bundle lets me do that so easily: one command with one executable that I'll already be using for other things like formatting, linting, and running non-browsers scripts. It'd be a shame if that dream died.

P.S. Thank you to all the maintainers that work on Deno. I realize you've put in a ton of time and effort and that managing an open source project can be a thankless task where people have baseless expectations that their every demand will be met. I hope this didn't come across that way, just sharing my use case.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 21, 2021

I think this is the most compelling use case though I think deno compile also covers this need.

Partially. It doesn't make it easy to combine "lib a" and "lib b" and have something that is deployable. As other stated, just copying the binary as well is painful/useless in some instances. One can also do a deno bundle as a build step and then host that some place and then everyone with the CLI can just import myLib from "https://example.com/myLib.js". If we get type emitting working with deno bundle then people can even use the bundles strongly typed.

It isn't just about my deployments, it is about making code available to others simply, without having to worry about resolving dependencies.

@dsherret
Copy link
Member

dsherret commented Jun 22, 2021

As other stated, just copying the binary as well is painful/useless in some instances. One can also do a deno bundle as a build step and then host that some place and then everyone with the CLI can just import myLib from "https://example.com/myLib.js". If we get type emitting working with deno bundle then people can even use the bundles strongly typed.

I'm not sure we should encourage users to ship libraries with their dependencies bundled (libraries distributing minified bundles would be terrible for debugging #6900). I think that should be up to the user making the final distribution of an application (not a library) to make those decisions rather than midway through the dependency graph. Additionally, it makes it more difficult to understand what depedencies a library is pulling in... which makes it harder to catch the same dependency used multiple times (so it might be included multiple times in the final output), or duplicate dependencies with different versions, or to analyze code for auditing purposes.

It is alot slower to use compiling in a JavaScript tool chain. Plus you would have to install a 75 MB binary each time your project has an update.

Running deno compile <file-path> seems almost just as fast to me. The 78MB file is 30 MB zipped, though I can see how that's not as convenient and obviously that grows with application size... dependening on what services are used I don't think this is a deal breaker and probably in the worst case nowadays is only a few seconds slower (I'm not so familiar with how fast different services transfer data though)... many deployments would need to download deno anyway.

Additionally, a huge advantage of deno compile is the same version of deno that was used on the CI to test the code is also what's used in the deployment. You don't need to configure your server environment to use it either... so overall I think that's a lot simpler and wonder if perhaps it should be encouraged over deno bundle for that purpose once it's stable.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 22, 2021

(libraries distributing minified bundles would be terrible for debugging #6900)

Not if we fully solve #8577 (WIP PR at #10698). The same thing could be argued for deno compile as it stands now.

I think that should be up to the user making the final distribution of an application (not a library) to make those decisions rather than midway through the dependency graph. Additionally, it makes it more difficult to understand what depedencies a library is pulling in... which makes it harder to catch the same dependency used multiple times (so it might be included multiple times in the final output), or duplicate dependencies with different versions, or to analyze code for auditing purposes.

These are good potentially good practices, given specific contexts. I don't see them as being material do the deno bundles utility.

so overall I think that's a lot simpler and should probably be encouraged over deno bundle once it's stable

They solve different problems differently. deno compile is suitable for some situations, deno bundle is suitable for others. They both have their place. Especially in environments where every binary has to be "authorised" to be installed, having a single file distributable allows people to install deno but be able to have multiple workloads they can run without installing n binaries for example.

@AkifumiSato
Copy link
Contributor

I feel that too complicated bundle is a big problem not only for Deno but also for Javascript itself.
It is still stage 1, but if this proposal is adopted and the requirements for bundler change, will the implementation of deno bundle be simplified?
https://github.com/littledan/proposal-module-fragments

@iugo
Copy link
Contributor

iugo commented Jun 22, 2021

We need deno compile, and have dynamic import support (#8655).

If deno bundle is deprecated to help improve deno compile, I think it is appropriate.

@jeff-hykin
Copy link

jeff-hykin commented Jun 17, 2023


...I just upgraded, saw the deprecation warning, and dug up this thread

1. What happened to this???

> I'm retracting this idea after reading through the discussion above.


I was biting my nails in 2021 reading this thread until I saw that^. It still worried me a little bit, but I thought I was good to invest my time into Deno and have never looked back. I told my friends "Deno is amazing because it does the minimum nessary without missing a single thing; the Deno team just 'gets it' ".


2. I love bundle the way it is

(and I don't care whether or not its renamed)

I already use esbuild, packup, vite, parcel, webpack, snowpack, etc for my web projects, who doesn't???

The whole point, literally 100% of the reasons people use deno bundle, is because ... it "just works"

  • its not that fast
  • there's no token mapping
  • no uglyifying
  • no tree shaking
  • no polyfills
  • no experimental T39 stage 3 proposal support
  • no importing CSS/SASS/LESS/png/jpeg/HTML
  • no code splitting
  • not inter-compatible with nodejs
  • nothing browser-specific is guarenteed to bundle correctly
  • and (most importanly) there's no

    • install step
    • having-to-tell-the-bundler-what-ECMA-Script-version-to-target / what-version-of-TypeScript-to-expect / whether-or-not-JSX-is-enabled
    • having-to-update-my-3rd-party-bundler-dependency-after-updating-deno-because-of-ECMA-script-version-changes

Bundle might as well be called deno halfway-compile as that's all it needs to do (no additional features/overhead for the Deno Team). I am totally against feature creep, to the point of actively opposing features like polyfills, because it would be against the minimalist ideals that Deno was founded/marketed on. But dropping bundle support? I would sooner agree with dropping typescript support.

@dgreensp
Copy link

dgreensp commented Jun 23, 2023

@jeff-hykin I agree, I was using Deno.emit as a dirt-simple alternative to webpack, and it made me super happy. I felt like I was reclaiming some of the sanity lost by messing around with webpack config files over the years at various jobs. Then Deno.emit went away, but I could still use deno bundle. Now that is going away. I think I'd be a fool to rely on deno_emit at this point, which was nonfunctional when released and probably will always be in some form of neglect. There is so much churn in Deno. Features being added and removed and changed around.

I am going to see if I can find some solution in a similar spirit so I can serve some of my codebase to the client without spending hours reading documentation and StackOverflow posts about some whole other thing like esbuild. I'm tired of bundlers, tired of NPM... that's why I liked Deno.

@5310
Copy link

5310 commented Jun 23, 2023

It doesn't make up the loss of simplicity Deno Emit and Bundle offered, but lately I've been using Lume for purely front-end work (as in, no static generation), and found its ESbuild plugin to be the closest thing to the no-fuss NPM-less tooling dream that we lost.

I just write my HTML as Markdown files (no changes to the content), CSS as is, and all code as Typescript with standard ESM modules, and have even used packages like Lit from NPM. And "it just works".

@bartlomieju
Copy link
Member

Thanks for the feedback, we hear you and are looking into potential solutions to the problem.

@jeff-hykin
Copy link

@ others. I was sad at the lack of reasoning/discussion (seems to me like deprecation came out of the blue), I came across the location of the follow-up discussion #15463
(This issue, and that one should probably be merged, especially since this thread is the one that shows up first on search engines)

@jeff-hykin
Copy link

jeff-hykin commented Jul 1, 2023

@bartlomieju, the "were looking into it" could come across as apathetic without (and kind of even with) that^ context. Kinda like my bank's automated "your call is very important to us, please stay on the line".

I know from the discord and office hours that you (@bartlomieju) and the team seem like great guys. I want to be on your side and support/defend the teams reasoning. "we will ensure Deno is a platform others can build on with trust" was in the heart of the announcement of the Deno Company, and I still believe you guys want that.

Which is why I'm really confused when features are removed without a full dicussion, a #1 to erode trust. I mean how can we understand/support the rationale when no reasoning provided (e.g. why is there no deno pack)?



The points I think are critical to address are:

  1. Proposal: deprecate deno bundle, add deno pack #15463, which was closed, talked about adding deno pack so what happened to deno pack? "We would deprecate deno bundle in the next minor release of Deno and remove it in the release after. We would introduce deno pack in the same minor release." It seems like the team went a different route without talking about it.
  2. In that issue, it sounded like the Deno team has long-term plans to support Deno pack, can you confirm/reject/discuss that?
  3. My understanding is that deno compile requires bundling, so how is the team going to support compiling if the deno team can't support bundling? Is deno compile planned on also being removed?


Last, I think there's an incomplete discussion around SWC, module fragments, and scope creep from the linked issue. So I'll try to continue from the parts I believe are dangling:
  1. Maybe there is something I'm missing (and I'll talk about scope creep in a second), but as someone who does parsing (checkout deno-tree-sitter ✨) I don't understand why the team used SWC instead of just making there own correct-but-not-optimal bundler. And to put my money where my mouth is, I wrote my own JS bundler in a few hours using Deno. It only handles ES imports, and doesn't handle typescript, but aside from new ES features, I don't see any reason why it would need any maintainance. TLDR; if SWC is problematic, why not ditch it instead of ditching bundling altogether.
  2. On the note of the SWC bundler, it makes me even more confused when I hear the team say "users can just use esbuild". If esbuild reliable-enough/good-enough/clean-enough for users, then how is it not good enough for the Deno team to use internally instead of the swc bundler? A built-in bundler can do an objectively better job by shipping with default-build options that match the binary (e.g. ES Script versions, Typescript versions) and allow bundling to "just work" What makes esbuild not reliable/good for deno to use internally, but yet good enough for users to use?
  3. I actively oppose Deno scope creep, so when that issue about deno bundle -> deno pack mentions adding code minification, SystemJS modules (aka node module support), source maps, etc and the "alternative" is total removal of Deno bundle, I can't see anything other than scope creep. Why are these features being considered? Why is the alternative deprecating bundle with no replacement command? We just want a bundler that works for Deno code.
  4. Finally, to wrap up the scope-creep discussion, and specifically address NodeJS compatibility. I really sincerely want to ask the team to take a moment and reflect on the original goal/announcement of Deno. 'NodeJS has unfixable problems -- which is why we made Deno.' Circular dependencies, peer dependencies, unversioned dependencies, install scripts, node-gyp, etc, I could not agree more that NodeJS is an unfixable mess. I'm fine with trying to support Node, especially the core API, but its a "sometimes it works, which is nice" feature its not a core tennant of Deno's feature set. Deno was/is a fresh start. That was -- and I hope still is -- the selling point of Deno. I use Deno modules BECAUSE they don't carry over all the baggage from NodeJS. Deno bundle does not need to support Node modules (ever). If it does, or does in some capacity, great. But if node compatibility is the justification for deprecating deno bundle, then I think the team has lost the original vision in persuit of trying to garner a larger userbase. (Again I must speculate because of the lack of transparency)

@dsherret
Copy link
Member

dsherret commented Jul 1, 2023

Which is why I'm really confused when features are removed without a full dicussion, a #1 to erode trust. I mean how can we understand/support the rationale when no reasoning provided (e.g. why is there no deno pack)?

The feature wasn't really removed. It was moved to deno_emit. You can see usage instructions for bundling from a JS api here: https://github.com/denoland/deno_emit/blob/main/js/README.md#bundle

It seems like the team went a different route without talking about it.

You can read about the deprecation here: https://deno.com/blog/v1.31#deno-bundle-deprecation

In that issue, it sounded like the Deno team has long-term plans to support Deno pack, can you confirm/reject/discuss that?

That issue is closed. There are no long term plans to support deno pack at the moment.

My understanding is that deno compile requires bundling, so how is the team going to support compiling if the deno team can't support bundling? Is deno compile planned on also being removed?

It doesn't require bundling. It uses eszip internally: https://github.com/denoland/eszip

On the note of the SWC bundler, it makes me even more confused when I hear the team say "users can just use esbuild". If esbuild reliable-enough/good-enough/clean-enough for users, then how is it not good enough for the Deno team to use internally instead of the swc bundler?

This would introduce yet another JS/TS parser in Deno and create a lot of complexity. For one, esbuild is also written in Go and not Rust.

Also, esbuild has a versioned API with a lot of complexity. Something built into the runtime needs stability going forward. Using something with a JS api is preferable to support complex use cases IMO.

Btw, esbuild is used in fresh: https://github.com/denoland/fresh

Why is the alternative deprecating bundle with no replacement command?

Again, see deno_emit: https://github.com/denoland/deno_emit/blob/main/js/README.md#bundle

@jeff-hykin
Copy link

jeff-hykin commented Jul 12, 2023

@dsherret Thanks for clarifying major points like Deno compile (and the eszip link), and no planned support for deno pack. What you said about esbuild totally makes sense, and is exactly the kind of conversation I would hope to have.

With that in mind, I still think it is critical to address "what happened to Deno pack". And to clarify what I'm asking about is: I wouldn't close an issue, treat the issue as a "wontfix", and not leave a comment. Wontfix is necessary part of software, I don't have a problem with that. But if I am going to treat something as wontfix, I explain my reasoning before closing it, and make it clear that I'm closing-without-fixing (not just closing and waiting till the next release and then let people figure out it was wontfix). If you addressed this and I missed it, I apologize for that. But it was the first thing on my critical-to-address list and to me it seems like it was missed. And just to be super clear, my question is; why was it closed as wontfix without a comment saying/explaining that?

Going back to the full discussion.

1. Why I consider it removal

The feature wasn't really removed

@dsherret I'm glad you bring this up, as it connects with the lack of detail in the 1.31 announcement.

Defintions of "removed" aside, normally I wouldn't be concerned about a feature going from 1st party support (e.g. deno binary/builtins) to 2nd party support (e.g. deno std modules). Why? Because I have confidence in the deno team that 2nd party modules are well maintained/reviewed, and that old versions of std modules work with new versions of deno without fail. If anything I generally believe "if it could moved from core to std, it probably should be moved from core to std".

So, for Deno bundle, why would I be defensive about moving it out of the binary? Well I'm concerned precisely because of the 1.31 announcement. My TLDR of the announcement is "maintaining the bundler is hard, and we don't think that feature is important, so we're dumping what we have at the moment into a 3rd party module". I say 3rd party because it's not part of the std library (which I believe was done because, again, the whole point is to not waste effort maintaining it).

2. The 1.31 Announcement

If the announcement said "its deprecated because we feel like it" I wouldn't be able to criticize that from a logic/soundess standpoint. I might be sad/annoyed, but the team would've been fully transparent and their reasoning would be sound.

However, if the 1.31 announcement is the justification, then I think clarification is needed because the reasoning (or implied reasoning) doesn't make sense.

  1. The announcement seems to avoid saying "because", or "that's why". There is a "therefore", but for the most part it says thing like "bundle was deprecated", followed by "bundling is hard" without connecting them.

  2. I'm willing to assume the best, maybe this was because of a language barrier. So I will connect the dots, in good faith, and believe part 1 of the announcement wants us to assume "We deprecated bundle because users got confused about the name" and "We deprecated bundle because we don't want to drain our resources building a full web bundler into deno". Neither of these seem like sound reasoning in light of this thread, because the obvious solution is for bundle to be renamed to "pack" and simply not support web bundling. I haven't heard any reason in any thread or announcement suggesting that the obvious solution was a bad idea. And I think someone on the team should say something like "We think excluding is better than renaming because... x,y,z"

  3. In good faith, I'll continue to interpret the second section as "We deprecated bundle because there are already good userland solutions". I've discussed why built-in has exclusive benefits so I'll consider this addressed for now. The more interesting assumed-justification is "We deprecated bundle because, if code works with deno run, we want it to work with every other command, including deno bundle (either do it right or don't do it at all). Because we've decided Node compat is mission-critical, and bundling node modules is really hard, we won't be able to maintainably and reliably make bundle work with node compat. For that reason we're deprecating the bundle command (which doesn't support node modules) and moving it into a 3rd party repo." I feel like I'm having to put a lot of words in the Deno team's mouth for that statement; I don't feel confident that it's accurate. Which is why I'm still following up and looking for confirmation. If my assumption is accurate, then I don't know why the team didn't just lead with that reason and the follow with "There were also smaller problems such as [web bundling confusion, existing maintaince problems] that added to this decision."

@mreinstein
Copy link
Contributor

I'm willing to assume the best

Probably wise given this is a free and open source project. Deno ain't exactly Oracle here. ;)

IMO there's clear indication from the deno team this won't be supported; it's in the first comment that Ryan started this issue with.

I would rather not take up any more time from the deno team on this and let them focus on building actual deno capabilities and fixing bugs rather than tending to these long winded and legalistic meta conversations.

@dgreensp
Copy link

@jeff-hykin I just want to say, one Deno user/developer to another, that everything you wrote makes a lot of sense to me. I was making enthusiastic use of Deno.emit and then "deno bundle," and I followed all the release notes, and read the issue threads, and I saw the writing on the wall (that this functionality was essentially being abandoned), but I don't feel like there was direct and understandable communication about this. Deno_emit has been receiving some commits, but at release it was non-functional and untested. Overall it doesn't seem like something to rely on.

I actually did think--somewhere in my head, until the latest messages here, or until very recently--that "deno compile" used this functionality, so it was in Deno somewhere, and that "deno pack" was coming at some point.

The funny thing to me is that "deno bundle" is actually a fantastic replacement for a bundler, if you are just trying to bundle code. Just as Deno's way of doing modules replaces NPM without doing all the things NPM can do. I imagine Deno's early adopters include a lot of people who greatly dislike the complexity and fragility of NPM. So to me, embracing NPM is connected to this shift because it takes a ton of resources and also represents a philosophical shift towards being more entangled with the complexity of the rest of the JS ecosystem in order to be more popular.

At the end of the day, though, the Deno team gets to choose their focus and scope. The total scope is very large, let's be clear. It's not like Deno is trying to keep a narrow focus and this wouldn't fit with that. It's just something to shave off rather than maintain, I think, because you have to cut scope somewhere.

@jeff-hykin
Copy link

jeff-hykin commented Jul 13, 2023

@mreinstein

I would rather not take up any more time from the deno team on this and let them focus on building actual deno capabilities and fixing bugs rather than tending to these long winded and legalistic meta conversations.

Actually that's why I waited a few days to respond. I don't want to make a mountain out of a mole hill, and it's easy to question myself with "what do I hope to accomplish by responding?"

The answer is; I hope to learn if the team made an honest oversight or is just surface-level responding. Just like someone eating my lunch without asking, bundle being removed is a small negligible event. The problem is if I ask someone why they ate my lunch without asking, and they just avoid my question and pretend nothing is wrong. Then I stop hanging out with that person. I invest a lot of time into writing Deno libraries because of the original philosophy, community, and respect.

@ry
Copy link
Member Author

ry commented Jul 13, 2023

We're deprecating deno bundle because it's unmaintained, a source of technical debt, not extensible, solving only a narrow use-case. The narrow use case being, pack up my Deno program into a single file. It's difficult to define the scope of this command - because in bundling in general is a pretty complex process.

I hear the feedback that some people liked it - but it doesn't seem to outweigh the problems.

There are other solutions - esbuild, deno_emit, eszip.

@jeff-hykin
Copy link

jeff-hykin commented Jul 13, 2023

So (final question/input from me) deprecating it was not primarily because of nodeJS/commonJS support? @ry

@ry
Copy link
Member Author

ry commented Jul 13, 2023

Support of npm has further complicated the situation. It's not possible for a relatively simple deno bundle implementation with npm packages, like we've been able to get away with for https imports.

@dsherret
Copy link
Member

So deprecating it was not primarily because of nodeJS/commonJS support?

Just some added context that this issue was created over a year before npm support landed in Deno and about half a year before discussions about npm support became serious.

@jeff-hykin
Copy link

jeff-hykin commented Jul 13, 2023

Thanks @ry it means a lot to me to have you answer directly.

Just some added context that this issue was created over a year before npm support landed in Deno and about half a year before discussions about npm support became serious.

Yeah don't worry I was in the thread back then too 😁 I just didn't know if node was the core reason this was re-evaulated with a different conclusion.

Thanks to the input here though, I feel confident I can paint a full picture now and lay this issue to rest for good. Even better I think it can give people like you @dgreensp and me a good deal of comfort.

@jeff-hykin
Copy link

jeff-hykin commented Jul 13, 2023

R.I.P. deno bundle

To anyone arriving here from Google, this should summarize the whole thread.

Note: I'm not a maintainer, I just liked deno bundle a lot and didn't understand why support was being dropped

  1. Why was it deprecated: If the maintainers could have, they would go back in time and never advertise bundling as a feature. What seemed straightforward at the start, regular http imports, continued and still continues to evolve new edgecases. Bundle is not used for Deno compile, and because of CSS/PNG/etc it is also not used for web bundling, making the usecase fairly niche; basically offline non-compiled CLI apps. New Typescript features and EcmaScript features like top-level await added a lot of maintaince work. All of that might have been managable. However, NodeJS compatibility played a role by forcing either an even-more narrow usecase (can't bundle node-dependent offline CLI apps) or an extreme difficulty increase (trying to fully bundle node modules; which is provably impossible to perfectly automate). The final straw was likely additonal complexity like this ongoing TC39 proposal with a new import keyword that partially-imports WASM modules.
  2. Transparency issue: I'm going to guess that the lack of transparency from the Deno team stemmed from having a gut feeling that the bundler was bad/costly without having a concrete way to demonstrate it. This issue was first closed because of community feedback and a lack of concrete reasons, but then effectively reopened after those nebulous reasons accumulated again over time. There was some other vagueness, but it was addressed after requests to clarify.
  3. Deno Philosophy Concerns: There were, and possibly still are, concerns that deprecating this indicates a major change in the Deno all-in-one it-just-works philosophy. I don't think this is the case. I think Ryan and the rest of the team were somewhat avoiding commenting on philosophy because of uncertainty. Which to me is a good sign that the core philosophy isn't changing. E.g. NodeJS was not confirmed as mission-critical in the way I was starting to suspect it might be, but it also wasn't denied as an important feature. On one hand there's death-from-lack-of-adoption and on the other is becoming the evil we as Deno devs seek to destroy. Ryan probably thinks about that trade off more than any of us. I'll miss the bundler, but I'm relieved to say; I think Deno is still in good hands.
  4. What now: If you want to help, I've made deno_bundle CLI tool which uses esbuild along with the deno plugin (made by the Deno team). Its designed to replicate the just-works deno build behavior. The builtin deno bundle functionality will be preserved but pseudo-archived by being moved to deno_emit.

@nickguimond
Copy link

I'm not mad, I'm just dissappointed

@goddtriffin
Copy link

For those looking for a copy+paste solution for bundling for the browser, here is what I've been using:

1. Create a new file: bundle.ts

Make sure to update entryPoints and outdir.

import * as esbuild from "https://deno.land/x/[email protected]/mod.js";
import { denoPlugins } from "jsr:@luca/[email protected]";

esbuild.build({
  plugins: [...denoPlugins()],
  entryPoints: ["<input>/<dir>/script.ts"],
  outdir: "<output>/<dir>/",
  bundle: true,
  platform: "browser",
  format: "esm",
  target: "esnext",
  minify: true,
  sourcemap: true,
  treeShaking: true,
});
await esbuild.stop();

2. Run it!

deno run --allow-read --allow-write --allow-env --allow-net --allow-run bundle.ts

You can create a deno task to make running this easier. Add this to your deno.jsonc:

{
  "tasks": {
    "bundle": "deno run --allow-read --allow-write --allow-env --allow-net --allow-run bundle.ts"
  }
}

Helpful resources:


For more context, check out my post on this topic: https://www.toddgriffin.me/blog/how-to-bundle-deno-typescript-for-the-browser

@scriptmaster
Copy link

You could try:

sergeant (The microfrontends bundler for deno) https://github.com/scriptmaster/sergeant

-or-

import * as esbuild from "https://deno.land/x/[email protected]/mod.js";
import { denoPlugins } from "https://deno.land/x/[email protected]/mod.ts";

esbuild.build({
  plugins: [...denoPlugins()],
  entryPoints: ["./main.ts"],
  outdir: "../dist/",
  bundle: true,
  platform: "browser",
  format: "esm",
  target: "esnext",
  minify: true,
  sourcemap: true,
  treeShaking: true,
});

await esbuild.stop();

@AmbroiseS
Copy link

My one line for replacing deno bundle and transpiling typescript. (Not for web).

esbuild --bundle install.ts --outfile=install-os.js --target=deno1 --platform=neutral

Not sure if --platform arg is necessary.

@GerbenRampaart
Copy link

Can anyone explain to me, (no provocation intended), why Bun is doubling down on a new bundler which seems to improve every release, and Deno is deprecating it?

@bartlomieju
Copy link
Member

bartlomieju commented Sep 5, 2024

Can anyone explain to me, (no provocation intended), why Bun is doubling down on a new bundler which seems to improve every release, and Deno is deprecating it?

@GerbenRampaart the deno bundle command had a huge mismatch in what users expected (a general purpose bundler with a bunch of setting knobs) with what it really was (a dedicated tool to create a single file out of a Deno specific project). It was conceived in the early days of Deno, when Node.js compatibility was very nascent. Additionally the underlying implementation (swc_bundler) hasn't been improving a lot. We decided it's best to deprecate and remove it for Deno 2.

We do still have our eyes on providing an out-of-the-box general purpose bundler, and we did some exploration on using https://rolldown.rs/ or https://rspack.dev/, but it's not something that will happen for Deno 2.0 release. Maybe in Deno 2.1 or later.

@jflatow
Copy link
Contributor

jflatow commented Nov 15, 2024

I found deno bundle extremely useful exactly how it behaved and was indeed relying on it. In case this helps anyone else, and as deno emit does not expose a CLI by default, I created a simple drop-in replacement: https://github.com/jflatow/bundy

@jeff-hykin
Copy link

jeff-hykin commented Nov 15, 2024

It kinda got lost in the conversation @jflatow , but I've been maintaining deno_bundle as a drop-in replacement for ~1.5 years now. I'd love you have your help! And hopefully it'll save you some effort too. I just recently added --watch support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
suggestion suggestions for new features (yet to be agreed) swc related to swc (bundling/transpiling)
Projects
None yet
Development

No branches or pull requests