├── VERSION ├── metadata └── changes │ ├── 2.0.2.txt │ ├── 1.2.0.txt │ ├── 2.0.4.txt │ ├── 2.0.5.txt │ ├── 2.0.6.txt │ ├── 1.4.0.txt │ ├── 1.1.1.txt │ ├── 1.1.2.txt │ ├── 2.0.3.txt │ ├── 1.1.0.txt │ ├── 1.0.0.txt │ ├── 2.0.1.txt │ ├── 1.3.0.txt │ ├── 2.0.0.txt │ └── 0.1.0.txt ├── .prettierrc ├── .gitignore ├── .cix.yml ├── docker ├── docker-compose.yaml.template └── Dockerfile.template ├── scripts ├── bump-hook ├── rel-push-prog ├── create-hugo-site └── create-docker-machine-and-run-it ├── LICENSE ├── gulp ├── util.js ├── watch.js └── build.js ├── package.json ├── index.js ├── CHANGES └── README.md /VERSION: -------------------------------------------------------------------------------- 1 | 2.0.6 2 | -------------------------------------------------------------------------------- /metadata/changes/2.0.2.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.2 2 | 3 | - Fix plugin names 4 | -------------------------------------------------------------------------------- /metadata/changes/1.2.0.txt: -------------------------------------------------------------------------------- 1 | 2017-03-18 - 1.2.0 2 | 3 | Add support for less files 4 | -------------------------------------------------------------------------------- /metadata/changes/2.0.4.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.4 2 | 3 | - Set saner htmlmin defaults 4 | -------------------------------------------------------------------------------- /metadata/changes/2.0.5.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.5 2 | 3 | - Fix scripts task build source 4 | -------------------------------------------------------------------------------- /metadata/changes/2.0.6.txt: -------------------------------------------------------------------------------- 1 | 2018-10-28 - 2.0.6 2 | 3 | - Log relative path while watching styles -------------------------------------------------------------------------------- /metadata/changes/1.4.0.txt: -------------------------------------------------------------------------------- 1 | 2017-11-27 - 1.4.0 2 | 3 | - Add docker support (#24) 4 | - Minifyhtml (#31) 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "printWidth": 80, 4 | "semi": false, 5 | "useTabs": false, 6 | "tabWidth": 2 7 | } 8 | -------------------------------------------------------------------------------- /metadata/changes/1.1.1.txt: -------------------------------------------------------------------------------- 1 | 2017-02-12 - 1.1.1 2 | 3 | ```hugulp build``` now creates a site without drafts and without 4 | baseUrl 5 | -------------------------------------------------------------------------------- /metadata/changes/1.1.2.txt: -------------------------------------------------------------------------------- 1 | 2017-03-17 - 1.1.2 2 | 3 | ```hugulp``` now processes subdirectories in the assets folders, if present. 4 | -------------------------------------------------------------------------------- /metadata/changes/2.0.3.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.3 2 | 3 | - Make sure all tasks are executed 4 | - Display pipeline being executed 5 | - Display space optimization achieved 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | public 3 | 4 | # node 5 | node_modules 6 | *.log 7 | 8 | # bower 9 | bower_components 10 | src/vendor 11 | 12 | # docker 13 | Dockerfile 14 | docker-compose.yaml 15 | -------------------------------------------------------------------------------- /metadata/changes/1.1.0.txt: -------------------------------------------------------------------------------- 1 | 2017-01-28 - 1.1.0 2 | 3 | hugulp now uses hugo default config file (config.toml) 4 | 5 | You can specify an alternative config, via a command line switch 6 | -c, --config 7 | -------------------------------------------------------------------------------- /metadata/changes/1.0.0.txt: -------------------------------------------------------------------------------- 1 | 2017-01-08 - 1.0.0 2 | hugulp is now a standalone tool. 3 | 4 | This allows for the following improvements 5 | - Easier to work on multiple sites 6 | - Easier to update 7 | - Can be used in CI/CD workflows 8 | -------------------------------------------------------------------------------- /metadata/changes/2.0.1.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.1 2 | 3 | - Run styles/scripts tasks on watch invocation 4 | - Add granular imagemin configuration 5 | - Adjust default .hugulprc 6 | - Fix JSON syntax in README 7 | - Fix update instructions 8 | -------------------------------------------------------------------------------- /.cix.yml: -------------------------------------------------------------------------------- 1 | test: 2 | script: 3 | # - scripts/rel-push-prog 4 | only: 5 | - /^wrk.*$/ 6 | 7 | deploy: 8 | script: 9 | - scripts/rel-push-prog 10 | - npm publish 11 | only: 12 | - /^rel.*$/ 13 | -------------------------------------------------------------------------------- /metadata/changes/1.3.0.txt: -------------------------------------------------------------------------------- 1 | 2017-03-20 - 1.3.0 2 | 3 | Added a command to display the current version: ```hugulp version``` 4 | 5 | A bug that was preventing the styles folder to react to changes was fixed. 6 | 7 | Additionally: 8 | - Upgrade dependencies 9 | - Replace gulp.watch with gulp-watch 10 | -------------------------------------------------------------------------------- /docker/docker-compose.yaml.template: -------------------------------------------------------------------------------- 1 | --- 2 | version: '3' 3 | services: 4 | app: 5 | labels: 6 | app: "app" 7 | build: 8 | context: . 9 | command: /bin/sh -c './scripts/create-hugo-site -a ./app;cd app;hugulp watch' 10 | volumes: 11 | - .:/home/node/app 12 | - /home/node/app/node_modules 13 | ports: 14 | - "3000:3000" 15 | - "3001:3001" 16 | -------------------------------------------------------------------------------- /metadata/changes/2.0.0.txt: -------------------------------------------------------------------------------- 1 | 2017-12-12 - 2.0.0 2 | 3 | This is a re-thinking of hugulp, in order to be more flexible and better support hugo's features. 4 | 5 | hugulp now works as a post-processor, optimizing the output that hugo generates in the public folder. 6 | 7 | You can now invoke hugo from the command line as it best suits you and use any theme you want. 8 | 9 | Check the README for v2 docs. 10 | -------------------------------------------------------------------------------- /metadata/changes/0.1.0.txt: -------------------------------------------------------------------------------- 1 | 2017-01-06 - 0.1.0 2 | - Initial commit 3 | - syntax fix for package.json 4 | - Add missing semicolons 5 | - Replace tabs with spaces 6 | - Update reference.js 7 | - - Update packages 8 | - Improve project details and instructions 9 | - Fix syntax error 10 | - Delete public folder when running gulp task. Also delete (if existing) the public folder inside hugo. 11 | - Update dependencies 12 | - Implement CI automation 13 | - Add missing variable 14 | 15 | 16 | -------------------------------------------------------------------------------- /docker/Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM node:7.9.0-alpine 2 | # Set environment variable 3 | ARG RUN_AS=node 4 | ARG HUGO_VERSION=0.20.6 5 | ARG HUGO_BINARY="hugo_${HUGO_VERSION}_Linux-64bit" 6 | RUN apk update && apk add py-pygments && rm -rf /var/cache/apk/* 7 | # Download and install hugo 8 | RUN mkdir /usr/local/hugo 9 | ADD https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY}.tar.gz \ 10 | /usr/local/hugo/ 11 | RUN tar xzf /usr/local/hugo/${HUGO_BINARY}.tar.gz -C /usr/local/hugo/ \ 12 | && ln -s /usr/local/hugo/hugo /usr/local/bin/hugo \ 13 | && rm /usr/local/hugo/${HUGO_BINARY}.tar.gz 14 | RUN npm install -g hugulp 15 | ENV HOME=/home/$RUN_AS 16 | COPY package.json $HOME/web/ 17 | RUN chmod 755 $HOME/* && chown -R $RUN_AS:$RUN_AS $HOME/* 18 | USER $RUN_AS 19 | # Change working directory 20 | WORKDIR $HOME/web/ 21 | USER root 22 | COPY . $HOME/web/ 23 | RUN chown -R $RUN_AS:$RUN_AS $HOME/* 24 | USER $RUN_AS -------------------------------------------------------------------------------- /scripts/bump-hook: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function error { 4 | NAME=$1 5 | 6 | printf "$1" 7 | exit 1 8 | } 9 | 10 | APP_VERSION=$(cat VERSION 2> /dev/null) 11 | 12 | if [[ -z $APP_VERSION ]]; then 13 | error "Unable to find VERSION file. Please check and try again" 14 | fi 15 | 16 | echo "Version is $APP_VERSION" 17 | 18 | npm --no-git-tag-version -f version ${APP_VERSION} 19 | 20 | TAG=`git describe --abbrev=0 --tags 2> /dev/null` 21 | 22 | if [[ -z "$TAG" ]]; then 23 | COMMITS=`git --no-pager log --reverse --pretty=format:'- %s' | egrep -v '.*Closes' | egrep -v '.*Merge' 2> /dev/null` 24 | else 25 | COMMITS=`git --no-pager log --reverse --pretty=format:'- %s' "$TAG"...HEAD | egrep -v '.*Closes' | egrep -v '.*Merge' 2> /dev/null` 26 | fi 27 | 28 | PREVIOUS=`cat metadata/changes/${TAG}.txt 2> /dev/null` 29 | 30 | cat < metadata/changes/${APP_VERSION}.txt 31 | `date +%F` - ${APP_VERSION} 32 | ${COMMITS} 33 | 34 | ${PREVIOUS} 35 | EOF 36 | 37 | code metadata/changes/${APP_VERSION}.txt 38 | 39 | echo "Bumped versions successfully" 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Juan B. Rodriguez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /gulp/util.js: -------------------------------------------------------------------------------- 1 | // system 2 | const fs = require('fs') 3 | const path = require('path') 4 | 5 | // common 6 | const gulp = require('gulp') 7 | 8 | // styles 9 | const sass = require('gulp-sass') 10 | const less = require('gulp-less') 11 | const concat = require('gulp-concat') 12 | 13 | // parameters 14 | const config = JSON.parse( 15 | fs.readFileSync(path.join(process.cwd(), '.hugulprc')) 16 | ) 17 | 18 | // helper functions 19 | function getStylesStreams() { 20 | const lessStream = gulp 21 | .src(path.join(config.watch.source, config.path.styles, '**/*.less')) // i.e.: assets/styles/**/*.less 22 | .pipe(less()) 23 | .pipe(concat('less-files.css')) 24 | 25 | const scssStream = gulp 26 | .src(path.join(config.watch.source, config.path.styles, '**/*.s[a|c]ss')) // i.e.: assets/styles/**/*.s[a|c]ss 27 | .pipe(sass()) 28 | .pipe(concat('scss-files.css')) 29 | 30 | const cssStream = gulp 31 | .src(path.join(config.watch.source, config.path.styles, '**/*.css')) // i.e.: assets/styles/**/*.css 32 | .pipe(concat('css-files.css')) 33 | 34 | return [lessStream, scssStream, cssStream] 35 | } 36 | 37 | module.exports = { getStylesStreams } 38 | -------------------------------------------------------------------------------- /scripts/rel-push-prog: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function error { 4 | echo -e "$1" >&2 5 | exit 1 6 | } 7 | 8 | PROG="hugulp" 9 | VERSION=`cat VERSION 2> /dev/null` 10 | 11 | git checkout rel/$VERSION 12 | 13 | # This sections deals with pushing the current tag 14 | # to the $PROG github repo 15 | REMOTE=`git remote get-url github 2> /dev/null` 16 | if [[ -z "$REMOTE" ]]; then 17 | git remote add github gitjbr:jbrodriguez/$PROG.git 18 | else 19 | git remote set-url github gitjbr:jbrodriguez/$PROG.git 20 | fi 21 | 22 | # TAG=`git describe --abbrev=0 --tags 2> /dev/null` 23 | # if [[ -z "$TAG" ]]; then 24 | # error "Unable to retrieve latest tag" 25 | # fi 26 | 27 | BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null) 28 | if [[ -z $BRANCH ]]; then 29 | error "Unable to obtain branch name. Please check and try again." 30 | fi 31 | 32 | git push --tags github $BRANCH 33 | if [ $? -ne 0 ]; then 34 | error "Unable to push branch ${BRANCH} to github" 35 | fi 36 | 37 | DESCRIPTION=`cat metadata/changes/$VERSION.txt 2> /dev/null` 38 | 39 | github-release --verbose release \ 40 | --user jbrodriguez \ 41 | --repo "$PROG" \ 42 | --tag "$VERSION" \ 43 | --name "$VERSION" \ 44 | --description "$DESCRIPTION" \ 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hugulp", 3 | "version": "2.0.6", 4 | "description": "website", 5 | "files": [ 6 | "index.js", 7 | "gulp" 8 | ], 9 | "bin": { 10 | "hugulp": "./index.js" 11 | }, 12 | "scripts": { 13 | "gulp": "gulp", 14 | "test": "echo \"Error: no test specified\" && exit 1" 15 | }, 16 | "author": "Juan B. Rodriguez", 17 | "license": "MIT", 18 | "dependencies": { 19 | "commander": "^2.12.2", 20 | "del": "^3.0.0", 21 | "gulp": "^3.9.1", 22 | "gulp-autoprefixer": "^4.0.0", 23 | "gulp-changed": "^3.1.1", 24 | "gulp-clean-css": "^3.9.0", 25 | "gulp-concat": "^2.6.1", 26 | "gulp-debug": "^3.1.0", 27 | "gulp-htmlmin": "^3.0.0", 28 | "gulp-imagemin": "^4.0.0", 29 | "gulp-jshint": "^2.0.4", 30 | "gulp-less": "^3.3.2", 31 | "gulp-rev": "^8.1.0", 32 | "gulp-rev-delete-original": "^0.2.3", 33 | "gulp-rev-replace": "^0.4.3", 34 | "gulp-sass": "^3.1.0", 35 | "gulp-size": "^2.1.0", 36 | "gulp-svgmin": "^1.2.4", 37 | "gulp-uglify": "^3.0.0", 38 | "gulp-util": "^3.0.8", 39 | "gulp-watch": "^4.3.11", 40 | "jshint": "^2.9.5", 41 | "merge-stream": "^1.0.1", 42 | "path": "^0.12.7", 43 | "pkginfo": "^0.4.1", 44 | "pump": "^2.0.0", 45 | "rev-del": "^1.0.5", 46 | "run-sequence": "^2.2.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scripts/create-hugo-site: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Creates pre-requiste hugo site 4 | set -eu 5 | 6 | readonly PROGNAME=$(basename "$0") 7 | readonly ARGS="$@" 8 | APP_NAME="app" 9 | 10 | usage() { 11 | cat <<- EOF 12 | Usage: ./scripts/$PROGNAME optional options 13 | 14 | Creates folders needed to run hulgulp if they do not exist 15 | 16 | OPTIONS: 17 | -a --app-name the name of the app. It defaults to app 18 | -h --help show this help 19 | 20 | Example: 21 | Run with a hugo website name set to website 22 | 23 | ./scripts/$PROGNAME -a website 24 | EOF 25 | } 26 | 27 | cmdline() { 28 | local arg= 29 | local args= 30 | for arg; do 31 | local delim="" 32 | case "$arg" in 33 | # Copied from: http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/ 34 | # Translate --machine-name to -m (short options) 35 | --app-name) args="${args}-a ";; 36 | --help) args="${args}-h ";; 37 | #pass through anything else 38 | *) [[ "${arg:0:1}" == "-" ]] || delim="\"" 39 | args="${args}${delim}${arg}${delim} ";; 40 | esac 41 | done 42 | 43 | OPTIND=1 44 | while getopts "ha:" OPTION; do 45 | case "$OPTION" in 46 | h) 47 | usage 48 | exit 0 49 | ;; 50 | a) 51 | APP_NAME=$OPTARG 52 | ;; 53 | esac 54 | done 55 | shift "$((OPTIND-1))" # Shift off the options and optional --. 56 | return 0 57 | } 58 | 59 | create_hugo_site() { 60 | if [ ! -d "$APP_NAME" ]; then 61 | hugo new site "$APP_NAME" 62 | fi 63 | } 64 | 65 | create_assets_folders() { 66 | if [ ! -d "${APP_NAME}/assets" ]; then 67 | mkdir -p "${APP_NAME}"/assets/img 68 | mkdir -p "${APP_NAME}"/assets/styles 69 | mkdir -p "${APP_NAME}"/assets/scripts 70 | fi 71 | } 72 | 73 | ####################### 74 | # Main function # 75 | ####################### 76 | if [[ $# -gt 0 ]]; then 77 | cmdline "$@" 78 | fi 79 | create_hugo_site 80 | create_assets_folders 81 | -------------------------------------------------------------------------------- /gulp/watch.js: -------------------------------------------------------------------------------- 1 | // system 2 | const fs = require('fs') 3 | const path = require('path') 4 | 5 | // parameters 6 | const config = JSON.parse( 7 | fs.readFileSync(path.join(process.cwd(), '.hugulprc')) 8 | ) 9 | 10 | // common 11 | const gulp = require('gulp') 12 | const sequence = require('run-sequence') 13 | const watch = require('gulp-watch') 14 | const gutil = require('gulp-util') 15 | 16 | // styles 17 | const merge = require('merge-stream') 18 | const concat = require('gulp-concat') 19 | const helper = require('./util') 20 | 21 | // scripts 22 | const jshint = require('gulp-jshint') 23 | 24 | gulp.task('watch', function() { 25 | const styles = [ 26 | path.join(config.watch.source, config.path.styles, '**', '*.s[a|c]ss'), 27 | path.join(config.watch.source, config.path.styles, '**', '*.less'), 28 | path.join(config.watch.source, config.path.styles, '**', '*.css') 29 | ] 30 | 31 | gutil.log(gutil.colors.green(`running styles task ...`)) 32 | gulp.start('styles') 33 | 34 | gutil.log(gutil.colors.green(`watching ${JSON.stringify(styles)}`)) 35 | 36 | watch(styles, {}, function handle(param) { 37 | const relativePath = function(path) { 38 | return path.substring(String(process.cwd()).length) 39 | } 40 | gutil.log( 41 | gutil.colors.yellow( 42 | `styles: ${JSON.stringify(relativePath(param.history[0]))} - ${param.event}` 43 | ) 44 | ) 45 | 46 | gulp.start('styles') 47 | }) 48 | 49 | const scripts = [ 50 | path.join(config.watch.source, config.path.scripts, '**', '*.js') 51 | ] 52 | 53 | gutil.log(gutil.colors.green(`running scripts task ...`)) 54 | gulp.start('scripts') 55 | 56 | gutil.log(gutil.colors.green(`watching ${JSON.stringify(scripts)}`)) 57 | 58 | watch(scripts, {}, function handle(param) { 59 | gutil.log( 60 | gutil.colors.yellow( 61 | `scripts: ${JSON.stringify(param.history[0])} - ${param.event}` 62 | ) 63 | ) 64 | 65 | gulp.start('scripts') 66 | }) 67 | }) 68 | 69 | gulp.task('styles:cleancss', function() { 70 | const streams = helper.getStylesStreams() 71 | 72 | return merge(...streams) 73 | .pipe(concat('styles.css')) 74 | .pipe(gulp.dest(path.join(config.watch.target, config.path.styles))) // i.e.: static/styles/styles.css 75 | }) 76 | 77 | // default styles task 78 | gulp.task('styles', function(cb) { 79 | sequence('styles:cleancss', cb) 80 | }) 81 | 82 | gulp.task('scripts', function() { 83 | return gulp 84 | .src(path.join(config.watch.source, config.path.scripts, '**', '*.js')) 85 | .pipe(jshint()) 86 | .pipe(jshint.reporter('default')) 87 | .pipe(gulp.dest(path.join(config.watch.target, config.path.scripts))) 88 | }) 89 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path') 4 | const fs = require('fs') 5 | const program = require('commander') 6 | const gulp = require('gulp') 7 | const pkginfo = require('pkginfo')(module, 'version') 8 | const gutil = require('gulp-util') 9 | 10 | function init() { 11 | gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`)) 12 | 13 | const hugulpRc = path.join(process.cwd(), '.hugulprc') 14 | 15 | if (fs.existsSync(hugulpRc)) { 16 | gutil.log( 17 | gutil.colors.yellow('.hugulprc already exists (initialization skipped)') 18 | ) 19 | return 20 | } 21 | 22 | const config = { 23 | version: 2, 24 | pipeline: ['images', 'styles', 'scripts', 'fingerprint', 'html'], 25 | path: { 26 | styles: 'styles', 27 | images: 'images', 28 | scripts: 'scripts' 29 | }, 30 | watch: { 31 | source: 'assets', 32 | target: 'static' 33 | }, 34 | build: { 35 | source: 'public', 36 | target: 'public' 37 | }, 38 | autoprefixer: { 39 | browsers: ['last 2 versions'] 40 | }, 41 | cleancss: { 42 | advanced: false 43 | }, 44 | htmlmin: { 45 | collapseWhitespace: true 46 | }, 47 | gifsicle: { interlaced: true }, 48 | jpegtran: { progressive: true }, 49 | optipng: { optimizationLevel: 5 }, 50 | svgo: { 51 | plugins: [{ removeViewBox: true }, { cleanupIDs: false }] 52 | } 53 | } 54 | 55 | fs.writeFileSync(hugulpRc, JSON.stringify(config, null, ' ')) 56 | 57 | gutil.log( 58 | gutil.colors.green( 59 | 'hugulp has been initialized (.hugulprc was created with default values)' 60 | ) 61 | ) 62 | } 63 | 64 | function build() { 65 | gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`)) 66 | 67 | require(path.join(fs.realpathSync(__dirname), 'gulp', 'build')) 68 | gulp.start('build') 69 | } 70 | 71 | function watch() { 72 | gutil.log(gutil.colors.red(`hugulp v${module.exports.version}`)) 73 | 74 | require(path.join(fs.realpathSync(__dirname), 'gulp', 'watch')) 75 | gulp.start('watch') 76 | } 77 | 78 | function version() { 79 | console.log('hugulp v' + module.exports.version) 80 | } 81 | 82 | program 83 | .command('init') 84 | .description('create default .hugulprc') 85 | .action(init) 86 | 87 | program 88 | .command('version') 89 | .description('display version information') 90 | .action(version) 91 | 92 | program 93 | .command('build') 94 | .description('optimize site (for publishing purposes)') 95 | .action(build) 96 | 97 | program 98 | .command('watch') 99 | .description('watch for changes to styles and/or javascript') 100 | .action(watch) 101 | 102 | program.parse(process.argv) 103 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | Version 2.0.6 - 2018-10-28 2 | - log relative path while watching styles (#45) 3 | 4 | 5 | Version 2.0.5 - 2017-12-12 6 | - Fix scripts task build source 7 | 8 | 9 | Version 2.0.4 - 2017-12-12 10 | - Set saner htmlmin defaults 11 | 12 | 13 | Version 2.0.3 - 2017-12-12 14 | - Make cleancss the default styles transformation 15 | - Display pipeline being executed 16 | - Restore default styles logic 17 | - Add callback to sequence call 18 | - Display space optimization achieved 19 | 20 | 21 | Version 2.0.2 - 2017-12-12 22 | - Fix plugin names 23 | 24 | 25 | Version 2.0.1 - 2017-12-12 26 | - Run styles/scripts tasks on watch invocation 27 | - Use proper JSON syntax 28 | - Fix update instructions 29 | - Add granular imagemin configuration 30 | - Adjust default .hugulprc 31 | 32 | 33 | Version 2.0.0 - 2017-12-12 34 | - Read/compile sass and scss (#37) 35 | - Replace var (#34) 36 | - Replace yarn with npm5 37 | - Use standard format 38 | - Implement hugulp next 39 | - Add init command 40 | - Clean up & add logging 41 | - Code refactoring 42 | - Add missing package 43 | - Update docs for v2 44 | - Implements next 45 | - Remove v1 code 46 | - Fix inclusion of production files 47 | - Use vscode instead of atom 48 | 49 | 50 | Version 1.4.0 - 2017-11-27 51 | - Add docker support (#24) 52 | - Minifyhtml (#31) 53 | 54 | 55 | Version 1.3.0 - 2017-03-20 56 | - Add less support 57 | - Ignore log files 58 | - Expand glob for assets 59 | - Update README 60 | - Remove log file 61 | - Release 1.2.0 62 | - Display hugulp version 63 | - Add less to watched files 64 | - Upgrade dependencies 65 | - Replace gulp.watch with gulp-watch 66 | - Fix styles folder watch 67 | - Update README 68 | 69 | 70 | Version 1.2.0 - 2017-03-18 71 | - Ignore log files 72 | - Add less support 73 | - Expand glob for assets 74 | - Update README 75 | - Remove log file 76 | 77 | 78 | Version 1.1.2 - 2017-03-17 79 | - Process subdirectories 80 | 81 | 82 | Version 1.1.1 - 2017-02-12 83 | - Fix build command 84 | 85 | 86 | Version 1.1.0 - 2017-01-28 87 | - Use hugo default config file 88 | 89 | 90 | Version 1.0.0 - 2017-01-08 91 | - Add commander dependency 92 | - Create cli interface 93 | - Rename src folder to assets 94 | - Remove files no longer required 95 | - Support css files 96 | - Rewrite instructions 97 | - Publish to npm on CI 98 | - Update package.json upon new release 99 | 100 | 101 | Version 0.1.0 - 2017-01-06 102 | - Initial commit 103 | - syntax fix for package.json 104 | - Add missing semicolons 105 | - Replace tabs with spaces 106 | - Update reference.js 107 | - - Update packages 108 | - Improve project details and instructions 109 | - Fix syntax error 110 | - Delete public folder when running gulp task. Also delete (if existing) the public folder inside hugo. 111 | - Update dependencies 112 | - Implement CI automation 113 | - Add missing variable 114 | -------------------------------------------------------------------------------- /gulp/build.js: -------------------------------------------------------------------------------- 1 | // system 2 | const fs = require('fs') 3 | const path = require('path') 4 | 5 | // parameters 6 | const config = JSON.parse( 7 | fs.readFileSync(path.join(process.cwd(), '.hugulprc')) 8 | ) 9 | 10 | // common 11 | const gulp = require('gulp') 12 | const sequence = require('run-sequence') 13 | const debug = require('gulp-debug') 14 | const size = require('gulp-size') 15 | const pump = require('pump') 16 | const gutil = require('gulp-util') 17 | 18 | // images 19 | const imagemin = require('gulp-imagemin') 20 | 21 | // styles 22 | const autoprefixer = require('gulp-autoprefixer') 23 | const cleancss = require('gulp-clean-css') 24 | const merge = require('merge-stream') 25 | const concat = require('gulp-concat') 26 | const helper = require('./util') 27 | // const changed = require('gulp-changed') 28 | 29 | // scripts 30 | const jshint = require('gulp-jshint') 31 | const uglify = require('gulp-uglify') 32 | 33 | // revision 34 | const rev = require('gulp-rev') 35 | const revdel = require('rev-del') 36 | const delorg = require('gulp-rev-delete-original') 37 | const del = require('del') 38 | 39 | // reference 40 | const replace = require('gulp-rev-replace') 41 | 42 | // minify html 43 | const htmlmin = require('gulp-htmlmin') 44 | 45 | gulp.task('build', function(cb) { 46 | gutil.log( 47 | gutil.colors.green(`building site ... (${JSON.stringify(config.pipeline)})`) 48 | ) 49 | 50 | // config.pipeline is an array of task names 51 | // i.e.: ['images', 'styles'] 52 | sequence(...config.pipeline, cb) 53 | }) 54 | 55 | // .pipe(changed('staging/img')) 56 | gulp.task('images', function() { 57 | return gulp 58 | .src(path.join(config.build.source, config.path.images, '**', '*.*')) // i.e.: public/images/**/*.* 59 | .pipe( 60 | imagemin([ 61 | imagemin.gifsicle(config.gifsicle), 62 | imagemin.jpegtran(config.jpegtran), 63 | imagemin.optipng(config.optipng), 64 | imagemin.svgo(config.svgo) 65 | ]) 66 | ) 67 | .pipe(gulp.dest(path.join(config.build.target, config.path.images))) // i.e.: public/images 68 | }) 69 | 70 | gulp.task('styles:cleancss', function() { 71 | const streams = helper.getStylesStreams() 72 | 73 | return merge(...streams) 74 | .pipe(autoprefixer(config.autoprefixer)) 75 | .pipe(cleancss(config.cleancss)) 76 | .pipe(concat('styles.css')) 77 | .pipe(size({ title: 'styles: ' })) 78 | .pipe(gulp.dest(path.join(config.build.target, config.path.styles))) // i.e.: public/styles/styles.css 79 | }) 80 | 81 | // default styles task 82 | gulp.task('styles', function(cb) { 83 | sequence('styles:cleancss', cb) 84 | }) 85 | 86 | gulp.task('scripts', function() { 87 | return gulp 88 | .src(path.join(config.watch.source, config.path.scripts, '**', '*.js')) 89 | .pipe(jshint()) 90 | .pipe(jshint.reporter('default')) 91 | .pipe(uglify()) 92 | .pipe(size({ title: 'scripts: ' })) 93 | .pipe(gulp.dest(path.join(config.build.target, config.path.scripts))) 94 | }) 95 | 96 | gulp.task('revision', function() { 97 | return gulp 98 | .src( 99 | [ 100 | path.join(config.build.source, config.path.styles, '**/*.css'), 101 | path.join(config.build.source, config.path.scripts, '**/*.js'), 102 | path.join(config.build.source, config.path.images, '**/*.*') 103 | ], 104 | { base: path.join(process.cwd(), config.build.source) } 105 | ) 106 | .pipe(rev()) 107 | .pipe(delorg()) 108 | .pipe(gulp.dest(config.build.target)) 109 | .pipe(rev.manifest()) 110 | .pipe(revdel({ dest: config.build.target })) 111 | .pipe(gulp.dest(config.build.target)) 112 | }) 113 | 114 | gulp.task('reference', function() { 115 | const manifest = gulp.src(path.join(config.build.source, 'rev-manifest.json')) 116 | 117 | return gulp 118 | .src([ 119 | path.join(config.build.source, '**/*.html'), 120 | path.join(config.build.source, '**/*.xml'), 121 | path.join(config.build.source, '**/*.css') 122 | ]) 123 | .pipe( 124 | replace({ 125 | manifest: manifest, 126 | replaceInExtensions: ['.html', '.xml', '.css'] 127 | }) 128 | ) 129 | .pipe(gulp.dest(config.build.target)) 130 | }) 131 | 132 | gulp.task('fingerprint', function(cb) { 133 | sequence('revision', 'reference', cb) 134 | }) 135 | 136 | gulp.task('html', function(cb) { 137 | pump( 138 | [ 139 | gulp.src(path.join(config.build.source, '**', '*.html')), 140 | htmlmin(config.htmlmin), 141 | size({ title: 'html: ' }), 142 | gulp.dest(config.build.target) 143 | ], 144 | cb 145 | ) 146 | }) 147 | -------------------------------------------------------------------------------- /scripts/create-docker-machine-and-run-it: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Setup a docker machine for development 4 | set -eu 5 | 6 | readonly PROGNAME=$(basename "$0") 7 | readonly ARGS=("$@") 8 | # Docker settings 9 | HUGO_VERSION=0.20.6 10 | NODE_VERSION="7.9.0-alpine" 11 | APP_NAME="app" 12 | DETACHED= 13 | check_where_cmd_is_run() { 14 | # Check if script is being run from the root directory 15 | if [ ! -d 'gulp' ]; then 16 | cat <<- EOF 17 | Please run this script from the root directory. 18 | 19 | Example: 20 | ./scripts/create-docker-machine-and-run-it 21 | 22 | -- OR -- 23 | 24 | bash ./scripts/create-docker-machine-and-run-it 25 | EOF 26 | exit 1 27 | fi 28 | } 29 | 30 | usage() { 31 | cat <<- EOF 32 | Usage: ./scripts/$PROGNAME optional options 33 | 34 | Setups a docker machine and runs it for development. 35 | 36 | OPTIONS: 37 | -g --hugo-version the hugo version to be installed. Minus v or version prefix. It defaults to 0.9 38 | -n --node-version the node version to be installed. Minus v or version prefix. It defaults to 6.10.0 39 | -a --app-name the name of the app. It defaults to app 40 | -d --detached detached mode: Run containers in the background, print new container names. 41 | -h --help show this help 42 | 43 | Examples: 44 | Run with default settings: 45 | 46 | ./scripts/$PROGNAME 47 | 48 | Run with custom machine name, specific hugo version, specific node version and run docker in detached mode: 49 | 50 | bash ./scripts/$PROGNAME -a app-name -g 0.9 -n 6.10.0 51 | EOF 52 | } 53 | 54 | cmdline() { 55 | local arg= 56 | local args= 57 | for arg; do 58 | local delim="" 59 | case "$arg" in 60 | # Copied from: http://www.kfirlavi.com/blog/2012/11/14/defensive-bash-programming/ 61 | # Translate --machine-name to -m (short options) 62 | --hugo-version) args="${args}-g ";; 63 | --node-version) args="${args}-n ";; 64 | --app-name) args="${args}-a ";; 65 | --detached) args="${args}-d ";; 66 | --help) args="${args}-h ";; 67 | #pass through anything else 68 | *) [[ "${arg:0:1}" == "-" ]] || delim="\"" 69 | args="${args}${delim}${arg}${delim} ";; 70 | esac 71 | done 72 | while getopts "g:n:a:dh" OPTION; do 73 | case "$OPTION" in 74 | h) 75 | usage 76 | exit 0 77 | ;; 78 | g) 79 | HUGO_VERSION=$OPTARG 80 | ;; 81 | n) 82 | NODE_VERSION=$OPTARG 83 | ;; 84 | a) 85 | APP_NAME=$OPTARG 86 | ;; 87 | d) 88 | DETACHED='-d' 89 | ;; 90 | esac 91 | done 92 | return 0 93 | } 94 | 95 | create_docker_file() { 96 | # Check to make sure Dockerfile exist 97 | if [ ! -f './docker/Dockerfile.template' ]; then 98 | echo "This script requires ./docker/Dockerfile.template file to setup docker." 99 | exit 1 100 | fi 101 | echo "Creating Dockerfile file..." 102 | cp ./docker/Dockerfile.template ./Dockerfile 103 | # Replace some lines in existing Dockerfile. 104 | # Set sed -i option to '' to prevent it from creating backup files 105 | # Replace node version set value 106 | sed -i '' -e "s|^FROM node:\([0-9\.]*\).*|FROM node:$NODE_VERSION|" \ 107 | Dockerfile 108 | # Replace hugo version with set value 109 | sed -i '' -e "s|^ARG HUGO_VERSION=\([0-9\.]*\).*|ARG HUGO_VERSION=$HUGO_VERSION|" \ 110 | Dockerfile 111 | # Replace app home directory with set value 112 | sed -i '' -e "s|\$HOME/[a-zA-Z0-9]*/$|\$HOME/$APP_NAME/|g" \ 113 | Dockerfile 114 | echo "Dockerfile successfully created." 115 | } 116 | 117 | setup_docker() { 118 | # Check if docker is installed on the machine 119 | if ! docker version > /dev/null; then 120 | echo "Please docker-engine and docker-compose are required to be installed on the host machine" 121 | echo "https://docs.docker.com/engine/installation/" 122 | echo "https://docs.docker.com/compose/" 123 | exit 1 124 | fi 125 | create_docker_file 126 | } 127 | 128 | setup_docker_compose() { 129 | # Check to make sure docker-compose template file exist 130 | if [ ! -f './docker/docker-compose.yaml.template' ]; then 131 | echo "This script requires ./docker/docker-compose.yaml.template file to setup docker-compose." 132 | exit 1 133 | fi 134 | echo "Creating docker-compose.yaml file..." 135 | cp ./docker/docker-compose.yaml.template ./docker-compose.yaml 136 | echo "docker-compose.yaml successfully created." 137 | sed -i '' -e "s/app:/${APP_NAME}:/" \ 138 | docker-compose.yaml 139 | sed -i '' -e "s/app/$APP_NAME/g" \ 140 | docker-compose.yaml 141 | if [[ "$DETACHED" != "" ]]; then 142 | docker-compose up --build "$DETACHED" "$APP_NAME" 143 | else 144 | docker-compose up --build "$APP_NAME" 145 | fi 146 | } 147 | 148 | ####################### 149 | # Main function # 150 | ####################### 151 | if [[ $# -gt 0 ]]; then 152 | cmdline "${ARGS[@]}" 153 | fi 154 | check_where_cmd_is_run 155 | setup_docker 156 | setup_docker_compose 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DEPRECATION NOTICE 2 | 3 | I'll archive the repo by the end of August 2021. 4 | 5 | The main reason is [Hugo pipes](https://gohugo.io/hugo-pipes/) are built-in and pretty much cover what Hugulp does. 6 | 7 | I think the only part missing is image optimization, but I think you can build a pipe to do it. 8 | 9 | The other reason is it badly needs an update to gulp 4 and although it doesn't seem like that hard a task, I don't have the appetite to do it. 10 | 11 | # hugulp 2 12 | 13 | ## v2 Breaking changes 14 | 15 | If you're using hugulp v1, please take note of the following changes: 16 | 17 | * hugo is no longer invoked by hugulp 18 | 19 | use hugo as per its docs, then invoke hugulp build 20 | 21 | * put your assets in the static folder 22 | 23 | for example, static/styles, static/images, static/scripts 24 | 25 | * themes are supported out of the box 26 | 27 | _Note: If you need sass/less/js pre-processing, read v2 docs below_ 28 | 29 | ## Description 30 | 31 | `hugulp` is a tool to optimize the assets of a [Hugo](https://gohugo.io) website. 32 | 33 | The main idea is to recreate the famous [Ruby on Rails Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html), which minifies, concatenates and fingerprints the assets used in your website. 34 | 35 | This leads to less and smaller network requests to your page, improving overall user experience. 36 | 37 | Read [this blog post](https://jbrio.net/posts/mobile-friendly-website-2/) and [this article](https://medium.com/@juanbrodriguez/hugulp-a-hugo-gulp-toolchain-94f72ccc3577) for additional context. 38 | 39 | _Note: These articles refer to v1_ 40 | 41 | It's internally driven by [Gulp](https://gulpjs.com). 42 | 43 | This project Includes the following tools, tasks and workflows: 44 | 45 | * [sass](https://github.com/dlmanning/gulp-sass) (super fast libsass) 46 | * [less](https://github.com/plus3network/gulp-less) 47 | * [autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer) 48 | * [clean-css](https://github.com/scniro/gulp-clean-css) 49 | * [jshint](https://github.com/spalger/gulp-jshint) 50 | * [uglify](https://github.com/terinjokes/gulp-uglify) 51 | * [imagemin](https://github.com/sindresorhus/gulp-imagemin) (only [changed images](https://github.com/sindresorhus/gulp-changed)) 52 | * [gulp-rev](https://github.com/sindresorhus/gulp-rev), [gulp-rev-replace](https://github.com/jamesknelson/gulp-rev-replace) (fingerprinting) 53 | * [htmlmin](https://github.com/jonschlinkert/gulp-htmlmin) 54 | * [watch](https://github.com/floatdrop/gulp-watch) 55 | 56 | ## Installation 57 | 58 | [Node](https://nodejs.org) needs to be installed in your system. 59 | 60 | Then just 61 | 62 | ```bash 63 | $ npm install -g hugulp 64 | ``` 65 | 66 | Or you can build and run using [docker](https://www.docker.com): 67 | 68 | ```bash 69 | # Default docker setup: 70 | $ ./scripts/create-docker-machine-and-run-it 71 | 72 | # -- OR -- 73 | 74 | # Run with custom machine name, specific hugo version, specific node version and run docker in detached mode: 75 | $ ./scripts/create-docker-machine-and-run-it -a app-devel -g 0.20.6 -n 6.10.0 -d 76 | ``` 77 | 78 | **Note:** You only run the `./scripts/create-docker-machine-and-run-it` if you want to create a new docker machine. Once the docker machine is created, you have to use docker commands to manage it. Please be familiar with docker in this regard. 79 | 80 | ## Getting Started 81 | 82 | The most common usage scenario would be: 83 | 84 | ```bash 85 | $ hugo new site yoursite 86 | $ cd yoursite 87 | $ hugulp init 88 | # create content 89 | # add images (static/images), css (static/styles) and javascript (static/scripts) 90 | $ hugo server -D # for development 91 | # development is done, ready to publish 92 | $ rm -rf public # clean up public folder, it will be re-generated by hugo 93 | $ hugo # for release/production/deployment 94 | $ hugulp build # optimize the site by running the asset pipeline 95 | ``` 96 | 97 | Another scenario would be to include sass/less pre-processing: 98 | 99 | ```bash 100 | $ hugo new site yoursite 101 | $ cd yoursite 102 | $ hugulp init 103 | # create content 104 | # add images (static/images), and javascript (static/scripts) 105 | # add sass/less (assets/styles) 106 | $ hugo server -D # for development 107 | $ hugulp watch # to convert sass/less (assets/styles) into css (static/styles) 108 | # development is done, ready to publish 109 | $ rm -rf public # clean up public folder, it will be re-generated by hugo 110 | $ hugo # for release/production/deployment 111 | $ hugulp build # optimize the site by running the asset pipeline 112 | ``` 113 | 114 | In both cases, you could chain the last 3 commands: 115 | 116 | ```bash 117 | $ rm -rf public && hugo && hugulp build 118 | ``` 119 | 120 | `hugulp` requires a configuration file (`.hugulprc`), which is created by the `hugulp init` command (you can create the file manually if you want). 121 | 122 | This is the default `.hugulprc`: 123 | 124 | ```json 125 | { 126 | "version": 2, 127 | "pipeline": ["images", "styles", "scripts", "fingerprint", "html"], 128 | "path": { 129 | "styles": "styles", 130 | "images": "images", 131 | "scripts": "scripts" 132 | }, 133 | "watch": { 134 | "source": "assets", 135 | "target": "static" 136 | }, 137 | "build": { 138 | "source": "public", 139 | "target": "public" 140 | }, 141 | "autoprefixer": { 142 | "browsers": ["last 2 versions"] 143 | }, 144 | "cleancss": { 145 | "advanced": false 146 | }, 147 | "htmlmin": { 148 | "collapseWhitespace": true 149 | }, 150 | "gifsicle": { "interlaced": true }, 151 | "jpegtran": { "progressive": true }, 152 | "optipng": { "optimizationLevel": 5 }, 153 | "svgo": { 154 | "plugins": [{ "removeViewBox": true }, { "cleanupIDs": false }] 155 | } 156 | } 157 | ``` 158 | 159 | You can easily customize `hugulp`'s behavior, by modifying this configuration file, as described below. 160 | 161 | ## Available Commands 162 | 163 | ### hugulp watch 164 | 165 | `hugulp` will assist you if you're using sass/less (and javascript), which require pre-processing. 166 | 167 | It will watch for changes to styles or script files, process them and write them to hugo's static folder, according to the following table 168 | 169 | | In Folder | Looks for | Operation | Written to | 170 | | -------------- | :------------------: | -------------------------------------- | -------------- | 171 | | assets/styles | s[a\|c]ss, less, css | Convert sass/less to css | static/styles | 172 | | assets/scripts | js | Lint javascript code (_soon babelify_) | static/scripts | 173 | 174 | _Note: It searches the folders recursively_ 175 | 176 | The table above applies to `hugulp` run with a default `.hugulprc`. 177 | 178 | You can customize the folder names: `resources` instead of `assets`, `js` instead of `scripts` and so on. 179 | 180 | This is described in the `.hugulprc` section below. 181 | 182 | ### hugulp build 183 | 184 | It optimizes the site that hugo built, by running the asset pipeline as defined in `.hugulprc` (field _pipeline_). 185 | 186 | Additionally, files are not watched for changes 187 | 188 | ### hugulp version 189 | 190 | Display installed version. 191 | 192 | ### hugulp init 193 | 194 | Create a default `.hugulprc`. 195 | 196 | ## Configuration 197 | 198 | By editing the `.hugulprc` configuration file, you can customize almost anything about `hugulp`. 199 | 200 | Description of each field follows: 201 | 202 | ### pipeline 203 | 204 | Defines which tasks of the asset pipeline will be executed (`hugulp build` command) 205 | 206 | Type: array
207 | Default: 208 | 209 | ```json 210 | "pipeline": ["images", "styles", "scripts", "fingerprint", "html"] 211 | ``` 212 | 213 | | Task | Description | 214 | | ----------- | ------------------------------------------------------------------ | 215 | | images | minify images with `imagemin` | 216 | | styles | pre-process `sass`/`less`/css, then `clean-css` | 217 | | scripts | `jshint`, then `uglify` | 218 | | fingerprint | fingerprint with `rev`, then replace references with `rev-replace` | 219 | | html | minify html with `htmlmin` | 220 | 221 | Let's say you don't want to fingerprint the assets. Just set _pipeline_ to 222 | 223 | ```json 224 | "pipeline": ["images", "styles", "scripts", "html"] 225 | ``` 226 | 227 | By removing the _fingerprint_ task, it will not be executed. 228 | 229 | Note that tasks are executed sequentially. 230 | 231 | ### path 232 | 233 | Defines the name of the folders where your assets are located/will be transferred to. 234 | 235 | Type: object
236 | Default: 237 | 238 | ```json 239 | "path": { 240 | "styles": "styles", 241 | "images": "images", 242 | "scripts": "scripts" 243 | } 244 | ``` 245 | 246 | So if you prefer your styles folder to be called css, and scripts to be called js, you would change it to: 247 | 248 | ```json 249 | "path": { 250 | "styles": "css", 251 | "images": "images", 252 | "scripts": "js" 253 | } 254 | ``` 255 | 256 | ### watch 257 | 258 | Define which folders to watch for changes, for the `hugulp watch` command. 259 | 260 | Type: object
261 | Default: 262 | 263 | ```json 264 | "watch": { 265 | "source": "assets", 266 | "target": "static" 267 | } 268 | ``` 269 | 270 | This field works together with the path field. 271 | 272 | With a default `.hugulprc`, it will watch `assets/styles` and `assets/scripts` (recursively). 273 | 274 | If you customized `path` as per above, it will watch `assets/css` and `assets/js`. 275 | 276 | If you additionally want the `assets` folder to be called `resources`, change _source_ to `resources` 277 | 278 | ```json 279 | "watch": { 280 | "source": "resources", 281 | "target": "static" 282 | } 283 | ``` 284 | 285 | then it will watch `resources/css` and `resources/js` 286 | 287 | Finally, the changes will be written to the well-known hugo static folder. 288 | 289 | With a default `.hugulprc`, files will be written to `static/styles` and `static/scripts`. 290 | 291 | ### build 292 | 293 | Defines the folders referenced during the `hugulp build` command 294 | 295 | Type: object
296 | Default: 297 | 298 | ```json 299 | "build": { 300 | "source": "public", 301 | "target": "public" 302 | } 303 | ``` 304 | 305 | This should generally be left unchanged. 306 | 307 | `hugo` will output to the public folder by default, so `hugulp build` will process the files in-place. 308 | 309 | ### autoprefixer 310 | 311 | Options for `autoprefixer`. Check [gulp-autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer) for documentation. 312 | 313 | Task: `styles` 314 | 315 | Type: object
316 | Default: 317 | 318 | ```json 319 | "autoprefixer": { 320 | "browsers": ["last 2 versions"] 321 | } 322 | ``` 323 | 324 | ### cleancss 325 | 326 | Options for `clean-css`. Check [gulp-clean-css](https://github.com/scniro/gulp-clean-css) for documentation. 327 | 328 | Task: `styles` 329 | 330 | Default: 331 | 332 | ```json 333 | "cleancss": { 334 | "advanced": false 335 | } 336 | ``` 337 | 338 | ### htmlmin 339 | 340 | Options for `htmlmin`. Check [gulp-htmlmin](https://github.com/jonschlinkert/gulp-htmlmin) for documentation. 341 | 342 | Task: `html` 343 | 344 | Default: 345 | 346 | ```json 347 | "htmlmin": { 348 | "collapsedWhitespace": true 349 | } 350 | ``` 351 | 352 | ### gifsicle 353 | 354 | Options for `gifsicle`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation. 355 | 356 | Task: `images` 357 | 358 | Default: 359 | 360 | ```json 361 | "gifsicle": { 362 | "interlaced": true 363 | } 364 | ``` 365 | 366 | ### jpegtran 367 | 368 | Options for `jpegtran`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation. 369 | 370 | Task: `images` 371 | 372 | Default: 373 | 374 | ```json 375 | "jpegtran": { 376 | "progressive": true 377 | } 378 | ``` 379 | 380 | ### optipng 381 | 382 | Options for `optipng`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation. 383 | 384 | Task: `images` 385 | 386 | Default: 387 | 388 | ```json 389 | "optipng": { 390 | "optimizationLevel": 5 391 | } 392 | ``` 393 | 394 | ### svgo 395 | 396 | Options for `svgo`. Check [gulp-imagemin](https://github.com/sindresorhus/gulp-imagemin) for documentation. 397 | 398 | Task: `images` 399 | 400 | Default: 401 | 402 | ```json 403 | "svgo": { 404 | "plugins": [{ "removeViewBox": true }, { "cleanupIDs": false }] 405 | } 406 | ``` 407 | 408 | ## How to update 409 | 410 | Whenever a new `hugulp` version becomes available, you can update it by running 411 | 412 | ```bash 413 | $ npm install -g hugulp 414 | ``` 415 | 416 | ## PR 417 | 418 | Pull Requests are welcome :thumbsup:. 419 | 420 | ## Share 421 | 422 | Made by [Juan B. Rodriguez](http://jbrodriguez.io), with a MIT License. 423 | 424 | Please [share the article or leave your comments](http://jbrodriguez.io/mobile-friendly-website-2/). 425 | --------------------------------------------------------------------------------