Under the hood we are using tsup as our bundler, it’s based on esbuild, quick and flexible.

tsconfig.json

To support proper ts support and correct moduleResolution, we are using the new shiny moduleResolution option BUNDLER

designed primarily for bundlers and runtimes that include a range of Node-like resolution features and ESM syntax, but do not enforce the strict resolution rules that accompany ES modules in Node or in the browser. Special consideration has also been given for bundlers and runtimes that understand TypeScript natively and do not require compilation to JavaScript by tsc before consumption.

In short, bundler won’t have opinionated bridges to resolve the module which leave us a cleaner bundler to work with. (Previously, we are using very old moduleResolution: node The option will only support CJS, hence require an ESM module and cause the bundler can not be used by console)

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["dom", "dom.iterable", "es2022"],
    "allowJs": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx",
    "incremental": false,
    "declaration": true,
    "sourceMap": true,
    "emitDeclarationOnly": true,
    "strict": true
  }
}

tsup.config.ts

We bundle ESM/CJS separately and export them with different path. Additionally, we export server in different path too. In the future we will try to separate each folder to different path and have different import to decrease the page bundle size of console

const cfg: Options = {
  sourcemap: false,
  minify: false,
  dts: false,
  format: ["esm", "cjs"],
  loader: {
    ".js": "jsx",
  },
  splitting: false,
  esbuildOptions(options) {
    options.external = [
      "react",
      "react-dom",

      // vitest is using some nodejs modules that is not available under our bundle env
      // it will cause Could not resolve "#async_hooks" error
      "#async_hooks",
    ];
  },
};

export default defineConfig([
  {
    ...cfg,
    entry: {
      index: "src/server/index.ts",
    },
    outDir: "dist/server",
  },
  {
    ...cfg,
    entry: {
      index: "src/index.ts",
    },
    outDir: "dist",
  },
]);

package.json

We are using new exports syntax to correctly export our library.

{
	"exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.mjs"
      },
      "require": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js"
      }
    },
    "./server": {
      "import": {
        "types": "./dist/server/index.d.ts",
        "default": "./dist/server/index.mjs"
      },
      "require":{
        "types": "./dist/server/index.d.ts",
        "default": "./dist/server/index.js"
      }
    }
  },
}

Limitation

When consume the @instill-ai/toolkit in console-cloud, we need to use transpilePackage

Next chanllenge