Merge pull request #63 from locomotivemtl/gulp

Gulp
This commit is contained in:
Antoine Boulanger
2018-09-05 15:11:47 -04:00
committed by GitHub
29 changed files with 128 additions and 878 deletions

View File

@@ -1,4 +1,3 @@
{
"presets": [ "env" ],
"plugins": [ "babel-plugin-transform-export-extensions" ]
"presets": ["@babel/preset-env"]
}

View File

@@ -1,408 +0,0 @@
{
"remove-empty-rulesets": true,
"always-semicolon": true,
"color-case": "upper",
"block-indent": " ",
"color-shorthand": false,
"element-case": "lower",
"eof-newline": true,
"leading-zero": true,
"quotes": "double",
"space-before-colon": "",
"space-after-colon": " ",
"space-before-combinator": " ",
"space-after-combinator": " ",
"space-between-declarations": "\n",
"space-before-opening-brace": " ",
"space-after-opening-brace": "\n",
"space-before-selector-delimiter": "",
"space-before-closing-brace": "\n",
"strip-spaces": true,
"tab-size": true,
"sort-order": [
[
"$variable"
],
[
"$include"
],
[
"position",
"top",
"right",
"bottom",
"left",
"z-index",
"display",
"visibility",
"-webkit-flex-direction",
"-moz-flex-direction",
"-ms-flex-direction",
"-o-flex-direction",
"flex-direction",
"-webkit-flex-order",
"-moz-flex-order",
"-ms-flex-order",
"-o-flex-order",
"flex-order",
"-webkit-flex-pack",
"-moz-flex-pack",
"-ms-flex-pack",
"-o-flex-pack",
"flex-pack",
"float",
"clear",
"-webkit-flex-align",
"-moz-flex-align",
"-ms-flex-align",
"-o-flex-align",
"flex-align",
"overflow",
"-ms-overflow-x",
"-ms-overflow-y",
"overflow-x",
"overflow-y",
"-webkit-overflow-scrolling",
"clip",
"-webkit-box-sizing",
"-moz-box-sizing",
"box-sizing",
"margin",
"margin-top",
"margin-right",
"margin-bottom",
"margin-left",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"min-width",
"min-height",
"max-width",
"max-height",
"width",
"height",
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"border",
"border-spacing",
"border-collapse",
"border-width",
"border-style",
"border-color",
"border-top",
"border-top-width",
"border-top-style",
"border-top-color",
"border-right",
"border-right-width",
"border-right-style",
"border-right-color",
"border-bottom",
"border-bottom-width",
"border-bottom-style",
"border-bottom-color",
"border-left",
"border-left-width",
"border-left-style",
"border-left-color",
"-webkit-border-radius",
"-moz-border-radius",
"border-radius",
"-webkit-border-top-left-radius",
"-moz-border-radius-topleft",
"border-top-left-radius",
"-webkit-border-top-right-radius",
"-moz-border-radius-topright",
"border-top-right-radius",
"-webkit-border-bottom-right-radius",
"-moz-border-radius-bottomright",
"border-bottom-right-radius",
"-webkit-border-bottom-left-radius",
"-moz-border-radius-bottomleft",
"border-bottom-left-radius",
"-webkit-border-image",
"-moz-border-image",
"-o-border-image",
"border-image",
"-webkit-border-image-source",
"-moz-border-image-source",
"-o-border-image-source",
"border-image-source",
"-webkit-border-image-slice",
"-moz-border-image-slice",
"-o-border-image-slice",
"border-image-slice",
"-webkit-border-image-width",
"-moz-border-image-width",
"-o-border-image-width",
"border-image-width",
"-webkit-border-image-outset",
"-moz-border-image-outset",
"-o-border-image-outset",
"border-image-outset",
"-webkit-border-image-repeat",
"-moz-border-image-repeat",
"-o-border-image-repeat",
"border-image-repeat",
"-webkit-border-top-image",
"-moz-border-top-image",
"-o-border-top-image",
"border-top-image",
"-webkit-border-right-image",
"-moz-border-right-image",
"-o-border-right-image",
"border-right-image",
"-webkit-border-bottom-image",
"-moz-border-bottom-image",
"-o-border-bottom-image",
"border-bottom-image",
"-webkit-border-left-image",
"-moz-border-left-image",
"-o-border-left-image",
"border-left-image",
"-webkit-border-corner-image",
"-moz-border-corner-image",
"-o-border-corner-image",
"border-corner-image",
"-webkit-border-top-left-image",
"-moz-border-top-left-image",
"-o-border-top-left-image",
"border-top-left-image",
"-webkit-border-top-right-image",
"-moz-border-top-right-image",
"-o-border-top-right-image",
"border-top-right-image",
"-webkit-border-bottom-right-image",
"-moz-border-bottom-right-image",
"-o-border-bottom-right-image",
"border-bottom-right-image",
"-webkit-border-bottom-left-image",
"-moz-border-bottom-left-image",
"-o-border-bottom-left-image",
"border-bottom-left-image",
"background",
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
"background-color",
"background-image",
"background-attachment",
"background-position",
"-ms-background-position-x",
"-ms-background-position-y",
"background-position-x",
"background-position-y",
"-webkit-background-clip",
"-moz-background-clip",
"background-clip",
"background-origin",
"-webkit-background-size",
"-moz-background-size",
"-o-background-size",
"background-size",
"background-repeat",
"box-decoration-break",
"-webkit-box-shadow",
"-moz-box-shadow",
"box-shadow",
"color",
"table-layout",
"caption-side",
"empty-cells",
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
"quotes",
"content",
"counter-increment",
"counter-reset",
"-ms-writing-mode",
"vertical-align",
"text-align",
"-webkit-text-align-last",
"-moz-text-align-last",
"-ms-text-align-last",
"text-align-last",
"text-decoration",
"text-emphasis",
"text-emphasis-position",
"text-emphasis-style",
"text-emphasis-color",
"text-indent",
"-ms-text-justify",
"text-justify",
"text-outline",
"text-transform",
"text-wrap",
"-ms-text-overflow",
"text-overflow",
"text-overflow-ellipsis",
"text-overflow-mode",
"text-shadow",
"white-space",
"word-spacing",
"-ms-word-wrap",
"word-wrap",
"-ms-word-break",
"word-break",
"-moz-tab-size",
"-o-tab-size",
"tab-size",
"-webkit-hyphens",
"-moz-hyphens",
"hyphens",
"letter-spacing",
"font",
"font-weight",
"font-style",
"font-variant",
"font-size-adjust",
"font-stretch",
"font-size",
"font-family",
"src",
"line-height",
"opacity",
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
"-ms-interpolation-mode",
"-webkit-filter",
"-ms-filter",
"filter",
"resize",
"cursor",
"nav-index",
"nav-up",
"nav-right",
"nav-down",
"nav-left",
"-webkit-transition",
"-moz-transition",
"-ms-transition",
"-o-transition",
"transition",
"-webkit-transition-delay",
"-moz-transition-delay",
"-ms-transition-delay",
"-o-transition-delay",
"transition-delay",
"-webkit-transition-timing-function",
"-moz-transition-timing-function",
"-ms-transition-timing-function",
"-o-transition-timing-function",
"transition-timing-function",
"-webkit-transition-duration",
"-moz-transition-duration",
"-ms-transition-duration",
"-o-transition-duration",
"transition-duration",
"-webkit-transition-property",
"-moz-transition-property",
"-ms-transition-property",
"-o-transition-property",
"transition-property",
"-webkit-transform",
"-moz-transform",
"-ms-transform",
"-o-transform",
"transform",
"-webkit-transform-origin",
"-moz-transform-origin",
"-ms-transform-origin",
"-o-transform-origin",
"transform-origin",
"-webkit-animation",
"-moz-animation",
"-ms-animation",
"-o-animation",
"animation",
"-webkit-animation-name",
"-moz-animation-name",
"-ms-animation-name",
"-o-animation-name",
"animation-name",
"-webkit-animation-duration",
"-moz-animation-duration",
"-ms-animation-duration",
"-o-animation-duration",
"animation-duration",
"-webkit-animation-play-state",
"-moz-animation-play-state",
"-ms-animation-play-state",
"-o-animation-play-state",
"animation-play-state",
"-webkit-animation-timing-function",
"-moz-animation-timing-function",
"-ms-animation-timing-function",
"-o-animation-timing-function",
"animation-timing-function",
"-webkit-animation-delay",
"-moz-animation-delay",
"-ms-animation-delay",
"-o-animation-delay",
"animation-delay",
"-webkit-animation-iteration-count",
"-moz-animation-iteration-count",
"-ms-animation-iteration-count",
"-o-animation-iteration-count",
"animation-iteration-count",
"-webkit-animation-direction",
"-moz-animation-direction",
"-ms-animation-direction",
"-o-animation-direction",
"animation-direction",
"pointer-events",
"unicode-bidi",
"direction",
"-webkit-columns",
"-moz-columns",
"columns",
"-webkit-column-span",
"-moz-column-span",
"column-span",
"-webkit-column-width",
"-moz-column-width",
"column-width",
"-webkit-column-count",
"-moz-column-count",
"column-count",
"-webkit-column-fill",
"-moz-column-fill",
"column-fill",
"-webkit-column-gap",
"-moz-column-gap",
"column-gap",
"-webkit-column-rule",
"-moz-column-rule",
"column-rule",
"-webkit-column-rule-width",
"-moz-column-rule-width",
"column-rule-width",
"-webkit-column-rule-style",
"-moz-column-rule-style",
"column-rule-style",
"-webkit-column-rule-color",
"-moz-column-rule-color",
"column-rule-color",
"break-before",
"break-inside",
"break-after",
"page-break-before",
"page-break-inside",
"page-break-after",
"orphans",
"widows",
"-ms-zoom",
"zoom",
"max-zoom",
"min-zoom",
"user-zoom",
"orientation",
"..."
]
]
}

