Giter Club home page Giter Club logo

grunt-html-boiler's Introduction

Grunt HTML Boiler

Built with Grunt

A starting point for Grunt.js HTML projects/repositories.

About

This repo is just an example of my preferred Grunt-powered asset/theme files workflow.

It’s my preference to separate asset/theme files from server-side code/templates. A few advantages to this type of setup is:

  1. Updating theme becomes as simple as changing one variable (see below).
  2. Build and commit theme files separately from server-side logic/templates.

This repo also serves as an example of how one can use Grunt (via grunt-env and grunt-preprocess tasks) to build a “development” and “production” index.html, and other, file(s).

Demos

Development

Assuming you already have Grunt.js installed …

Note: The Grunt command line interface gets installed locally, so you can skip $ npm install -g grunt-cli if you use the $ npm run commands.

Installation

Here’s a few ways to install this code:

  1. Download as a zip.
  2. Clone it: $ git clone https://github.com/mhulse/grunt-html-boiler.git.
  3. Fork it and clone: $ git clone [email protected]:USERNAME/grunt-html-boiler.git.

Setup dependencies

Navigate to the local repo’s build/ directory:

$ cd grunt-html-boiler/build/

Install Grunt tasks:

$ npm install

Optionally, install the latest Bower plugin versions:

$ grunt bower
# … or:
$ npm run bower

… this will install plugins (as defined in build/bower.json) into the build/files/plugins/ directory; in order to keep things tidy, I’ve created these symlinks:

Plugin Destination
build/plugins/fastclick/fastclick.js build/scripts/fastclick.js
build/plugins/jquery/jquery.js build/scripts/jquery.js
build/plugins/normalize-css/normalize.css build/styles/partials/_normalize.scss

Development preview

Test the development build:

$ grunt
# … or:
$ grunt dev
# … or:
$ npm run dev

Visit the development build:

http://localhost/grunt-html-boiler/dev/

Note: The above URL will depend upon your local development environment; for previewing my projects I use XAMPP.

Alternatively, you could setup grunt-contrib-connect (#37).

Edit

At this point, you can modify any of the files, especially the ones found in the build/files/ directory.

Modify build/package.json to meet the needs of your repo/project.

Note: The production key’s value is the URI where the final production files will live.

To make life easier while developing, run:

$ grunt watch
# … or:
$ npm run watch

… the watch command will run a development build any time these directories/file(s) change:

build/Gruntfile.js
build/files/scripts/<%= pkg.ns %>.*.js
build/files/scripts/**/*
build/files/styles/**/*
build/files/templates/**/*

Production build

Once you’re ready to do a production build, run:

$ grunt prod
# … or:
$ npm run prod

Push the production build to your GitHub repo.

Depending on your setup, you may need to pull the latest build to your production server.

Visit the production build locally:

http://localhost/grunt-html-boiler/prod/

Note: The production build’s asset files are absolutely linked to the production server; hence the need to push the latest files there before previewing the production’s HTML file and related assets.

Update production theme

Finally, in a real world scenario, you would update the asset path (on your live templates) by updating the URL to the latest production build. For example, here’s a simple PHP function one could use in a WordPress functions.php file:

/**
 * Theme build version.
 *
 * Called like so: <?=theme_build()?>
 */

function theme_build() {
	
	return '/prod/1.0.0/20140222/1'; // Edit this string to update theme across site.
	
}

… and on the template level:

<link rel="stylesheet" href="http://static.foo.com<?=theme_build()?>/styles/grunt-html-boiler.min.css">
<script src="http://static.foo.com<?=theme_build()?>/js/grunt-html-boiler.min.js"></script>

Notes

  1. This project generates two groups of Grunt-built files: 1) Un-minified/uglified, and 2) minified/uglified. I prefer having my development- and production-generated files separately built.

  2. This project puts the “build” code a level deep off the root. In my opinion, having the source files out of the root and in a sub-directory allows for the overall setup to be more organized and streamlined.

Links

Real-world

Personal projects that have used grunt-html-boiler as a starting point:

Build instructions?

… and other development notes, can be found here.

Contributing

Please read the CONTRIBUTING.md.

Feedback

Bugs? Constructive feedback? Questions?


LEGAL

Copyright © 2016 Micky Hulse

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this work except in compliance with the License. You may obtain a copy of the License in the LICENSE file, or at:

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an ”AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

:octocat:

grunt-html-boiler's People

Contributors

mhulse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

grunt-html-boiler's Issues

Errors on $ grunt

Running $ grunt out of the box results in the following error:

