First commit
This commit is contained in:
201
hGameTest/node_modules/haxe-loader/README.md
generated
vendored
Normal file
201
hGameTest/node_modules/haxe-loader/README.md
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
# 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
|
||||
223
hGameTest/node_modules/haxe-loader/index.js
generated
vendored
Normal file
223
hGameTest/node_modules/haxe-loader/index.js
generated
vendored
Normal file
@@ -0,0 +1,223 @@
|
||||
"use_strict";
|
||||
|
||||
const loaderUtils = require('loader-utils');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const exec = require('child_process').exec;
|
||||
const tmp = require('tmp');
|
||||
const hash = require('hash-sum');
|
||||
const split = require('haxe-modular/tool/bin/split');
|
||||
|
||||
const cache = Object.create(null);
|
||||
|
||||
module.exports = function(hxmlContent) {
|
||||
const context = this;
|
||||
const options = loaderUtils.getOptions(context) || {};
|
||||
context.cacheable && context.cacheable();
|
||||
const cb = context.async();
|
||||
|
||||
const request = context.resourcePath;
|
||||
if (!request) {
|
||||
// Loader was called without specifying a hxml file
|
||||
// Expecting a require of the form '!haxe-loader?hxmlName/moduleName!'
|
||||
fromCache(context, context.query, cb);
|
||||
return;
|
||||
}
|
||||
|
||||
const ns = path.basename(request).replace('.hxml', '');
|
||||
const jsTempFile = makeJSTempFile(ns);
|
||||
const { jsOutputFile, classpath, args } = prepare(options, context, ns, hxmlContent, jsTempFile);
|
||||
|
||||
registerDepencencies(context, classpath);
|
||||
|
||||
// Execute the Haxe build.
|
||||
console.log('haxe', args.join(' '));
|
||||
exec(`haxe ${args.join(' ')}`, (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
// If the hxml file outputs something other than client JS, we should not include it in the bundle.
|
||||
// We're only passing it through webpack so that we get `watch` and the like to work.
|
||||
if (!jsOutputFile) {
|
||||
// We allow the user to configure a timeout so the server has a chance to restart before webpack triggers a page refresh.
|
||||
var delay = options.delayForNonJsBuilds || 0;
|
||||
setTimeout(() => {
|
||||
// We will include a random string in the output so that the dev server notices a difference and triggers a page refresh.
|
||||
cb(null, "// " + Math.random())
|
||||
}, delay);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the resulting JS file and return the main module
|
||||
const processed = processOutput(ns, jsTempFile, jsOutputFile);
|
||||
if (processed) {
|
||||
updateCache(context, ns, processed, classpath);
|
||||
}
|
||||
returnModule(context, ns, 'Main', cb);
|
||||
});
|
||||
};
|
||||
|
||||
function updateCache(context, ns, { contentHash, results }, classpath) {
|
||||
cache[ns] = { contentHash, results, classpath };
|
||||
}
|
||||
|
||||
function processOutput(ns, jsTempFile, jsOutputFile) {
|
||||
const content = fs.readFileSync(jsTempFile.path);
|
||||
// Check whether the output has changed since last build
|
||||
const contentHash = hash(content);
|
||||
if (cache[ns] && cache[ns].hash === contentHash)
|
||||
return null;
|
||||
|
||||
// Split output
|
||||
const modules = findImports(content);
|
||||
const debug = fs.existsSync(`${jsTempFile.path}.map`);
|
||||
const results = split.run(jsTempFile.path, jsOutputFile, modules, debug, true)
|
||||
.filter(entry => entry && entry.source);
|
||||
|
||||
// Inject .hx sources in map file
|
||||
results.forEach(entry => {
|
||||
if (entry.map) {
|
||||
const map = entry.map.content = JSON.parse(entry.map.content);
|
||||
map.sourcesContent = map.sources.map(path => {
|
||||
try {
|
||||
if (path.startsWith('file:///')) path = path.substr(8);
|
||||
return fs.readFileSync(path).toString();
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Delete temp files
|
||||
jsTempFile.cleanup();
|
||||
|
||||
return { contentHash, results };
|
||||
}
|
||||
|
||||
function returnModule(context, ns, name, cb) {
|
||||
const { results, classpath } = cache[ns];
|
||||
if (!results.length) {
|
||||
throw new Error(`${ns}.hxml did not emit any modules`);
|
||||
}
|
||||
|
||||
const entry = results.find(entry => entry.name === name);
|
||||
if (!entry) {
|
||||
throw new Error(`${ns}.hxml did not emit a module called '${name}'`);
|
||||
}
|
||||
|
||||
cb(null, entry.source.content, entry.map ? entry.map.content : null);
|
||||
}
|
||||
|
||||
function fromCache(context, query, cb) {
|
||||
// To locate a split module we expect a query of the form '?hxmlName/moduleName'
|
||||
const options = /\?([^/]+)\/(.*)/.exec(query);
|
||||
if (!options) {
|
||||
throw new Error(`Invalid query: ${query}`);
|
||||
}
|
||||
const ns = options[1];
|
||||
const name = options[2];
|
||||
|
||||
const cached = cache[ns];
|
||||
if (!cached) {
|
||||
throw new Error(`${ns}.hxml is not a known entry point`);
|
||||
}
|
||||
|
||||
registerDepencencies(context, cached.classpath);
|
||||
|
||||
if (!cached.results.length) {
|
||||
throw new Error(`${ns}.hxml did not emit any modules`);
|
||||
}
|
||||
returnModule(context, ns, name, cb);
|
||||
}
|
||||
|
||||
function findImports(content) {
|
||||
// Webpack.load() emits a call to System.import with a query to haxe-loader
|
||||
const reImports = /System.import\("!haxe-loader\?([^!]+)/g;
|
||||
const results = [];
|
||||
|
||||
let match = reImports.exec(content);
|
||||
while (match) {
|
||||
// Module reference is of the form 'hxmlName/moduleName'
|
||||
const name = match[1].substr(match[1].indexOf('/') + 1);
|
||||
results.push(name);
|
||||
match = reImports.exec(content);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
function makeJSTempFile() {
|
||||
const path = tmp.tmpNameSync({ postfix: '.js' });
|
||||
const nop = () => {};
|
||||
const cleanup = () => {
|
||||
fs.unlink(path, nop);
|
||||
fs.unlink(`${path}.map`, nop);
|
||||
};
|
||||
return { path, cleanup };
|
||||
}
|
||||
|
||||
function registerDepencencies(context, classpath) {
|
||||
// Listen for any changes in the classpath
|
||||
classpath.forEach(path => context.addContextDependency(path));
|
||||
}
|
||||
|
||||
function prepare(options, context, ns, hxmlContent, jsTempFile) {
|
||||
const args = [];
|
||||
const classpath = [];
|
||||
let jsOutputFile = null;
|
||||
let mainClass = 'Main';
|
||||
let isNodeJs = false;
|
||||
|
||||
// Add args that are specific to hxml-loader
|
||||
if (options.debug) {
|
||||
args.push('-debug');
|
||||
}
|
||||
args.push('-D', `webpack_namespace=${ns}`);
|
||||
|
||||
// Process all of the args in the hxml file.
|
||||
for (let line of hxmlContent.split('\n')) {
|
||||
line = line.trim();
|
||||
if (line === '' || line.substr(0, 1) === '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let space = line.indexOf(' ');
|
||||
let name = space > -1 ? line.substr(0, space) : line;
|
||||
args.push(name);
|
||||
|
||||
if (name === '--next') {
|
||||
var err = `${context.resourcePath} included a "--next" line, hxml-loader only supports a single build per hxml file.`;
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
if (space > -1) {
|
||||
let value = line.substr(space + 1).trim();
|
||||
|
||||
if (name === '-js' && !isNodeJs) {
|
||||
jsOutputFile = value;
|
||||
args.push(jsTempFile.path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name === '-cp') {
|
||||
classpath.push(path.resolve(value));
|
||||
}
|
||||
|
||||
if (name === '-lib' && value == 'hxnodejs') {
|
||||
isNodeJs = true;
|
||||
if (jsOutputFile) {
|
||||
// If a JS output file was already set to use a webpack temp file, go back and undo that.
|
||||
args = args.map(arg => (arg === jsTempFile.path) ? value : arg);
|
||||
jsOutputFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
args.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.extra) args.push(options.extra);
|
||||
|
||||
return { jsOutputFile, classpath, args };
|
||||
}
|
||||
53
hGameTest/node_modules/haxe-loader/package.json
generated
vendored
Normal file
53
hGameTest/node_modules/haxe-loader/package.json
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"_from": "haxe-loader@^0.5.0",
|
||||
"_id": "haxe-loader@0.5.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-crF8DxbxJfRmn4e/9r62tQYujeY=",
|
||||
"_location": "/haxe-loader",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "haxe-loader@^0.5.0",
|
||||
"name": "haxe-loader",
|
||||
"escapedName": "haxe-loader",
|
||||
"rawSpec": "^0.5.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.5.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#DEV:/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/haxe-loader/-/haxe-loader-0.5.0.tgz",
|
||||
"_shasum": "72b17c0f16f125f4669f87bff6beb6b5062e8de6",
|
||||
"_spec": "haxe-loader@^0.5.0",
|
||||
"_where": "/home/andreas/Documents/Projects/haxe/openfl/nigger",
|
||||
"author": {
|
||||
"name": "Jason O'Neil",
|
||||
"email": "jason.oneil@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jasononeil/webpack-haxe-loader/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"hash-sum": "^1.0.2",
|
||||
"haxe-modular": "^0.6.0",
|
||||
"loader-utils": "^1.1.0",
|
||||
"tmp": "0.0.31"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A webpack loader allowing you to compile Haxe as part of your Webpack build",
|
||||
"files": [
|
||||
"index.js",
|
||||
"README.md"
|
||||
],
|
||||
"homepage": "https://github.com/jasononeil/webpack-haxe-loader#readme",
|
||||
"license": "MIT",
|
||||
"name": "haxe-loader",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jasononeil/webpack-haxe-loader.git"
|
||||
},
|
||||
"version": "0.5.0"
|
||||
}
|
||||
Reference in New Issue
Block a user