client/build: organize assets into directories
This commit is contained in:
parent
dd3774ee57
commit
d8c20b89c6
7 changed files with 42 additions and 23 deletions
|
@ -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');
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
4
client/public/.gitignore
vendored
4
client/public/.gitignore
vendored
|
@ -1,2 +1,2 @@
|
||||||
*.*
|
data/
|
||||||
!.gitignore
|
index.htm
|
||||||
|
|
2
client/public/css/.gitignore
vendored
Normal file
2
client/public/css/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
2
client/public/img/.gitignore
vendored
Normal file
2
client/public/img/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
2
client/public/js/.gitignore
vendored
Normal file
2
client/public/js/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
Loading…
Reference in a new issue