├── README.md ├── assets └── logo.png ├── index.html ├── index.js ├── package.json ├── src ├── app.css └── app.jsx └── webpack.config.js /README.md: -------------------------------------------------------------------------------- 1 | # React Demo 2 | 3 | [JSBox Node.js](https://cyanzhong.github.io/jsbox-nodejs/#/en/) example that shows you: 4 | 5 | - How to use 3rd-party node modules 6 | - How to transpile projects with `webpack` and `babel` 7 | - How to serve a website with `express` 8 | - How to open a website with native module like `safari` 9 | 10 | # Instructions 11 | 12 | - Install [JSBox](https://apps.apple.com/us/app/id1312014438) 2.0 13 | - Run `npm install` to resolve dependencies -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cyanzhong/jsbox-react-demo/08ba57ce0e43bf1d8433cb3c2caae267ef2a64a6/assets/logo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const webpack = require("webpack"); 3 | const webpackMiddleware = require("webpack-dev-middleware"); 4 | const safari = require("safari"); 5 | 6 | const config = require("./webpack.config.js"); 7 | const transpiler = webpack(config); 8 | const middleware = webpackMiddleware(transpiler, { 9 | publicPath: config.output.publicPath, 10 | watchOptions: { 11 | ignored: /.*/ 12 | } 13 | }); 14 | 15 | const app = express(); 16 | app.use(middleware); 17 | app.get("/", (req, res) => { 18 | res.sendFile("index.html", { 19 | root: __dirname 20 | }); 21 | }); 22 | 23 | const port = 8848; 24 | app.listen(port); 25 | 26 | const url = `http://localhost:${port}`; 27 | console.log(`Launching website at: ${url}`); 28 | safari.open(url); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsbox-react-demo", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "@babel/core": "7.x.x", 6 | "@babel/preset-env": "7.x.x", 7 | "@babel/preset-react": "7.x.x", 8 | "babel-loader": "8.x.x", 9 | "css-loader": "2.1.x", 10 | "express": "4.16.x", 11 | "file-loader": "^4.0.0", 12 | "react": "16.x.x", 13 | "react-dom": "16.x.x", 14 | "style-loader": "0.x.x", 15 | "url-loader": "^2.0.0", 16 | "webpack": "4.x.x", 17 | "webpack-dev-middleware": "3.7.x" 18 | } 19 | } -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | background-color: #282c34; 7 | } 8 | 9 | .Container { 10 | text-align: center; 11 | } 12 | 13 | .Header { 14 | min-height: 100vh; 15 | display: flex; 16 | flex-direction: column; 17 | align-items: center; 18 | justify-content: center; 19 | font-size: 17px; 20 | color: white; 21 | } 22 | 23 | .React-logo { 24 | animation: ReactAnimation infinite 20s linear; 25 | height: 24vmin; 26 | pointer-events: none; 27 | } 28 | 29 | .Link { 30 | color: #61dafb; 31 | } 32 | 33 | @keyframes ReactAnimation { 34 | from { 35 | transform: rotate(0deg); 36 | } 37 | to { 38 | transform: rotate(360deg); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/app.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import ReactLogo from "../assets/logo.png"; 4 | import "./app.css"; 5 | 6 | class App extends React.Component { 7 | render() { 8 | return ( 9 |
10 |
11 | logo 12 |

Hello, World!

13 | 17 | Getting Started 18 | 19 |
20 |
21 | ); 22 | } 23 | } 24 | 25 | ReactDOM.render(, document.getElementById("container")); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | mode: "development", 5 | entry: { 6 | app: ["./src/app.jsx"] 7 | }, 8 | module: { 9 | rules: [ 10 | { 11 | test: pattern => { 12 | return /\.(js|jsx)$/.test(pattern); 13 | }, 14 | exclude: pattern => { 15 | return /node_modules/.test(pattern); 16 | }, 17 | use: { 18 | loader: "babel-loader", 19 | options: { 20 | presets: [ 21 | "@babel/preset-env", 22 | "@babel/preset-react" 23 | ] 24 | } 25 | } 26 | }, 27 | { 28 | test: pattern => { 29 | return /\.css$/.test(pattern); 30 | }, 31 | exclude: pattern => { 32 | return /node_modules/.test(pattern); 33 | }, 34 | use: [ 35 | "style-loader", 36 | "css-loader" 37 | ] 38 | }, 39 | { 40 | test: pattern => { 41 | return /\.(png|jp(e*)g|svg)$/.test(pattern); 42 | }, 43 | exclude: pattern => { 44 | return /node_modules/.test(pattern); 45 | }, 46 | use: [ 47 | { 48 | loader: "url-loader", 49 | options: { 50 | limit: 8000, 51 | name: "images/[hash]-[name].[ext]" 52 | } 53 | } 54 | ] 55 | } 56 | ] 57 | }, 58 | plugins: [], 59 | output: { 60 | filename: "[name].bundle.js", 61 | path: path.resolve(__dirname, "./dist"), 62 | publicPath: "/" 63 | } 64 | }; --------------------------------------------------------------------------------