mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-29 18:46:20 -05:00
Extend build process to support multiple views
This commit is contained in:
parent
bf907af53b
commit
41176aaee1
12 changed files with 151 additions and 19 deletions
16
Makefile
16
Makefile
|
@ -1,5 +1,5 @@
|
||||||
ESLINT=./node_modules/.bin/eslint
|
ESLINT=./node_modules/.bin/eslint
|
||||||
LIVE=./node_modules/.bin/live-server
|
NODE=node
|
||||||
WATCH=./node_modules/.bin/watch
|
WATCH=./node_modules/.bin/watch
|
||||||
WEBPACK=./node_modules/.bin/webpack
|
WEBPACK=./node_modules/.bin/webpack
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ build:
|
||||||
@make webpack
|
@make webpack
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf ./build/*.*
|
rm -rf ./build
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
|
|
||||||
static:
|
static:
|
||||||
|
@ -27,6 +27,7 @@ test:
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
$(ESLINT) ./*.js
|
$(ESLINT) ./*.js
|
||||||
|
$(ESLINT) ./server/*.js
|
||||||
$(ESLINT) ./src/*.jsx
|
$(ESLINT) ./src/*.jsx
|
||||||
$(ESLINT) ./src/mixins/*.jsx
|
$(ESLINT) ./src/mixins/*.jsx
|
||||||
$(ESLINT) ./src/views/**/*.jsx
|
$(ESLINT) ./src/views/**/*.jsx
|
||||||
|
@ -34,15 +35,14 @@ lint:
|
||||||
|
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
start:
|
|
||||||
@make watch
|
|
||||||
$(LIVE) ./build --port=8888 --wait=200 --no-browser
|
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
|
$(WATCH) "make clean && make static" ./static &
|
||||||
$(WEBPACK) -d --watch &
|
$(WEBPACK) -d --watch &
|
||||||
$(WATCH) "make static" ./static &
|
|
||||||
wait
|
wait
|
||||||
|
|
||||||
|
start:
|
||||||
|
node ./server/index.js
|
||||||
|
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
.PHONY: build clean static webpack test lint start watch
|
.PHONY: build clean static webpack test lint watch start
|
||||||
|
|
|
@ -6,10 +6,17 @@
|
||||||
### To Build
|
### To Build
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
During development, you can use `npm run watch` to cause any update you make to files in either `./static` or `./src` to trigger a rebuild of the project.
|
||||||
|
|
||||||
|
### To Run
|
||||||
|
```bash
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
Once running, open `http://localhost:8888` in your browser. Any update you make to files in either `./static` or `./src` should trigger a rebuild of the project and cause your browser to refresh to reflect those changes.
|
Once running, open `http://localhost:8888` in your browser. If you wish to have the server reload automatically, you can install either [nodemon](https://github.com/remy/nodemon) or [forever](https://github.com/foreverjs/forever).
|
||||||
|
|
||||||
### To Test
|
### To Test
|
||||||
```bash
|
```bash
|
||||||
|
|
13
package.json
13
package.json
|
@ -5,7 +5,9 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "make start",
|
"start": "make start",
|
||||||
"test": "make test"
|
"test": "make test",
|
||||||
|
"watch": "make watch",
|
||||||
|
"build": "make build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -17,14 +19,19 @@
|
||||||
"url": "https://github.com/llk/scratch-www/issues"
|
"url": "https://github.com/llk/scratch-www/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/llk/scratch-www#readme",
|
"homepage": "https://github.com/llk/scratch-www#readme",
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
|
"bunyan": "1.4.0",
|
||||||
|
"compression": "1.5.2",
|
||||||
|
"express": "4.13.3",
|
||||||
|
"lodash.defaults": "3.1.2",
|
||||||
|
"mustache": "2.1.3"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"css-loader": "0.17.0",
|
"css-loader": "0.17.0",
|
||||||
"eslint": "1.3.1",
|
"eslint": "1.3.1",
|
||||||
"eslint-plugin-react": "3.3.1",
|
"eslint-plugin-react": "3.3.1",
|
||||||
"json-loader": "0.5.2",
|
"json-loader": "0.5.2",
|
||||||
"jsx-loader": "0.13.2",
|
"jsx-loader": "0.13.2",
|
||||||
"live-server": "0.8.1",
|
|
||||||
"node-sass": "3.3.2",
|
"node-sass": "3.3.2",
|
||||||
"react": "0.13.3",
|
"react": "0.13.3",
|
||||||
"sass-loader": "2.0.1",
|
"sass-loader": "2.0.1",
|
||||||
|
|
4
server/defaults.json
Normal file
4
server/defaults.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"title": "Scratch - Imagine, Program, Share",
|
||||||
|
"description": "Scratch is a free programming language and online community where you can create your own interactive stories, games, and animations."
|
||||||
|
}
|
35
server/handler.js
Normal file
35
server/handler.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
var crypto = require('crypto');
|
||||||
|
var defaults = require('lodash.defaults');
|
||||||
|
var fs = require('fs');
|
||||||
|
var mustache = require('mustache');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
function Handler (route) {
|
||||||
|
// Route definition
|
||||||
|
defaults(route, require('./defaults.json'));
|
||||||
|
|
||||||
|
// Render template
|
||||||
|
var location = path.resolve(__dirname, './template.html');
|
||||||
|
var template = fs.readFileSync(location, 'utf8');
|
||||||
|
var output = mustache.render(template, route);
|
||||||
|
var checksum = crypto.createHash('md5').update(output).digest('hex');
|
||||||
|
|
||||||
|
return function (req, res) {
|
||||||
|
res.set({
|
||||||
|
'Content-Type': 'text/html',
|
||||||
|
'Cache-Control': 'public, max-age=31536000',
|
||||||
|
'Etag': 'W/"' + checksum + '"'
|
||||||
|
});
|
||||||
|
res.send(output);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export a new instance
|
||||||
|
*/
|
||||||
|
module.exports = function (route) {
|
||||||
|
return new Handler(route);
|
||||||
|
};
|
29
server/index.js
Normal file
29
server/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
var compression = require('compression');
|
||||||
|
var express = require('express');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var handler = require('./handler');
|
||||||
|
var log = require('./log');
|
||||||
|
var routes = require('./routes.json');
|
||||||
|
|
||||||
|
// Server setup
|
||||||
|
var app = express();
|
||||||
|
app.disable('x-powered-by');
|
||||||
|
app.use(log());
|
||||||
|
app.use(compression());
|
||||||
|
app.use(express.static(path.resolve(__dirname, '../build'), {
|
||||||
|
lastModified: true,
|
||||||
|
maxAge: '1y'
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Bind routes
|
||||||
|
for (var item in routes) {
|
||||||
|
var route = routes[item];
|
||||||
|
app.get(route.pattern, handler(route));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start listening
|
||||||
|
var port = process.env.PORT || 8888;
|
||||||
|
app.listen(port, function () {
|
||||||
|
process.stdout.write('Server listening on port ' + port + '\n');
|
||||||
|
});
|
14
server/log.js
Normal file
14
server/log.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
var bunyan = require('bunyan');
|
||||||
|
|
||||||
|
module.exports = function () {
|
||||||
|
var logger = bunyan.createLogger({
|
||||||
|
name: 'www',
|
||||||
|
serializers: {req: bunyan.stdSerializers.req}
|
||||||
|
});
|
||||||
|
|
||||||
|
return function (req, res, next) {
|
||||||
|
req.log = logger;
|
||||||
|
req.log.info({req: req});
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
11
server/routes.json
Normal file
11
server/routes.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"pattern": "/",
|
||||||
|
"view": "splash"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "/about",
|
||||||
|
"view": "about",
|
||||||
|
"title": "About"
|
||||||
|
}
|
||||||
|
]
|
|
@ -6,8 +6,8 @@
|
||||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>Scratch</title>
|
<title>Scratch - {{title}}</title>
|
||||||
<meta name="description" content="Scratch is a free programming language and online community where you can create your own interactive stories, games, and animations." />
|
<meta name="description" content="{{description}}" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="/css/lib/normalize.min.css" />
|
<link rel="stylesheet" href="/css/lib/normalize.min.css" />
|
||||||
</head>
|
</head>
|
||||||
|
@ -20,6 +20,6 @@
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script src="/js/lib/react.js"></script>
|
<script src="/js/lib/react.js"></script>
|
||||||
<script src="/js/main.bundle.js"></script>
|
<script src="/js/main.bundle.js"></script>
|
||||||
<script src="/js/splash.bundle.js"></script>
|
<script src="/js/{{view}}.bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
15
src/views/about/about.jsx
Normal file
15
src/views/about/about.jsx
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
var React = require('react');
|
||||||
|
|
||||||
|
require('./about.scss');
|
||||||
|
|
||||||
|
var View = React.createClass({
|
||||||
|
render: function () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>I am the about page!</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
React.render(<View />, document.getElementById('view'));
|
3
src/views/about/about.scss
Normal file
3
src/views/about/about.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#view {
|
||||||
|
|
||||||
|
}
|
|
@ -1,11 +1,18 @@
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var webpack = require('webpack');
|
var webpack = require('webpack');
|
||||||
|
var routes = require('./server/routes.json');
|
||||||
|
|
||||||
|
// Prepare all entry points
|
||||||
|
var entry = {
|
||||||
|
main: './src/main.jsx'
|
||||||
|
};
|
||||||
|
routes.forEach(function (route) {
|
||||||
|
entry[route.view] = './src/views/' + route.view + '/' + route.view + '.jsx';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Config
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: entry,
|
||||||
main: './src/main.jsx',
|
|
||||||
splash: './src/views/splash/splash.jsx'
|
|
||||||
},
|
|
||||||
devtool: 'source-map',
|
devtool: 'source-map',
|
||||||
externals: {
|
externals: {
|
||||||
'react': 'React',
|
'react': 'React',
|
||||||
|
|
Loading…
Reference in a new issue