diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..29f6e7e --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +*.min.js +*.build.js diff --git a/lib/extensions/browser-sync.js b/lib/extensions/browser-sync.js new file mode 100644 index 0000000..79d6ad6 --- /dev/null +++ b/lib/extensions/browser-sync.js @@ -0,0 +1,39 @@ +'use strict'; + +const ChildProcess = require('child_process'); +const Util = require('util'); + +module.exports = [ + { + type: 'onPostStart', + method: async (server) => { + + if (!server.realm.pluginOptions.developmentMode) { + return; + } + + const bs = server.app.bs = require('browser-sync').create(); + const base = server.realm.settings.files.relativeTo; + const run = (cmd) => ChildProcess.spawn('npm', ['run', cmd], { stdio: 'inherit' }); + + bs.watch(`${base}/public/**/*.scss`).on('change', () => run('prebuild:css')); + bs.watch([`${base}/public/**/*.js`, '!**/*.build.*']).on('change', () => run('prebuild:js')); + + bs.watch(`${base}/templates/**/*`).on('change', bs.reload); + bs.watch(`${base}/public/**/*.{build.js,css}`).on('change', bs.reload); + + await Util.promisify(bs.init)({ proxy: server.info.uri }); + } + }, + { + type: 'onPreStop', + method: (server) => { + + if (!server.app.bs) { + return; + } + + server.app.bs.exit(); + } + } +]; diff --git a/lib/path.js b/lib/path.js new file mode 100644 index 0000000..4d168fc --- /dev/null +++ b/lib/path.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = __dirname; diff --git a/lib/plugins/@hapi.inert.js b/lib/plugins/@hapi.inert.js new file mode 100644 index 0000000..8b46fbb --- /dev/null +++ b/lib/plugins/@hapi.inert.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = {}; diff --git a/lib/plugins/@hapi.vision.js b/lib/plugins/@hapi.vision.js new file mode 100644 index 0000000..8b46fbb --- /dev/null +++ b/lib/plugins/@hapi.vision.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = {}; diff --git a/lib/public/css/main.build.css b/lib/public/css/main.build.css new file mode 100644 index 0000000..edb8068 --- /dev/null +++ b/lib/public/css/main.build.css @@ -0,0 +1,5 @@ +body { + color: white; + background-color: black; } + +/*# sourceMappingURL=main.build.css.map */ \ No newline at end of file diff --git a/lib/public/css/main.build.css.map b/lib/public/css/main.build.css.map new file mode 100644 index 0000000..ac743d7 --- /dev/null +++ b/lib/public/css/main.build.css.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "file": "main.build.css", + "sources": [ + "main.scss" + ], + "names": [], + "mappings": "AAAA,AAAA,IAAI,CAAC;EACD,KAAK,EAAE,KAAK;EACZ,gBAAgB,EAAE,KAAK,GAC1B" +} \ No newline at end of file diff --git a/lib/public/css/main.build.min.css b/lib/public/css/main.build.min.css new file mode 100644 index 0000000..76a97e4 --- /dev/null +++ b/lib/public/css/main.build.min.css @@ -0,0 +1 @@ +body{background-color:#000;color:#fff} \ No newline at end of file diff --git a/lib/public/css/main.scss b/lib/public/css/main.scss new file mode 100644 index 0000000..a8cb6c2 --- /dev/null +++ b/lib/public/css/main.scss @@ -0,0 +1,4 @@ +body { + color: white; + background-color: black; +} diff --git a/lib/public/js/main.build.js b/lib/public/js/main.build.js new file mode 100644 index 0000000..2022945 --- /dev/null +++ b/lib/public/js/main.build.js @@ -0,0 +1,7 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i layout title="Home" }} + + {{#*inline "content"}} + Hello, pals! This is the homepage. + {{/inline}} + +{{/layout}} diff --git a/lib/templates/partials/layout.hbs b/lib/templates/partials/layout.hbs new file mode 100644 index 0000000..9084299 --- /dev/null +++ b/lib/templates/partials/layout.hbs @@ -0,0 +1,32 @@ + + + + {{title}} + + {{#if options.developmentMode}} + + {{else}} + + {{/if}} + + {{#> head-block}} + {{!-- Custom content per page could be added. --}} + {{/head-block}} + + + + {{#> content}} + {{!-- Content goes here. --}} + {{/content}} + + {{#if options.developmentMode}} + + {{else}} + + {{/if}} + + {{#> scripts-block}} + {{!-- Custom scripts per page can be added. --}} + {{/scripts-block}} + + diff --git a/lib/view-manager.js b/lib/view-manager.js new file mode 100644 index 0000000..27e0fe7 --- /dev/null +++ b/lib/view-manager.js @@ -0,0 +1,18 @@ +'use strict'; + +const Handlebars = require('handlebars'); + +module.exports = (server, options) => ({ + path: 'templates', + partialsPath: 'templates/partials', + helpersPath: 'templates/helpers', + isCached: !options.developmentMode, + defaultExtension: 'hbs', + engines: { + hbs: Handlebars + }, + context: { + options, + baseURI: server.realm.modifiers.route.prefix || '' + } +}); diff --git a/package.json b/package.json index 3f61bfd..f4b710c 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,24 @@ "scripts": { "start": "node server", "test": "lab -a @hapi/code -L", - "lint": "eslint ." + "lint": "eslint .", + "prebuild:css": "node-sass lib/public/css/main.scss lib/public/css/main.build.css --source-map true", + "build:css": "postcss lib/public/css/main.build.css -o lib/public/css/main.build.min.css --use cssnano --no-map", + "prebuild:js": "browserify lib/public/js/main.js -o lib/public/js/main.build.js -d -t [ babelify --presets [ @babel/preset-env ] ]", + "build:js": "uglifyjs lib/public/js/main.build.js -o lib/public/js/main.build.min.js", + "build": "npm run build:css && npm run build:js" }, "dependencies": { "@hapi/boom": "9.x.x", + "@hapi/inert": "6.x.x", + "@hapi/vision": "6.x.x", "@hapipal/haute-couture": "4.x.x", + "handlebars": "4.x.x", "joi": "17.x.x" }, "devDependencies": { + "@babel/preset-env": "7.x.x", + "@babel/core": "7.x.x", "@hapi/code": "8.x.x", "@hapi/eslint-config-hapi": "13.x.x", "@hapi/eslint-plugin-hapi": "4.x.x", @@ -24,8 +34,16 @@ "@hapipal/hpal-debug": "2.x.x", "@hapipal/toys": "3.x.x", "babel-eslint": "10.x.x", + "babelify": "10.x.x", + "browser-sync": "2.x.x", + "browserify": "17.x.x", + "cssnano": "5.x.x", "dotenv": "8.x.x", "eslint": "7.x.x", - "exiting": "6.x.x" + "exiting": "6.x.x", + "node-sass": "5.x.x", + "postcss": "8.x.x", + "postcss-cli": "8.x.x", + "uglify-js": "3.x.x" } } diff --git a/server/manifest.js b/server/manifest.js index ffb9f26..18241ca 100644 --- a/server/manifest.js +++ b/server/manifest.js @@ -31,7 +31,13 @@ module.exports = new Confidence.Store({ plugins: [ { plugin: '../lib', // Main plugin - options: {} + options: { + developmentMode: { + $filter: { $env: 'NODE_ENV' }, + $default: true, + production: false + } + } }, { plugin: {