javascriptbrowserifygrunt-browserifybabelify

Browserify and Babelify give {classname} is not defined error


Given this TS file:

export default class Rob {
    Start(): void {
        console.log("Hello, world!");
    }
}

Which I am transforming with a Grunt task that looks like this:

browserify: {
    rob: {
        src: "./rob/rob.js",
        dest: "./wwwroot/rob.js",
        options: {
            transform: [["babelify", { "presets": ["@babel/preset-env"] }]]
        }
    }
}

I run a simple HTML file like this:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Test bed</title>
    <script src="rob.js"></script>
    <script>
        window.addEventListener("DOMContentLoaded", function () {
            var r = new Rob();
            r.Start();
        });
    </script>
</head>
<body>
    <p>Hello, world!</p>
</body>
</html>

Which results in Uncaught ReferenceError: Rob is not defined

I have seen several questions like this on SO but those seemed to be related to a misuse of context (for example not this-ing something or this-ing something when that was not appropriate). Here the context is irrelevant; I just want to see my console.log in the console.

My package.json looks like this:

{
  "version": "1.0.0",
  "name": "robtest",
  "private": true,
  "devDependencies": {
      "@babel/core": "7.9.6",
      "@babel/preset-env": "7.9.6",
      "babel-preset-es2015": "7.0.0-beta.3",
      "babelify": "10.0.0",
      "grunt": "^1.1.0",
      "grunt-browserify": "5.3.0"
  }
}

My steps have been to

This outputs a JS file that looks to my eye to be about what I would want, including this snippet:

var Rob = /*#__PURE__*/function () {
  function Rob() {
    _classCallCheck(this, Rob);
  }

  _createClass(Rob, [{
    key: "Start",
    value: function Start() {
      console.log("Hello, world!");
    }
  }]);

  return Rob;
}();

exports["default"] = Rob;

Chrome also tells me that rob.js is loaded OK and I can see the content in the source explorer when the HTML page has loaded.

My question is simply: why the reference error in this instance?

Edit: as a bit of an addition to the accepted answer: If I edit the ts to call itself (to act as its own entry point):

export default class Rob {
    Start(): void {
        console.log("Hello, world!");
    }
}
const r = new Rob();
r.Start();

Then everything runs as it should do - which suits my use case just fine.


Solution

  • If you observe the entire output file rob.js, you will notice that it is actually an IIFE. This means that everything inside rob.js is not going to be visible to the "outside world". You cannot interact with it in this way.

    You can either write the entire logic in the "pre-compile" phase, in typescript, or you can use a different bundling system which supports authoring libraries such as webpack