Skip to content

Instantly share code, notes, and snippets.

@hiukky
Forked from danieldietrich/README.md
Created June 1, 2022 19:14
Show Gist options
  • Save hiukky/11ab10b316e65620309cfe277aa69b00 to your computer and use it in GitHub Desktop.
Save hiukky/11ab10b316e65620309cfe277aa69b00 to your computer and use it in GitHub Desktop.
The easiest way to bundle a simple TypeScript web application

The easiest way to bundle a simple TypeScript web application

Packaging JavaScript applications can be a bit overwhelming. The popular project uglifyjs does not support ES6, it is cumbersome to configure the allmighty Webpack, bundlers like Parcel and Microbundle still have bugs or do not compile to ESM bundles that work in a browser. It is hard to figure out the best way to bundle an application.

Here I give a small example, how we achieve the goal using the

☕️ Prerequisites: Install Node.js

✨ Feature overview

  • Zero configuration bundling (esm, umd)
  • Proper entry point hints for npm, unpkg and when used as module
  • Runs with <script type='module'> in a web page

🚀 Initialize Node.js project

Go to a new directory say-hello/

npm init -y

Install dependencies

npm i -D typescript rollup terser

Replace package.json "scripts" (umd name sayHello is app specific)

"scripts": {
  "clean": "rm -fr dist",
    "build": "npm run clean && npm run lint && tsc --project tsconfig.build.json && npm run bundle:esm && npm run bundle:esm:min && npm run bundle:umd && npm run bundle:umd:min && npm run build:stats",
    "build:stats": "(echo '\\033[35;3m' ; cd dist && ls -lh index*js index*gz | tail -n +2 | awk '{print $5,$9}')",
    "bundle:esm": "rollup dist/index.js --file dist/index.mjs --format esm",
    "bundle:esm:min": "terser --ecma 6 --compress --mangle --module -o dist/index.min.mjs -- dist/index.mjs && gzip -9 -c dist/index.min.mjs > dist/index.min.mjs.gz",
    "bundle:umd": "rollup dist/index.js --file dist/index.umd.js --format umd --name sayHello",
    "bundle:umd:min": "terser --ecma 6 --compress --mangle -o dist/index.umd.min.js -- dist/index.umd.js && gzip -9 -c dist/index.umd.min.js > dist/index.umd.min.js.gz",
},

Replace "main" in package.json

- "main": "index.js"
+ "main": "dist/index.js",
+ "module": "dist/index.min.mjs",
+ "unpkg": "dist/index.umd.min.js",
+ "types": "dist/index.d.ts",
+ "files": [
+   "dist"
+ ],

Create TypeScript configuration tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "lib": ["es6", "dom", "dom.iterable"],
    "module": "es6",
    "moduleResolution": "node",
    "removeComments": true,
    "sourceMap": true,
    "strict": true,
    "target": "es6",
    "outDir": "./dist"
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "dist",
    "node_modules"
  ]
}

Create test application src/index.ts

export function sayHello() {
    return "Hi ya all!";
}

Create a file example/index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Say Hello</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="author" content="Daniel Dietrich">
    </head>
    <body>
        <noscript>
            You need to enable JavaScript to run this app.
        </noscript>
        <div id="app">
            Loading...
        </div>
        <script type="module">
            import { sayHello } from '../dist/index.mjs';
            document.getElementById('app').innerHTML = sayHello();
        </script>
    </body>
</html>

📦 Build the project

npm run build

Bundle

🥰 Directly using an ESM bundle in a web page

Loading our example web page example/index.html (might require to Disable Local File Restrictions in the browser)

Example

The interesting part

<script type="module">
    import { sayHello } from '../dist/index.mjs';
    document.getElementById('app').innerHTML = sayHello();
</script>

When published to npmjs.com, we can use the unpkg.com CDN to include our module in a web page

<script type="module">
-   import { sayHello } from '../dist/index.mjs';
+   import { sayHello } from 'https://unpkg.com/say-hello?module';
    document.getElementById('app').innerHTML = sayHello();
</script>

[Written by @danieldietrich]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment