Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get esbuild to include internal dependencies when using typescript

I am working on a vscode extension and am using esbuild to do the bundling/minification. I want to use the jsonc-parser NPM module. When I do this, esbuild runs OK but the extension won't load, giving an error "Activating extension failed: Cannot find module './impl/format'". I can reproduce this in a smaller example than the whole vscode extension, see the following:

Main file

import * as jsonc from 'jsonc-parser'
const example = '// Some comment\n{"a":1,"b":2}'
console.log(`Parsing ${example}`)
const errors = []
const mexample = jsonc.parse(example, errors)
console.log(`Result: ${JSON.stringify(mexample, null, 2)}`)
console.log(`Errors: ${JSON.stringify(errors)}`)

Relevant bits of package.json

"scripts": {
    "run-bundle": "node out.js",
    "bundle": "esbuild index.ts --bundle --platform=node --outfile=out.js"
  },
  "dependencies": {
    "jsonc-parser": "^3.0.0"
  },
  "devDependencies": {
    "esbuild": "^0.12.28"
  }

In the bundled out.js I can see

      var formatter = require2("./impl/format");
      var edit = require2("./impl/edit");
      var scanner = require2("./impl/scanner");
      var parser = require2("./impl/parser");

So it looks like esbuild hasn't picked these 'internal dependencies' up for bundling.

I've tried some options in tsconfig.json and package.json with no success.

like image 774
Peter Hull Avatar asked Oct 19 '25 19:10

Peter Hull


1 Answers

I raised an issue on GitHub and received the following explanation and work-around from user hyrious

This is because the jsonc-parser library exports a UMD file which uses require() indirectly, which prevents esbuild to analyze and bundle these dependencies. As a quick solution, you could use its ESM target in the module field by appending this option: --main-fields=module,main.

and from evanw

Having esbuild handle this automatically is out of scope since esbuild only handles require calls that can be statically-evaluated at compile time without partially-evaluating the input JavaScript code. The package not being bundler-friendly is a problem with the package, not with esbuild. As mentioned above, workarounds are:

  • Use --main-fields=module,main (may cause issues with other packages)
  • Write an esbuild plugin using onResolve to swap out just this one file (won't affect other packages)
  • Get Microsoft to make their code bundler-friendly
like image 119
Peter Hull Avatar answered Oct 21 '25 09:10

Peter Hull