202 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # 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 --watch` to watch any changes you make to a file and recompile.
 | |
|     - `webpack-dev-server` to hot-reload a page based on changes you make.
 | |
| 
 | |
| With this loader, you are able to:
 | |
| 
 | |
| - Use a `hxml` file as the entry point for your build.
 | |
| - Change any `*.hx` source 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
 | |
| 
 | |
| ```js
 | |
| 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`:
 | |
| 
 | |
| ```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()`](http://api.haxe.org/js/Lib.html#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:
 | |
| 
 | |
| ```haxe
 | |
| 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:
 | |
| 
 | |
| ```haxe
 | |
| 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](https://webpack.js.org/configuration/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:
 | |
| 
 | |
| ```js
 | |
|     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
 | |
| 
 | |
| <table>
 | |
|   <tbody>
 | |
|     <tr>
 | |
|       <td align="center">
 | |
|         <a href="https://github.com/jasononeil">
 | |
|           <img width="150" height="150" src="https://github.com/jasononeil.png?v=3&s=150">
 | |
|           </br>
 | |
|           Jason O'Neil
 | |
|         </a>
 | |
|       </td>
 | |
|       <td align="center">
 | |
|         <a href="https://github.com/elsassph">
 | |
|           <img width="150" height="150" src="https://github.com/elsassph.png?v=3&s=150">
 | |
|           </br>
 | |
|           Philippe Elsass
 | |
|         </a>
 | |
|       </td>
 | |
|     </tr>
 | |
|   <tbody>
 | |
| </table>
 | |
| 
 | |
| ### License
 | |
| 
 | |
| MIT
 |