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

Minified Build Support #44

Open
Offroaders123 opened this issue Jan 19, 2024 · 1 comment
Open

Minified Build Support #44

Offroaders123 opened this issue Jan 19, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@Offroaders123
Copy link
Owner

Offroaders123 commented Jan 19, 2024

I've been curious about looking into using esbuild instead of tsc to compile the source for use in Node and the browser. Things are still a little over my head in terms of implementing it nicely in conjunction with my existing tsconfig.json settings, so I'm going to wait before committing things yet. There were a bunch of resources I found while trying to look into this, but it's still just a little over my head which route is the right way to go for NBTify.

I think my trouble is that I want to allow for multiple different ways to be able to import NBTify. In the browser, I'd like to have a fully ESM-compatible bundled build (minified, with dependencies), where you can still do (essentially) import { feature } from "https://cdn.dev/nbtify". I also want a fully-ESM compatible non-bundled (dependency-wise), maybe minified, build for Node.js (not in CommonJS). I think my current hangup is whether or not the Node.js build should be minified, as it sounds like it's less helpful for tree-shaking when used with a bundler (since you would want to import the Node ESM version when used with something like Vite, rather than the one that already has the dependencies bundled in, as for the CDN ESM build). And for another part of this, how does this all work with that I also have a CLI script for NBTify, as well as needing to use tsc to provide type definitions for the library as a whole, for any of these combinations?

So maybe it's not that the setup for it is very hard, but that I haven't fully decided yet as to which is the best way to target each of these use-cases.

And yeah, what's the proper way to manage your "bin": "./dist/bin/index.js" setup, in conjunction with regular-old library exports? What folder structure do people usually use for that? And are these two separate esbuild entry points?

Should I still provide a CommonJS-specific build output? Or is it encourage towards moving away from the dual-package setup, for new packages? I haven't personally had really any issues with needing to use NBTify in CommonJS thus far, but maybe someone else needs it for something, and they don't want to/can't migrate to ESM yet. I'd like to be able to make NBTify work for them, rather than have them need to figure out all of this on their own. Using ESM in the Electron backend is a valid issue, but I think that sounds to be less of an issue as of the last year or two, since it supports ESM now.

Lots of links related to this one

https://souporserious.com/bundling-typescript-with-esbuild-for-npm/
https://github.com/souporserious/bundling-typescript-with-esbuild-for-npm
https://esbuild.github.io/getting-started/#build-scripts
https://esbuild.github.io/api/#outbase
https://bundlephobia.com/package/[email protected] (Seems to be fairly similar in size to what esbuild does in my current demos for this)
https://nodejs.org/api/packages.html#--input-type-flag (New find, didn't know -e had a flag for this! Awesome)
https://medium.com/outbrain-engineering/the-hidden-power-of-package-json-a93143ec0b7c (sciencesakura/mutf-8#17)
https://dev.to/andreasbergstrom/simplify-typescript-builds-with-esbuild-and-skip-tsctsx-2124
vitejs/vite#1585
https://news.ycombinator.com/item?id=28861433
https://www.youtube.com/watch?v=mSnDUMybZXk
https://blog.logrocket.com/getting-started-esbuild/
https://esbuild.github.io/content-types/#tsconfig-json
evanw/esbuild#1343 (I noticed this with TS a while back in setting up a proper ESM build as well, I like that esbuild followed TS with this one. It's the choice to stay consistent, rather than trying to fix things on it's own)
https://www.youtube.com/watch?v=z16rzIF5J40 (Unrelated, cool find)
https://www.youtube.com/watch?v=alrLzBTHFH8 (current song)

@Offroaders123 Offroaders123 added the enhancement New feature or request label Jan 19, 2024
@Offroaders123 Offroaders123 self-assigned this Jan 19, 2024
@Offroaders123
Copy link
Owner Author

I'm going to read over this issue again to see why I need to bundle it myself, it seems like it makes sense to just use a CDN to bundle it for plain-use instead? Maybe I'm forgetting part of the original concern, but what I just found through JSDelivr, it does appear to bundle dependencies for you, and it's still ESM-compatible!

https://cdn.jsdelivr.net/npm/nbtify/+esm
https://www.jsdelivr.com/package/npm/nbtify

Offroaders123 added a commit that referenced this issue May 14, 2024
This was an interesting one! Thankfully I found an issue page about MUTF-8 handling on the repo for Twoolie/NBT, the Python project. It gave me some insight and a file to test against. I wrote my own script to slim it down a bunch, and dedupe the tags that are used multiple times. It's crazy how big just book text can get!

I used this actual version of NBTify in this commit, to write the new content to the file. That's also why I diffed it out, I wanted to make sure when I slimmed it down that the content coming out of it was actually what it was supposed to be as well. When using older NBTify, it didn't work correctly, because MUTF-8 handles things different than standard UTF-8.

```js
// @ts-check

import { readFile, writeFile } from "node:fs/promises";
import * as NBT from "./NBTify/src/index.ts";

const data = await readFile("./hotbar.nbt");

const trimmed = data.subarray(0x000BAE96, 0x000CA7C2);
console.log(trimmed);

/** @type {NBT.NBTData<any>} */
const hotbar = await NBT.read(data);

const book = hotbar.data[0][1].tag.BlockEntityTag.Items[12];
console.log(book);

const mutf8Demo = await NBT.write(book);
console.log(mutf8Demo);

const demoDiff = mutf8Demo.subarray(1, -2);
console.log(Buffer.compare(trimmed, demoDiff));

await writeFile("./alien-book.nbt", mutf8Demo);
```

#42
#44
twoolie/NBT#144 (comment)
twoolie/NBT#144

I'm still not sure I'm going to use the dependency itself or if I should just emded that into NBTify on it's own. I think I may just use it as a dependency, as I've been trying to get more used to not reinventing the wheel for everything, unless that has benefits. The MUTF-8 library already does everything I need it to, and it's ESM TypeScript, so I'm not sure what other reason I have to not just use it, it's great! Eventually I want to move my compression handling into a separate module too, so I will have to use module resolution for that down the road either way. I say heck to it! Let's do it :) Gonna look into if there's anything I'm forgetting, before doing that though. I really like having the ability to use projects like these (NBTify) without needing a transpilation or build step. Modern CDNs seem to handle this nicely, so we'll see.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant