cometkim / espub Goto Github PK
View Code? Open in Web Editor NEWPerfect build tool for libraries, powered by esbuild
License: MIT License
Perfect build tool for libraries, powered by esbuild
License: MIT License
While Nanobundle respects "jsx": "preserve"
in TSConfig and emits it as-is, I found that it doesn't accept JSX family extensions (.jsx
, .mjsx
, .cjsx
) as output file extensions (instead it tries to look for something like index.mjsx.js
, ...)
Outputting files with JSX extensions is important because Vite doesn't accept JSX when the extension is just plain .js
. Transpiling the JSX when bundling isn't an option that I can consider. (since I'm currently building a library that exports a component for SolidJS)
Would it be possible to support outputting files with JSX extensions?
minifying with esbuild is not enough sometimes
having option to use other minifiers will be good.
Hi,
I like to prevent inlining packages imported like "react" and "@wordpress/components" BUT reference them from global variables.
An example: import { Button } from ''@wordpress/components';
should be transpiled to const { Button } = windows.wp.components;
microbundle allows "something like that" to declare globals as commandline option and also a way to do control at least inlining via convention : https://github.com/developit/microbundle/wiki/How-Microbundle-decides-which-dependencies-to-bundle
How can I do this with nanobundle ?
Kind regards,
Lars
Minimal reproduction: https://stackblitz.com/edit/node-h1e2ll (broken in browser; please download)
It seems like the platform of the entry doesn't take node
condition into account.
There's a non-trivial performance drop, but it's a worthwhile move given that nanobundle deals with small libraries.
TL; DR: I will build a new esbuild-powered build tool, called "espub"
nanobundle, as the name suggests, is a bundler. It aimed to provide effortless library building by adding some tweaks to esbuild's bundle mode. It's just like what microbundle does based on Rollup, that first inspired.
In v1, I focused on leveraging the full power of conditional exports in Node.js. And since TypeScript didn't support multiple entries at the time, this was a reasonable compromise. As a result, it was sufficient to support “small libraries” use cases and is compatible with the TypeScript ecosystem without noise.
I still use nanobundle actively in my daily work.
But at the same time, I see numerous cases where nanobundle is not a good fit because it is essentially a "bundler".
The bundler, by definition, removes the module semantics from the output after it has been performed. So I can't build things that depend on module semantics (I can approach it "cleverly", but it's overly complex or unpredictable)
While I was recognizing its limitations, I stopped exploring further features. And waiting for the ecosystem to move.
Time passed and things changed.
TypeScript projects can now adapt Node.js's conditional exports with the new moduleResolution
mode Node16
, NodeNext
and Bundler
Import attributes spec is standardized, and esbuild has added support recently. So users can specify more options at the module level. no need to customize loaders within the config.
XState v5 is released. It supports a better concurrency model than before with first-class actor support.
I still have trouble finding build tools that work for me in many situations.
Type checking is performed independently. tsc/babel is too slow to transpile. Most tools still don't handle conditional exports correctly. And more importantly, I moved most of my projects to ESM-first. I don't want to "bundle" my lib codes anymore.
It seems like there is still a chance to build a perfect esbuild wrapper. So I will do that.
It will be rebranded under the name "espub" because it is no longer a "bundle"-first tool. It will still be able to bundle stuff, maybe I can keep the "nanobundle" as its alias.
I'm definitely exploring in this Dec, but I can't promise anything.
I'm personally having productivity issues, and I also have other projects I'm involved with. Maybe you can make it faster than me.
I've actually seen a few close ones like tshy, pkgroll and bunchee. Unfortunately, none of them isn't for me. I don't expect someone to build it in a few months, so I'll do it soon eventually.
Just watch.
(Actually, I've already tried it a few times, and I rarely reuse existing code. It will be a completely rewritten codebase)
Seems it only emits dts for entry files.
I tried --no-sourcemap
flag with the v1.0.0 CLI and also tsconfig.ts sourceMap: false
. It stil generates sourcemaps.
Configurability by additional plugin support could be a good escape hatch for edges like #12.
Fortunately, nanobundle is a plain ESM, so it's very easy to achieve that via dynamic import .
Provide a way to configure additional plugins in addition to the currently built-in import maps and embedding deps plugins. Mostly it's just an esbuild plugin, but I need to provide additional dependencies for initialization.
I see that there is a no-op todo message for this flag! What issues do you foresee with implementing a build watcher?
Here is some prior art:
https://github.com/search?q=repo%3Aegoist%2Ftsup%20watch&type=code
of course it has more complexity to concern itself with than we do with only esbuild, but it's a start. also I don't see this implementation utilizing rebuild
method that esbuild
returns to make incremental builds work
I would be happy to help contribute this as part of our graphql/graphiql#2925 effort
We are building with the latest version.
The jsx syntax in the tsx file is expressed as it is without being built.
Is there no way?
// index.mjs
const buttonContent = <span>{children || ""}</span>;
The expected expression is:
const buttonContent = React.createElement("span", null, children || "");
Both cjs and mjs are the same.
jsx syntax doesn't compile.
// tsconfig
{
compilerOptions: {
jsx: "react" // not working
jsx: "react-jsx" // compile with jsx function
}
}
questions:
you published a duplicate of tsconfck to the public npm registry here https://www.npmjs.com/package/@nanobundle/tsconfck
possibly related to
https://github.com/cometkim/nanobundle/blob/558264786333ce4bdd6a6ac857bf560dd3eefb97/CHANGELOG.md?plain=1#L119
it still points to the original repo in the metadata though and it's not immediately clear what changes were made.
I would prefer you either take it down or update the metadata/readme so people don't get confused.
If there was an issue for you in tsconfck, i'd be interested to hear about it and see if it is something that needs to be fixed in the original.
https://nodejs.org/api/packages.html#subpath-imports
The resolution rules for the imports
field are otherwise analogous to the exports
field.
What if nanobundle is gonna be bundler-agnostic and can take advantage of SWC instead of esbuild as configuration?
When trying to bundle a package with its entry point set to a .cjs
file (originally sourced from a .cts
file) in an ESM package, types aren't generated.
Source code is generated, however.
package.json
file with its type
property set to module
./src/index.cts
filetsconfig.json
file with the following content:
{
"compilerOptions": {
"target": "ES6",
"module": "Node16",
"sourceMap": true,
"sourceRoot": "./src",
"outDir": "./lib"
}
}
npx nanobundle build
index.cjs
file is generated. The index.d.cts
file is not."type": "module"
from your package.json
and run the command againd.cts
file is now generatedIt seems like the sourceFile
array of the types
entry is built incorrectly.
The sourceFile
of the types
entry contains the following paths:
[
"./src/index.d.cts",
"./src/index.ts"
]
Where you'd actually expect something like this:
[
"./src/index.d.cts",
"./src/index.cts",
"./src/index.d.ts", // Maybe? idk
"./src/index.ts" // Was already present in the original output - so why not leaving it in as well
]
[debug] parsed entries [
{
key: 'main',
entryPath: './lib/index.cjs',
mode: undefined,
minify: false,
sourcemap: true,
platform: 'neutral',
module: 'commonjs',
sourceFile: [
'./src/index.cts',
'./src/index.cjs',
'./src/index.ts',
'./src/index.js',
[length]: 4
],
outputFile: './lib/index.cjs',
customConditions: [ [length]: 0 ]
},
{
key: 'types',
entryPath: './lib/index.d.cts',
mode: undefined,
minify: false,
sourcemap: true,
platform: 'neutral',
module: 'dts',
sourceFile: [
'./src/index.d.cts',
'./src/index.ts',
[length]: 2
],
outputFile: './lib/index.d.cts',
customConditions: [ [length]: 0 ]
},
[length]: 2
]
According to the docs
If both "exports" and "main" are defined, the "exports" field takes precedence over "main". "exports" are not specific to ES modules or CommonJS; "main" is overridden by "exports" if it exists. As such "main" cannot be used as a fallback for CommonJS but it can be used as a fallback for legacy versions of Node.js that do not support the "exports" field.
"imports": {
"#shared/*.js": "./src/shared/*.js",
"#globals/*.js": {
"default": "./src/globals/*.default.js",
"custom": "./src/globals/*.js"
}
},
nanobundle is kinda esbuild config generator internally, it can codegen instead of executing it.
This can be used as an escape hatch while some configs are incompatible.
Equivalent to the "eject" command.
Support hiding module by specifying it to null
, for example
"exports": {
"./*": "./dist/src/*",
"./internal/*": null
}
ios_saf
or ios
browserslist query is not handled properly
nanobundle clean
to clean outputsnanobundle build --clean
to clean before build starthttps://nodejs.org/api/packages.html#subpath-patterns
Node.js exports/imports map has a multi-entry syntax similar to glob.
For subpath pattern imports entries, it can simply add support via a glob matcher like picomatch.
On the other hand, subpath pattern exports are not supported by bundlers, including nanobundle, as they imply the existence of "unbundled modules".
Given that ES modules are supported in both Node.js and browsers today, I'm assuming that if treating subpath pattern exports as an external module won't cause any problems. If so, it can be solved by extending the existing embedPlugin behavior.
nanobundle build
currently requires explicit source
entry and doesn't support multiple entry.
I was thinking this is good enough for "tiny modules", and less problematic for legacy bundlers not support node exports
resolution such as Webpack 4.
But for now, I'm thinking less about the legacy bundler and getting more usefulness.
If there are multiple entries, explicit mappings will be too verbose or malformed.
implicit mappings would be good strategy here
{
// config namespace
"nanobundle": {
"source": {
"./lib": "./src",
}
},
"exports": {
".": "./lib/index.mjs", // -> "./src/index.m?(js|ts)"
},
"bin": {
"my-cli": "./cli.mjs" // -> "./cli.m?(js|ts)",
}
}
Note: this will be a major milestone for nanobundle v2
Bundling is for the application, bundling in NPM libraries is of no value (since we don't support UMD bundle)
Another problem with bundling is that it is incompatible with some Node.js semantics, such as subpath pattern exports. This is a blocker for some issues (#45, #48)
But building a library without bundling is not trivial today. Bundlers like esbuild and webpack don't support it. So it requires to use a transpiler like Babel or TypeScript separately with complex config.
nanobundle will v2 provides a no-bundle esbuild configuration. And will promotes it to default behavior later. May include rebranding as it is no longer "bundle".
Hello,
noEmit
option from .tsconfig.json
means that any result is not required by tsc
, including d.ts
files.types
property of package.json
describes that the project should keep d.ts
files.This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
semver
, @types/semver
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
@vitest/coverage-v8
, vitest
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
.github/workflows/codeql.yml
actions/checkout v4
github/codeql-action v2
github/codeql-action v2
github/codeql-action v2
.github/workflows/nanobundle-integration.yml
actions/checkout v4
actions/setup-node v4
actions/checkout v4
actions/setup-node v4
codecov/codecov-action v3
.github/workflows/release.yml
actions/checkout v4
actions/setup-node v4
cometkim/yarn-changeset-action v1
package.json
@changesets/cli ^2.27.1
all-contributors-cli ^6.26.1
typescript ^5.3.3
packages/nanobundle/package.json
@cometjs/core ^2.1.0
browserslist ^4.22.2
esbuild ^0.19.0
kleur ^4.1.5
meow ^12.0.0
pretty-bytes ^6.0.0
semver ^7.3.8
string-dedent ^3.0.1
tsconfck ^3.0.0
xstate ^4.35.0
@types/node ^18.0.0
@types/semver ^7.3.13
@vitest/coverage-v8 ^0.34.6
@xstate/cli ^0.5.0
pkg-types ^1.0.1
typescript ^5.0.0
vitest ^0.34.6
typescript ^5.0.0
node >=18.0.0
vite ^5.0.0
yarn 4.0.2
How can I generator the index.d.ts file without a bundle file?
For example,
nanobundle build --generate-dts dist/index.d.ts
The user may also specify conditions not formally discussed in the Node.js community. e.g., for node --condition worker,
the package.json
should be able to specify an entry for this case.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.