6
6
var gulp = require ( 'gulp' ) ,
7
7
path = require ( 'path' ) ,
8
8
browserSync = require ( 'browser-sync' ) . create ( ) ,
9
- argv = require ( 'minimist' ) ( process . argv . slice ( 2 ) ) ;
9
+ argv = require ( 'minimist' ) ( process . argv . slice ( 2 ) ) ,
10
+ chalk = require ( 'chalk' ) ;
10
11
11
- function resolvePath ( pathInput ) {
12
- return path . resolve ( pathInput ) . replace ( / \\ / g, "/" ) ;
12
+ /**
13
+ * Normalize all paths to be plain, paths with no leading './',
14
+ * relative to the process root, and with backslashes converted to
15
+ * forward slashes. Should work regardless of how the path was
16
+ * written. Accepts any number of parameters, and passes them along to
17
+ * path.resolve().
18
+ *
19
+ * This is intended to avoid all known limitations of gulp.watch().
20
+ *
21
+ * @param {...string } pathFragment - A directory, filename, or glob.
22
+ */
23
+ function normalizePath ( ) {
24
+ return path
25
+ . relative (
26
+ process . cwd ( ) ,
27
+ path . resolve . apply ( this , arguments )
28
+ )
29
+ . replace ( / \\ / g, "/" ) ;
13
30
}
14
31
15
32
/******************************************************
16
33
* COPY TASKS - stream assets from source to destination
17
34
******************************************************/
18
35
// JS copy
19
- gulp . task ( 'pl-copy:js' , function ( ) {
20
- return gulp . src ( '**/*.js' , { cwd : resolvePath ( paths ( ) . source . js ) } )
21
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . js ) ) ) ;
36
+ gulp . task ( 'pl-copy:js' , function ( ) {
37
+ return gulp . src ( '**/*.js' , { cwd : normalizePath ( paths ( ) . source . js ) } )
38
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . js ) ) ) ;
22
39
} ) ;
23
40
24
41
// Images copy
25
- gulp . task ( 'pl-copy:img' , function ( ) {
26
- return gulp . src ( '**/*.*' , { cwd : resolvePath ( paths ( ) . source . images ) } )
27
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . images ) ) ) ;
42
+ gulp . task ( 'pl-copy:img' , function ( ) {
43
+ return gulp . src ( '**/*.*' , { cwd : normalizePath ( paths ( ) . source . images ) } )
44
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . images ) ) ) ;
28
45
} ) ;
29
46
30
47
// Favicon copy
31
- gulp . task ( 'pl-copy:favicon' , function ( ) {
32
- return gulp . src ( 'favicon.ico' , { cwd : resolvePath ( paths ( ) . source . root ) } )
33
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . root ) ) ) ;
48
+ gulp . task ( 'pl-copy:favicon' , function ( ) {
49
+ return gulp . src ( 'favicon.ico' , { cwd : normalizePath ( paths ( ) . source . root ) } )
50
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . root ) ) ) ;
34
51
} ) ;
35
52
36
53
// Fonts copy
37
- gulp . task ( 'pl-copy:font' , function ( ) {
38
- return gulp . src ( '*' , { cwd : resolvePath ( paths ( ) . source . fonts ) } )
39
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . fonts ) ) ) ;
54
+ gulp . task ( 'pl-copy:font' , function ( ) {
55
+ return gulp . src ( '*' , { cwd : normalizePath ( paths ( ) . source . fonts ) } )
56
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . fonts ) ) ) ;
40
57
} ) ;
41
58
42
59
// CSS Copy
43
- gulp . task ( 'pl-copy:css' , function ( ) {
44
- return gulp . src ( resolvePath ( paths ( ) . source . css ) + '/*.css' )
45
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . css ) ) )
60
+ gulp . task ( 'pl-copy:css' , function ( ) {
61
+ return gulp . src ( normalizePath ( paths ( ) . source . css ) + '/*.css' )
62
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . css ) ) )
46
63
. pipe ( browserSync . stream ( ) ) ;
47
64
} ) ;
48
65
49
66
// Styleguide Copy everything but css
50
- gulp . task ( 'pl-copy:styleguide' , function ( ) {
51
- return gulp . src ( resolvePath ( paths ( ) . source . styleguide ) + '/**/!(*.css)' )
52
- . pipe ( gulp . dest ( resolvePath ( paths ( ) . public . root ) ) )
67
+ gulp . task ( 'pl-copy:styleguide' , function ( ) {
68
+ return gulp . src ( normalizePath ( paths ( ) . source . styleguide ) + '/**/!(*.css)' )
69
+ . pipe ( gulp . dest ( normalizePath ( paths ( ) . public . root ) ) )
53
70
. pipe ( browserSync . stream ( ) ) ;
54
71
} ) ;
55
72
56
73
// Styleguide Copy and flatten css
57
- gulp . task ( 'pl-copy:styleguide-css' , function ( ) {
58
- return gulp . src ( resolvePath ( paths ( ) . source . styleguide ) + '/**/*.css' )
59
- . pipe ( gulp . dest ( function ( file ) {
74
+ gulp . task ( 'pl-copy:styleguide-css' , function ( ) {
75
+ return gulp . src ( normalizePath ( paths ( ) . source . styleguide ) + '/**/*.css' )
76
+ . pipe ( gulp . dest ( function ( file ) {
60
77
//flatten anything inside the styleguide into a single output dir per http://stackoverflow.com/a/34317320/1790362
61
78
file . path = path . join ( file . base , path . basename ( file . path ) ) ;
62
- return resolvePath ( path . join ( paths ( ) . public . styleguide , '/css' ) ) ;
79
+ return normalizePath ( path . join ( paths ( ) . public . styleguide , '/css' ) ) ;
63
80
} ) )
64
81
. pipe ( browserSync . stream ( ) ) ;
65
82
} ) ;
@@ -79,24 +96,33 @@ function getConfiguredCleanOption() {
79
96
return config . cleanPublic ;
80
97
}
81
98
99
+ /**
100
+ * Performs the actual build step. Accomodates both async and sync
101
+ * versions of Pattern Lab.
102
+ * @param {function } done - Gulp done callback
103
+ */
82
104
function build ( done ) {
83
- patternlab . build ( done , getConfiguredCleanOption ( ) ) ;
105
+ const buildResult = patternlab . build ( ( ) => { } , getConfiguredCleanOption ( ) ) ;
106
+
107
+ // handle async version of Pattern Lab
108
+ if ( buildResult instanceof Promise ) {
109
+ return buildResult . then ( done ) ;
110
+ }
111
+
112
+ // handle sync version of Pattern Lab
113
+ done ( ) ;
114
+ return null ;
84
115
}
85
116
86
117
gulp . task ( 'pl-assets' , gulp . series (
87
- gulp . parallel (
88
- 'pl-copy:js' ,
89
- 'pl-copy:img' ,
90
- 'pl-copy:favicon' ,
91
- 'pl-copy:font' ,
92
- 'pl-copy:css' ,
93
- 'pl-copy:styleguide' ,
94
- 'pl-copy:styleguide-css'
95
- ) ,
96
- function ( done ) {
97
- done ( ) ;
98
- } )
99
- ) ;
118
+ 'pl-copy:js' ,
119
+ 'pl-copy:img' ,
120
+ 'pl-copy:favicon' ,
121
+ 'pl-copy:font' ,
122
+ 'pl-copy:css' ,
123
+ 'pl-copy:styleguide' ,
124
+ 'pl-copy:styleguide-css'
125
+ ) ) ;
100
126
101
127
gulp . task ( 'patternlab:version' , function ( done ) {
102
128
patternlab . version ( ) ;
@@ -122,9 +148,7 @@ gulp.task('patternlab:loadstarterkit', function (done) {
122
148
done ( ) ;
123
149
} ) ;
124
150
125
- gulp . task ( 'patternlab:build' , gulp . series ( 'pl-assets' , build , function ( done ) {
126
- done ( ) ;
127
- } ) ) ;
151
+ gulp . task ( 'patternlab:build' , gulp . series ( 'pl-assets' , build ) ) ;
128
152
129
153
gulp . task ( 'patternlab:installplugin' , function ( done ) {
130
154
patternlab . installplugin ( argv . plugin ) ;
@@ -141,41 +165,71 @@ function getSupportedTemplateExtensions() {
141
165
}
142
166
function getTemplateWatches ( ) {
143
167
return getSupportedTemplateExtensions ( ) . map ( function ( dotExtension ) {
144
- return resolvePath ( paths ( ) . source . patterns ) + '/**/ *' + dotExtension ;
168
+ return normalizePath ( paths ( ) . source . patterns , '**' , ' *' + dotExtension ) ;
145
169
} ) ;
146
170
}
147
171
148
- function reload ( ) {
172
+ /**
173
+ * Reloads BrowserSync.
174
+ * Note: Exits more reliably when used with a done callback.
175
+ */
176
+ function reload ( done ) {
149
177
browserSync . reload ( ) ;
178
+ done ( ) ;
150
179
}
151
180
152
- function reloadCSS ( ) {
181
+ /**
182
+ * Reloads BrowserSync, with CSS injection.
183
+ * Note: Exits more reliably when used with a done callback.
184
+ */
185
+ function reloadCSS ( done ) {
153
186
browserSync . reload ( '*.css' ) ;
187
+ done ( ) ;
154
188
}
155
189
156
190
function watch ( ) {
157
- gulp . watch ( resolvePath ( paths ( ) . source . css ) + '/**/*.css' , { awaitWriteFinish : true } ) . on ( 'change' , gulp . series ( 'pl-copy:css' , reloadCSS ) ) ;
158
- gulp . watch ( resolvePath ( paths ( ) . source . styleguide ) + '/**/*.*' , { awaitWriteFinish : true } ) . on ( 'change' , gulp . series ( 'pl-copy:styleguide' , 'pl-copy:styleguide-css' , reloadCSS ) ) ;
159
-
160
- var patternWatches = [
161
- resolvePath ( paths ( ) . source . patterns ) + '/**/*.json' ,
162
- resolvePath ( paths ( ) . source . patterns ) + '/**/*.md' ,
163
- resolvePath ( paths ( ) . source . data ) + '/*.json' ,
164
- resolvePath ( paths ( ) . source . fonts ) + '/*' ,
165
- resolvePath ( paths ( ) . source . images ) + '/*' ,
166
- resolvePath ( paths ( ) . source . meta ) + '/*' ,
167
- resolvePath ( paths ( ) . source . annotations ) + '/*'
168
- ] . concat ( getTemplateWatches ( ) ) ;
169
-
170
- console . log ( patternWatches ) ;
171
-
172
- gulp . watch ( patternWatches , { awaitWriteFinish : true } ) . on ( 'change' , gulp . series ( build , reload ) ) ;
191
+ const watchers = [
192
+ {
193
+ name : 'CSS' ,
194
+ paths : [ normalizePath ( paths ( ) . source . css , '**' , '*.css' ) ] ,
195
+ config : { awaitWriteFinish : true } ,
196
+ tasks : gulp . series ( 'pl-copy:css' , reloadCSS )
197
+ } ,
198
+ {
199
+ name : 'Styleguide Files' ,
200
+ paths : [ normalizePath ( paths ( ) . source . styleguide , '**' , '*' ) ] ,
201
+ config : { awaitWriteFinish : true } ,
202
+ tasks : gulp . series ( 'pl-copy:styleguide' , 'pl-copy:styleguide-css' , reloadCSS )
203
+ } ,
204
+ {
205
+ name : 'Source Files' ,
206
+ paths : [
207
+ normalizePath ( paths ( ) . source . patterns , '**' , '*.json' ) ,
208
+ normalizePath ( paths ( ) . source . patterns , '**' , '*.md' ) ,
209
+ normalizePath ( paths ( ) . source . data , '**' , '*.json' ) ,
210
+ normalizePath ( paths ( ) . source . fonts , '**' , '*' ) ,
211
+ normalizePath ( paths ( ) . source . images , '**' , '*' ) ,
212
+ normalizePath ( paths ( ) . source . js , '**' , '*' ) ,
213
+ normalizePath ( paths ( ) . source . meta , '**' , '*' ) ,
214
+ normalizePath ( paths ( ) . source . annotations , '**' , '*' )
215
+ ] . concat ( getTemplateWatches ( ) ) ,
216
+ config : { awaitWriteFinish : true } ,
217
+ tasks : gulp . series ( build , reload )
218
+ }
219
+ ] ;
220
+
221
+ watchers . forEach ( watcher => {
222
+ console . log ( '\n' + chalk . bold ( 'Watching ' + watcher . name + ':' ) ) ;
223
+ watcher . paths . forEach ( p => console . log ( ' ' + p ) ) ;
224
+ gulp . watch ( watcher . paths , watcher . config , watcher . tasks ) ;
225
+ } ) ;
226
+ console . log ( ) ;
173
227
}
174
228
175
- gulp . task ( 'patternlab:connect' , gulp . series ( function ( done ) {
229
+ gulp . task ( 'patternlab:connect' , gulp . series ( function ( done ) {
176
230
browserSync . init ( {
177
231
server : {
178
- baseDir : resolvePath ( paths ( ) . public . root )
232
+ baseDir : normalizePath ( paths ( ) . public . root )
179
233
} ,
180
234
snippetOptions : {
181
235
// Ignore all HTML files within the templates folder
@@ -199,8 +253,7 @@ gulp.task('patternlab:connect', gulp.series(function(done) {
199
253
'text-align: center'
200
254
]
201
255
}
202
- } , function ( ) {
203
- console . log ( 'PATTERN LAB NODE WATCHING FOR CHANGES' ) ;
256
+ } , function ( ) {
204
257
done ( ) ;
205
258
} ) ;
206
259
} ) ) ;
0 commit comments