Convert app into node version with express.
This commit is contained in:
1 parent
dbeead9e99
commit
b997194a96
12 files changed
+6682
-99
No files matched your search
@@ -1,2 +1,3 @@
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
public/bundle.js
|
public/bundle.js
|
||||||
|
**/dist
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Program",
|
||||||
|
"skipFiles": [
|
||||||
|
"<node_internals>/**"
|
||||||
|
],
|
||||||
|
"program": "${workspaceFolder}/src/back/app.js"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Generated
+6513
File diff suppressed because it is too large.
Load diff
+7
-1
@@ -4,15 +4,21 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack --watch",
|
"start-front": "webpack --watch",
|
||||||
|
"start-back": "node src/back/app.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"nodemon": "^2.0.4",
|
||||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||||
"webpack": "^4.41.2",
|
"webpack": "^4.41.2",
|
||||||
"webpack-cli": "^3.3.10",
|
"webpack-cli": "^3.3.10",
|
||||||
"webpack-dev-server": "^3.9.0"
|
"webpack-dev-server": "^3.9.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"mustache-express": "^1.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
body {
|
||||||
|
background-color: #222;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid black;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-btn:hover {
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-div {
|
||||||
|
border: 1px green solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-div {
|
||||||
|
border: 1px red solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<title>Textual game</title>
|
|
||||||
<meta name="description" content="The HTML5 Herald">
|
|
||||||
<meta name="author" content="SitePoint">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="css/styles.css?v=1.0">
|
|
||||||
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
background-color: #222;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.choice-btn {
|
|
||||||
padding: 5px 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid black;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.choice-btn:hover {
|
|
||||||
background-color: #ccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.choice-div {
|
|
||||||
border: 1px green solid;
|
|
||||||
}
|
|
||||||
.node-div {
|
|
||||||
border: 1px red solid;
|
|
||||||
}
|
|
||||||
#content {
|
|
||||||
width: 500px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="content">
|
|
||||||
<h1>Textual Game</h1>
|
|
||||||
<div id="history"></div>
|
|
||||||
<div id="choices"></div>
|
|
||||||
</div>
|
|
||||||
<script src="./bundle.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!function(n){var e={};function t(o){if(e[o])return e[o].exports;var c=e[o]={i:o,l:!1,exports:{}};return n[o].call(c.exports,c,c.exports,t),c.l=!0,c.exports}t.m=n,t.c=e,t.d=function(n,e,o){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:o})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(t.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var c in n)t.d(o,c,function(e){return n[e]}.bind(null,c));return o},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(module,exports){eval("let jsonContent = [];\n\nfunction printChoices(node) {\n if (node.choices) {\n return node.choices.forEach(choice => {\n const newBtn = document.createElement('button');\n newBtn.onclick = () => selectChoice(choice.id);\n newBtn.innerHTML = choice.text;\n newBtn.classList.add('choice-btn');\n document.getElementById('choices').appendChild(newBtn);\n });\n }\n}\n\nfunction selectChoice(choiceId) {\n console.log('Click on choice ', choiceId);\n const allChoices = jsonContent.flatMap(node =>\n !node.choices ? [] : node.choices\n );\n const selectedChoice = allChoices.find(choice => choice.id === choiceId);\n const nextNode = jsonContent.find(node => node.id === selectedChoice.nextNode);\n\n addChoiceToHistory(selectedChoice);\n updateActiveNode(nextNode);\n}\n\nfunction addChoiceToHistory(selectedChoice) {\n const choiceDiv = document.createElement('div');\n choiceDiv.innerHTML = selectedChoice.text;\n choiceDiv.classList.add('choice-div');\n document.getElementById('history').appendChild(choiceDiv);\n}\n\nfunction updateActiveNode(node) {\n const nodeDiv = document.createElement('div');\n nodeDiv.innerHTML = node.text;\n nodeDiv.classList.add('node-div');\n document.getElementById('history').appendChild(nodeDiv);\n\n document.getElementById('choices').innerHTML = '';\n printChoices(node);\n}\n\nwindow.onload = () => {\n fetch('/nodes', {\n method: 'GET'\n })\n .then(response => response.json())\n .then(data => {\n jsonContent = data;\n updateActiveNode(jsonContent[0]);\n });\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvZnJvbnQvaW5kZXguanM/YzhlYyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wiLCJmaWxlIjoiMC5qcyIsInNvdXJjZXNDb250ZW50IjpbImxldCBqc29uQ29udGVudCA9IFtdO1xuXG5mdW5jdGlvbiBwcmludENob2ljZXMobm9kZSkge1xuICAgIGlmIChub2RlLmNob2ljZXMpIHtcbiAgICAgICAgcmV0dXJuIG5vZGUuY2hvaWNlcy5mb3JFYWNoKGNob2ljZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdCdG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICAgICAgICAgIG5ld0J0bi5vbmNsaWNrID0gKCkgPT4gc2VsZWN0Q2hvaWNlKGNob2ljZS5pZCk7XG4gICAgICAgICAgICBuZXdCdG4uaW5uZXJIVE1MID0gY2hvaWNlLnRleHQ7XG4gICAgICAgICAgICBuZXdCdG4uY2xhc3NMaXN0LmFkZCgnY2hvaWNlLWJ0bicpO1xuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Nob2ljZXMnKS5hcHBlbmRDaGlsZChuZXdCdG4pO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNlbGVjdENob2ljZShjaG9pY2VJZCkge1xuICAgIGNvbnNvbGUubG9nKCdDbGljayBvbiBjaG9pY2UgJywgY2hvaWNlSWQpO1xuICAgIGNvbnN0IGFsbENob2ljZXMgPSBqc29uQ29udGVudC5mbGF0TWFwKG5vZGUgPT5cbiAgICAgICAgIW5vZGUuY2hvaWNlcyA/IFtdIDogbm9kZS5jaG9pY2VzXG4gICAgKTtcbiAgICBjb25zdCBzZWxlY3RlZENob2ljZSA9IGFsbENob2ljZXMuZmluZChjaG9pY2UgPT4gY2hvaWNlLmlkID09PSBjaG9pY2VJZCk7XG4gICAgY29uc3QgbmV4dE5vZGUgPSBqc29uQ29udGVudC5maW5kKG5vZGUgPT4gbm9kZS5pZCA9PT0gc2VsZWN0ZWRDaG9pY2UubmV4dE5vZGUpO1xuXG4gICAgYWRkQ2hvaWNlVG9IaXN0b3J5KHNlbGVjdGVkQ2hvaWNlKTtcbiAgICB1cGRhdGVBY3RpdmVOb2RlKG5leHROb2RlKTtcbn1cblxuZnVuY3Rpb24gYWRkQ2hvaWNlVG9IaXN0b3J5KHNlbGVjdGVkQ2hvaWNlKSB7XG4gICAgY29uc3QgY2hvaWNlRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgY2hvaWNlRGl2LmlubmVySFRNTCA9IHNlbGVjdGVkQ2hvaWNlLnRleHQ7XG4gICAgY2hvaWNlRGl2LmNsYXNzTGlzdC5hZGQoJ2Nob2ljZS1kaXYnKTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGlzdG9yeScpLmFwcGVuZENoaWxkKGNob2ljZURpdik7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUFjdGl2ZU5vZGUobm9kZSkge1xuICAgIGNvbnN0IG5vZGVEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlRGl2LmlubmVySFRNTCA9IG5vZGUudGV4dDtcbiAgICBub2RlRGl2LmNsYXNzTGlzdC5hZGQoJ25vZGUtZGl2Jyk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2hpc3RvcnknKS5hcHBlbmRDaGlsZChub2R
Line truncated
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
const mustacheExpress = require('mustache-express');
|
||||||
|
const express = require('express');
|
||||||
|
const nodes = require('./nodes.json');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
// Register '.mustache' extension with The Mustache Express
|
||||||
|
app.engine('mustache', mustacheExpress());
|
||||||
|
|
||||||
|
app.set('view engine', 'mustache');
|
||||||
|
app.set('views', __dirname + '/views');
|
||||||
|
app.use(express.static('public'));
|
||||||
|
|
||||||
|
app.get('/', (request, response) => {
|
||||||
|
response.render('home', { title: 'Textual game!' });
|
||||||
|
});
|
||||||
|
app.get('/nodes', (request, response) => {
|
||||||
|
response.setHeader('Content-Type', 'application/json');
|
||||||
|
response.end(JSON.stringify(nodes));
|
||||||
|
});
|
||||||
|
app.get('/app-bundle.js', (request, response) => {
|
||||||
|
response.download(`${__dirname}/../../dist/app-bundle.js`);
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(3000, () => {
|
||||||
|
console.log('Example app listening on port 3000!');
|
||||||
|
});
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "node-1",
|
||||||
|
"text": "Node 1",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"id": "choice-1",
|
||||||
|
"text": "Choice 1",
|
||||||
|
"nextNode": "node-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "choice-2",
|
||||||
|
"text": "Choice 2",
|
||||||
|
"nextNode": "node-exit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "choice-3",
|
||||||
|
"text": "Choice 3",
|
||||||
|
"nextNode": "node-exit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "node-2",
|
||||||
|
"text": "Node 2",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"id": "choice-3",
|
||||||
|
"text": "Choice 3",
|
||||||
|
"nextNode": "node-exit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "choice-4",
|
||||||
|
"text": "Choice 4",
|
||||||
|
"nextNode": "node-exit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "node-exit",
|
||||||
|
"text": "Game over!"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>Textual game</title>
|
||||||
|
<meta name="description" content="The HTML5 Herald">
|
||||||
|
<meta name="author" content="SitePoint">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="content">
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
<div id="history"></div>
|
||||||
|
<div id="choices"></div>
|
||||||
|
</div>
|
||||||
|
<script src="js/app-bundle.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,44 +1,15 @@
|
|||||||
const jsonContent = [{
|
let jsonContent = [];
|
||||||
id: 'node-1',
|
|
||||||
text: 'Node 1',
|
|
||||||
choices: [{
|
|
||||||
id: 'choice-1',
|
|
||||||
text: 'Choice 1',
|
|
||||||
nextNode: 'node-2'
|
|
||||||
}, {
|
|
||||||
id: 'choice-2',
|
|
||||||
text: 'Choice 2',
|
|
||||||
nextNode: 'node-exit'
|
|
||||||
}, {
|
|
||||||
id: 'choice-3',
|
|
||||||
text: 'Choice 3',
|
|
||||||
nextNode: 'node-exit'
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
id: 'node-2',
|
|
||||||
text: 'Node 2',
|
|
||||||
choices: [{
|
|
||||||
id: 'choice-3',
|
|
||||||
text: 'Choice 3',
|
|
||||||
nextNode: 'node-exit'
|
|
||||||
}, {
|
|
||||||
id: 'choice-4',
|
|
||||||
text: 'Choice 4',
|
|
||||||
nextNode: 'node-exit'
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
id: 'node-exit',
|
|
||||||
text: 'Game over!'
|
|
||||||
}];
|
|
||||||
|
|
||||||
function printChoices(node) {
|
function printChoices(node) {
|
||||||
return node.choices.forEach(choice => {
|
if (node.choices) {
|
||||||
const newBtn = document.createElement('button');
|
return node.choices.forEach(choice => {
|
||||||
newBtn.onclick = () => selectChoice(choice.id);
|
const newBtn = document.createElement('button');
|
||||||
newBtn.innerHTML = choice.text;
|
newBtn.onclick = () => selectChoice(choice.id);
|
||||||
newBtn.classList.add('choice-btn');
|
newBtn.innerHTML = choice.text;
|
||||||
document.getElementById('choices').appendChild(newBtn);
|
newBtn.classList.add('choice-btn');
|
||||||
});
|
document.getElementById('choices').appendChild(newBtn);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectChoice(choiceId) {
|
function selectChoice(choiceId) {
|
||||||
@@ -71,5 +42,12 @@ function updateActiveNode(node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
updateActiveNode(jsonContent[0]);
|
fetch('/nodes', {
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
jsonContent = data;
|
||||||
|
updateActiveNode(jsonContent[0]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
+8
-10
@@ -2,15 +2,16 @@ const webpack = require("webpack");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
|
const UglifyJSPlugin = require("uglifyjs-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
let config = {
|
entry: {
|
||||||
entry: "./src/index.js",
|
app: "./src/front/index.js",
|
||||||
|
},
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, "./public"),
|
path: path.resolve(__dirname, "./public/js"),
|
||||||
filename: "./bundle.js"
|
filename: "[name]-bundle.js"
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
contentBase: path.resolve(__dirname, "./public"),
|
contentBase: path.resolve(__dirname, "./public/js"),
|
||||||
historyApiFallback: true,
|
historyApiFallback: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
open: true,
|
open: true,
|
||||||
@@ -21,7 +22,4 @@ let config = {
|
|||||||
new webpack.SourceMapDevToolPlugin({})
|
new webpack.SourceMapDevToolPlugin({})
|
||||||
],
|
],
|
||||||
devtool: "eval-source-map"
|
devtool: "eval-source-map"
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
module.exports = config;
|
|
||||||
Reference in new issue
Block a user