Skip to content

The simplest Webpack Loader for the Haxe programming language.

License

Notifications You must be signed in to change notification settings

vrescobar/webpack-simple-haxe-loader

 
 

Repository files navigation

The simplest Webpack Loader for Haxe code

This is the simplest and most compatible Haxe loader for webpack that exists.

It takes the javascript output as it is created by your hxml haxe file and passes it to webpack without any other additional transformation. That means that any library, feature or haxe version will be supported as long as the generated JS files by your hxml are self-contained.

That means that in your projects you can use the newest haxe release and just import your new JS ES6 Haxe generated classes without any trouble. Or use any additional library or extern without the risk of any incompatibility, as you would do in any other bare haxe project.

Example of usage with ES6 class import style:

import {MyClass} from '../build.hxml'; 
var a = new MyClass();

import * as hx from 'hx/app.hxml'; 
var b = new hx.MyClass();

// Also es5 build is still supported
const haxe_ns = require('src/NS/build.hxml'); 
var c = haxe_ns.MyClass();

During development with yarn serve a complete rebuild of such hxml will be retriggered when any file under the haxe class path is changed.

Features tested and technical notes

No tricks or hacks were applied: the single js file generated by your haxe project is pushed to webpack. The symbols you marked as @exposed will be available at module level. If a main is included it will be executed at import time.

That means:

  • Import seamlessly any Haxe code to a larger Javascript project.
  • During development, any change on the haxe source files will retrigger a rebuild.
  • There is support for compilation as library only
  • There is support for a Main (optional)
  • All symbols exposed will be at the namespace from your hxml
  • ES6 javascript code from Haxe 4 works fine (Haxe version 4 has the flag -D js-es=6)
  • You can pass generated ES6 code to a babel pipeline within webpack.
  • SourceMaps: if any *.map files are found these will be passed to webpack (Haxe's flag -D source-map-content)
  • No one stops you from generating Type Script definitions with -lib hxtsdgen (see project)
  • Chrome and webpack source maps perfect in Chrome when using devtool: 'source-map'. Firefox never worked for me.

Because it just uses the raw vanilla haxe's HXML file and reads the whole bundle you could use virtually any library, extern as long as it creates a single bundle as pointed by the flags -js <filename>.

Not tested:

  • If there are many -js targets (due --next usage) each bundle is read and passed to webpack. This option has not been tested yet.
  • Splitting a single hxml build in multiple files has not been tested and I believe that this falls out of the scope from this simple loader since as far as I know it is not an option supported out of the box ba the haxe compiler.

Installation & Setup

NPM:

npm install --save-dev https://github.com/vrescobar/webpack-simple-haxe-loader

Yarn:

yarn add --dev https://github.com/vrescobar/webpack-simple-haxe-loader

In the future I might build the project and release it at npm... or not.

Configuration

  1. Create a build hxml named for example app.hxml:
-D js-es=6
-D source-map-content
-cp srchx/
-js bin/haxeapp.js
MyClass
# A main is not necessary but it works:
# -main Main 
  1. Exclude from git the folder where you want to generate your Haxe's output:
echo "bin/" >> .gitignore
  1. Create a haxe class named MyClass at srchx/MyClass.hx
@:expose
class MyClass {
  var names:Array<String>;
  function new() {
    this.names = new Array();
  }
  public function addName(name:String) {
    this.names.push(name);
  }
  public function hello() {
    var names = this.names.map(n -> 'Hi $n!');
    return names.join("\n");
  }
  public function test() {
	  throw "Thrown exception";
  }
}

You can test now already whether haxe compiles by using: haxe app.hxml. The only requirement on haxe is that bin/haxeapp.js and bin/haxeapp.js.map are generated.

  1. Setup your webpack. If you use vue-cli with chainWebpack edit your vue.config.js:
module.exports = {
  configureWebpack: {
    devtool: 'source-map',
  chainWebpack: (config) => {
    config.module
      .rule('simple-haxe-loader')
      .test(/\.hxml$/)
      .use('simple-haxe-loader')
        .loader('simple-haxe-loader')
        .options({
          debug: true
        })
      .end()
  }
}

If you use instead webpack.config.js something like that:

module.exports = {
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.hxml$/,
        loader: 'simple-haxe-loader',
        options: {
          debug: true
        }
      }
    ]
  }
}
  1. Use your class from javascript (remember to import paths relatives to the source):
import {MyClass} from '../app.hxml';
var c = new MyClass();
c.addName("Haxe")
c.addName("Webpack!")
console.log(c.hello());
c.test_exception()
  1. Develop as usual

Use yarn serve or npm serve as usual and look at the javascript console. Hopefully even the source maps point to the proper failing line of code.

Hi Haxe!
Hi Webpack!!
Boot.hx:33 Uncaught Error: Thrown exception
    at MyClass.test (MyClass.hx:18)

Supported options

A few options were kept from the original project. Be aware that debug and server will be just strings concatenated to the end of your hxml commands!

  • options.server : -> (string) Adds the option to compiler's "--server " command line
  • options.debug -> (boolean) Passes the flag "-debug" to the end of haxe's command

The following options are kept for debugging purposes and I might remove them in future revisions:

  • options.ignoreWarnings -> (boolean) Ignores haxe's compile warnings warnings
  • options.logCommand -> (boolean) Prints haxe's command when compiling
  • options.emitStdoutAsWarning -> (boolean) Any STDOUT form haxe's compilation will be printed as warning

Story and Additional Credits

Although I myself (Víctor) wrote most of the current loader, the code was originally forked from the original webpack-haxe-loader writen by Jason O'Neil.

The motivation for this fork was to create a loader which supports raw haxe javascript as emitted. If I could import those emitted js files in my javascript project, why the webpack loader was so picky on certain haxe features and versions and forced me to have a main file?

Originally I needed to support ES6 and Haxe libraries in a larger Javascript project (larger Vue.js project with little Haxe). I didn't like that a main file was required. In addition the original loader crashed with exposed libraries.

The code still uses a part of the original structure and the additional feature support comes from stripping down unnecessary parts of the original project. I publish this fork as I believe the fork will not be accepted in a Pull Request as having different goals.

For a more complex use case don't hesitate to check the original repository.

License

MIT

About

The simplest Webpack Loader for the Haxe programming language.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 51.0%
  • Haxe 48.4%
  • Shell 0.6%