diff --git a/Gruntfile.js b/Gruntfile.js index 06e694e..2ee0a28 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,157 +1,14 @@ -/****************************************************** - * PATTERN LAB NODE - * EDITION-NODE-GRUNT - * The grunt wrapper around patternlab-node core, providing tasks to interact with the core library and move supporting frontend assets. -******************************************************/ - -module.exports = function (grunt) { - - var path = require('path'), - argv = require('minimist')(process.argv.slice(2)); - - // load all grunt tasks - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-browser-sync'); - - /****************************************************** - * PATTERN LAB CONFIGURATION - ******************************************************/ - - //read all paths from our namespaced config file - var config = require('./patternlab-config.json'), - pl = require('patternlab-node')(config); - - function paths() { - return config.paths; - } - - function getConfiguredCleanOption() { - return config.cleanPublic; - } - - grunt.registerTask('patternlab', 'create design systems with atomic design', function (arg) { - - if (arguments.length === 0) { - pl.build(function(){}, getConfiguredCleanOption()); - } - - if (arg && arg === 'version') { - pl.version(); - } - - if (arg && arg === "patternsonly") { - pl.patternsonly(function(){},getConfiguredCleanOption()); - } - - if (arg && arg === "help") { - pl.help(); - } - - if (arg && arg === "starterkit-list") { - pl.liststarterkits(); - } - - if (arg && arg === "starterkit-load") { - pl.loadstarterkit(argv.kit); - } - - if (arg && (arg !== "version" && arg !== "patternsonly" && arg !== "help" && arg !== "starterkit-list" && arg !== "starterkit-load")) { - pl.help(); - } - }); +'use strict'; +module.exports = function(grunt) { grunt.initConfig({ - - /****************************************************** - * COPY TASKS - ******************************************************/ - copy: { - main: { - files: [ - { expand: true, cwd: path.resolve(paths().source.js), src: '**/*.js', dest: path.resolve(paths().public.js) }, - { expand: true, cwd: path.resolve(paths().source.css), src: '*.css', dest: path.resolve(paths().public.css) }, - { expand: true, cwd: path.resolve(paths().source.images), src: '*', dest: path.resolve(paths().public.images) }, - { expand: true, cwd: path.resolve(paths().source.fonts), src: '*', dest: path.resolve(paths().public.fonts) }, - { expand: true, cwd: path.resolve(paths().source.root), src: 'favicon.ico', dest: path.resolve(paths().public.root) }, - { expand: true, cwd: path.resolve(paths().source.styleguide), src: ['*', '**'], dest: path.resolve(paths().public.root) }, - // slightly inefficient to do this again - I am not a grunt glob master. someone fix - { expand: true, flatten: true, cwd: path.resolve(paths().source.styleguide, 'styleguide', 'css', 'custom'), src: '*.css)', dest: path.resolve(paths().public.styleguide, 'css') } - ] - } - }, - /****************************************************** - * SERVER AND WATCH TASKS - ******************************************************/ - watch: { - all: { - files: [ - path.resolve(paths().source.css + '**/*.css'), - path.resolve(paths().source.styleguide + 'css/*.css'), - path.resolve(paths().source.patterns + '**/*'), - path.resolve(paths().source.fonts + '/*'), - path.resolve(paths().source.images + '/*'), - path.resolve(paths().source.data + '*.json'), - path.resolve(paths().source.js + '/*.js'), - path.resolve(paths().source.root + '/*.ico') - ], - tasks: ['default', 'bsReload:css'] - } - }, - browserSync: { - dev: { + patternlab: { options: { - server: path.resolve(paths().public.root), - watchTask: true, - watchOptions: { - ignoreInitial: true, - ignored: '*.html' - }, - snippetOptions: { - // Ignore all HTML files within the templates folder - blacklist: ['/index.html', '/', '/?*'] - }, - plugins: [ - { - module: 'bs-html-injector', - options: { - files: [path.resolve(paths().public.root + '/index.html'), path.resolve(paths().public.styleguide + '/styleguide.html')] - } - } - ], - notify: { - styles: [ - 'display: none', - 'padding: 15px', - 'font-family: sans-serif', - 'position: fixed', - 'font-size: 1em', - 'z-index: 9999', - 'bottom: 0px', - 'right: 0px', - 'border-top-left-radius: 5px', - 'background-color: #1B2032', - 'opacity: 0.4', - 'margin: 0', - 'color: white', - 'text-align: center' - ] - } + // You can overwrite default config here } - } - }, - bsReload: { - css: path.resolve(paths().public.root + '**/*.css') } }); - /****************************************************** - * COMPOUND TASKS - ******************************************************/ - - grunt.registerTask('default', ['patternlab', 'copy:main']); - grunt.registerTask('patternlab:watch', ['patternlab', 'copy:main', 'watch:all']); - grunt.registerTask('patternlab:serve', ['patternlab', 'copy:main', 'browserSync', 'watch:all']); - + grunt.loadTasks('tasks'); }; diff --git a/README.md b/README.md index 3a1e1d6..4a8677e 100644 --- a/README.md +++ b/README.md @@ -19,20 +19,25 @@ It's also highly recommended that you [install grunt](http://gruntjs.com/getting ## Installing -There are two methods for downloading and installing the Grunt Edition: +### Use npm -* [Download a pre-built package](#download-a-pre-built-package) -* [Use npm](#use-npm) +`npm` is a dependency management and package system which can pull in all of the Grunt Edition's dependencies for you. There are two ways of using `npm` to install the Grunt Edition of Pattern Lab Node: -### Download a pre-built package +#### Install as a Dependency of an existing project -The fastest way to get started with the Grunt Edition is to [download the pre-built version](https://github.com/pattern-lab/edition-node-grunt/releases) from the [releases page](https://github.com/pattern-lab/edition-node-grunt/releases). The pre-built project comes with the [Base Starterkit for Mustache](https://github.com/pattern-lab/starterkit-mustache-base) installed by default. +First, install the Grunt Edition as a dependency of your project using [npm install](https://docs.npmjs.com/cli/install): -**Please note:** Pattern Lab Node uses [npm](https://www.npmjs.com/) to manage project dependencies. To upgrade the Grunt Edition or to install plug-ins you'll need to be familiar with npm. + cd project/ + npm install edition-node-grunt --save-dev + +This will install the Grunt Edition into a directory called `node_modules` in `install/location/`. + +Next, add the edition-node-grunt [tasks](http://gruntjs.com/getting-started#loading-grunt-plugins-and-tasks) to your main [Gruntfile](http://gruntjs.com/getting-started#the-gruntfile) by adding `grunt.loadNpmTasks('edition-node-grunt');`. See [Sample Gruntfile](#sample-gruntfiles) for help. + +Now, continue on and finish [setting up your configuration](#set-up-and-configuration). -### Use npm -`npm` is a dependency management and package system which can pull in all of the Grunt Edition's dependencies for you. To accomplish this: +#### Install the Grunt Edition of Pattern Lab Node as standalone * download or `git clone` this repository to an install location. @@ -45,16 +50,56 @@ The fastest way to get started with the Grunt Edition is to [download the pre-bu Running `npm install` from a directory containing a `package.json` file will download all dependencies defined within. -#### Install the Grunt Edition of Pattern Lab Node as a Dependency +## Set up and Configuration +Run `grunt patternlab:set-up` to create a default source directory for your Pattern Lab project. This is only necessary if your installed the Grunt Edition as a dependency. -Most people want to run Pattern Lab Node standalone and not as a dependency. If you wish to install as a dependency you can do the following: +Pattern Lab runs using the default configs defined in the [default-config.json](/default-config.json) file. -Use npm's [`install` command](https://docs.npmjs.com/cli/install) with an argument to install the Grunt Edition into a location of your choosing. In Terminal type: +If you want to change any of these configurations you can create your own `config.json` file and then add its path to your Gruntfile as the `config_file` option. See [Sample Gruntfile](#sample-gruntfiles) for help. Make sure your config file includes **ALL** the necessary configurations. - cd install/location/ - npm install edition-node-grunt +You can also add your custom configurations directly in your Gruntfile as options. These options will only overwrite the existing default configurations so don't worry about including them all. Again see [Sample Gruntfile](#sample-gruntfiles) for help. Note, overwriting options in your Gruntfile does not nest so if you overwrite the `"paths"` config, be sure to include **ALL** the source and public paths information. -This will install the Grunt Edition into a directory called `node_modules` in `install/location/`. +## Sample Gruntfiles +Your Gruntfile.js could look something like this: + +``` +module.exports = function(grunt) { + + grunt.initConfig({ + + patternlab: { + // You can place a path do your own config file here + options: { + config_file: "config.json" + } + } + }); + + grunt.loadNpmTasks('edition-node-grunt'); +}; + +``` + +Or this: + +``` +module.exports = function(grunt) { + + grunt.initConfig({ + + patternlab: { + // You can overwrite default config directly in your Gruntfile + options: { + "cleanPublic" : false, + "patternExportDirectory": "./exports/" + } + } + }); + + grunt.loadNpmTasks('edition-node-grunt'); +}; + +``` ## Getting started @@ -76,6 +121,14 @@ To list all available commands type: grunt patternlab:help +### Set Up Pattern Lab source directories + +To generate the default Pattern Lab source directories: + + grunt patternlab:set-up + +See [Set up and Configuration](#set-up-and-configuration) + ### Generate Pattern Lab To generate the front-end for Pattern Lab type: diff --git a/patternlab-config.json b/default-config.json similarity index 100% rename from patternlab-config.json rename to default-config.json diff --git a/tasks/Gruntfile.js b/tasks/Gruntfile.js new file mode 100644 index 0000000..347e742 --- /dev/null +++ b/tasks/Gruntfile.js @@ -0,0 +1,176 @@ +/****************************************************** + * PATTERN LAB NODE + * EDITION-NODE-GRUNT + * The grunt wrapper around patternlab-node core, providing tasks to interact with the core library and move supporting frontend assets. +******************************************************/ + +module.exports = function (grunt) { + var patternLab = require('patternlab-node'); + var default_pl_config = require('../default-config.json'); + + var path = require('path'), + argv = require('minimist')(process.argv.slice(2)); + + // load all grunt tasks + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-browser-sync'); + + grunt.registerTask('patternlab', 'create design systems with atomic design', function (arg) { + /****************************************************** + * PATTERN LAB CONFIGURATION + ******************************************************/ + var config; + + // Use specified config or else use default + var options = this.options(default_pl_config); + if (options.config_file) { + // If seperate config file was specified + config = grunt.file.readJSON(options.config_file); + } else { + // Else use specified/default config + config = options; + } + + var pl = patternLab(config); + if (arguments.length === 0) { + pl.build(function(){}, config.cleanPublic); + + // Move other files + grunt.task.run(['copy:main']); + } + + var patternlab_targets = { + "set-up": function () { + grunt.task.run(['copy:set-up']); + }, + "version": function () { + pl.version(); + }, + "patternsonly": function () { + pl.patternsonly(function(){},config.cleanPublic); + }, + "help": function () { + pl.help(); + }, + "starterkit-list": function () { + pl.liststarterkits(); + }, + "starterkit-load": function () { + pl.loadstarterkit(argv.kit); + } + }; + + if (arg) { + if (patternlab_targets[arg]) { + patternlab_targets[arg](); + } else { + pl.help(); + } + } + + /****************************************************** + * COPY TASKS + ******************************************************/ + + // relative path to default source dir + var rel_path = path.relative(process.cwd(), __dirname); + + grunt.config('copy', { + main: { + files: [ + { expand: true, cwd: path.resolve(config.paths.source.js), src: '**/*.js', dest: path.resolve(config.paths.public.js) }, + { expand: true, cwd: path.resolve(config.paths.source.css), src: '*.css', dest: path.resolve(config.paths.public.css) }, + { expand: true, cwd: path.resolve(config.paths.source.images), src: '*', dest: path.resolve(config.paths.public.images) }, + { expand: true, cwd: path.resolve(config.paths.source.fonts), src: '*', dest: path.resolve(config.paths.public.fonts) }, + { expand: true, cwd: path.resolve(config.paths.source.root), src: 'favicon.ico', dest: path.resolve(config.paths.public.root) }, + { expand: true, cwd: path.resolve(config.paths.source.styleguide), src: ['*', '**'], dest: path.resolve(config.paths.public.root) }, + // slightly inefficient to do this again - I am not a grunt glob master. someone fix + { expand: true, flatten: true, cwd: path.resolve(config.paths.source.styleguide, 'styleguide', 'css', 'custom'), src: '*.css)', dest: path.resolve(config.paths.public.styleguide, 'css') } + ] + }, + "set-up": { + files: [{ + expand: true, + cwd: rel_path + '/../source/', + src: '**', + dest: 'source/' + }] + } + }); + + /****************************************************** + * SERVER AND WATCH TASKS + ******************************************************/ + grunt.config('watch', { + all: { + files: [ + path.resolve(config.paths.source.css + '**/*.css'), + path.resolve(config.paths.source.styleguide + 'css/*.css'), + path.resolve(config.paths.source.patterns + '**/*'), + path.resolve(config.paths.source.fonts + '/*'), + path.resolve(config.paths.source.images + '/*'), + path.resolve(config.paths.source.data + '*.json'), + path.resolve(config.paths.source.js + '/*.js'), + path.resolve(config.paths.source.root + '/*.ico') + ], + tasks: ['default', 'bsReload:css'] + } + }); + + grunt.config('browserSync', { + dev: { + options: { + server: path.resolve(config.paths.public.root), + watchTask: true, + watchOptions: { + ignoreInitial: true, + ignored: '*.html' + }, + snippetOptions: { + // Ignore all HTML files within the templates folder + blacklist: ['/index.html', '/', '/?*'] + }, + plugins: [ + { + module: 'bs-html-injector', + options: { + files: [path.resolve(config.paths.public.root + '/index.html'), path.resolve(config.paths.public.styleguide + '/styleguide.html')] + } + } + ], + notify: { + styles: [ + 'display: none', + 'padding: 15px', + 'font-family: sans-serif', + 'position: fixed', + 'font-size: 1em', + 'z-index: 9999', + 'bottom: 0px', + 'right: 0px', + 'border-top-left-radius: 5px', + 'background-color: #1B2032', + 'opacity: 0.4', + 'margin: 0', + 'color: white', + 'text-align: center' + ] + } + } + } + }); + + grunt.config('bsReload', { + css: path.resolve(config.paths.public.root + '**/*.css') + }); + }); + + /****************************************************** + * COMPOUND TASKS + ******************************************************/ + + grunt.registerTask('patternlab:watch', ['patternlab', 'watch:all']); + grunt.registerTask('patternlab:serve', ['patternlab', 'browserSync', 'watch:all']); + +};