Running "jshint:init" (jshint) task

./Gruntfile.js
56 | ' /\n\n',
^ Extra comma. (it breaks older versions of IE)
93 | verbose: true, // Debug output.
^ Extra comma. (it breaks older versions of IE)
95 | },
^ Extra comma. (it breaks older versions of IE)
97 | },
^ Extra comma. (it breaks older versions of IE)
117 | './files/templates/__/
',
^ Extra comma. (it breaks older versions of IE)
121 | tasks: ['default'],
^ Extra comma. (it breaks older versions of IE)
138 | jshintrc: '.jshintrc', // Defined options and globals.
^ Extra comma. (it breaks older versions of IE)
145 | './files/scripts/<%= pkg.name %>..js',
^ Extra comma. (it breaks older versions of IE)
147 | ],
^ Extra comma. (it breaks older versions of IE)
163 | NODE_ENV: 'DEVELOPMENT',
^ Extra comma. (it breaks older versions of IE)
169 | NODE_ENV: 'PRODUCTION',
^ Extra comma. (it breaks older versions of IE)
171 | },
^ Extra comma. (it breaks older versions of IE)
187 | force: true, // Allows for deletion of folders outside current working dir (CWD). Use with caution.
^ Extra comma. (it breaks older versions of IE)
193 | '../dev/__/
',
^ Extra comma. (it breaks older versions of IE)
200 | '../index.html',
^ Extra comma. (it breaks older versions of IE)
202 | ],
^ Extra comma. (it breaks older versions of IE)
221 | banner: '<%= banner.short %>',
^ Extra comma. (it breaks older versions of IE)
233 | './files/scripts/<%= pkg.name %>.init.js',
^ Extra comma. (it breaks older versions of IE)
234 | ],
^ Extra comma. (it breaks older versions of IE)
238 | },
^ Extra comma. (it breaks older versions of IE)
240 | },
^ Extra comma. (it breaks older versions of IE)
259 | sourcemap: 'none', // Generate CSS source maps?
^ Extra comma. (it breaks older versions of IE)
268 | style: 'expanded', // Output style. Can be nested, compact, compressed, expanded.
^ Extra comma. (it breaks older versions of IE)
275 | '../dev/styles/development.css': './files/styles/development.scss',
^ Extra comma. (it breaks older versions of IE)
277 | },
^ Extra comma. (it breaks older versions of IE)
286 | style: 'compressed',
^ Extra comma. (it breaks older versions of IE)
292 | '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/styles/<%= pkg.name %>.min.css': './files/styles/<%= pkg.name %>.scss',
^ Extra comma. (it breaks older versions of IE)
294 | },
^ Extra comma. (it breaks older versions of IE)
296 | },
^ Extra comma. (it breaks older versions of IE)
324 | version: '<%= pkg.version %>',
^ Extra comma. (it breaks older versions of IE)
326 | },
^ Extra comma. (it breaks older versions of IE)
341 | '!latest.html',
^ Extra comma. (it breaks older versions of IE)
343 | dest: '../dev/',
^ Extra comma. (it breaks older versions of IE)
345 | },
^ Extra comma. (it breaks older versions of IE)
347 | ],
^ Extra comma. (it breaks older versions of IE)
360 | 'index.html',
^ Extra comma. (it breaks older versions of IE)
362 | dest: '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',
^ Extra comma. (it breaks older versions of IE)
367 | dest: '../prod/index.html',
^ Extra comma. (it breaks older versions of IE)
369 | },
^ Extra comma. (it breaks older versions of IE)
371 | ],
^ Extra comma. (it breaks older versions of IE)
373 | },
^ Extra comma. (it breaks older versions of IE)
399 | '!/source/',
^ Extra comma. (it breaks older versions of IE)
401 | dest: '../dev/',
^ Extra comma. (it breaks older versions of IE)
403 | },
^ Extra comma. (it breaks older versions of IE)
405 | ],
^ Extra comma. (it breaks older versions of IE)
420 | '!/junk/',
^ Extra comma. (it breaks older versions of IE)
422 | dest: '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',
^ Extra comma. (it breaks older versions of IE)
428 | dest: '../index.html',
^ Extra comma. (it breaks older versions of IE)
430 | },
^ Extra comma. (it breaks older versions of IE)
434 | ],
^ Extra comma. (it breaks older versions of IE)

Too many errors. (90% scanned).

51 errors in 5 files

npm run grunt ...

Change or allow package.json to run "grunt" all by itself; this would allow for any task name or command line flags to be passed after command which is a bit more flexible.

