Skip to content

Commit

Permalink
Merge pull request #7 from ddimitrioglo/dev
Browse files Browse the repository at this point in the history
#WB v1.1.0 relase
  • Loading branch information
Dmitri Dimitrioglo authored Mar 9, 2018
2 parents abbb609 + d7475d0 commit 093cf30
Show file tree
Hide file tree
Showing 21 changed files with 197 additions and 57 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# web-boost

<img src="https://github.com/ddimitrioglo/web-boost/blob/dev/web-boost-logo.svg" width="200"/>
<img src="https://cdn.rawgit.com/ddimitrioglo/web-boost/master/web-boost-logo.svg" width="200"/>

`web-boost` - boost your static site development.

Expand All @@ -10,10 +10,18 @@ Web-boost is a static site generator with page-speed optimisations. You build a
and routing - web-boost will compile it into highly optimised static pages.

* Uglify, concat & minify `javascript` files
* Compile, concat & minify `scss`/`css` files
* Compile, concat & minify `css`/`scss`/`sass` files
* Compile & minify `twig` templates
* Optimise `.jpg` and `.png` files

> To speed-up compilation, all the minified files (`.min.css` and `.min.js`) will be just concatenated
### Installation

`npm install -g web-boost`

> Global installation is preferable but not required
### Usage

* Generate application with `web-boost-cli` (see [user guide][1]) or create it yourself by following the [structure][2]
Expand Down
3 changes: 2 additions & 1 deletion bin/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const pngquant = require('imagemin-pngquant');
const jpegRecompress = require('imagemin-jpeg-recompress');
const Route = require('../src/route');
const config = require('../src/config');
const logger = require('../src/logger');
const appPath = process.cwd();