View File

@@ -1,5 +1,4 @@
# editorconfig.org
root = true
[*]
@@ -10,5 +9,9 @@ indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{md,markdown}]
[*.md]
trim_trailing_whitespace = false
[{*.yml,*.json}]
indent_size = 2
indent_style = space

View File

@@ -1,46 +0,0 @@
{
"env": {
"browser": true,
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"ecmaFeatures": {
"arrowFunctions": true,
"binaryLiterals": true,
"blockBindings": true,
"classes": true,
"defaultParams": true,
"destructuring": true,
"forOf": true,
"generators": true,
"modules": true,
"objectLiteralComputedProperties": true,
"objectLiteralDuplicateProperties": true,
"objectLiteralShorthandMethods": true,
"objectLiteralShorthandProperties": true,
"octalLiterals": true,
"regexUFlag": true,
"regexYFlag": true,
"spread": true,
"superInFunctions": false,
"templateStrings": true,
"unicodeCodePointEscapes": true,
"globalReturn": true,
"jsx": true
},
"rules": {
"eqeqeq": 2,
"strict": 0,
"no-empty": 1,
"no-alert": 2,
"no-eval": 2,
"quotes": [1, "single", "avoid-escape"],
"no-trailing-spaces": [2, { "skipBlankLines": true }],
"eol-last": 0,
"yoda": [2, "never", { "exceptRange": true }]
}
}

19
.gitignore vendored
View File

@@ -1,16 +1,3 @@
# Package Managers
# -------
composer.phar
composer.lock
yarn.lock
vendor/
node_modules/
bower_components/
# Logging
# -------
*.log
error_log
logs/
node_modules
.DS_Store
Thumbs.db

View File

@@ -1,3 +0,0 @@
{
"esversion": 6
}

View File

@@ -1,35 +0,0 @@
/**
* Grunt Task Wrangler
*
* @copyright Copyright © 2016 Locomotive
* @license Licensed under the MIT license.
*/
'use strict';
module.exports = function (grunt)
{
var path = require('path');
require('load-grunt-config')(grunt, {
configPath: path.join(process.cwd(), 'build/grunt/config'),
data: {
paths: {
grunt: 'build/grunt',
npm: 'node_modules',
js: {
src: 'assets/scripts',
dist: 'www/assets/scripts'
},
css: {
src: 'assets/styles',
dist: 'www/assets/styles'
},
img: {
src: 'assets/images',
dist: 'www/assets/images'
}
}
}
});
};

View File

@@ -3,33 +3,25 @@ Locomotive's Front-end Boilerplate
Front-end boilerplate for projects by [Locomotive][locomtl].
## Requirements
## Installation
```sh
# install mbp and gulp
npm install mbp gulp@next -g
```
| Prerequisite | How to check | How to install |
| --------------- | ------------- | -------------------------------- |
| Node.js 4.1.1 | `node -v` | [nodejs.org](https://nodejs.org) |
| Grunt >= 0.1.13 | `grunt -v` | `npm install -g grunt-cli` |
## Usage
```sh
# init your project
mbp init locomotivemtl/locomotive-boilerplate <directory>
## Getting started
1. **Get the latest node modules**
- `npm install -g npm-check-updates`
- `npm-check-updates -u`
- `npm install`
BrowserSync will automatically inject, refresh and sync all your browsers.
2. **Set your project**
- `build/browserSync.js` update proxy
- `assets/scripts/utils/environment.js` update `APP_NAME`
3. **Run grunt, BrowserSync and start coding**
- `grunt sync`
### Grunt
Each Grunt task has it's own file in the `grunt_tasks` folder.
# run default watch task
gulp
```
## Configuration
Change the mentions of `boilerplate` for your project's name in
- `mconfig.json`
- `assets/scripts/utils/environment.js`
## CSS
@@ -127,4 +119,4 @@ Legend
`display()` -> (BaseTransition) `displayView()` -> display animations & `*readyToDestroy`
-> init new modules
`[readyToRemove]` -> reinit()
`[readyToRemove]` -> reinit()

14
build/concat.js Normal file
View File

@@ -0,0 +1,14 @@
import gulp from 'gulp';
import gulpConcat from 'gulp-concat';
import paths from '../mconfig.json';
function concat() {
return gulp
.src([
`${paths.scripts.vendors.src}*.js`
])
.pipe(gulpConcat(`${paths.scripts.vendors.main}.js`))
.pipe(gulp.dest(paths.scripts.dest));
}
export default concat;

View File

@@ -1,41 +0,0 @@
{
"default": [
"build"
],
"sync": [
"browserSync",
"browserify:dev",
"watch",
"notify:watch"
],
"build": [
"sass",
"postcss",
"cssmin",
"browserify:prod",
"concat:prod",
"uglify",
"svg_sprite",
"notify:build"
],
"w": [
"browserify:dev",
"watch",
"notify:watch"
],
"c": [
"csscomb"
],
"j": [
"eslint"
],
"p": [
"phplint"
]
}

View File

@@ -1,20 +0,0 @@
module.exports = {
options: {
open : false,
proxy : 'locomotive-boilerplate.test',
port : 3000,
watchTask : true,
notify : false
},
dev: {
bsFiles: {
src : [
'<%= paths.css.dist %>/**/*.css',
'<%= paths.js.dist %>/**/*.js',
'<%= paths.img.dist %>/**/*.svg',
'**/*.php',
'**/*.html',
]
}
}
};

View File

@@ -1,39 +0,0 @@
module.exports = {
options: {
browserifyOptions: {
debug: false
},
exclude: "",
transform: [
['babelify', {
presets: ['env'],
plugins: [
['transform-class-properties']
]
}]
]
},
dev: {
options: {
browserifyOptions: {
debug: true
},
watch: true
},
src: [
'<%= paths.js.src %>/**/*.js',
'!<%= paths.js.src %>/vendors/**/*.js'
],
dest: '<%= paths.js.dist %>/app.js'
},
prod: {
options: {
banner: '/*! <%= package.title %> - <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
src: [
'<%= paths.js.src %>/**/*.js',
'!<%= paths.js.src %>/vendors/**/*.js'
],
dest: '<%= paths.js.dist %>/app.js'
}
};

View File

@@ -1,14 +0,0 @@
module.exports = {
prod: {
options: {
banner: '/*! Dependencies for <%= package.title %> - <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
src : [
'<%= paths.js.src %>/vendors/**/*.js',
'<%= paths.npm %>/pjax/pjax.js',
'<%= paths.npm %>/svg4everybody/dist/svg4everybody.js'
],
dest : '<%= paths.js.dist %>/vendors.js'
}
};

View File

@@ -1,15 +0,0 @@
module.exports = {
options: {
config: '.csscomb.json'
},
dev: {
files: [
{
expand : true,
cwd : '<%= paths.css.src %>',
src : [ '**/*.scss', '!base/_fonts.scss' ],
dest : '<%= paths.css.src %>'
}
]
}
};

View File

@@ -1,13 +0,0 @@
module.exports = {
options: {},
prod: {
files: [
{
expand : true,
cwd : '<%= paths.css.dist %>',
src : [ '**/*.css', '!**/*.min.css' ],
dest : '<%= paths.css.dist %>'
}
]
}
};

View File

@@ -1,11 +0,0 @@
module.exports = {
options: {
quiet : false,
format : require('eslint-tap'),
configFile : '.eslintrc'
},
dev: [
'<%= paths.js.src %>/**/*.js',
'!<%= paths.js.src %>/vendors/**/*.js'
]
};

View File

@@ -1,36 +0,0 @@
module.exports = {
notify_hooks: {
options: {
enabled : true,
success : true,
duration : 3,
title : '<%= package.name %>',
max_jshint_notifications : 5
}
},
watch: {
options: {
message: 'Keeping an eye out, Chief!'
}
},
build: {
options: {
message: 'Everything is ready to go!'
}
},
sass: {
options: {
message: 'CSS is compiled'
}
},
javascript: {
options: {
message: 'JavaScript is compiled'
}
},
svg: {
options: {
message: 'SVG is concatenated'
}
}
};

View File

@@ -1,12 +0,0 @@
module.exports = {
options: {
swapPath : '/tmp',
phpArgs : {
// add -f for fatal errors
'-lf': null
}
},
dev: [
'**/*.php'
]
};

View File

@@ -1,27 +0,0 @@
module.exports = function (grunt, options)
{
return {
options: {
map: false,
processors: [
require('autoprefixer')({
browsers: [ 'last 2 versions', '> 1%', 'ie >= 9' ]
}),
require('postcss-banner')({
banner: grunt.template.process('! <%= package.title %> - <%= grunt.template.today("yyyy-mm-dd") %> ', { data: options })
})
]
},
prod: {
files: [
{
expand : true,
flatten : true,
cwd : '<%= paths.css.dist %>',
src : [ '**/*.css', '!**/*.min.css' ],
dest : '<%= paths.css.dist %>'
}
]
}
}
};

View File

@@ -1,17 +0,0 @@
module.exports = {
options: {
sourceMap : false,
outputStyle : 'expanded'
},
prod: {
files: [
{
expand : true,
cwd : '<%= paths.css.src %>',
src : [ '**/*.scss' ],
dest : '<%= paths.css.dist %>',
ext : '.css'
}
]
}
};

View File

@@ -1,29 +0,0 @@
module.exports = {
options : {
svg: {
xmlDeclaration : false,
namespaceIDs : true,
doctypeDeclaration : false,
cleanupNumericValues : true,
removeTitle : true,
removeDesc : true
}
},
prod: {
expand : true,
cwd : '<%= paths.img.src %>',
src : [ '**/*.svg', '!sprite.svg' ],
dest : '<%= paths.img.dist %>',
options : {
mode: {
symbol: {
dest : '.',
sprite : 'sprite.svg',
example : {
dest: '../../../build/sprite.symbol.html'
}
}
}
}
}
}

View File

@@ -1,13 +0,0 @@
module.exports = {
options: {},
prod: {
files: [
{
expand : true,
cwd : '<%= paths.js.dist %>',
src : [ '**/*.js', '!**/*.min.js' ],
dest : '<%= paths.js.dist %>'
}
]
}
};

View File

@@ -1,27 +0,0 @@
module.exports = {
options: {
spawn: false,
livereload: false
},
javascript_vendors: {
files: [ '<%= paths.js.src %>/vendors/**/*.js', '<%= paths.grunt %>/config/concat.js' ],
tasks: [ 'concat', 'notify:javascript' ]
},
sass: {
files: [ '<%= paths.css.src %>/**/*.scss' ],
tasks: [ 'sass', 'postcss', 'notify:sass' ]
},
svg: {
files: [ '<%= paths.img.src %>/**/*.svg' ],
tasks: [ 'svg_sprite', 'notify:svg' ]
},
tasks: {
options: {
reload: true
},
files: [
'Gruntfile.js',
'<%= paths.grunt %>/**/*'
]
}
};

14
build/serve.js Normal file
View File

@@ -0,0 +1,14 @@
import browserSync from 'browser-sync';
import paths from '../mconfig.json';
export const server = browserSync.create();
function serve(done) {
server.init({
notify: false,
proxy: paths.url
});
done();
}
export default serve;

22
build/watch.js Normal file
View File

@@ -0,0 +1,22 @@
import gulp from 'gulp';
import paths from '../mconfig.json';
import styles from './styles.js';
import scripts from './scripts.js';
import svgs from './svgs.js';
import concat from './concat.js';
import { server } from './serve.js';
function watch() {
gulp.watch(paths.styles.src, styles);
gulp.watch(paths.scripts.src, gulp.series(scripts, reload));
gulp.watch(paths.scripts.vendors.src, concat);
gulp.watch(paths.views.src, reload);
gulp.watch(paths.svgs.src, gulp.series(svgs, reload));
}
function reload(done) {
server.reload();
done();
}
export default watch;

16
gulpfile.babel.js Normal file
View File

@@ -0,0 +1,16 @@
import gulp from 'gulp';
import styles from './build/styles.js';
import scripts from './build/scripts.js';
import concat from './build/concat.js';
import svgs from './build/svgs.js';
import serve from './build/serve.js';
import watch from './build/watch.js';
import { buildStyles, buildScripts } from './build/build.js';
const compile = gulp.series(styles, scripts, svgs, concat);
const main = gulp.series(compile, serve, watch);
const build = gulp.series(compile, buildStyles, buildScripts);
gulp.task('default', main);
gulp.task('compile', compile);
gulp.task('build', build);

33
mconfig.json Executable file
View File

@@ -0,0 +1,33 @@
{
"url": "boilerplate.test",
"src": "./assets/",
"dest": "./www/",
"build": "./build/",
"styles": {
"src": "./assets/styles/",
"dest": "./www/assets/styles/",
"main": "main"
},
"scripts": {
"src": "./assets/scripts/",
"dest": "./www/assets/scripts/",
"main": "app",
"vendors": {
"src": "./assets/scripts/vendors/",
"main": "vendors"
}
},
"svgs": {
"src": "./assets/images/sprite/",
"dest": "./www/assets/images/"
},
"views": {
"src": "./views/boilerplate/template/"
},
"modules": {
"build": "gulp",
"style": "sass",
"script": "js",
"view": false
}
}

View File

@@ -1,4 +1,3 @@
{
"private": true,
"name": "@locomotivemtl/boilerplate",
@@ -6,33 +5,10 @@
"version": "1.0.0",
"author": "Locomotive <info@locomotive.ca>",
"dependencies": {
"pjax": "0.0.0",
"svg4everybody": "0.0.0"
"pjax": "*",
"svg4everybody": "*"
},
"devDependencies": {
"autoprefixer": "0.0.0",
"babel-core": "0.0.0",
"babel-preset-env": "0.0.0",
"babel-plugin-transform-class-properties": "0.0.0",
"babel-plugin-transform-export-extensions": "0.0.0",
"babelify": "0.0.0",
"eslint-tap": "0.0.0",
"glob": "0.0.0",
"grunt": "0.0.0",
"grunt-browser-sync": "0.0.0",
"grunt-browserify": "0.0.0",
"grunt-contrib-concat": "0.0.0",
"grunt-contrib-cssmin": "0.0.0",
"grunt-contrib-uglify": "0.0.0",
"grunt-contrib-watch": "0.0.0",
"grunt-csscomb": "0.0.0",
"grunt-eslint": "0.0.0",
"grunt-notify": "0.0.0",
"grunt-phplint": "0.0.0",
"grunt-postcss": "0.0.0",
"grunt-sass": "0.0.0",
"grunt-svg-sprite": "0.0.0",
"load-grunt-config": "0.0.0",
"postcss-banner": "0.0.0"
"gulp-concat": "*"
}
}