DEV Community

EGOIST
EGOIST

Posted on

13 5

Bundle a TypeScript library with Bili

Bili is a bundler built on the top of Rollup, it can be really convenient if you wanna bundle your library in multiple formats, nowadays it's pretty common to build a JavaScript library that works in CommonJS, UMD and ES Modules.

Bili also works with TypeScript seamlessly, this post will walk you through creating a simple TypeScript library.

Get Started

Let's get started by creating a new project to learn how to use TypeScript with Bili:

mkdir my-lib
cd my-lib
yarn init -y # Create a package.json
yarn add bili --dev

Next install TypeScript related dependencies:

yarn add typescript rollup-plugin-typescript2 --dev

We will use rollup-plugin-typescript2 instead of the official rollup-plugin-typescript because the latter does not perform type-checking during compilation.

Now Bili will automatically use rollup-plugin-typescript2 if you're building a .ts file.

TypeScript Config

To let TypeScript perform proper type-checking, a tsconfig.json is necessary, you can create one by running the TypeScript compiler with --init flag:

yarn tsc --init

Feel free to tweak the options in tsconfig.json to suit your needs.

Bundle in Multiple Formats

We will create a src/index.ts in my-lib:

# Create src/index.ts
mkdir src
echo "export default 42" > src/index.ts
# Bundle it in CommonJS and ESM format
# Omit `--format <format>` to bundle in CommonJS only
yarn bili src/index.ts --format cjs --format esm

Then src/index.ts will be bundled to dist/index.js:

'use strict';

var index = 42;

module.exports = index;

And dist/index.mjs:

var index = 42;

export default index;

It's recommended to add dist (generated by Bili) and .rpt2_cache (generated by rollup-plugin-typescript2) in .gitignore file.

Generate Declaration Files

To generate corresponding .d.ts files for files in src folder, first you need to enable compilerOptions.declaration in your tsconfig.json:

{
  "compilerOptions": {
    "declaration": true
  }
}

Then create bili.config.ts to configure TypeScript to include src folder only:

import { Config } from 'bili'

const config: Config = {
  plugins: {
    typescript2: {
      // Override the config in `tsconfig.json`
      tsconfigOverride: {
        include: ['src']
      }
    }
  },

  // Let's take this opportunity to move the CLI flags here as well
  input: 'src/index.ts',
  output: {
    format: ['cjs', 'esm']
  }
}

export default config

Note that we didn't set include: ['src'] in tsconfig.json directly, because in most cases your editor like VS Code will use that file by default and you don't want other files like ./my-lib/test/index.test.ts to be excluded.

Finally let's run yarn bili and the declaration file will be generated to dist/index.d.ts:

declare const _default: 42;
export default _default;

Configure package.json

{
  "name": "my-lib",
  "main": "dist/index.js",
  "module": "dist/index.mjs"
  "types": "dist/index.d.ts",
  "files": ["dist"],
  "scripts": {
    "build": "bili",
    "prepublishOnly": "npm run build"
  }
}

Now you can publish it on npm and the types can be found when others are using it.

Check out https://github.com/egoist/objql for a simple real-world TypeScript library.

Related Links

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

Top comments (3)

Collapse
 
renoirb profile image
Renoir

This is amazing!
Code changed a lot since last time I imported it.
TypeScript definitions and typings annotations are also nice.
Thanks!

While experimenting with the version bump, I realized maybe I misunderstood how to make different bundles not just by format, but by target runtime (e.g. Jest test runner, browser, etc).

I'm experimenting github.com/renoirb/experiments-201... this in this reproduction repository, and opened a ticket.

I will contribute documentation once I've understood how to do it properly. I must be missing something.

Collapse
 
frank1e0927 profile image
Frankie

Egoist真强

Collapse
 
steveohoh profile image
steveo

Amazing work

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay