Search code examples
javascriptesbuild

How to remove module.exports with esbuild to prevent "module is not defined" error in browser?


I have a simple JavaScript class I run tests against with Jest. Here's a greatly simplified version of it.

class MyFormatter {
  formatText(str){
    return 'foo ' + str
  }
}

module.exports = MyFormatter;

In jest I can import it with require and run my tests. It all works great.

const MyFormatter = require("./my-formatter");
let mf = new MyFormatter()
//etc...

Now I want to use this class in a simple static browser-based project. I have tried using esbuild to minify and place the generated file in my web project folder

esbuild lib/my-formatter.js --minify --outfile=web/my-formatter.min.js

I include both the newly generated/minified file in my document

<script src="my-formatter.min.js"></script>
<script src="script.js"></script>

and then within script.js I can just call new MyFormatter() since it's in the global namespace.

This works but I get this console error

Uncaught ReferenceError: module is not defined

due to the module.exports that is left in the minified file.

Is there a way to remove this with esbuild so that I don't get a console error? Am I thinking about this the wrong way and is there something else I should be doing instead?


I have tried adding the --bundle flag as well, but that wraps everything in an anonymous function and I lose class name in the global namespace. the output file becomes

(() => {
    var u = (i, e) => () => (
        e || i((e = { exports: {} }).exports, e), e.exports
    );
    var f = u((c, l) => {
        var s = class {
          //... my code is here
        };
        l.exports = s;
    });
    f();
})();

Which is unusable to me from the other script file


Solution

  • Here's what I did that worked. Since I have lib/my-formatter.js which contains my library and web/script.js where I want to use it.

    Within web/script.js I simply require the library and use it normally

    const MyFormatter = require("../lib/my-formatter");
    const my = new MyFormatter();
    

    Now I instead create a bundle from THIS file instead of the library

    esbuild web/script.js --bundle --minify --outfile=web/script.min.js
    

    Now I just link to this bundled file: <script src="script.min.js"></script>