/**
Expand All @@ -32,7 +33,7 @@ Promise.all(promises).then(() => {
]
})
}).then(() => {
console.log('Compilation finished');
logger.log('Compilation finished');
}).catch(err => {
throw err;
});
6 changes: 4 additions & 2 deletions cli-component/index.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ const destinationPath = path.resolve(process.cwd(), destination);
const appPackageJson = path.join(destination, 'package.json');

fse.copy(sourcePath, destinationPath).then(() => {
let packageSrc = JSON.parse(fs.readFileSync(appPackageJson));
let packageOut = JSON.stringify(packageSrc, (key, val) => (key === 'name') ? appName : val, 2);
fs.renameSync(`${appPackageJson}.tmpl`, appPackageJson);

const packageSrc = JSON.parse(fs.readFileSync(appPackageJson));
const packageOut = JSON.stringify(packageSrc, (key, val) => (key === 'name') ? appName : val, 2);

fs.writeFileSync(appPackageJson, packageOut);

Expand Down
4 changes: 2 additions & 2 deletions cli-component/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "web-boost-cli",
"version": "0.0.5",
"version": "1.0.3",
"description": "Web-boost application generator",
"bin": {
"web-boost-cli": "index.js"
"web-boost-cli": "./index.js"
},
"author": "ddimitrioglo",
"license": "MIT",
Expand Down
5 changes: 5 additions & 0 deletions cli-component/skeleton/assets/styles/base.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.container {
ul {
padding-left: 5px;
}
}
2 changes: 1 addition & 1 deletion cli-component/skeleton/assets/styles/index.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$primary-color: green;
@import './styles/variables';

.jumbotron {
margin: 40px 20px;
Expand Down
2 changes: 1 addition & 1 deletion cli-component/skeleton/assets/styles/user.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$primary-color: blue;
@import './styles/variables';

.jumbotron {
margin: 40px 20px;
Expand Down
1 change: 1 addition & 0 deletions cli-component/skeleton/assets/styles/variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$primary-color: blue;
12 changes: 0 additions & 12 deletions cli-component/skeleton/package.json

This file was deleted.

12 changes: 12 additions & 0 deletions cli-component/skeleton/package.json.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "web-boost-skeleton",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/web-boost/bin/run.js",
"compile": "node node_modules/web-boost/bin/compile.js"
},
"devDependencies": {
"web-boost": "^1.1.0"
}
}
8 changes: 7 additions & 1 deletion cli-component/skeleton/web-boost.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"$": {
"common": [
"styles/bootstrap.min.css",
"styles/base.scss"
]
},
"routes": {
"/": {
"view": "index.twig",
Expand All @@ -11,7 +17,7 @@
"js/index.js"
],
"css/index.min.css": [
"styles/bootstrap.min.css",
"$.common",
"styles/index.scss"
]
}
Expand Down
8 changes: 7 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Frequently asked questions

To be updated...
* **How do I get the route name from the template?**

Yes, there is a build-in variable `routeName`, so you can use it in your templates `{{ routeName }}`

* **Is @import supported in .scss/.sass files?**

Yes, just provide a path related to "app.assets" directory. Ex: `@import './styles/variables';`
48 changes: 27 additions & 21 deletions docs/structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,49 @@
### App structure

```text
app // Root of your application
├─ assets // Assets source directory
│  ├─ img // Image folder
app/ # Root of your application
├─ assets/ # Source directory for all assets
│  ├─ img/ # Image folder
│  ├─ fonts/ # Fonts folder
│  ├─ index.js
│  └─ index.scss
├─ views // Templates directory
├─ views/ # Templates directory
│  ├─ index.twig
│  └─ layout.twig
├─ public // Compiled assets directory
├─ web-boost.json // Web-boost configuration file
├─ public/ # Destination directory for compiled/minimized assets
├─ web-boost.json # Web-boost configuration file
└─ package.json
```
> Image folder is always `img` which is relative to "app.assets" (supported `.jpg` and `.png`)
> Image folder is **always** `img` (**not** `imgs`, `images` etc.) which is relative to "app.assets" (supported `.jpg` and `.png`)
### Configuration file (`web-boost.json`)

```text
{
"app": { // Application config object [Optional]
"views": "views", // Templates directory [Optional, default: "views"]
"public": "public", // Compiled assets directory [Optional, default: "public"]
"assets": "assets" // Assets source directory [Optional, default: "assets"]
"$": { # Global config object [Optional]
"common": [ # Common assets block (accessible via "$.common" across config)
"styles/bootstrap.min.css",
"styles/main.scss"
]
},
"routes": { // A list of web-boost application routes [Required]
"/": { // Route slug [Required]
"view": "index.twig", // View to render (relative to "app.views") [Required]
"vars": { // View variables [Optional, default: {}]
"app": { # Application config object [Optional]
"views": "views", # Templates directory [Optional, default: "views"]
"assets": "assets" # Assets source directory [Optional, default: "assets"]
},
"routes": { # A list of web-boost application routes [Required]
"/": { # Route slug [Required]
"view": "index.twig", # View to render (relative to "app.views") [Required]
"vars": { # View variables [Optional, default: {}]
"name": "John",
"age": "26" // Example: "<p>{{ age }}-Year-Old {{ name }} liked our repo ;)</p>"
"age": "26" # Example: "<p>{{ age }}-Year-Old {{ name }} liked our repo ;)</p>"
},
"assets": { // Route specific assets [Optional, default: {}]
"js/index.min.js": [ // Assets destination file (relative to "app.public")
"js/main.js", // Assets source files (relative to "app.assets")
"js/index.js" // js/main.js + js/index.js => js/index.min.js
"assets": { # Route specific assets [Optional, default: {}]
"js/index.min.js": [ # Assets destination file (relative to "app.public")
"$.common", # Common assets block == ["styles/bootstrap.min.css", "styles/main.scss"]
"js/index.js"
],
"css/index.min.css": [
"styles/main.scss", // styles/main.scss + styles/index.scss => css/index.min.css
"styles/main.scss", # styles/main.scss + styles/index.scss => css/index.min.css
"styles/index.scss"
]
}
Expand Down
7 changes: 6 additions & 1 deletion helpers/twig.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
'use strict';

const Twig = require('twig');
const logger = require('../src/logger');

/**
* Twig configuration
*/
Twig.extendFunction('asset', (asset) => {
return asset.replace(/^@/, '/');
try {
return asset.replace(/^@/, '/');
} catch (error) {
logger.error(`'asset()' syntax error: ${error.message}`);
}
});