Ignore "junk/" folders

'!**/junk/**',

Useful pattern for placeholder image junk folders, or things like /fonts and /psd.

Use above pattern to organize cruft.

Re-think folder and naming structure

Via @iamchriswick in #35:

But, the name "build" confused me a bit, cause for me build sounds like something that has been built.

Maybe like this:

grunt-html-boiler
├── build
│ ├── dev
│ │ ├── images
│ │ ...
│ ├── prod
│ │ ├── 1.0.0
│ │ ...
├── work
│ ├── files
│ │ ├── .jshintrc
│ │ ├── Gruntfile.js
│ │ ├── README.md
│ │ ├── bower.json
│ │ ├── README
│ │ └── package.json
│ .editorconfig
│ .gitattributes
│ .gitignore
│ file001.txt
│ CONTRIBUTING.md
│ LICENSE
│ README.md
│ index.html

Example of multi-file preprocess html

http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically

/*----------------------------------( PREPROCESS )----------------------------------*/

/**
 * Grunt task around preprocess npm module.
 *
 * @see https://github.com/onehealth/grunt-preprocess
 * @see https://github.com/onehealth/preprocess
 * @see http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
 */

preprocess : {

    options : {

        context : {

            title : '<%= pkg.title %>',
            description : '<%= pkg.description %>',
            name : '<%= pkg.name %>',
            version : '<%= pkg.version %>',
            homepage : '<%= pkg.homepage %>',
            production : '<%= pkg.production %>',
            now : '<%= now %>',
            ver : '<%= ver %>',

        },

    },

    dev : {

        expand : true,
        cwd : './files/templates/',
        src : [
            '**/*.html',
            '!latest.html',
        ],
        dest : '../dev/',

    },

    prod : {

        expand : true,
        cwd : './files/templates/',
        src : [
            '**/*.html',
            '!latest.html',
        ],
        dest : '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',

    },

    redirect : {

        src : './files/templates/latest.html',
        dest : '../prod/index.html',

    },

},

Just to show that one can process may files.

Scripts in package.json

Make note in README that one can run grunt locally instead of installing globally with this:


  "scripts": {
    "dev": "grunt",
    "prod": "grunt prod"
  }

Template lang

Would be nice to a full-on template language. Need to research.

Setup rsync for deployment

"deploy:stage": "rsync -avz -e \"ssh -p 1234\" dist/ [email protected]:/etc/path/to/vhost/dir/",

The above taken from a work project that uses rsync to deploy only the needed folders to make site and/or assets hosted on dev/prod servers.

I kinda like this over using git and pulling the full repo; instead, use rsync to push only the code needed.

Things to add to README

Might want to mention:

  1. Importance of having the dev and prod builds separate; having one replace the other (in terms of generated files) is not optimal. You want to have the ability to view both at same time; more importantly, you'll also want to make sure your production builds always point to production-built files (if dev replaces prod, there's always a possibility that your production site could end up using dev-built files). I mention this because I've worked with setups where the dev build wiped out the prod build and vice versa.
  2. Having my "build" code, or "source", a level deep. The point is the code becomes a bit more organized in the instances where the root level needs to have boilerplate files, grunt-generated files and/or demo folders grunt-js-boiler is a good example of this. There may be times where visitors don't care about the source files and want to go directly to the end result. IMHO, having source files in a sub-folder allows the overall setup to be more clean.
  3. Other?

Copy production index page to root?

Might be nice to copy a production index.html page to the root of repo for easy viewing/hosting all from one location:

copy : {

    dev : {

        files : [

            {

                expand : true,
                cwd : './files/',
                src : [
                    'images/**/*',
                    'pages/**/*',
                    'scripts/**/*',
                ],
                dest : '../dev/',

            },

        ],

    },

    prod : {

        files : [

            {

                expand : true,
                cwd : './files/',
                src : [
                    'images/**/*',
                ],
                dest : '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',

            }, {

                // COPY INDEX TO ROOT:
                src: '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/index.html',
                dest: '../index.html',

            },

        ],

    },

},

"ghb" namespace

I find that I change this NS for every project. It's kinda an annoying step.

Couple of options:

  1. Make the default NS (i.e., ghb) something more generically useful, like MAH (my initials?) or NS (for namespace?).
  2. Document steps needed to take to change.
  3. Live with ghb?

I'd like to roll with the first thought. NS might be nice and good … Maybe use NS and document steps needed to change?

Link to drone …

… For a more basic real word example, see Drone. I used grunt-html-boiler as a starting point Drone. 👍

