Refactoring for deployment

Renamed view field in routes to “name” to match scratch-www, not using “view” field because all scratchJr views are name/name.jsx

renamed server to dev-server, and app.js to index.js for consistency with www, and to make clear it’s only the way it runs in development.

Added html-webpack-plugin
This commit is contained in:
chrisgarrity 2016-09-21 13:02:23 -04:00
parent 595a5a3093
commit a2125b48c9
9 changed files with 136 additions and 44 deletions

View file

@ -24,7 +24,7 @@ webpack:
# ------------------------------------
start:
$(NODE) ./server/app.js
$(NODE) ./dev-server/index.js
# ------------------------------------

22
dev-server/handler.js Executable file
View file

@ -0,0 +1,22 @@
/**
* Constructor
*/
function Handler (route) {
// Handle redirects
if (route.redirect) {
return (req, res) => { res.redirect(route.redirect); };
}
var url = '/' + route.name + '.html';
return function (req, res, next) {
req.url = url;
next();
};
}
/**
* Export a new instance
*/
module.exports = function (route) {
return new Handler(route);
};

View file

@ -13,9 +13,6 @@ var app = express ();
for (var routeId in routes) {
(function (route) {
app.get(route.pattern, handler(route));
app.get(route.pattern + '.html', function (req, res) {
res.redirect(route.pattern);
});
})(routes[routeId]);
}

View file

@ -33,6 +33,7 @@
"eslint": "3.4.0",
"eslint-plugin-json": "1.2.0",
"eslint-plugin-react": "6.2.0",
"html-webpack-plugin": "2.22.0",
"json-loader": "0.5.4",
"node-sass": "3.8.0",
"postcss-loader": "0.11.1",

View file

@ -1,29 +0,0 @@
var fs = require('fs');
var mustache = require('mustache');
var path = require('path');
/**
* Constructor
*/
function Handler (route) {
// Render template
var location = path.resolve(__dirname, '../src/template.html');
var template = fs.readFileSync(location, 'utf8');
var output = mustache.render(template, route);
return function (req, res) {
res.set({
'Content-Type': 'text/html',
'Cache-Control': 'public, max-age=31536000'
});
res.send(output);
};
}
/**
* Export a new instance
*/
module.exports = function (route) {
return new Handler(route);
};

View file

@ -1,42 +1,42 @@
[
{
"pattern": "/",
"view": "index",
"name": "index",
"title": "Home"
},
{
"pattern": "/about(/*)?",
"view": "about",
"name": "about",
"title": "About"
},
{
"pattern": "/learn(/*)?",
"view": "learn",
"name": "learn",
"title": "Learn"
},
{
"pattern": "/teach(/*)?",
"view": "teach",
"name": "teach",
"title": "Teach"
},
{
"pattern": "/donate",
"view": "donate",
"name": "donate",
"title": "Donate"
},
{
"pattern": "/privacy",
"view": "privacy",
"name": "privacy",
"title": "Privacy"
},
{
"pattern": "/hoc",
"view": "hoc",
"name": "hoc",
"title": "Hour of Code"
},
{
"pattern": "/eula",
"view": "eula",
"name": "eula",
"title": "Terms and Conditions"
}
]

31
src/template-config.js Normal file
View file

@ -0,0 +1,31 @@
/**
* Default options for the html-webpack-plugin HTML renderer
*
* See https://github.com/ampedandwired/html-webpack-plugin#configuration
* for possible options. Any other options will be available to the template
* under `htmlWebpackPlugin.options`
*/
module.exports = {
// html-webpack-plugin options
template: './src/template.ejs',
inject: false,
// Search and metadata
title: 'Coding for Young Children',
description:
'With ScratchJr, young children (ages 5-7) can program their ' +
'own interactive stories and games.',
// override if mobile-friendly
viewportWidth: 'device-width',
// Open graph
og_image: 'https://www.scratchjr.org/images/scratchjrlogo.png',
og_image_type: 'image/png',
og_image_width: 1337,
og_image_height: 367,
// Analytics & Monitoring
ga_tracker: process.env.GA_TRACKER || ''
};

52
src/template.ejs Normal file
View file

@ -0,0 +1,52 @@
<!DOCTYPE html>
<!--[if lt IE 9 ]> <html class="ie8"> <![endif]-->
<!--[if IE 9 ]> <html class="ie9"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html> <!--<![endif]-->
<head>
<meta charset="UTF-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=942, initial-scale=1">
<title>ScratchJr - <%= htmlWebpackPlugin.options.title %></title>
<!-- Prevent mobile Safari from making phone numbers -->
<meta name="format-detection" content="telephone=no">
<!-- Search & Open Graph-->
<meta name="description" content="<%= htmlWebpackPlugin.options.description %>" />
<meta name="google-site-verification" content="m_3TAXDreGTFyoYnEmU9mcKB4Xtw5mw6yRkuJtXRKxM" />
<meta property="og:url" content="https://scratch.mit.edu/" />
<meta property="og:type" content="website" />
<meta property="og:title" content="Scratch - <%= htmlWebpackPlugin.options.title %>" />
<meta property="og:description" content="<%= htmlWebpackPlugin.options.description %>" />
<meta property="og:image" content="<%- htmlWebpackPlugin.options.og_image %>" />
<meta property="og:image:type" content="<%- htmlWebpackPlugin.options.og_image_type %>" />
<meta property="og:image:width" content="<%- htmlWebpackPlugin.options.og_image_width %>" />
<meta property="og:image:height" content="<%- htmlWebpackPlugin.options.og_image_height %>" />
<!-- Favicon & ScratchJr styles -->
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/style/site.css">
<link rel="stylesheet" type="text/css" href="/style/content.css">
<!-- Transifex -->
<script type="text/javascript">
window.liveSettings = {
api_key: "5e440a933b4d46b8a37bc7627a1e76e0"
}
</script>
<script type="text/javascript" src="//cdn.transifex.com/live.js"></script>
</head>
<body>
<div class="txlive">
<div id="app"></div>
</div>
<!-- Scripts -->
<script src="/<%= htmlWebpackPlugin.files.chunks[htmlWebpackPlugin.options.route.name].entry %>"></script>
</body>
</html>

View file

@ -1,12 +1,21 @@
var CopyWebpackPlugin = require('copy-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
var routes = require('./src/routes.json');
// Prepare all entry points
var entry = {};
var entry = {
common: [
// Vendor
'react',
'react-dom'
]
};
routes.forEach(function (route) {
entry[route.view] = './src/views/' + route.view + '/' + route.view + '.jsx';
if (!route.redirect) {
entry[route.name] = './src/views/' + route.name + '/' + route.name + '.jsx';
}
});
module.exports = {
@ -44,5 +53,14 @@ module.exports = {
new CopyWebpackPlugin([{
from: 'static'
}])
]
].concat(routes
.filter(function (route) {return !route.redirect;})
.map(function (route) {
return new HtmlWebpackPlugin(Object.assign({}, require('./src/template-config.js'), {
title: route.title,
filename: route.name + '.html',
route: route
}));
})
)
};