chrisguttandin / automation-events

A module which provides an implementation of an automation event list.
MIT License
12 stars 1 forks source link

Bundle into single file dist #49

Open dy opened 2 years ago

dy commented 2 years ago

Follow-up from https://github.com/audiojs/web-audio-api/pull/86.

Right now build is not bundled: https://npmfs.com/package/automation-events/4.0.14/build/es2019/module.js In fact it can be problematic to use without tooling (ESM requires .js on importing files).

Multiple files also affect performance in minor way.

I'd propose bundling into a single dist with eg. rollup, to make it look more like that: https://cdn.skypack.dev/-/automation-events@v4.0.14-SxsVX5kjhG9wh5gACFPZ/dist=es2019,mode=imports/optimized/automation-events.js

That will make it easier for consumer (either browser or node), smaller and faster on load.

Ideally not even shipping full source via npm to reduce install time as well, and just minimally ship single dist file. That would allow to drop @babel/runtime and tslib direct deps. Just look how much they install - nothing of that is used, just waste of traffic = user time.

dy commented 2 years ago

@chrisguttandin if you would like I can handle it.

chrisguttandin commented 2 years ago

I definitely agree that I need to update the way I publish packages. I do for example want to update from es2019 to es2022 code.

To make my life easier I tend to use the exact same configuration for all my repos. Otherwise it gets just too time consuming to maintain a different solution for each of them. That's why I try to not mess things up for anyone as best as I can when I make any changes. :-)

I'm not sure if I understand the advantage of bundling all dependencies. Isn't it a huge plus to get dependencies deduped at build time to make sure the browser bundle contains only one instance of each dependency? I understand that it makes things easier for those who don't use bundlers but if I understand it correctly it would make things worse for those who do.

Is there a way to ship a bundle and an unbundled version simultaneously?

dy commented 2 years ago

Is there a way to ship a bundle and an unbundled version simultaneously?

Yes, many packages do that (eg. htm) − shipping source along with dist.

Not shipping dist forces consumers to use bundler and/or import-maps, which is a hassle. Also makes DX less smooth: slower install, slower import. Dist expands consumers spectrum also.

Ideally I'm for the boons you mention (dedupe, saves time), but practically deps are rarely interesting. They make sense when they're meaningful, not just code structuring.

Besides bundlers tend to get old (eg. bundlephobia is having issues with old webpack for almost a year) and subscribe to lifetime maintenance, rather than save time.

chrisguttandin commented 2 years ago

One thing that I - as someone who always uses a bundler - don't know is how people use a package published on npm directly in the browser. Do you manually search for a bundle with inlined dependencies within the downloaded files and then import it from there?

import { something } from 'node_modules/package-name/anywhere/inside/the/package.js';

Or is there a more or less standardized way where such a bundle could be found? Should it have a certain name? What kind of JavaScript would be expected? Something that conforms to the latest ES2022 spec or something different?

Sorry for all these questions. I really appreciate your help.

dy commented 2 years ago

These are good questions.

I know 5 standard ways packages are consumed in browser.

  1. Oldschool manual copy-paste/download dist files under /vendor or /lib folder, the way to work with jQuery (still the most ubiquitous lib in the internet). microjs supposes that way as primary. Basically you manually assemble deps, which is not as expensive as it may sound: in many scenarios that takes less time than configuring webpack, but provides security/simplicity/stability/compactness/cheap maintenance.

  2. UMD/standalone npm packages can be consumed as <script src="https://unpkg.com/react@16.7.0/umd/react.production.min.js"> via unpkg, skypack or other CDNs, implying that package ships single dist.

  3. ESM npm packages can be consumed as import myPackage from "'https://cdn.skypack.dev/myPackage'" via unpkg?module or skypack. Skypack is even able to bundle CJS to ESM for you. But generally if package has many sources, it makes many fetch requests, which is waste of bw and time.

  4. npm i mypackage via HTML + import-maps:

    <!-- this shim is optional -->
    <script async src="https://ga.jspm.io/npm:es-module-shims@1.4.6/dist/es-module-shims.js"></script>
    <script type="importmap">
    {
    "imports": {
    "my-package" : "./node_modules/my-package/my-package.js",
    }
    </script>
    <script type="module">import mypackage from 'my-package'</script>

    then this html file can be simply opened in Firefox or some static web-server used. When there are many internal modules, all of them may need to be mapped in importmap, which is a headache.

  5. npm i mypackage with bundler and associated expenses.

dy commented 2 years ago

'node_modules/package-name/anywhere/inside/the/package.js'

BTW source internals are unreliable for importing. For that purpose node defines package.exports to fix the exported internal parts.