Giancarlo Buomprisco

Giancarlo Buomprisco

·2 min read

Build Typescript libraries for the browser with Nx

This article shows how to set up your Webpack configuration to build Typescript libraries with Nx

I have quite a few libraries in my Nx workspaces, and most of them are built using their tooling (Angular, Stencil).

Also, I have a few vanilla Typescript libraries that need to be consumed within a Browser environment. Originally, I used to bundle them with the builder @nrwl/web:bundle - which got deprecated with Nx 9.

I needed to find another way.

The best way I found to achieve an even better result is by using the builder @nrwl/node:build, extended with a Webpack configuration.

Configuration

Here's the configuration that I use to build browser-compatible distributions of my library sdk:

"sdk": {
  "root": "libs/sdk",
  "sourceRoot": "libs/sdk/src",
  "projectType": "library",
  "schematics": {},
  "architect": {
    "build": {
      "builder": "@nrwl/node:build",
      "options": {
        "outputPath": "dist/sdk",
        "main": "libs/sdk/src/index.ts",
        "tsConfig": "libs/sdk/tsconfig.lib.json",
        "project": "libs/sdk/package.json",
        "webpackConfig": "libs/sdk/webpack.config.js"
      },
      "configurations": {
        "production": {
          "fileReplacements": [
            {
              "replace": "libs/sdk/src/environments/environment.ts",
              "with": "libs/sdk/src/environments/environment.prod.ts"
            }
          ]
        }
      }
    }
  }
}

Webpack configuration

As you may have noticed, I have also supplied a Webpack configuration file. It's needed, as we want to tell Webpack to produce a browser bundle.

Also, we can extend the configuration with any plugin we want. For example, I used Terser to optimize the size of the output.

const TerserPlugin = require('terser-webpack-plugin')

module.exports = (config) => {
  return {
    ...config,
    externals: [],
    target: "web",
    plugins: [
      ...config.plugins,
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          ecma: 6,
        },
      }),
    ],
    devtool: false,
    output: {
      ...config.output,
      filename: 'sdk.umd.js',
      libraryTarget: 'umd',
    },
  };
};

Bundling the Typescript library

In order to bundle the library, I run the following command:

> ng run sdk:build
Starting type checking service...
Using 10 workers with 2048MB memory limit
Hash: c02b92c803ac182c3da8
Built at: 07/26/2020 1:00:34 AM
Entrypoint main = sdk.umd.js
chunk    {0} sdk.umd.js (main) 35.3 KiB [entry] [rendered]

———————————————————————————————————————————————

>  NX   SUCCESS  Running target "build" succeeded

If you enjoyed this article, follow me on Twitter