Haxe Loader for Webpack
This loader allows you to load hxml files directly into webpack, and included the Haxe-compiled Javascript result directly in your bundle.
There are several reasons for doing this:
- If you are going to use NPM libraries as externs, you need to compile with Webpack or Browserify etc. Having the two compile steps (Haxe and Webpack) makes it easier.
- There's a good chance you'll want webpack anyway for compiling CSS (or SASS or LESS), managing static assets, or minifying the resulting JS bundle.
- When Webpack is set up right, it has a nice development experience, with things like:
webpack --watchto watch any changes you make to a file and recompile.webpack-dev-serverto hot-reload a page based on changes you make.
With this loader, you are able to:
- Use a
hxmlfile as the entry point for your build. - Change any
*.hxsource file, and have haxe re-compile, webpack re-bundle, and the browser refresh automatically as soon as you save.
Currently the loader only supports HXML files which export exactly one output, so you cannot use --next to build multiple things. Instead you can use multiple hxml files and list each of them in Webpack.
If you try to build a hxml file that is for another target, like Neko, PHP or CPP - the hxml file will be executed and an empty JS file will be passed on to webpack, which you can safely ignore - see below for details.
Example webpack configuration
module.exports = {
entry: {
client: './client.hxml',
server: './server.hxml', // Could compile PHP or Neko etc, does not have to be JS.
},
output: {
path: __dirname + "/www/assets",
filename: '[name].bundle.js'
},
module: {
rules: [
// Have a rule that explains hxml files should use `haxe-loader`.
{
test: /\.hxml$/,
loader: 'haxe-loader',
}
]
},
};
You can also add some convenience scripts to your package.json:
"scripts": {
"build": "webpack -p",
"start": "webpack-dev-server --open",
"server": "cd www && nodemon server.js",
"test": "cd www && node test.js",
"test_watch": "cd www && nodemon test.js"
},
Now you can run:
- `yarn build` - Use webpack to build a production copy of your app
- `yarn start` - Start the webpack dev server, which will watch for changes, recompile and refresh the browser.
- `yarn server` - Start a NodeJS server (if "www/server.js" is a NodeJS file you have compiled)
- `yarn test` - Run a test suite once (if "www/test.js" is a NodeJS file you have compiled)
- `yarn test_watch` - Build and run a test suite on every change (if "www/test.js" is a NodeJS file you have compiled)
Please note npm run ... also works just fine.
Requiring files
Note: you must add -lib haxe-loader to your HXML to use the Webpack class.
Synchronous requires
To require 3rd party NPM modules, you can use @:jsRequire metadata or
js.Lib.require().
However, those requires are relative to you HXML file! It also cannot be compiled on platforms other than JS.
It is thus recommended to call instead:
Webpack.require('./MyFile.css'); // requires a CSS file in the same directory as the current ".hx" file
Webpack.require('../locales.json'); // requires a JSON file in the parent directory of the current ".hx" file
It is silently ignored on non-JS targets. In future we may try to handle require statements for other targets.
Asynchronous requires (code splitting)
To leverage code splitting, you must use the Webpack.load require,
and provide the Haxe module you want to load as a separate bundle:
import com.MyComponent;
...
Webpack.load(MyComponent).then(function(_){
var comp = new MyComponent();
});
Using this API, the Haxe compiler output will be processed and cut into separate files.
Dev server setup
You can use webpack-dev-server to watch changes and auto-refresh a page after Haxe has compiled any changes.
Install webpack-dev-server
yarn add --dev webpack-dev-server # Or you can `npm install --dev webpack-dev-server`
Add some configuration to your webpack.config.js:
devServer: {
contentBase: "./www", // Your web root is in the "www" folder
publicPath: "/assets/", // The JS or assets webpack is building are in "www/assets"
overlay: true, // Display compilation errors in the browser
},
Add a script to your package.json:
"scripts": {
"start": "webpack-dev-server --open",
},
Run yarn run start to start the development server.
If you have a backend you want to use, for example Nekotools running on http://localhost:2000, webpack-dev-server comes with a proxy:
devServer: {
contentBase: "./www", // The server will run from this directory
overlay: true, // If there are errors while rebuilding they will be overlayed on the page
proxy: { // Proxy all requests to localhost:2000
"/": {
changeOrigin: true,
target: "http://localhost:2000"
}
},
publicPath: "/js/" // Webpack assets are compiled to this folder, these will be intercepted by the dev server (and not proxied).
},
Compiling non-JS assets
You can use Webpack and haxe-loader to compile all of your hxml files, not just those targeting client side Javascript. This way you can have webpack watch, rebuild and refresh your page for PHP, NodeJS, Neko etc.
When you use this option, Haxe will output the compilation files specified in your hxml file, but Webpack will still emit a JS bundle.
For example, you might end up with a file named php-server.bundle.js.
If you look inside, you'll realise that this file contains nothing other than some webpack boilerplate.
You do not need to include this file as a script in your HTML.
If you do however, webpack-dev-server will know to refresh the page every time the PHP files are rebuilt.
If you are using NodeJS as a server, and would like it to restart after a compilation, you can use "nodemon":
nodemon server.js
Given that there will be a delay between Haxe finishing building "server.js" and nodemon restarting the server, you may wish to delay webpack refreshing the page. You can specify a delay in milliseconds using the "delayForNonJsBuilds" option:
module: {
rules: [
{
test: /\.hxml$/,
use: [{ loader: 'haxe-loader', options: {delayForNonJsBuilds: 300} }],
},
],
}
Contributing
Don't hesitate to create a pull request. Every contribution is appreciated.
Maintainers
Jason O'Neil |
Philippe Elsass |
License
MIT