added project files
This commit is contained in:
parent
b3d759b8f7
commit
33e18d8f2a
9
app/build.hxml
Normal file
9
app/build.hxml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
-lib haxe-loader
|
||||||
|
-lib react
|
||||||
|
-lib react-router-4
|
||||||
|
|
||||||
|
-cp src
|
||||||
|
-js app.js
|
||||||
|
-main App
|
||||||
|
|
||||||
|
-D react_hot
|
||||||
14
app/hmm.json
Normal file
14
app/hmm.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "haxe-loader",
|
||||||
|
"type": "haxelib",
|
||||||
|
"version": "0.9.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "react",
|
||||||
|
"type": "haxelib",
|
||||||
|
"version": "1.4.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
25
app/package.json
Normal file
25
app/package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "webpack-haxe-example",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"css-loader": "^2.0.2",
|
||||||
|
"file-loader": "^3.0.1",
|
||||||
|
"haxe-loader": "^0.9.0",
|
||||||
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"react": "^16.7.0",
|
||||||
|
"react-dom": "^16.7.0",
|
||||||
|
"react-router": "^5.2.0",
|
||||||
|
"react-router-dom": "^5.2.0",
|
||||||
|
"style-loader": "^0.23.1",
|
||||||
|
"webpack": "^4.28.2",
|
||||||
|
"webpack-cli": "^3.1.2",
|
||||||
|
"webpack-dev-server": "^3.1.12"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "webpack-dev-server",
|
||||||
|
"build:dev": "webpack",
|
||||||
|
"build": "webpack"
|
||||||
|
}
|
||||||
|
}
|
||||||
131
app/readme.md
Normal file
131
app/readme.md
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
# Modular Haxe JS with Webpack
|
||||||
|
|
||||||
|
This project demonstrates the creation of a Haxe-JavaScript modular project leveraging Webpack
|
||||||
|
for bundling (code and assets) and lazy loading.
|
||||||
|
|
||||||
|
It's really easy and absolutely transparent in the code!
|
||||||
|
|
||||||
|
**Note: this is a "vanilla DOM" example - no 3rd party library involved!**
|
||||||
|
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
### Leveraging Webpack features
|
||||||
|
|
||||||
|
You will need to get familiar with how Webpack works - thankfully the documentation
|
||||||
|
is excellent nowadays: [https://webpack.js.org/](https://webpack.js.org/)
|
||||||
|
|
||||||
|
A project aims at creating a Webpack loader for Haxe:
|
||||||
|
[https://github.com/jasononeil/webpack-haxe-loader](https://github.com/jasononeil/webpack-haxe-loader)
|
||||||
|
|
||||||
|
Every asset dependency should be explictely required, so Webpack knows what to include
|
||||||
|
in the output folder. With the right configuration, small assets can even be inlined in
|
||||||
|
the bundle to reduce the number of requests.
|
||||||
|
|
||||||
|
```haxe
|
||||||
|
Webpack.require('./index.css');
|
||||||
|
|
||||||
|
var img = new Image();
|
||||||
|
img.src = Webpack.require('./logo.png');
|
||||||
|
```
|
||||||
|
|
||||||
|
Even the HTML page is generated by a plugin, so everything has to go through Webpack.
|
||||||
|
|
||||||
|
### Haxe JS code splitting
|
||||||
|
|
||||||
|
Haxe JS isn't normally capable of code splitting, but the core functionality was
|
||||||
|
developped within the (Webpack-free) Haxe Modular project:
|
||||||
|
[https://github.com/elsassph/haxe-modular](https://github.com/elsassph/haxe-modular)
|
||||||
|
|
||||||
|
The Haxe Webpack loader will leverage the code splitting feature when you request
|
||||||
|
modules asynchronously:
|
||||||
|
|
||||||
|
```haxe
|
||||||
|
import com.Foo;
|
||||||
|
...
|
||||||
|
// Extract Foo (and dependencies) into a separate bundle
|
||||||
|
Webpack.load(Foo).then(function(_) {
|
||||||
|
// Foo is now loaded
|
||||||
|
var foo = new Foo();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webpack config
|
||||||
|
|
||||||
|
Webpack's "magic" is configured in the `webpack.config.js`. It is a very powerful and
|
||||||
|
flexible system which is documented here: [https://webpack.js.org/](https://webpack.js.org/)
|
||||||
|
|
||||||
|
The basics is that the `haxe-loader` allow to "require" an
|
||||||
|
[HXML file](https://haxe.org/manual/compiler-usage-hxml.html),
|
||||||
|
which in turn will provide the (splitted) JS output to Webpack.
|
||||||
|
|
||||||
|
This feature is added as a "rule" in the config:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
test: /\.hxml$/,
|
||||||
|
loader: 'haxe-loader',
|
||||||
|
options: {
|
||||||
|
extra: `-D some_extra=arguments`,
|
||||||
|
debug: debugMode
|
||||||
|
}
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
HXMLs can be require directly from JS code, or as an entry point, which allows to
|
||||||
|
make a pure Haxe Webpack project:
|
||||||
|
```
|
||||||
|
entry: {
|
||||||
|
app: './build.hxml'
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Tools
|
||||||
|
|
||||||
|
Using [yarn](https://yarnpkg.com) for node modules is recommended:
|
||||||
|
|
||||||
|
npm install yarn -g
|
||||||
|
|
||||||
|
Using [hmm](https://github.com/andywhite37/hmm) for haxelibs is recommended:
|
||||||
|
|
||||||
|
haxelib --global install hmm
|
||||||
|
haxelib --global run hmm setup
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
Install npm and haxe dependencies:
|
||||||
|
|
||||||
|
yarn install
|
||||||
|
hmm install
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
Then start Webpack webserver, open `http://localhost:9000`, and enjoy live reload:
|
||||||
|
|
||||||
|
yarn start
|
||||||
|
|
||||||
|
### Hot Module Replacement
|
||||||
|
|
||||||
|
Hot-Module Replacement is the technique allowing, while your browser is showing your
|
||||||
|
live application, to hot-reload CSS and the Haxe modules!
|
||||||
|
|
||||||
|
React views in asynchronous modules will automatically refresh themselves if you edit
|
||||||
|
and save: Webpack will recompile the project, reload the module, and re-render the
|
||||||
|
views without losing state. un and try editing `Foo.hx`!
|
||||||
|
|
||||||
|
For that you only need to:
|
||||||
|
- add `-D react_hot` in your `hxml`,
|
||||||
|
- call `ReactHMR.autoRefresh` after the main render (see `App.hx`),
|
||||||
|
- run in live debug mode (`yarn start`).
|
||||||
|
|
||||||
|
### Releasing
|
||||||
|
|
||||||
|
To build the project statically, run:
|
||||||
|
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
For a production release:
|
||||||
|
|
||||||
|
export NODE_ENV=production
|
||||||
|
yarn build -p
|
||||||
15
app/src/App.css
Normal file
15
app/src/App.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
/* margin: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
main{
|
||||||
|
margin: 20px;
|
||||||
|
background-color: #eee;
|
||||||
|
min-height: 300px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
43
app/src/App.hx
Normal file
43
app/src/App.hx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import react.router.ReactRouter;
|
||||||
|
import react.router.BrowserRouter;
|
||||||
|
import react.router.Route;
|
||||||
|
import react.router.Switch;
|
||||||
|
import react.router.bundle.Bundle;
|
||||||
|
import Webpack.*;
|
||||||
|
import Root;
|
||||||
|
|
||||||
|
|
||||||
|
class App {
|
||||||
|
static var STYLES = require('./App.css');
|
||||||
|
static var Rewt = ReactRouter.withRouter(Root);
|
||||||
|
static public function main() {
|
||||||
|
new App();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
var root = createRoot();
|
||||||
|
|
||||||
|
var rootComponent = react.ReactDOM.render(jsx('
|
||||||
|
<$BrowserRouter>
|
||||||
|
<$Switch>
|
||||||
|
<$Rewt/>
|
||||||
|
</$Switch>
|
||||||
|
</$BrowserRouter>
|
||||||
|
|
||||||
|
'), root);
|
||||||
|
|
||||||
|
#if debug
|
||||||
|
ReactHMR.autoRefresh(rootComponent);
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
function createRoot() {
|
||||||
|
var current = js.Browser.document.getElementById('root');
|
||||||
|
if (current != null) return current;
|
||||||
|
current = Dom.div();
|
||||||
|
current.id = 'root';
|
||||||
|
Dom.body().appendChild(current);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
app/src/Dom.hx
Normal file
16
app/src/Dom.hx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
class Dom {
|
||||||
|
static var TEMP = js.Browser.document.createDivElement();
|
||||||
|
|
||||||
|
inline static public function div() {
|
||||||
|
return js.Browser.document.createDivElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static public function html(html: String) {
|
||||||
|
TEMP.innerHTML = html;
|
||||||
|
return TEMP.firstElementChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static public function body() {
|
||||||
|
return js.Browser.document.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
83
app/src/Root.hx
Normal file
83
app/src/Root.hx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import com.Foo;
|
||||||
|
import com.Foo2;
|
||||||
|
import components.Header;
|
||||||
|
import components.HomeContent;
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import react.ReactComponent;
|
||||||
|
import react.React.CreateElementType;
|
||||||
|
import react.router.ReactRouter;
|
||||||
|
import react.router.Route.RouteRenderProps;
|
||||||
|
import react.router.Route;
|
||||||
|
|
||||||
|
|
||||||
|
private typedef RootState = {
|
||||||
|
route: String,
|
||||||
|
?component: react.React.CreateElementType
|
||||||
|
}
|
||||||
|
|
||||||
|
private typedef RootProps = {
|
||||||
|
> RouteRenderProps,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Root extends react.ReactComponentOf<RootProps,RootState> {
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
super();
|
||||||
|
state = { route:'' };
|
||||||
|
}
|
||||||
|
|
||||||
|
override function componentDidMount() {
|
||||||
|
trace("wattfak");
|
||||||
|
switch (state.route) {
|
||||||
|
default:
|
||||||
|
Webpack.load(Foo).then(function(_) {
|
||||||
|
setState(cast { component:Foo });
|
||||||
|
trace("foo");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function yeet(){
|
||||||
|
//state.route="yeet";
|
||||||
|
//trace(state);
|
||||||
|
//setState({route:"yeetnt"});
|
||||||
|
}
|
||||||
|
|
||||||
|
override function render() {
|
||||||
|
return jsx('
|
||||||
|
<div>
|
||||||
|
<Header/>
|
||||||
|
<!--Current path is ${props.location.pathname} and component is ${state.route}-->
|
||||||
|
<!--${renderContent()}-->
|
||||||
|
<main>
|
||||||
|
<$Route exact="true" path="/">
|
||||||
|
<HomeContent/>
|
||||||
|
</$Route>
|
||||||
|
<$Route path="/projects">
|
||||||
|
<h1>Projects</h1>
|
||||||
|
</$Route>
|
||||||
|
<$Route path="/links">
|
||||||
|
<h1>Links</h1>
|
||||||
|
</$Route>
|
||||||
|
<$Route path="/gameservers">
|
||||||
|
<h1>Game Servers</h1>
|
||||||
|
<p></p>
|
||||||
|
</$Route>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderContent() {
|
||||||
|
if(state.route != props.location.pathname){
|
||||||
|
state.route = props.location.pathname;
|
||||||
|
}
|
||||||
|
if (state.component == null)
|
||||||
|
return jsx('
|
||||||
|
<span>Loading...</span>
|
||||||
|
');
|
||||||
|
else
|
||||||
|
return jsx('
|
||||||
|
<state.component />
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/src/bundles/MyBundle.hx
Normal file
12
app/src/bundles/MyBundle.hx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import react.ReactComponent;
|
||||||
|
import react.router.Route.RouteRenderProps;
|
||||||
|
|
||||||
|
@:expose('default')
|
||||||
|
class MyBundle extends ReactComponentOfProps<RouteRenderProps> {
|
||||||
|
// If you want to execute code when this bundle is _first_ loaded:
|
||||||
|
public static function onLoad() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
}
|
||||||
14
app/src/com/Foo.css
Normal file
14
app/src/com/Foo.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.foo {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foo .yeah {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.foo .yeah p {
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: solid 1px red;
|
||||||
|
}
|
||||||
27
app/src/com/Foo.hx
Normal file
27
app/src/com/Foo.hx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package com;
|
||||||
|
|
||||||
|
import react.ReactComponent;
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import Webpack.*;
|
||||||
|
|
||||||
|
class Foo extends ReactComponent {
|
||||||
|
|
||||||
|
static var STYLES = require('./Foo.css');
|
||||||
|
static var IMG = require('./bug.png');
|
||||||
|
static var CONFIG = require('../config.json');
|
||||||
|
|
||||||
|
public function yeet(){
|
||||||
|
trace(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
override function render() {
|
||||||
|
return jsx('
|
||||||
|
<div className="foo">
|
||||||
|
<img src=$IMG/> ${CONFIG.hello}!
|
||||||
|
<p onClick=${yeet}> ${CONFIG.yeet}!</p>
|
||||||
|
<hr/>
|
||||||
|
Let\'s do some HRM guys<br/>
|
||||||
|
</div>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
24
app/src/com/Foo2.hx
Normal file
24
app/src/com/Foo2.hx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package com;
|
||||||
|
|
||||||
|
import react.ReactComponent;
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import Webpack.*;
|
||||||
|
|
||||||
|
class Foo2 extends ReactComponent {
|
||||||
|
|
||||||
|
static var STYLES = require('./Foo.css');
|
||||||
|
static var IMG = require('./bug.png');
|
||||||
|
static var CONFIG = require('../config.json');
|
||||||
|
|
||||||
|
|
||||||
|
override function render() {
|
||||||
|
return jsx('
|
||||||
|
<div className="foo2">
|
||||||
|
nooo
|
||||||
|
<img src=$IMG/> ${CONFIG.hello}!
|
||||||
|
<hr/>
|
||||||
|
Let\'s do some HRM guys<br/>
|
||||||
|
</div>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
app/src/com/bug.png
Normal file
BIN
app/src/com/bug.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 774 B |
14
app/src/components/Header.css
Normal file
14
app/src/components/Header.css
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
header {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
header nav a{
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.selected{
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
.logo{
|
||||||
|
font-size: 3vw;
|
||||||
|
}
|
||||||
36
app/src/components/Header.hx
Normal file
36
app/src/components/Header.hx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package components;
|
||||||
|
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import react.ReactComponent;
|
||||||
|
import Webpack.*;
|
||||||
|
import react.router.NavLink;
|
||||||
|
|
||||||
|
class Header extends ReactComponent{
|
||||||
|
static var STYLES = require('./Header.css');
|
||||||
|
public function yeet(){
|
||||||
|
props.foo();
|
||||||
|
}
|
||||||
|
override function render() {
|
||||||
|
return jsx('
|
||||||
|
<header>
|
||||||
|
<div className="logo">
|
||||||
|
subsonics
|
||||||
|
</div>
|
||||||
|
<nav>
|
||||||
|
<$NavLink exact="true" to="/" activeClassName="selected">
|
||||||
|
Home
|
||||||
|
</NavLink>
|
||||||
|
<$NavLink to="/links" activeClassName="selected">
|
||||||
|
Links
|
||||||
|
</NavLink>
|
||||||
|
<$NavLink to="/projects" activeClassName="selected">
|
||||||
|
Projects
|
||||||
|
</NavLink>
|
||||||
|
<$NavLink to="/gameservers" activeClassName="selected">
|
||||||
|
Game Servers
|
||||||
|
</NavLink>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
0
app/src/components/HomeContent.css
Normal file
0
app/src/components/HomeContent.css
Normal file
22
app/src/components/HomeContent.hx
Normal file
22
app/src/components/HomeContent.hx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package components;
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import react.ReactComponent;
|
||||||
|
import js.Browser;
|
||||||
|
import Webpack.*;
|
||||||
|
|
||||||
|
class HomeContent extends ReactComponent {
|
||||||
|
|
||||||
|
static var STYLES = require('./HomeContent.css');
|
||||||
|
|
||||||
|
public function yeet(){
|
||||||
|
trace(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
override public function render() {
|
||||||
|
return jsx('
|
||||||
|
<p onClick=${yeet}>
|
||||||
|
kak
|
||||||
|
</p>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
34
app/src/components/MainRouter.hx
Normal file
34
app/src/components/MainRouter.hx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package components;
|
||||||
|
|
||||||
|
import react.ReactMacro.jsx;
|
||||||
|
import react.ReactComponent;
|
||||||
|
import react.router.BrowserRouter;
|
||||||
|
import react.router.Route;
|
||||||
|
import react.router.Switch;
|
||||||
|
import react.router.bundle.Bundle;
|
||||||
|
|
||||||
|
class MainRouter extends ReactComponent {
|
||||||
|
override public function render() {
|
||||||
|
return jsx('
|
||||||
|
<$BrowserRouter>
|
||||||
|
<$Switch>
|
||||||
|
<!-- Using default loader component (`<div className="loader" />`) -->
|
||||||
|
<!-- and default error component (`<div className="error" />`) -->
|
||||||
|
<!-- /!\\ Warning: your component should have the `@:expose("default")` meta -->
|
||||||
|
<!-- See example below in "Bundle initialization code" -->
|
||||||
|
<$Route
|
||||||
|
path="/bundle1"
|
||||||
|
component=${Bundle.load(first.FirstBundle)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Using custom loader and/or error component -->
|
||||||
|
<!-- The error component will get an `error` prop with the load error as `Dynamic` -->
|
||||||
|
<$Route
|
||||||
|
path="/bundle2"
|
||||||
|
component=${Bundle.load(second.SecondBundle, CustomLoader, CustomError)}
|
||||||
|
/>
|
||||||
|
</$Switch>
|
||||||
|
</$BrowserRouter>
|
||||||
|
');
|
||||||
|
}
|
||||||
|
}
|
||||||
4
app/src/config.json
Normal file
4
app/src/config.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"hello": "This is an asynchronous module" ,
|
||||||
|
"yeet": "yote"
|
||||||
|
}
|
||||||
122
app/webpack.config.js
Normal file
122
app/webpack.config.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
//
|
||||||
|
// Webpack documentation is fairly extensive,
|
||||||
|
// just search on https://webpack.js.org/
|
||||||
|
//
|
||||||
|
// Be careful: there are a lot of outdated examples/samples,
|
||||||
|
// so always check the official documentation!
|
||||||
|
//
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
|
// Options
|
||||||
|
const buildMode = process.env.NODE_ENV || 'development';
|
||||||
|
const debugMode = buildMode !== 'production';
|
||||||
|
const dist = __dirname + '/www/';
|
||||||
|
|
||||||
|
// Sourcemaps: https://webpack.js.org/configuration/devtool/
|
||||||
|
// - 'cheap-module-source-map': fastest in Haxe-only setup
|
||||||
|
// - 'eval-source-map': fast, but JS bundle is somewhat obfuscated
|
||||||
|
// - 'source-map': slow, but JS bundle is readable
|
||||||
|
// - undefined: no map, and JS bundle is readable
|
||||||
|
const sourcemapsMode = debugMode ? 'cheap-module-source-map' : undefined;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configuration:
|
||||||
|
// This configuration is still relatively minimalistic;
|
||||||
|
// each section has many more options
|
||||||
|
//
|
||||||
|
module.exports = {
|
||||||
|
mode: 'development',
|
||||||
|
// List all the JS modules to create
|
||||||
|
// They will all be linked in the HTML page
|
||||||
|
entry: {
|
||||||
|
app: './build.hxml'
|
||||||
|
},
|
||||||
|
// Generation options (destination, naming pattern,...)
|
||||||
|
output: {
|
||||||
|
path: dist,
|
||||||
|
publicPath: '/',
|
||||||
|
filename: '[name].[hash:7].js'
|
||||||
|
},
|
||||||
|
// Module resolution options (alias, default paths,...)
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.json']
|
||||||
|
},
|
||||||
|
// Sourcemaps option for development
|
||||||
|
devtool: sourcemapsMode,
|
||||||
|
// Live development server (serves from memory)
|
||||||
|
devServer: {
|
||||||
|
contentBase: dist,
|
||||||
|
compress: true,
|
||||||
|
host: "0.0.0.0",
|
||||||
|
inline: true,
|
||||||
|
historyApiFallback: true,
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
||||||
|
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"},
|
||||||
|
public: "https://dev.subsonics.nl",
|
||||||
|
port: 9000,
|
||||||
|
overlay: true,
|
||||||
|
hot: true,
|
||||||
|
disableHostCheck: true
|
||||||
|
},
|
||||||
|
// List all the processors
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
// Haxe loader (through HXML files for now)
|
||||||
|
{
|
||||||
|
test: /\.hxml$/,
|
||||||
|
loader: 'haxe-loader',
|
||||||
|
options: {
|
||||||
|
// Additional compiler options added to all builds
|
||||||
|
extra: '-D build_mode=' + buildMode,
|
||||||
|
debug: debugMode,
|
||||||
|
logCommand: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Static assets loader
|
||||||
|
// - you will need to adjust for webfonts
|
||||||
|
// - you may use 'url-loader' instead which can replace
|
||||||
|
// small assets with data-urls
|
||||||
|
{
|
||||||
|
test: /\.(gif|png|jpg|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[hash:7].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// CSS processor/loader
|
||||||
|
// - this is where you can add sass/less processing,
|
||||||
|
// - also consider adding postcss-loader for autoprefixing
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
'style-loader',
|
||||||
|
'css-loader'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Plugins can hook to the compiler lifecycle and handle extra tasks
|
||||||
|
plugins: [
|
||||||
|
// HMR: enable globally
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
// HMR: prints more readable module names in the browser console on updates
|
||||||
|
new webpack.NamedModulesPlugin(),
|
||||||
|
// HMR: do not emit compiled assets that include errors
|
||||||
|
new webpack.NoEmitOnErrorsPlugin(),
|
||||||
|
|
||||||
|
// Like generating the HTML page with links the generated JS files
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: 'Webpack + Haxe example'
|
||||||
|
})
|
||||||
|
// You may want to also:
|
||||||
|
// - finer control of minify/uglify process using UglifyJSPlugin,
|
||||||
|
// - extract the small CSS chunks into a single file using ExtractTextPlugin
|
||||||
|
// - avoid modules duplication using CommonsChunkPlugin
|
||||||
|
// - inspect your JS output weight using BundleAnalyzerPlugin
|
||||||
|
],
|
||||||
|
};
|
||||||
4435
app/yarn.lock
Normal file
4435
app/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user