First commit
This commit is contained in:
82
hGameTest/node_modules/haxe-modular/bin/cmd.js
generated
vendored
Executable file
82
hGameTest/node_modules/haxe-modular/bin/cmd.js
generated
vendored
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const args = [].concat(process.argv);
|
||||
const debugMode = remove(args, '-debug');
|
||||
const webpackMode = remove(args, '-webpack');
|
||||
const debugSourceMap = remove(args, '-debugmap');
|
||||
const dump = remove(args, '-dump');
|
||||
|
||||
if (args.length < 3)
|
||||
return printUsage();
|
||||
|
||||
if (debugMode || webpackMode) {
|
||||
console.log('Options:');
|
||||
if (debugMode) console.log('- generate sourcemaps');
|
||||
if (webpackMode) console.log('- generate webpack-compatible source');
|
||||
}
|
||||
|
||||
const t0 = new Date().getTime();
|
||||
const input = args[2];
|
||||
const output = args[3];
|
||||
const modules = args.slice(4);
|
||||
|
||||
const split = require('../tool/bin/split');
|
||||
const result = split.run(input, output, modules, debugMode, webpackMode, debugSourceMap, dump);
|
||||
|
||||
for (file of result) {
|
||||
if (!file || !file.source) continue;
|
||||
if (file.map) {
|
||||
writeIfChanged(file.map.path, file.map.content);
|
||||
}
|
||||
if (file.source) {
|
||||
const content = file.map
|
||||
? `${file.source.content}\n//# sourceMappingURL=${path.basename(file.map.path)}`
|
||||
: file.source.content;
|
||||
writeIfChanged(file.source.path, content);
|
||||
}
|
||||
if (file.debugMap) {
|
||||
writeIfChanged(file.source.path + '.map.html', file.debugMap);
|
||||
}
|
||||
}
|
||||
|
||||
const t1 = new Date().getTime();
|
||||
console.log(`Total process: ${t1 - t0}ms`);
|
||||
|
||||
|
||||
/* TOOLS */
|
||||
|
||||
function remove(a, v) {
|
||||
const i = a.indexOf(v);
|
||||
if (i < 0) return false;
|
||||
a.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
function hasChanged(path, content) {
|
||||
if (!fs.existsSync(path)) return true;
|
||||
var original = String(fs.readFileSync(path));
|
||||
return original != content;
|
||||
}
|
||||
|
||||
function writeIfChanged(path, content) {
|
||||
if (hasChanged(path, content)) {
|
||||
console.log('Write ' + path);
|
||||
fs.writeFileSync(path, content);
|
||||
}
|
||||
}
|
||||
|
||||
function printUsage() {
|
||||
console.log(`
|
||||
Haxe-JS code splitting, usage:
|
||||
haxe-split [-debug] [-webpack] <input.js> <output.js> [<module-1> ... <module-n>]
|
||||
|
||||
Arguments:
|
||||
-debug : generate source maps
|
||||
-webpack : generate webpack-compatible source
|
||||
input.js : path to input JS source
|
||||
output.js: path to output JS source
|
||||
module-i : qualified Haxe module name to split
|
||||
`);
|
||||
}
|
||||
58
hGameTest/node_modules/haxe-modular/package.json
generated
vendored
Normal file
58
hGameTest/node_modules/haxe-modular/package.json
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"_from": "haxe-modular@^0.6.0",
|
||||
"_id": "haxe-modular@0.6.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-yk58W3aqS/u88ojmsrObj5IuKig=",
|
||||
"_location": "/haxe-modular",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "haxe-modular@^0.6.0",
|
||||
"name": "haxe-modular",
|
||||
"escapedName": "haxe-modular",
|
||||
"rawSpec": "^0.6.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.6.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/haxe-loader"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/haxe-modular/-/haxe-modular-0.6.0.tgz",
|
||||
"_shasum": "ca4e7c5b76aa4bfbbcf288e6b2b39b8f922e2a28",
|
||||
"_spec": "haxe-modular@^0.6.0",
|
||||
"_where": "/home/andreas/Documents/Projects/haxe/openfl/nigger/node_modules/haxe-loader",
|
||||
"author": {
|
||||
"name": "Philippe Elsass"
|
||||
},
|
||||
"bin": {
|
||||
"haxe-split": "bin/cmd.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/elsassph/haxe-modular/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"acorn": "^4.0.3",
|
||||
"graphlib": "^2.1.1",
|
||||
"react-deep-force-update": "^2.0.1",
|
||||
"react-proxy": "^2.0.8",
|
||||
"source-map": "^0.5.6"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Code splitting and hot-reload for Haxe-JS applications.",
|
||||
"files": [
|
||||
"bin",
|
||||
"tool/bin",
|
||||
"runtime"
|
||||
],
|
||||
"homepage": "https://github.com/elsassph/haxe-modular#readme",
|
||||
"license": "ISC",
|
||||
"main": "runtime/index.js",
|
||||
"name": "haxe-modular",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/elsassph/haxe-modular.git"
|
||||
},
|
||||
"version": "0.6.0"
|
||||
}
|
||||
373
hGameTest/node_modules/haxe-modular/readme.md
generated
vendored
Normal file
373
hGameTest/node_modules/haxe-modular/readme.md
generated
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
# Modular Haxe-JS
|
||||
|
||||
Code splitting and hot-reload for Haxe-JS applications.
|
||||
|
||||
*Haxe modular is a set of tools and support classes allowing Webpack-like code-splitting,
|
||||
lazy loading and hot code reloading. Without Webpack and the JS fatigue.*
|
||||
|
||||
For complete architecture examples using this technique you can consult:
|
||||
|
||||
- [Haxe React+Redux sample](https://github.com/elsassph/haxe-react-redux)
|
||||
- [Haxe React+MMVC sample](https://github.com/elsassph/haxe-react-mmvc)
|
||||
|
||||
Notes:
|
||||
- There is in fact also a [webpack-haxe-loader](https://github.com/jasononeil/webpack-haxe-loader),
|
||||
based on this library.
|
||||
- Do not confuse with [modular-js](https://github.com/explorigin/modular-js/network),
|
||||
which has a similar general goal but a different approach based on emitting one JS file
|
||||
per Haxe class (check the forks).
|
||||
|
||||
> This project is compatible with Haxe 3.2.1+
|
||||
|
||||
## Context
|
||||
|
||||
JavaScript is one of the target platforms of
|
||||
[Haxe](http://haxe.org/documentation/introduction/language-introduction.html),
|
||||
a mature, strictly typed, high level, programming language offering a powerful type system
|
||||
and FP language features. The compiler stays very fast, even with massive codebases.
|
||||
|
||||
If anything, *optimised bundling* is exactly was Haxe does best: Haxe offers out of the
|
||||
box incomparable dead-code elimination and generates very efficient JavaScript.
|
||||
|
||||
What Haxe lacks natively is *code splitting and HMR*. Haxe doesn't suggest any best
|
||||
practice to implement it.
|
||||
|
||||
The goal of this project is to propose one robust and scalable solution.
|
||||
|
||||
## Overview of solution
|
||||
|
||||
1. NPM dependencies bundling in a single libs/vendor JavaScript file
|
||||
|
||||
Best practice (for speed and better caching) is to regroup all the NPM dependencies
|
||||
into a single JavaScript file, traditionally called `vendor.js` or `libs.js`.
|
||||
|
||||
2. Haxe-JS code and source-maps splitting, and lazy-loading
|
||||
|
||||
Code splitting works by identifying features which can be asynchronously loaded at
|
||||
run time. JS bundles can be created automatically by using the `Bundle.load` helper.
|
||||
|
||||
4. Hot-reload
|
||||
|
||||
A helper class can be used listen to a LiveReload server and reload lazy-loaded
|
||||
modules automatically.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
You need to install both a Haxe library and a NPM module:
|
||||
|
||||
# code splitting and hot-reload
|
||||
npm install haxe-modular --save
|
||||
|
||||
# Haxe support classes
|
||||
haxelib install modular
|
||||
|
||||
Add to your HXML:
|
||||
|
||||
# Haxe support classes and output rewriting
|
||||
-lib modular
|
||||
|
||||
|
||||
## NPM dependencies bundling
|
||||
|
||||
Best practice (for compilation speed and better caching) is to regroup all the NPM
|
||||
dependencies into a single JavaScript file, traditionally called `vendor.js` or `libs.js`.
|
||||
|
||||
It is absolutely required when doing a modular Haxe application sharing NPM modules,
|
||||
and in particular if you want to use the React hot-reload functionality.
|
||||
|
||||
### Template
|
||||
|
||||
Create a `src/libs.js` file using the following template:
|
||||
|
||||
```javascript
|
||||
//
|
||||
// npm dependencies library
|
||||
//
|
||||
(function(scope) {
|
||||
'use-strict';
|
||||
scope.__registry__ = Object.assign({}, scope.__registry__, {
|
||||
//
|
||||
// list npm modules required in Haxe
|
||||
//
|
||||
'react': require('react'),
|
||||
'react-dom': require('react-dom'),
|
||||
'redux': require('redux')
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// enable React hot-reload
|
||||
require('haxe-modular');
|
||||
}
|
||||
|
||||
})(typeof $hx_scope != "undefined" ? $hx_scope : $hx_scope = {});
|
||||
```
|
||||
|
||||
It hopefully is understandable that we are defining a "registry" of NPM modules.
|
||||
In the browser we will have a global object `window.$hx_scope.__registry__` used by
|
||||
Modular to resolve NPM modules.
|
||||
|
||||
It is important to correctly name the keys of the object (eg. `'react'`) to match the
|
||||
Haxe require calls (eg. `@:jsRequire('react')`).
|
||||
|
||||
For React hot-module replacement, you just have to `require('haxe-modular')`. Notice
|
||||
that this enablement is only for development mode and will be removed when doing a
|
||||
release build.
|
||||
|
||||
Tip: there is nothing forcing your to register NPM modules, you can register any
|
||||
valid JavaScript object here.
|
||||
|
||||
### Building
|
||||
|
||||
The library must be "compiled", that is required modules should be injected,
|
||||
typically using [Browserify](http://browserify.org/) (small, simple, and fast).
|
||||
|
||||
For development (code with sourcemaps):
|
||||
|
||||
browserify src/libs.js -o bin/libs.js -d
|
||||
|
||||
For release, optimise and minify:
|
||||
|
||||
cross-env NODE_ENV=production browserify src/libs.js | uglifyjs -c -m > bin/libs.js
|
||||
|
||||
The difference is significant: React+Redux goes from 1.8Mb for dev to 280Kb for release
|
||||
(and 65Kb with `gzip -6`).
|
||||
|
||||
Note:
|
||||
- `NODE_ENV=production` will tell UglifyJS to remove "development" code from modules,
|
||||
- `-d` to make source-maps, `-c` to compress, and `-m` to "mangle" (rename variables),
|
||||
- [cross-env](https://www.npmjs.com/package/cross-env) is needed to be able to set the
|
||||
`NODE_ENV` variable on Windows. Alternatively you can use `envify`.
|
||||
|
||||
### Usage
|
||||
|
||||
If you use NPM libraries (like React and its multiple addons), you will want to create
|
||||
at least one library. The library MUST be loaded before your Haxe code referencing
|
||||
them is loaded.
|
||||
|
||||
Simply reference the library file in your `index.html` in the right order:
|
||||
|
||||
```html
|
||||
<script src="libs.js"></script>
|
||||
<script src="index.js"></script>
|
||||
```
|
||||
|
||||
You can create other libraries, and even use the same [lazy loading](#lazy-loading) method
|
||||
to load them on demand, just like you will load Haxe modules. If you have a Haxe module
|
||||
with its own NPM dependencies, you will load the dependencies first, then the Haxe module.
|
||||
|
||||
**Important:**
|
||||
- all the NPM dependencies have to be moved into these NPM bundles,
|
||||
- do not run Browserify on the Haxe-JS files!
|
||||
|
||||
|
||||
## Haxe-JS code splitting
|
||||
|
||||
Code splitting requires a bit more planning than in JavaScript, so **read carefully**!
|
||||
|
||||
Features need to have one entry point class that can be loaded asynchronously.
|
||||
|
||||
A good way to split is to break down your application into "routes" (cf.
|
||||
[react-router](https://github.com/ReactTraining/react-router/tree/master/docs)) or
|
||||
reusable complex components.
|
||||
|
||||
### How it works
|
||||
|
||||
- A graph of the classes "direct references" is created,
|
||||
- The references graph is split at the entry point of bundles,
|
||||
- Each bundle will include the direct (non-split) graph of classes,
|
||||
- unless the class is present in the main bundle (it will be shared).
|
||||
|
||||
What is a direct reference?
|
||||
- `new A()`
|
||||
- `A.b` / `A.c()`
|
||||
- `Std.is(o, A)`
|
||||
- `cast(o, A)`
|
||||
- ...
|
||||
|
||||
#### Difference between Debug and Release builds
|
||||
|
||||
Debug builds are optimised for "hot-reload":
|
||||
|
||||
- Enums are compiled in the main bundle, otherwise you may load several incompatible
|
||||
instances of the enum definitions.
|
||||
- Transitive dependencies will be duplicated (eg. sub-components of views may be
|
||||
included in several routes) so you can hot-reload these sub-components.
|
||||
|
||||
Release builds are optimised for size:
|
||||
|
||||
- All classes (and their dependencies) used in more than one bundle will be included
|
||||
in the main bundle.
|
||||
|
||||
## Bundling
|
||||
|
||||
The `Bundle` class provides the module extraction functionality which then translates into
|
||||
the regular "Lazy loading" API.
|
||||
|
||||
```haxe
|
||||
import myapp.view.MyAppView;
|
||||
...
|
||||
Bundle.load(MyAppView).then(function(_) {
|
||||
// Class myapp.view.MyAppView can be safely used from now on.
|
||||
// It's time to render the view.
|
||||
new MyAppView();
|
||||
});
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
`Bundle.load(module:Class, loadCss:Bool = false):Promise<String>`
|
||||
|
||||
- `module`: the entry point class reference,
|
||||
- `loadCss`: optionally load a CSS file of the same name.
|
||||
- returns a Promise providing the name of the loaded module
|
||||
|
||||
(API is identical generally to the "Lazy loading" feature below)
|
||||
|
||||
### React-router usage
|
||||
|
||||
`Bundle.loadRoute(MyAppView)` generates a wrapper function to satisfy React-router's
|
||||
async routes API using [getComponent](https://github.com/ReactTraining/react-router/blob/master/docs/API.md#getcomponentnextstate-callback):
|
||||
|
||||
```js
|
||||
<Route getComponent=${Bundle.loadRoute(MyAppView)} />
|
||||
```
|
||||
|
||||
Magic! `MyAppView` will be extracted in its own bundle and loaded lazily when the
|
||||
route is activated.
|
||||
|
||||
|
||||
## Lazy loading
|
||||
|
||||
The `Require` class provides Promise-based lazy-loading functionality for JS files:
|
||||
|
||||
```haxe
|
||||
Require.module('view').then(function(_) {
|
||||
// 'view.js' was loaded and evaluated.
|
||||
});
|
||||
```
|
||||
|
||||
`Require.module` returns the same Promise for a same module unless it failed,
|
||||
otherwise, calling the function again will attempt to reload the failed script.
|
||||
|
||||
### API
|
||||
|
||||
`Require.module(module:String, loadCss:Bool = false):Promise<String>`
|
||||
|
||||
- `module`: the name of the JS file to load (Haxe-JS module or library),
|
||||
- `loadCss`: optionally load a CSS file of the same name.
|
||||
- returns a Promise providing the name of the loaded module
|
||||
|
||||
`Require.jsPath`: relative path to JS files (defaults to `./`)
|
||||
|
||||
`Require.cssPath`: relative path to CSS files (defaults to `./`)
|
||||
|
||||
|
||||
## Hot-reload
|
||||
|
||||
Hot-reload functionality is based on the lazy-loading feature.
|
||||
|
||||
Calling `Require.hot` will set up a LiveReload hook. When a JS file loaded using
|
||||
`Require.module` will change, it will be automatically reloaded and the callbacks will
|
||||
be triggered to allow the application to handle the change.
|
||||
|
||||
```haxe
|
||||
#if debug
|
||||
Require.hot(function(_) {
|
||||
// Some lazy-loaded module has been reloaded (eg. 'view.js').
|
||||
// Class myapp.view.MyAppView reference has now been updated,
|
||||
// and new instances will use the newly loaded code!
|
||||
// It's time to re-render the view.
|
||||
new MyAppView();
|
||||
});
|
||||
#end
|
||||
```
|
||||
|
||||
**Important**: hot-reload does NOT update code in existing instances - you must create new
|
||||
instances of reloaded classes to use the new code.
|
||||
|
||||
### API
|
||||
|
||||
`Require.hot(?handler:String -> Void, ?forModule:String):Void`
|
||||
|
||||
- `handler`: a callback to be notified of modules having reloaded
|
||||
- `forModule`: if provided, only be notified of a specific module changes
|
||||
|
||||
### React hot-reload wrapper
|
||||
|
||||
When using hot-reload for React views you will want to use the handy `autoRefresh` wrapper:
|
||||
|
||||
```haxe
|
||||
var app = ReactDOM.render(...);
|
||||
|
||||
#if (debug && react_hot)
|
||||
ReactHMR.autoRefresh(app);
|
||||
#end
|
||||
```
|
||||
|
||||
The feature leverages [react-proxy](https://github.com/gaearon/react-proxy/tree/master) and
|
||||
needs to be enabled by calling `require('haxe-modular')`, preferably in your NPM modules bundle.
|
||||
|
||||
Note: you must compile with `-D react_hot`. The feature is only enabled in `debug` mode.
|
||||
|
||||
### LiveReload server
|
||||
|
||||
The feature is based on the [LiveReload](https://livereload.com) API. `Require` will
|
||||
set a listener for `LiveReloadConnect` and register a "reloader plugin" to handle changes.
|
||||
|
||||
It is recommended to simply use [livereloadx](http://nitoyon.github.io/livereloadx/). The
|
||||
static mode dynamically injects the livereload client API script in HTML pages served:
|
||||
|
||||
npm install livereloadx -g
|
||||
livereloadx -s bin
|
||||
open http://localhost:35729
|
||||
|
||||
The reloader plugin will prevent page reloading when JS files change, and if the JS file
|
||||
corresponds to a lazy-loaded module, it is reloaded and re-evaluated.
|
||||
|
||||
The feature is simply based on filesystem changes, so you just have to rebuild the
|
||||
Haxe-JS application and let LiveReload inform our running application to reload some of
|
||||
the JavaScript files.
|
||||
|
||||
PS: stylesheets and static images will be normally live reloaded.
|
||||
|
||||
## Known issues
|
||||
|
||||
### Problem with init
|
||||
|
||||
If you don't know what `__init__` is, don't worry :)
|
||||
[If your're curious](http://old.haxe.org/doc/advanced/magic#initialization-magic)
|
||||
|
||||
When using `__init__` you may generate code that will not be moved to the right bundle:
|
||||
|
||||
- assume that `__init__` code will be duplicated in all the bundles,
|
||||
- unless you generate calls to static methods.
|
||||
|
||||
```haxe
|
||||
class MyComponent
|
||||
{
|
||||
static function __init__()
|
||||
{
|
||||
// these lines will go in all the bundles
|
||||
var foo = 42;
|
||||
untyped window.something = function() {...}
|
||||
|
||||
// these lines will go in the bundle containing MyComponent
|
||||
MyComponent.doSomething();
|
||||
if (...) MyComponent.anotherThing();
|
||||
|
||||
// this line will go in the bundle containing OtherComponent
|
||||
OtherComponent.someProp = 42;
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Further troubleshooting
|
||||
|
||||
Modular recognises a few additional debugging flags:
|
||||
|
||||
- `-D modular_dump`: generate an additional `.graph` file showing the relationship
|
||||
between classes,
|
||||
- `-D modular_debugmap`: generate, for each module, an additiona; `.map.html` file
|
||||
showing a visual representation of the sourcemap.
|
||||
48
hGameTest/node_modules/haxe-modular/runtime/index.js
generated
vendored
Normal file
48
hGameTest/node_modules/haxe-modular/runtime/index.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
var createProxy = require('react-proxy').default;
|
||||
var deepForceUpdate = require('react-deep-force-update');
|
||||
var React = require('react');
|
||||
|
||||
/* COMPONENT PROXY */
|
||||
|
||||
var proxies = {};
|
||||
|
||||
function register(classRef, name, file)
|
||||
{
|
||||
if (classRef == null || name == null || file == null) return;
|
||||
var key = name + '@' + file;
|
||||
if (proxies[key]) {
|
||||
classRef.__hx_proxy__ = key;
|
||||
classRef.displayName = name;
|
||||
proxies[key].update(classRef);
|
||||
}
|
||||
else {
|
||||
classRef.__hx_proxy__ = key;
|
||||
classRef.displayName = name;
|
||||
}
|
||||
}
|
||||
|
||||
function refresh(rootElement)
|
||||
{
|
||||
deepForceUpdate(rootElement);
|
||||
}
|
||||
|
||||
/* REACT OVERRIDE */
|
||||
|
||||
var _createElement = React.createElement;
|
||||
|
||||
React.createElement = function(type) {
|
||||
if (type && type.__hx_proxy__) {
|
||||
var proxy = proxies[type.__hx_proxy__];
|
||||
if (!proxy) proxy = proxies[type.__hx_proxy__] = createProxy(type);
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
args.unshift(proxy.get());
|
||||
return _createElement.apply(React, args);
|
||||
}
|
||||
|
||||
return _createElement.apply(React, arguments);
|
||||
}
|
||||
|
||||
module.exports = { register: register, refresh: refresh };
|
||||
|
||||
if (!window.__REACT_HOT_LOADER__)
|
||||
window.__REACT_HOT_LOADER__ = module.exports;
|
||||
1238
hGameTest/node_modules/haxe-modular/tool/bin/split.js
generated
vendored
Normal file
1238
hGameTest/node_modules/haxe-modular/tool/bin/split.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user