Exporting a class with ES6 (Babel)

87,574

Solution 1

Browserify is meant to be fed a single "entry point" file, through which it recursively traverses all of your require statements, importing the code from other modules. So you should be require'ing the _babel.js versions of modules, not _browserified.js ones.

From the looks of it, you intend for your app's "entry point" to be demos/helicopter_game/PlayState_browserified.js, yeah? If that's the case:

  • In PlayState.js, change it to import {Game} from "../../lib/pentagine_babel.js";.
  • In Gruntfile.js, remove "lib/pentagine_browserified.js": "lib/pentagine_babel.js".

Works for me. Let me know if that suffices or I am misunderstanding your requirements here.

P.S. You can use babelify to avoid having separate Grunt tasks for Babel and Browserify. See my answer here for an example.

Solution 2

I had a slightly different file configuration, that gave me some difficulty to get the "require" syntax to work in Node, but this post gave me the hint on how to used the babel-ified version of the file name.

I am using WebStorm with the FileWatcher option set to Babel, and I have the FileWatcher configured to watch all files with suffix .jsx, and rename the compiled output file from {my_file}.jsx to {my_file}-compiled.js.

So in my test case, I have 2 files:

Person.jsx:

class Person { ... }

export { Person as default}

and another file that wants to import it:

Test.jsx:

var Person = require('./Person-compiled.js');

I couldn't get the "require" statement to find the module until I started the file path with './' and also add '-compiled.js' to properly specify the file name so that Node es5 could find the module.

I was also able to use the "import" syntax:

import Person from './Person-compiled.js';

Since I have set up my WebStorm project as a Node ES5 project, I have to run 'Test-compiled.js' (not 'Test.jsx').

Share:
87,574
David Gomes
Author by

David Gomes

Software Engineer who is really interested in UX. Graduated in Software Engineering in Portugal. Currently @memsql, previously @Unbabel.

Updated on January 09, 2020

Comments

  • David Gomes
    David Gomes over 4 years

    I'm writing some frontend code with ECMAScript 6 (transpiled with BabelJS, and then browserified with Browserify) so that I can have a class in one file, export it and import it in another file.

    The way I'm doing this is:

    export class Game {
        constructor(settings) {
    
        ...
    
        }
    }
    

    And then on the file that imports the class I do:

    import {Game} from "../../lib/pentagine_browserified.js";
    var myGame = new Game(settings);
    

    I then compile it with grunt, this is my Gruntfile:

    module.exports = function(grunt) {
      "use strict";
    
      grunt.loadNpmTasks('grunt-babel');
      grunt.loadNpmTasks('grunt-browserify');
    
      grunt.initConfig({
        "babel": {
          options: {
    
            sourceMap: false
          },
          dist: {
            files: {
              "lib/pentagine_babel.js": "lib/pentagine.js",
              "demos/helicopter_game/PlayState_babel.js": "demos/helicopter_game/PlayState.js"
            }
          }
        },
    
        "browserify": {
          dist: {
            files: {
              "lib/pentagine_browserified.js": "lib/pentagine_babel.js",
              "demos/helicopter_game/PlayState_browserified.js": "demos/helicopter_game/PlayState_babel.js"
            }
          }
        }
      });
    
      grunt.registerTask("default", ["babel", "browserify"]);
    };
    

    However, on the new Game( call, I get the following error:

    Uncaught TypeError: undefined is not a function
    

    As so, what I did was analyse the generated code by Babel and Browserify and I found this line on PlayState_browserified.js:

    var Game = require("../../lib/pentagine_browserified.js").Game;
    

    I decided to print the require output:

    console.log(require("../../lib/pentagine_browserified.js"));
    

    And it is nothing but an empty object. I decided to check out the pentagine_browserified.js file:

    var Game = exports.Game = (function () {
    

    It seems like it is correctly exporting the class, but for some other reason it is not being required on the other file.

    Also, I'm sure the file is being required properly because changing the string "../../lib/pentagine_browserified.js" spits out a Not Found error, so it is going for the right file, that I'm sure about.