javascriptnode.jsmodulebrowserifybabelify

Importing class from module


I am trying to import a class from a module that I want to use in a browser. For this purpose I created an MCVE to check my understanding, though I get an

Uncaught SyntaxError: The requested module './test-class-bundle.js' does not provide an export named 'TestClass' error.

My MCVE consists of the following:

(1) A test-class.js that defines and exports the class TestClass.

(2) I use npm and gulp to browsify and babalify the test-class.js.

(3) example1.html is what I use to test this.

test-class.js

export class TestClass {
    constructor(greeting){
        this.greeting = greeting;
    }

    greet(){
        console.log(this.greeting);
    }
}

package.json

{
  "name": "test-class",
  "version": "1.0.0",
  "description": "",
  "main": "src/js/test-class.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "build": "gulp",
    "copyTests": "gulp copyTests",
    "startServer": "gulp startServer",
    "check": "gulp check"
  },
  "devDependencies": {
    "babel-preset-es2015": "^6.24.1",
    "babelify": "8.0.0",
    "browserify": "^16.2.3",
    "gulp": "^4.0.2",
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "del": "^4.1.1",
    "gulp-rename": "^1.4.0",
    "gulp-connect": "^5.7.0",
    "vinyl-source-stream": "^2.0.0",
    "webpack": "^4.35.0"
  }
}

gulpfile.js

//Include required modules
var gulp = require("gulp"),
    babelify = require('babelify'),
    browserify = require("browserify"),
    source = require("vinyl-source-stream"),
    connect = require('gulp-connect');

// Convert ES6 code in all js files in src/js folder and copy to
// build folder as bundle.js
gulp.task("build", function(){
    return browserify({
        entries: ["./src/js/test-class.js"]
    })
        .transform(babelify.configure({
            presets : ["es2015"]
        }))
        .bundle()
        .pipe(source("test-class-bundle.js"))
        .pipe(gulp.dest("./build"));
});

//Copy static files from html folder to build folder
gulp.task("copyTests", function(){
    return gulp.src("./test/html/*.*")
        .pipe(gulp.dest("./build"));
});

//Start a test server with doc root at build folder and
//listening to 9001 port. Home page = http://localhost:9001
gulp.task("startServer", function(){
    connect.server({
        root : "./build",
        livereload : true,
        port : 9001
    });
});

//Default task. This will be run when no task is passed in arguments to gulp
gulp.task("default", gulp.series("build", "copyTests"));

gulp.task("check", gulp.series("build", "copyTests", "startServer"));

example1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
</head>

<body>
<div><h2>Test</h2></div>
<script type="module">
    import {TestClass} from "./test-class-bundle.js";
    let testClass = new TestClass("Please work, pretty please!");
    testClass.greet();
</script>

</body>
</html>

Directory structure

/build
/src
    /js
         test-class.js
/test
    /html
         example1.html

I test this by running npm run check, which starts a server on localhost:9001, which when accessed from my browser, results in the given error appearing in the console log.

I have not used Javascript for over 10 years, so much of this is very new to me. If someone can enlighten me, I will really appreciate it. Thanks!


Solution

  • Depending on which browsers you have to support, you don't really need Gulp, Browserify and Babel. Try importing the JS file directly instead of the bundle, it works in all modern browsers (Edge, Firefox, Chrome, Safari):

    example1.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8"/>
    </head>
    
    <body>
    <div><h2>Test</h2></div>
    <script type="module">
        import {TestClass} from "./test-class.js";
        let testClass = new TestClass("Please work, pretty please!");
        testClass.greet();
    </script>
    
    </body>
    </html>
    

    If you must support Internet Explorer 11 and older, you cannot use <script type="module"> at all.