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.
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>
.
- 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.
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.
- 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
- Exclude from git the folder where you want to generate your Haxe's output:
echo "bin/" >> .gitignore
- 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.
- 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
}
}
]
}
}
- 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()
- 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)
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
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.
MIT