Premise
A used-in-production proof of concept bundler, @normed/bundle
bundles with output directory structure as the first class citizen. Given files in a source directory (defaults to src
) it transpiles and bundles the entrypoints into the destination directory (defaults to bundles
). The twist is that any file containing the pre-prefix static
is automatically an entrypoint, and aside from stripping the pre-prefix and transforming the prefix (ie. ts
-> js
) the relative structure remains the same.
Examples
in: out:
src/ bundles/
├─ api.ts |
├─ logger.ts |
├─ index.static.ts ├─ index.js
├─ public/ ├─ public/
├─ base.style.less |
├─ favicon.static.ico ├─ favicon.ico
├─ index.static.less ├─ index.css
├─ index.static.pug ├─ index.html
├─ index.static.ts ├─ index.js
Things to note
The following global javascript variables are available in most environments:
-
__filename
and__dirname
- refers to the executing bundle filename/dirname The following additional variables provided by@normed/bundle
, and do not exist by default if not built by@normed/bundle
: -
__source_filename
and__source_dirname
- refer to the original source files absolute filename/dirname -
__source_relative_filename
and__source_relative_dirname
- refer to the original source files filename/direnation relative to the source directory
The current version of @normed/bundle
is built on top of es-build for speed.
Configuration
Specify your configuration in your package.json
by adding the "bundle"
entry.
{
"bundle"?: {
"entrypoints"?: string[], // Manually specify entrypoints here.
"analyse"?: boolean, // When true, outputs bundle analysis files.
"typescript"?: {
"external"?: 'all' | string[], // Which dependencies not to include in the bundle.
"declarations"?: boolean, // emit typescript declarations.
}
}
}
Or if calling via the command line:
bundle --tsc-external
bundle --tsc-declarations
bundle --indir <directory>
bundle --outdir <directory>
bundle --platform <browser | web | node | server | library>
bundling
By default this utility exports the bundle
command; this command defaults to building mode, but it can be explicitly set if desired.
# These two commands are equivalent
yarn bundle
yarn bundle --build
cleaning
If you want bundle to delete the contents of the output directory, you can tell it to clean it:
yarn bundle --clean
watch mode (not yet implemented)
Watch mode is not yet implemented.
Logging
Increase logging with the --verbose
and --debug
flags. Decrease logging with the --quiet
flag.
yarn bundle --verbose
yarn bundle -v
yarn bundle --debug
yarn bundle --quiet
yarn bundle -q
entrypoints
All files ending in .static.<ext>
, .node.<ext>
, and .web.<ext>
are automatically picked up as entrypoints.
Any files you don't want to name with such a suffix can be added manually. To add the files anchovies.ts
and pics/cartoons.png
manually:
via package.json
:
{
"bundle": {
"entrypoints": [ "anchovies.ts", "pics/cartoons.png" ]
}
}
via cli:
yarn bundle --entrypoint anchovies.ts --entrypoint pics/cartoons.png
analyse
To get a report on bundle content and size enable analysis:
package.json
:
{
"bundle": {
"analyse": true
}
}
via cli:
bundle --analyse
Development
Feel free to contribute to the codebase, issues and code welcome.
build pipeline
@normed/bundle
is bootstrapped by being built from typescript to javascript first (using tsc
, output to dist
), then using the javascript output to build the original source (output to bundles-a
), then using that output to build the original source again (output to bundles
), and finally the last two outputs are compared to ensure they are the same. This acts as a nice little test to check some of the functionality of @normed/bundle
.
Potential errors
es-build, which is essentially the basis for this whole thing, breaks reproducible builds as it includes the full path to a file as both a comment and a map key. To get around this we manually replace certain paths on build. There is a good chance this will not work for globally installed modules and will break certain hard coded strings.