4.21 Running ES6 modules with webpack

We now understand the differences between internal and external modules and the different module formats that we can use at runtime. As you have been able to experience in this chapter dealing with modules is a problem because JavaScript has been lacking a module format that works everywhere. The good news is that that module format is about to arrive and you already know about it. I’m talking about ES6 modules. TypeScript allows us to use ES6 modules at runtime. This means that the same syntax can be used at design time and runtime. On top of that we can expect ES6 modules to work natively in all browsers and Node.js in the future. This is the main reason why you should always try to use ES6 modules.

Getting Ready

All you need to implement in this recipe is an installation of TypeScript version 2.0 or higher, Gulp and the following Gulp plugins:

  • gulp-webpack
  • gulp-typescript
  • babel-core
  • babel-loader
  • babel-preset-es2015

How to do it

First you must compile your TypeScript files into JavaScript files which use the ES6 module declaration syntax:

gulp.task('build-es6-to-es6', function () {
    const tsProject = ts.createProject('tsconfig.json', {
        typescript: require('typescript'),
        target: 'es6',
        module: 'es6'
    });

    const input = './src/module_definitions/design_time/external/es6/*.ts';
    const output = './src/module_definitions/run_time/external/es6/';

    return gulp.src(input)
        .pipe(tsProject())
        .pipe(gulp.dest(output));
});

Now that we have our JavaScript files ready we can proceed to load them. The bad news is that it is the majority of JavaScript engines have not fully implemented yet the support for ES6 modules. For that reason, we must use a module loader able to load ES6 modules. This is exactly the role of webpack in this example. SystemJS is also able to load ES6 modules but we decided to use webpack to extend the number of tools included in this chapter. We are going to use webpack as a module bundler to generate a file named bundle.js which will contain all our ES6 modules and we will be able to use in a web browser.

module.exports = {
  output : {
      filename: "bundle.js",
      // export itself to a global var
      libraryTarget: "var",
      // name of the global var: "Foo"
      library: "ndrscr"
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015']
        }
      }
    ]
  }
}

After configuring webpack we can create a new Gulp task to generate the bundle.js file:

gulp.task('bundle-es6-with-webpack', function () {
    const webpackConfig = require('./src/module_loaders/webpack/webpack.config.js');
    return gulp.src('./src/module_definitions/run_time/external/es6/ndrscr.js')
        .pipe(webpack(webpackConfig))
        .pipe(gulp.dest('./src/module_loaders/webpack/'));
});

Finally, we can proceed to load the bundle.js file and the app.js file from the HTML document.

<script src="../../src/module_loaders/webpack/bundle.js"></script>
<script src="../../src/module_loaders/webpack/app.js"></script>

How it works

The webpack configuration file is a CommonJS module that exports an object literal. The object literal contains the actual webpack configuration. In this case we have used the following options:

  • Filename: Allow us to set the name of the output file.
  • Library target: Allow us to decide how we want to resulting library to be used (as a global variable in this case).
  • Library: Allow us to set the name of the library at runtime (similar to Browserify standalone).
  • Loaders: Allow us to use an external plugin to be used during the load of the modules. In this case we are using Babel to compile the ES6 modules into ES5 JavaScript so we can use them in environments without ES6 modules support.
Please refer to https://webpack.js.org/concepts/configuration/ to learn more about the available webpack configuration options.

Source Code

Running ES6 modules with webpack

See also

Please refer to the recipes about ES6 modules to learn about the declaration of external modules. Refer to chapter one to learn more about Gulp.


Shiv Kushwaha

Author/Programmer