BETTER preprocess and copy task syntax!!!

Now I can ditch the preprocess misc:

/*----------------------------------( PREPROCESS )----------------------------------*/

/**
 * Grunt task around preprocess npm module.
 *
 * @see https://github.com/onehealth/grunt-preprocess
 * @see https://github.com/onehealth/preprocess
 * @see http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
 */

preprocess : {

    options : {

        context : {

            title : '<%= pkg.title %>',
            description : '<%= pkg.description %>',
            name : '<%= pkg.name %>',
            version : '<%= pkg.version %>',
            homepage : '<%= pkg.homepage %>',
            production : '<%= pkg.production %>',
            now : '<%= now %>',
            ver : '<%= ver %>',

        },

    },

    dev : {

        files: [

            {

                expand : true,
                cwd : './files/templates/',
                src : [
                    '**/*.*', // Greedy!
                    '!latest.html',
                ],
                dest : '../dev/',

            },

        ],

    },

    prod : {

        files: [

            {

                expand : true,
                cwd : './files/templates/',
                src : [
                    'index.html',
                ],
                dest : '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',

            }, {

                src : './files/templates/latest.html',
                dest : '../prod/index.html',

            },

        ],

    },

},

/*----------------------------------( COPY )----------------------------------*/

/**
 * Copy files and folders.
 *
 * @see https://github.com/gruntjs/grunt-contrib-copy
 * @see http://gruntjs.com/configuring-tasks#globbing-patterns
 */

copy : {

    dev : {

        files : [

            {

                expand : true,
                cwd : './files/',
                src : [
                    'images/**/*',
                    'pages/**/*',
                    'scripts/**/*',
                ],
                dest : '../dev/',

            },

        ],

    },

    prod : {

        files : [

            {

                expand : true,
                cwd : './files/',
                src : [
                    'images/**/*',
                ],
                dest : '../prod/<%= pkg.version %>/<%= now %>/<%= ver %>/',

            },

        ],

    },

},

No bower.json present

In your instruction you say that one can optionally, install the latest Bower plugin versions via $ grunt bower and that this this will install plugins (as defined in source/bower.json) into the source/files/plugins/ directory.

I can't seem to find either the source directory or a bower.json present in this repository...

Change css to styles

In the target dirs, instead of css for a folder name, use styles. This makes sense to me because I retain scripts name from source to dev/prod folders.

SCSS variables: Make better

I use a slightly new system. Kinda not the point of this repo, but since I'm using a variables file anyway for demo purposes, I might as well updated to be more in line with my latest approach for SASS variable naming/usage.

Update to latest dotfiles

$ curl -#L https://github.com/mhulse/gh-boiler/tarball/master | tar -xzv --strip-components 1 --include=*/{.editorconfig,.gitattributes,.gitignore} --exclude=*/**/*

Booyah!

Asset demo verbiage

Note: The production build’s asset files are absolutely linked to the production server; hence the need to push the latest files there before previewing the production’s HTML file and related assets.

Update production theme:

Finally, in a real world scenario, you would update the asset path by updating the URL to your latest production build. For example, here’s a simple PHP function one could use in a WordPress functions.php file:

Demo HTML

And last para above needs to clarify location.

Source files in asset folders

Would be nice to come up with a pattern I can use to easily ignore source asset files via the GruntFile copy and other tasks.

Currently I have folder names like psd or ai and junk. The junk works well to ignore: '!**/junk/**',, but I think it would be good to have a similar generic name for source files. The name source would work, but I already use /source at the root level, and I think using that name in two different contexts could be confusing. My gut is telling me to change the root name source to something else (like build/ maybe?) then I could use source/ in the children folders without feeling like I'm bastardizing the name.

Task optimization

In gulp, and should be the same in grunt, I can do:

gulp.src([
    'files/scripts/!(main)*.js',
    'files/scripts/main.js',
])

This allows me to glob, but then specify some sort of sane order.

Text update

... the watch command will run a development build any time these folders/file(s) change:

… change to:

… the `watch` command will run a development build any time these folders/file(s) change:

Dev in prod task?

Might be nice to require the dev build when doing a prod build.

For example, before:

grunt.registerTask('prod', ['init', 'env:prod', 'clean:prod', 'sass:prod', 'uglify:prod', 'preprocess:prod', 'copy:prod',]);

… after:

grunt.registerTask('prod', ['init', 'dev', 'env:prod', 'clean:prod', 'sass:prod', 'uglify:prod', 'preprocess:prod', 'copy:prod',]);

That way one can't forget.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.