Bundler

Deno bundler with the web in mind.

Donate Donate

Table of Contents

What is Bundler?

Bundler is a web bundler for deno. It allows to write code for the web like we are used to with deno.

Why use Bundler?

  • handles relative and absolute imports as well as url imports
  • smart splits dependencies
  • handles top level await
  • handles ts, tsx, js, jsx html, css, json, png, jpg, jpeg, ico, svg, and other file types
  • built in code optimazation and minification with --optimize option
  • built in file watcher with --watch option
  • typescript and javascript
    • handles dynamic import() statements
    • handles fetch() statements
    • handles WebWorker imports
    • handles ServiceWorker imports
  • html
    • handles <link>, <script>, <style> and <img> tags
    • handles style attributes
    • handles webmanifest files
  • css
    • handles css @import statements
    • supports postcss-preset-env stage 2 and nesting-rules by default

But there is deno bundle and Deno.emit, right?

deno bundle CLI command and Deno.emit can transpile and bundle a file to a standalone module. This might work for some occations but is limited to script files. Bundler uses Deno.emit and typescript compiler API under the hood to optimize code for the web.

Getting Started

Installation

deno install --unstable --allow-read --allow-write --allow-net --allow-env --name bundler https://deno.land/x/bundler/cli.ts

Info: You might need to specify --root /usr/local.

Usage

bundler bundle index.ts=index.js

CLI

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
–reload Reload everything
–reload=index.ts Reload only standard modules
–reload=a.ts,b.ts Reloads specific modules
false
–watch Watch files and re-bundle on change false

Supported File Types

Typescript and Javascript

Test

The file path must end with .ts, .tsx, .js, .jsx.

Transformation

Typescript code will be transpiled into javascript code.

Bundle

Bundler will bundle javascript sources together while smart splitting dependencies and injecting file paths.

Optimization

Bundler will optimize and minify code with the --optimize option using terser.

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";
object binding pattern export
export const { x, y, z } = obj;
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 path must end with .json.

Transformation

A json file will be transformed into an 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" }

Optimization

Bundler will minify code with the --optimize option using JSON.stringify without spaces.

Webmanifest

Webmanifest files are specially treated json files 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"
    }
  ]
}

Test

The file path can have any extension but must be imported with rel="webmanifest".

Html

Optimization

Bundler does not yet minify html 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 the css file is 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 using csso.

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 should be covered with todays css and postcss.

Support

Name Example Support
@import
@import "x.css";
@import url
@import url("x.css");
url
div { background: url('image.png'); }

Images

Test

The file must have .ico, .png, .jpg, .jpeg or .svg extension.

Optimization

Bundler minifies .svg files with the --optimize option using svgo.

Other

Other files can be fetched via the fetch API. They will not be transformed or optimized.

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. You can check out this example to see smart splitting in action.

Examples

Hello world

Components

Bundler API

Others

Unstable

This module requires deno to run with the --unstable flag. It is likely to change in the future.