client/build: organize assets into directories

This commit is contained in:
rr- 2016-05-21 12:33:02 +02:00
parent dd3774ee57
commit d8c20b89c6
7 changed files with 42 additions and 23 deletions

View file

@ -20,6 +20,14 @@ function convertKeysToCamelCase(input) {
return result; return result;
} }
function readTextFile(path) {
return fs.readFileSync(path, 'utf-8');
}
function writeFile(path, content) {
return fs.writeFileSync(path, content);
}
function getVersion() { function getVersion() {
return execSync('git describe --always --dirty --long --tags').toString(); return execSync('git describe --always --dirty --long --tags').toString();
} }
@ -30,7 +38,7 @@ function getConfig() {
const camelcaseKeys = require('camelcase-keys'); const camelcaseKeys = require('camelcase-keys');
function parseConfigFile(path) { function parseConfigFile(path) {
let result = yaml.load(fs.readFileSync(path, 'utf-8')); let result = yaml.load(readTextFile(path, 'utf-8'));
return convertKeysToCamelCase(result); return convertKeysToCamelCase(result);
} }
@ -55,6 +63,10 @@ function getConfig() {
return config; return config;
} }
function copyFile(source, target) {
fs.createReadStream(source).pipe(fs.createWriteStream(target));
}
function minifyJs(path) { function minifyJs(path) {
return require('uglify-js').minify(path).code; return require('uglify-js').minify(path).code;
} }
@ -74,12 +86,12 @@ function minifyHtml(html) {
function bundleHtml(config) { function bundleHtml(config) {
const underscore = require('underscore'); const underscore = require('underscore');
const babelify = require('babelify'); const babelify = require('babelify');
const baseHtml = fs.readFileSync('./html/index.htm', 'utf-8'); const baseHtml = readTextFile('./html/index.htm', 'utf-8');
const finalHtml = baseHtml const finalHtml = baseHtml
.replace( .replace(
/(<title>)(.*)(<\/title>)/, /(<title>)(.*)(<\/title>)/,
util.format('$1%s$3', config.name)); util.format('$1%s$3', config.name));
fs.writeFileSync('./public/index.htm', minifyHtml(finalHtml)); writeFile('./public/index.htm', minifyHtml(finalHtml));
glob('./html/**/*.tpl', {}, (er, files) => { glob('./html/**/*.tpl', {}, (er, files) => {
let compiledTemplateJs = '\'use strict\'\n'; let compiledTemplateJs = '\'use strict\'\n';
@ -87,13 +99,13 @@ function bundleHtml(config) {
compiledTemplateJs += 'let templates = {};'; compiledTemplateJs += 'let templates = {};';
for (const file of files) { for (const file of files) {
const name = path.basename(file, '.tpl').replace(/_/g, '-'); const name = path.basename(file, '.tpl').replace(/_/g, '-');
const templateText = minifyHtml(fs.readFileSync(file, 'utf-8')); const templateText = minifyHtml(readTextFile(file, 'utf-8'));
const functionText = underscore.template( const functionText = underscore.template(
templateText, {variable: 'ctx'}).source; templateText, {variable: 'ctx'}).source;
compiledTemplateJs += `templates['${name}'] = ${functionText};`; compiledTemplateJs += `templates['${name}'] = ${functionText};`;
} }
compiledTemplateJs += 'module.exports = templates;'; compiledTemplateJs += 'module.exports = templates;';
fs.writeFileSync('./js/.templates.autogen.js', compiledTemplateJs); writeFile('./js/.templates.autogen.js', compiledTemplateJs);
console.info('Bundled HTML'); console.info('Bundled HTML');
}); });
} }
@ -104,9 +116,10 @@ function bundleCss() {
let css = ''; let css = '';
for (const file of files) { for (const file of files) {
css += stylus.render( css += stylus.render(
fs.readFileSync(file, 'utf-8'), {filename: file}); readTextFile(file), {filename: file});
} }
fs.writeFileSync('./public/app.min.css', minifyCss(css)); writeFile('./public/css/app.min.css', minifyCss(css));
console.info('Bundled CSS'); console.info('Bundled CSS');
}); });
} }
@ -127,7 +140,7 @@ function bundleJs(config) {
b.bundle().pipe(outputFile); b.bundle().pipe(outputFile);
outputFile.on('finish', function() { outputFile.on('finish', function() {
if (compress) { if (compress) {
fs.writeFileSync(path, minifyJs(path)); writeFile(path, minifyJs(path));
} }
console.info(message); console.info(message);
}); });
@ -143,18 +156,18 @@ function bundleJs(config) {
b.add(require.resolve('babel-polyfill')); b.add(require.resolve('babel-polyfill'));
} }
writeJsBundle( writeJsBundle(
b, './public/vendor.min.js', 'Bundled vendor JS', true); b, './public/js/vendor.min.js', 'Bundled vendor JS', true);
} }
if (!process.argv.includes('--no-app-js')) { if (!process.argv.includes('--no-app-js')) {
let outputFile = fs.createWriteStream('./public/app.min.js'); let outputFile = fs.createWriteStream('./public/js/app.min.js');
let b = browserify({debug: config.debug}); let b = browserify({debug: config.debug});
if (config.transpile) { if (config.transpile) {
b = b.transform('babelify'); b = b.transform('babelify');
} }
writeJsBundle( writeJsBundle(
b.external(external).add(files), b.external(external).add(files),
'./public/app.min.js', './public/js/app.min.js',
'Bundled app JS', 'Bundled app JS',
!config.debug); !config.debug);
} }
@ -162,16 +175,18 @@ function bundleJs(config) {
} }
function bundleConfig(config) { function bundleConfig(config) {
fs.writeFileSync( writeFile(
'./js/.config.autogen.json', JSON.stringify(config)); './js/.config.autogen.json', JSON.stringify(config));
} }
function copyFile(source, target) { function bundleBinaryAssets() {
fs.createReadStream(source).pipe(fs.createWriteStream(target)); copyFile('./img/favicon.png', './public/img/favicon.png');
copyFile('./img/404.png', './public/img/404.png');
} }
const config = getConfig(); const config = getConfig();
bundleConfig(config); bundleConfig(config);
bundleBinaryAssets();
if (!process.argv.includes('--no-html')) { if (!process.argv.includes('--no-html')) {
bundleHtml(config); bundleHtml(config);
} }
@ -181,5 +196,3 @@ if (!process.argv.includes('--no-css')) {
if (!process.argv.includes('--no-js')) { if (!process.argv.includes('--no-js')) {
bundleJs(config); bundleJs(config);
} }
copyFile('./img/favicon.png', './public/favicon.png');
copyFile('./img/404.png', './public/404.png');

View file

@ -4,15 +4,15 @@
<meta charset='utf-8'/> <meta charset='utf-8'/>
<meta name='viewport' content='width=device-width, initial-scale=1.0'> <meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title><!-- configured in the config file --></title> <title><!-- configured in the config file --></title>
<link href='/app.min.css' rel='stylesheet' type='text/css'/> <link href='/css/app.min.css' rel='stylesheet' type='text/css'/>
<link href='//maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css' rel='stylesheet' type='text/css'/> <link href='//maxcdn.bootstrapcdn.com/font-awesome/4.6.0/css/font-awesome.min.css' rel='stylesheet' type='text/css'/>
<link href='//fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'/> <link href='//fonts.googleapis.com/css?family=Droid+Sans' rel='stylesheet' type='text/css'/>
<link rel='shortcut icon' type='image/png' href='/favicon.png'/> <link rel='shortcut icon' type='image/png' href='/img/favicon.png'/>
</head> </head>
<body> <body>
<div id='top-nav-holder'></div> <div id='top-nav-holder'></div>
<div id='content-holder'></div> <div id='content-holder'></div>
<script type='text/javascript' src='/vendor.min.js'></script> <script type='text/javascript' src='/js/vendor.min.js'></script>
<script type='text/javascript' src='/app.min.js'></script> <script type='text/javascript' src='/js/app.min.js'></script>
</body> </body>
</html> </html>

View file

@ -1,5 +1,5 @@
<div class='not-found'> <div class='not-found'>
<img src='/404.png' alt='404 Not found'/> <img src='/img/404.png' alt='404 Not found'/>
<p><%= ctx.path %> is not a valid URL.</p> <p><%= ctx.path %> is not a valid URL.</p>
<p><a href='/'>Back to main page</a></p> <p><a href='/'>Back to main page</a></p>
</div> </div>

View file

@ -1,2 +1,2 @@
*.* data/
!.gitignore index.htm

2
client/public/css/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

2
client/public/img/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore

2
client/public/js/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*
!.gitignore