diff --git a/README.md b/README.md index 8aaec31..59946e4 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ You also need `npm` in version 7 (because of 2nd version of lockfile which was i 2. Clone the repository to your computer. 3. Open the folder in command prompt and run **`npm install`** 4. Make any changes you would like to suggest. -5. In command prompt run **`npm run build`** which will compile it to the `/build` folder, where you can make sure it works – the easiest way to do so is to run **`npm run serve`**. You can also do both at once by running `npm test`. +5. In command prompt run **`npm run hot`** which will compile app to the `/build` folder, serve under [http://localhost:3000](http://localhost:3000), then open in your browser. Moreover, it restarts server every time you save your changes in a codebase. You can go even further by running `npm run hot:reload`, which will also trigger webpage reloads. 6. Add, Commit and Push your changes to your fork. 7. On the github page for your fork, click **New Pull Request** above the file list. 8. Change the **head repository** dropdown to your fork. diff --git a/package-lock.json b/package-lock.json index 6298697..04feffe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "sass": "^1.17.3" }, "devDependencies": { + "cross-env": "7.0.3", "reload": "^3.1.1", "wait-cli": "^1.0.0" } @@ -1528,6 +1529,53 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-env/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-env/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/cross-spawn": { "version": "3.0.1", "license": "MIT", @@ -2447,7 +2495,72 @@ "node_modules/fsevents": { "version": "1.2.12", "bundleDependencies": [ - "node-pre-gyp" + "node-pre-gyp", + "abbrev", + "ansi-regex", + "aproba", + "are-we-there-yet", + "balanced-match", + "brace-expansion", + "chownr", + "code-point-at", + "concat-map", + "console-control-strings", + "core-util-is", + "debug", + "deep-extend", + "delegates", + "detect-libc", + "fs-minipass", + "fs.realpath", + "gauge", + "glob", + "has-unicode", + "iconv-lite", + "ignore-walk", + "inflight", + "inherits", + "ini", + "is-fullwidth-code-point", + "isarray", + "minimatch", + "minimist", + "minipass", + "minizlib", + "mkdirp", + "ms", + "needle", + "nopt", + "npm-bundled", + "npm-normalize-package-bin", + "npm-packlist", + "npmlog", + "number-is-nan", + "object-assign", + "once", + "os-homedir", + "os-tmpdir", + "osenv", + "path-is-absolute", + "process-nextick-args", + "rc", + "readable-stream", + "rimraf", + "safe-buffer", + "safer-buffer", + "sax", + "semver", + "set-blocking", + "signal-exit", + "string_decoder", + "string-width", + "strip-ansi", + "strip-json-comments", + "tar", + "util-deprecate", + "wide-align", + "wrappy", + "yallist" ], "hasInstallScript": true, "license": "MIT", @@ -5598,6 +5711,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.6", "license": "MIT" @@ -6411,6 +6533,27 @@ "version": "1.1.1", "license": "ISC" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/signal-exit": { "version": "3.0.3", "license": "ISC" @@ -8847,6 +8990,37 @@ "core-util-is": { "version": "1.0.2" }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "cross-spawn": { "version": "3.0.1", "requires": { @@ -11575,6 +11749,12 @@ "path-is-absolute": { "version": "1.0.1" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.6" }, @@ -12119,6 +12299,21 @@ "setprototypeof": { "version": "1.1.1" }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "signal-exit": { "version": "3.0.3" }, diff --git a/package.json b/package.json index 7ea3aaf..cd8a3bc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "node ./build.js ./build", "serve": "node ./server.js ./build 3000", "test": "npm run build && npm run serve", - "hot": "concurrently \"nodemon --exec npm test\" \"await tcp localhost:3000 && open-cli http://localhost:3000\"" + "hot": "concurrently \"nodemon --exec npm test\" \"await tcp localhost:3000 && open-cli http://localhost:3000\"", + "hot:reload": "cross-env RELOAD=yes npm run hot" }, "author": "Lospec", "license": "ISC", @@ -31,6 +32,7 @@ "sass": "^1.17.3" }, "devDependencies": { + "cross-env": "7.0.3", "reload": "^3.1.1", "wait-cli": "^1.0.0" } diff --git a/server.js b/server.js index aec95c0..e6167ff 100644 --- a/server.js +++ b/server.js @@ -7,18 +7,18 @@ const BUILDDIR = process.argv[2] || './build'; const PORT = process.argv[3] || 3000; //ROUTE - index.htm -app.get('/', (req, res) => { +app.get('/', (req, res) => { res.sendFile(path.join(__dirname, BUILDDIR, 'index.htm'), {}, function (err) { - if(err){ + if (err) { console.log('error sending file', err); } else { console.log("Server: Successfully served index.html"); - + /*setTimeout(()=>{ console.log('closing server'); res.app.server.close(); process.exit(); - },1000*10); */ + },1000*10); */ } }); }); @@ -31,9 +31,18 @@ app.get('/pixel-editor/app', (req, res) => { //ROUTE - other files app.use(express.static(path.join(__dirname, BUILDDIR))); -reload(app).then(() => { - //start server - app.server = app.listen(3000, function () { - console.log('Web server listening on port ' + PORT) +// "reload" module allows us to trigger webpage reload automatically on file changes, but inside pixel editor it also +// makes browser steal focus from any other window in order to ask user about unsaved changes. It might be quite +// intrusive so we decided to give option to choose preferred workflow. +if (process.env.RELOAD === "yes") { + reload(app).then(() => { + //start server + app.server = app.listen(PORT, () => { + console.log(`Web server listening on port ${PORT} (with reload module)`); + }) + }); +} else { + app.listen(PORT, () => { + console.log(`Web server listening on port ${PORT}`); }) -}); +}