user17298649
user17298649

Reputation:

Make use of the TextEncoder class in Node and Browser environments

I want to create a library using Typescript. This library can be used inside Node and browser environments, so the configuration supplies support for both

( tsconfig.json )

{
  "compilerOptions": {
    "baseUrl": ".",
    "declaration": true,
    "esModuleInterop": true,
    "lib": [ "esnext", "dom" ],
    "module": "commonjs",
    "outDir": "dist",
    "resolveJsonModule": true,
    "strict": true,
    "target": "es2019",
  },
  "include": [
    "./**/*.ts"
  ],
  "exclude": [
    "./dist"
  ]
}

I'm using esbuild as a bundler. The package.json contains

{
  "name": "my-lib",
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc && esbuild ./dist/index.js --bundle --minify --sourcemap --outfile=./bundle/index.js"
  },
  "dependencies": {
    "esbuild": "0.14.36"
  },
  "devDependencies": {
    "typescript": "4.6.3"
  }
}

The library makes use of some "private" helper functions, I'm using the following sample code

import { TextEncoder } from 'util';

const encodeInput = function (input: string): Uint8Array {
  const textEncoder = new TextEncoder();

  return textEncoder.encode(input);
}

Running the build script command throws an esbuild error telling me that this only works for Node environments, not in the browser, which makes sense because

How can I make sure this library works in "both" worlds?

Upvotes: 3

Views: 1890

Answers (2)

jsejcksn
jsejcksn

Reputation: 33856

TextEncoder is a global in Node, so you don't need to import it. Use it directly, without the import statement, just like in the browser.

You also don't need to instantiate a new TextEncoder every time the function is invoked: it is a small performance optimization to instantiate it once, and then just alias the encode method. See below.

const encoder = new TextEncoder();
const encode = encoder.encode.bind(encoder);

console.log(encode('hello world'));

Upvotes: 3

Barry Michael Doyle
Barry Michael Doyle

Reputation: 10658

You can make use of the UMD (Universal Module Definition) tool to get around this problem.

In your tsconfig.json, just change module: "commonjs", to module: "umd", and it should build properly from there to work in all environments.

Upvotes: 0

Related Questions