module.exports = Twig;
18 changes: 17 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const Route = require('./src/route');
const config = require('./src/config');
const logger = require('./src/logger');
const express = require('express');

const app = express();
Expand All @@ -20,6 +21,7 @@ config.init(appPath);
app.set('views', config.getPath('app.views'));
app.use('/', express.static(config.getPath('app.public')));
app.use('/img', express.static(config.getPath('app.assets', 'img')));
app.use('/fonts', express.static(config.getPath('app.assets', 'fonts')));

/**
* Init web-boost routes
Expand All @@ -30,7 +32,9 @@ const appRoutes = Object.keys(routes).map(route => new Route(route, routes[route
/**
* Trigger assets compilation
*/
Promise.all(appRoutes.map(route => route.packAssets())).catch(err => { throw err; });
Promise.all(appRoutes.map(route => route.packAssets()))
.then(() => logger.info('Ok'))
.catch(err => handleError(err));

/**
* Init app routes
Expand All @@ -45,3 +49,15 @@ appRoutes.forEach(route => {
* Listen server
*/
app.listen(port);

/**
* @param {Error} error
*/
function handleError(error) {
let errorMsg = error.message;
if (error.code === 'ENOENT') {
errorMsg = `${error.path.replace(`${appPath}/`, '@')} does not exist`;
}

logger.error(errorMsg);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web-boost",
"version": "1.0.0",
"version": "1.1.0",
"description": "Static site generator with page-speed optimisations",
"main": "index.js",
"bin": {
Expand Down
7 changes: 5 additions & 2 deletions src/asset-factory.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

const config = require('./config');
const JsAsset = require('./js-asset');
const ScssAsset = require('./scss-asset');

Expand All @@ -9,15 +10,17 @@ class AssetFactory {
* @return {*}
*/
static create(file) {
let assetsPath = config.getPath('app.assets');
let type = file.getExt();

switch (type) {
case '.sass':
case '.less':
throw Error(`'${type}' is not supported`);
case '.sass':
return new ScssAsset(file, { includePaths: [assetsPath], indentedSyntax: true });
case '.scss':
case '.css':
return new ScssAsset(file);
return new ScssAsset(file, { includePaths: [assetsPath] });
case '.js':
return new JsAsset(file);
default:
Expand Down
2 changes: 1 addition & 1 deletion src/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class File {
*/
getLocalContent() {
return new Promise((resolve, reject) => {
fse.readFile(this.fullPath(), null, (err, data) => {
fse.readFile(this.fullPath(), (err, data) => {
return err ? reject(err) : resolve(data);
});
});
Expand Down
71 changes: 71 additions & 0 deletions src/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict';

class Logger {
/**
* @param message
*/
static log(message) {
Logger._log(Logger.LOG, message);
}

/**
* @param message
*/
static info(message) {
Logger._log(Logger.INFO, message);
}

/**
* @param {String} message
*/
static error(message) {
Logger._log(Logger.ERROR, message);
}

/**
* @param {String} type
* @param {String} message
* @private
*/
static _log(type, message) {
const time = `[${(new Date()).toISOString()}]`;

switch (type) {
case Logger.LOG:
console.log('✅', time, message);
break;
case Logger.INFO:
console.log('💡', time, message);
break;
case Logger.ERROR:
console.log('❌', time, message);
break;
}
}

/**
* @returns {String}
* @constructor
*/
static get LOG() {
return 'log';
}

/**
* @returns {String}
* @constructor
*/
static get INFO() {
return 'info';
}

/**
* @returns {String}
* @constructor
*/
static get ERROR() {
return 'error';
}
}

module.exports = Logger;
Loading

0 comments on commit 093cf30

Please sign in to comment.