Bundler
A Bundler with the web in mind.
Table of Contents
- Why Use Bundler?
- What Bundler Does
- Getting Started
- Usage
- Supported File Types
- Smart Splitting
- Examples
Why Use Bundler?
- works out of the box
- no configuration file
- powerful and fast
- built in smart splitting
- built in code optimization
But there is deno bundle, right?
Deno offers deno bundle to transpile a file to a standalone module. This might work for some occations but is limited to script files. Bundler works similar to deno bundle but with the web in mind.
What Bundler Does
- handles relative and absolute imports as well as url imports
- handles dynamic
import()statements andfetch()statements - handles
css@importstatements and supports postcss-preset-env stage 2 and nesting-rules by default - smart splits dependencies
- handles
html<link>,<script>,<img>and<style>tags,<div style="">attributes as well aswebmanifestfiles - handles
Web WorkerandService Workerimports - handles
ts,tsx,js,jsxhtml,css,json,png,jpg,jpeg,ico,svg,wasm - built in code optimazation and minification with
--optimizeoption - built in re-bundle with
--watchoption
Getting Started
Installation
deno install --unstable --allow-read --allow-write --allow-net --allow-env --name bundler https://deno.land/x/bundler/cli.tsInfo: You might need to specify --root /usr/local.
Usage
bundler bundle index.ts=index.jsCLI
Options
| Option | Description | Default |
|---|---|---|
| -c, –config <FILE> | Load tsconfig.json configuration file | {} |
| –out-dir <DIR> | Name of out_dir | “dist” |
| -h, –help | Prints help information | |
| –import-map <FILE> | UNSTABLE: Load import map file | {} |
| –optimize | Optimize source code | false |
| -L, –log-level | Set log level [possible values: debug, info] | debug |
| -q, –quiet | Suppress diagnostic output | false |
| -r, –reload | Reload source code | false |
| –watch | Watch files and re-bundle on change | false |
Supported File Types
typescript and javascript
Test
The file must have .ts, .tsx, .js, .jsx as extension or be an url without extension.
Transformation
Typescript code will be transpiled into javascript code.
Bundle
Bundler will bundle javascript sources toghether similar to deno bundle but smart split dependencies and inject other file paths.
Optimization
Bundler will optimize and minify code with the --optimize option.
Support
Bundler extracts dependencies from the following statements:
| Name | Example | Support |
|---|---|---|
| Imports | ||
| default import |
import x from "./x.ts" |
✅ |
| import statement |
import("./x.ts") |
✅ |
| named import |
import { x } from "./x.ts" |
✅ |
| namespace import |
import * as x from "./x.ts" |
✅ |
| Exports | ||
| default export |
export default "./x.ts" |
✅ |
| variable export |
export const x = "x" |
✅ |
| function export |
export function x() {} |
✅ |
| class export |
export class X {} |
✅ |
| named export |
export { x } from "./x.ts" |
✅ |
| namespace export |
export * as x from "./x.ts" |
✅ |
| unnamed export |
export * from "./x.ts" |
✅ |
| Others | ||
| fetch statement |
fetch("./x.ts") |
✅ |
| WebWorker |
new Worker("./x.ts") |
✅ |
| ServiceWorker |
navigator.serviceWorker.register("./x.ts") |
✅ |
json
Test
The file must have .json extension or any kind of extension if it is imported as a webmanifest.
Transformation
A json file will be transformed into a esm module if it is imported diretcly into typescript or javascript.
/* src/data.json */
{
"foo": "bar"
}/* src/x.ts */
import data from "./data.json"
console.log(data) // { "foo": "bar" }Webmanifest
Webmanifest files are specially treated and src properties in icons are extracted as dependencies.
<!-- src/index.html -->
<html>
<head>
<link rel="manifest" href="manifest.json">
</head>
<body>
</body>
</html>// src/manifest.json
{
"icons": [
{
"src": "images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
}
]
}Optimization
Bundler will minify code with the --optimize option.
html
Optimization
Bundler does not yet minify code with the --optimize option.
Support
Bundler extracts dependencies from the following statements:
| Name | Example | Support |
|---|---|---|
| script tag |
<script src="x.ts"> |
✅ |
| inline script |
<script> const x: string = "x" </script> |
✅ |
| link tag |
<link rel="manifest" href="x.json"> <link rel="stylesheet" href="x.css"> <link rel="icon" href="x.png"> |
✅ |
| img tag |
<img src="image.png"> |
✅ |
| style tag |
<style> div { background: url(‘image.png'); } </style> |
✅ |
| style attribute |
<div style="background: url(‘image.png');"></div> |
✅ |
css
Test
The file must have .css extension.
Transformation
A css file will be transformed into a esm module with a default string export if it is imported into typescript or javascript.
/* src/style.json */
div {
color: red;
}/* src/x.ts */
import data from "./style.css"
console.log(data) // div { color: red }Optimization
Bundler will optimize and minify code with the --optimize option.
Postcss
postcss-preset-env with stage 2 features and nesting-rules is enabled by default so you can use the latest css features out of the box.
A word on preprocessors
The functionality of css has grown in recent years and is native to browsers. Therefore bundler focuses on making css usage really easy instead of supporting preprocessors like sass, scss, less or stylus. Most features a preprocessor does is covered with todays css and postcss and supported by browsers.
images
Test
The file must have .ico, .png, .jpg, .jpeg or .svg extension.
Transformation
Image files cannot be imported directly into typescript or javascript (yet), so they will not be transformed in any way. Instead they should be fetched with via fetch API or Image API.
Optimization
Bundler does not yet optimize or compress images with the --optimize option.
wasm
wasm files cannot be imported directly into typescript or javascript (yet), so they will not be transformed in any way. Instead they should be fetched with via fetch API.
Optimization
Bundler does not optimize or compress wasm with the --optimize option.
Smart Splitting
Bundler automatically analyzes the dependency graph and splits dependencies into separate files, if the code is used in different entry points. This prevents code duplication and allows bundle files to share code.
Example
Structure
Have a.ts, b.ts and c.ts files where a.ts and b.ts both import c.ts
- src
a.ts- import
c.ts
- import
b.ts- import
c.ts
- import
c.ts
Single Entry Point
bundler bundle a.ts=a.jsHaving a.ts as the only entry point will bundle a.js like so:
a.jsa.tsc.ts
Multiple Entry Points
bundler bundle a.ts=a.js b.ts=b.jsHowever, if a.ts and b.ts are both entry points and both import c.ts, it will split c.ts as a third chunk (named here c.js).
a.jsa.ts- import
c.js
b.jsb.ts- import
c.js
c.jsc.ts
Examples
Hello world
Components
Others
Unstable
This module requires deno to run with the --unstable flag. Itis likely to change in the future.