coqui-ai / STT

🐸STT - The deep learning toolkit for Speech-to-Text. Training and deploying STT models has never been so easy.
https://coqui.ai
Mozilla Public License 2.0
2.23k stars 270 forks source link

Feature request: Support ESBuild #2294

Open johns10 opened 2 years ago

johns10 commented 2 years ago

Is your feature request related to a problem? Please describe. I would like to add stt_wasm to my esbuild pipeline. It currently fails because there are require statements in stt_wasm, which are guarded by ENVIRONMENT_IS_NODE during runtime, but not during compile time. I would like to be able to include stt_wasm in my deps and use a module import to include it in my project.

Describe the solution you'd like I'm not sure how to do it (once again, not a superior js programmer), but somehow guard the require statements or provide a default implementation when ENVIRONMENT_IS_NODE = false

Describe alternatives you've considered Hacking the js files. Providing an external implementation of require.

JamesReynolds commented 10 months ago

I've just found this comment and can offer a solution. I created an esbuild plugin that rewrites the ENVIRONMENT_IS... variables with consts during load which then allows esbuild's dead code elimination to remove the nodejs specific code:

const emscriptenPlugin = {
  name: 'emscripten',
  setup(build: PluginBuild) {
    build.onLoad({filter: /.*.js/}, ({path: filePath}) => {
      const readFileSync = require('fs').readFileSync;
      const extname = require('path').extname;
      const loader = extname(filePath).substring(1) as Loader;
      const contents = readFileSync(filePath, 'utf8')
        .replace(/var\s+ENVIRONMENT_IS_[A-Z_]*\s*=[^;]*;/g, '')
        .replace(/ENVIRONMENT_IS_WEB/g, "true")
        .replace(/ENVIRONMENT_IS_[A-Z_]*/g, "false");
      return {contents, loader};
    });
  }
};

My library is compiled with -sMODULARIZE=1 and -sASSERTIONS=1 - it seems that the latter is necessary to prevent over-enthusiastic pruning.

It may be worth raising this in esbuild: if it could automatically replace the detection code (e.g. typeof process=="object"...) with "false" when building for the web this would all work automatically without a plugin.