diff --git a/package-lock.json b/package-lock.json index c78a619..1111e8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1220,6 +1220,25 @@ "defer-to-connect": "^1.0.1" } }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/eslint": { "version": "7.2.5", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.5.tgz", @@ -1246,18 +1265,94 @@ "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", "dev": true }, + "@types/express": { + "version": "4.17.9", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.9.tgz", + "integrity": "sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz", + "integrity": "sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, + "@types/mime": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz", + "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==", + "dev": true + }, "@types/node": { "version": "14.14.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.9.tgz", "integrity": "sha512-JsoLXFppG62tWTklIoO4knA+oDTYsmqWxHRvd4lpmfQRNhX6osheUOWETP2jMoV/2bEHuMra8Pp3Dmo/stBFcw==", "dev": true }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/qs": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", + "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/react": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.0.tgz", + "integrity": "sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.0.tgz", + "integrity": "sha512-lUqY7OlkF/RbNtD5nIq7ot8NquXrdFrjSOR6+w9a9RFQevGi1oZO1dcJbXMeONAPKtZ2UrZOEJ5UOCVsxbLk/g==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/serve-static": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz", + "integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "4.8.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.1.tgz", @@ -2273,6 +2368,12 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "csstype": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.5.tgz", + "integrity": "sha512-uVDi8LpBUKQj6sdxNaTetL6FpeCqTjOvAQuQUa/qAqq8oOd4ivkbhgnqayl0dnPal8Tb/yB1tF+gOvCBiicaiQ==", + "dev": true + }, "date-fns": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", @@ -3591,8 +3692,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.14.0", @@ -3741,7 +3841,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -3955,8 +4054,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { "version": "1.8.0", @@ -4306,6 +4404,25 @@ } } }, + "react": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", + "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-dom": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", + "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.1" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -4550,6 +4667,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "scheduler": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", + "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", diff --git a/package.json b/package.json index 8566b1c..b480e02 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,30 @@ "name": "weblgl", "version": "1.0.0", "description": "A simple WebGL app to demonstrate my skills", - "scripts": {}, + "scripts": { + "type-check:server": "tsc --pretty --project config/tsconfig.server.json --noEmit", + "type-check:client": "tsc --pretty --project config/tsconfig.client.json --noEmit", + "type-check": "concurrently \"npm:type-check:server\" \"npm:type-check:client\"", + "type-check:server:watch": "tsc --watch --preserveWatchOutput --pretty --project config/tsconfig.server.dev.json --noEmit", + "type-check:client:watch": "tsc --watch --preserveWatchOutput --pretty --project config/tsconfig.client.dev.json --noEmit", + "type-check:watch": "concurrently \"npm:type-check:server:watch\" \"npm:type-check:client:watch\"", + "build:server:types": "tsc --emitDeclarationOnly --project config/tsconfig.server.json", + "build:server:js": "webpack --config config/webpack.server.prod.js", + "build:server": "npm run build:server:types && npm run build:server:js", + "build:client:types": "tsc --emitDeclarationOnly --project config/tsconfig.client.json", + "build:client:js": "webpack --config config/webpack.client.prod.js", + "build:client": "npm run build:client:types && npm run build:client:js", + "build": "rm -rf dist && npm run build:server && npm run build:client", + "dev:server:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput --pretty --project config/tsconfig.server.json", + "dev:server:js": "webpack --config config/webpack.server.dev.js", + "dev:server": "concurrently \"npm:dev:server:types\" \"npm:dev:server:js\"", + "dev:client:types": "tsc --emitDeclarationOnly --watch --preserveWatchOutput --pretty --project config/tsconfig.client.json", + "dev:client:js": "webpack --config config/webpack.client.dev.js", + "dev:client": "concurrently \"npm:dev:client:types\" \"npm:dev:client:js\"", + "dev:start": "mkdir -p dist/server && touch dist/server/bundle.js && nodemon dist/server/bundle.js", + "dev": "rm -rf dist && concurrently \"npm:dev:server\" \"npm:dev:client\" \"npm:dev:start\"", + "start": "node dist/server/bundle.js" + }, "repository": { "type": "git", "url": "https://git.gaetanbrochard.dev/gbrochar/weblgl.git" @@ -17,6 +40,9 @@ "@babel/preset-react": "^7.12.7", "@babel/preset-typescript": "^7.12.7", "@babel/runtime-corejs3": "^7.12.5", + "@types/express": "^4.17.9", + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0", "@typescript-eslint/eslint-plugin": "^4.8.1", "@typescript-eslint/parser": "^4.8.1", "babel-loader": "^8.2.1", @@ -35,6 +61,8 @@ }, "dependencies": { "ejs": "^3.1.5", - "express": "^4.17.1" + "express": "^4.17.1", + "react": "^17.0.1", + "react-dom": "^17.0.1" } } diff --git a/src/client/components/Root.tsx b/src/client/components/Root.tsx new file mode 100644 index 0000000..c8a3e23 --- /dev/null +++ b/src/client/components/Root.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +/** + * @return {jsx} The root component + */ +export default function Root() { + return ( +
+ Hello World from React ! +
+ ); +} diff --git a/src/client/main.tsx b/src/client/main.tsx new file mode 100644 index 0000000..e30f6b8 --- /dev/null +++ b/src/client/main.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import {hydrate, render} from 'react-dom'; +import Root from './components/Root'; + +const root = document.getElementById('root'); +let renderMethod; +if (root && root.innerHTML !== '') { + renderMethod = hydrate; +} else { + renderMethod = render; +} + +renderMethod(, document.getElementById('root')); diff --git a/src/server/main.ts b/src/server/main.ts new file mode 100644 index 0000000..27d0c2b --- /dev/null +++ b/src/server/main.ts @@ -0,0 +1,15 @@ +import express from 'express'; +import path from 'path'; + +const app = express(); + +app.set('view engine', 'ejs'); + +app.use('/static', express.static(path.join(__dirname, '../../public'))); +app.use('/js', express.static(path.join(__dirname, '../../dist/client'))); + +app.get('/', (_req, res) => { + res.render('index'); +}); + +app.listen(3001); \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 0000000..ab7644a --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,16 @@ + + + + + + + Web-Expo + + + + + +
+ + +