autofront 2.2.3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -81
- package/index.js +426 -118
- package/package.json +40 -48
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Autofront
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Automation of front-end by [Gulp](https://gulpjs.com) and [Bower](https://bower.io).
|
|
4
4
|
|
|
5
5
|
## Get started
|
|
6
6
|
|
|
7
7
|
### Gulp
|
|
8
8
|
|
|
9
|
-
Install its CLI
|
|
9
|
+
Install its CLI (following [the official manual](https://gulpjs.com/docs/en/getting-started/quick-start/) but skipping [the local package](https://gulpjs.com/docs/en/getting-started/quick-start/#install-the-gulp-package-in-your-devdependencies) and the next steps).
|
|
10
10
|
|
|
11
11
|
And put `gulpfile.js` simply with:
|
|
12
12
|
|
|
@@ -18,112 +18,86 @@ require('autofront');
|
|
|
18
18
|
|
|
19
19
|
[Install it](https://bower.io/#install-bower), [initialize it and save dependencies](https://bower.io/#save-packages).
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### Installation
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
24
|
npm install --save-dev autofront
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
###
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```html
|
|
32
|
-
<!DOCTYPE html>
|
|
33
|
-
<html>
|
|
34
|
-
<head>
|
|
35
|
-
<!-- build:css styles/vendor.css -->
|
|
36
|
-
<!-- bower:css --><!-- endbower -->
|
|
37
|
-
<!-- endbuild -->
|
|
38
|
-
</head>
|
|
39
|
-
<body>
|
|
40
|
-
<!-- build:js scripts/vendor.js -->
|
|
41
|
-
<!-- bower:js --><!-- endbower -->
|
|
42
|
-
<!-- endbuild -->
|
|
43
|
-
<!-- build:js scripts/app.js -->
|
|
44
|
-
<!-- inject:js -->
|
|
45
|
-
<!-- endinject -->
|
|
46
|
-
<!-- endbuild -->
|
|
47
|
-
</body>
|
|
48
|
-
</html>
|
|
49
|
-
```
|
|
27
|
+
### Source code
|
|
28
|
+
|
|
29
|
+
Place inside directory `src`; at least including the main page (`index.html`), without embedding tags (`<link>`s and `<script>`s).
|
|
50
30
|
|
|
51
31
|
### Run
|
|
52
32
|
|
|
53
|
-
Finally initiate
|
|
33
|
+
Finally, initiate the project, commanding:
|
|
54
34
|
|
|
55
35
|
```sh
|
|
56
36
|
gulp
|
|
57
37
|
```
|
|
58
38
|
|
|
59
|
-
A browser tab
|
|
39
|
+
A browser tab is opened. Now you are ready to develop!
|
|
60
40
|
|
|
61
|
-
|
|
41
|
+
To reach further, see below.
|
|
62
42
|
|
|
63
43
|
## Usage
|
|
64
44
|
|
|
65
45
|
### Tasks
|
|
66
46
|
|
|
67
|
-
The Gulp ones are
|
|
68
|
-
|
|
69
|
-
- `gulp` or `gulp serve` are for running a test server and develop with live reload.
|
|
70
|
-
- `gulp build` only builds production code, the distributable application (`dist` folder).
|
|
71
|
-
- With `gulp serve:dist`, a combination of the above is achieved: Specifically, the server runs that last version but without reload.
|
|
72
|
-
|
|
73
|
-
### Domains
|
|
74
|
-
|
|
75
|
-
On executing Gulp command, an additional parameter can be included (e.g.: `gulp --dev` or `gulp build --pro`) to indicate the domain of connection path. Defaults to `--local`.
|
|
76
|
-
|
|
77
|
-
These domain URLs would be searched in `package.json` listed in the property `domains` (optionally also `domainAliases`, to assign domain name for each alias).
|
|
78
|
-
|
|
79
|
-
And, to capture the selected URL string, put `{{AUTOFRONT_DOMAIN}}` where it would be located in your source code.
|
|
80
|
-
|
|
81
|
-
## Support
|
|
82
|
-
|
|
83
|
-
Positioning in source folder (`src`), you can utilize:
|
|
84
|
-
|
|
85
|
-
### HTML
|
|
86
|
-
|
|
87
|
-
Besides of required `index.html`, it is possible to add more files. In this case, they will be treated as [templates](https://docs.angularjs.org/api/ng/directive/ngInclude) and, to work properly with `dist`, AngularJS must to be [appropriately](#angularjs) on.
|
|
47
|
+
The Gulp ones are:
|
|
88
48
|
|
|
89
|
-
|
|
49
|
+
| Name | Details | Processes |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| `serve` (default) | Source code runs in a server with live reload. | <ul><li>Bower entry-point files catching.</li><li>Notification and injection of [environment](#environment-variables).</li><li>Compilation (Less, SCSS and Pug)[^1].</li><li>Set up[^2] of HTML5 mode.[^1]</li><li>Insertion of file with app info (`about.json`).</li></ul> |
|
|
52
|
+
| `build` | Production code is built (in folder `dist`). | The above and: <ul><li>Templates caching.[^1]</li><li>Concatenation to one hashed file (CSS and JS).</li><li>Minification (HTML, CSS, JS, images and JSON).</li><li>Console display of files size.</li></ul> |
|
|
53
|
+
| `serve:dist` | This distributable application is served but without the refreshing. | The same with the folder hidden. |
|
|
90
54
|
|
|
91
|
-
|
|
55
|
+
[^1]: [If it is on](#settings).
|
|
56
|
+
[^2]: Invocation of [`$locationProvider`](https://docs.angularjs.org/api/ng/provider/$locationProvider#html5Mode) and a `<base>` injected.
|
|
92
57
|
|
|
93
|
-
###
|
|
58
|
+
### Environment variables
|
|
94
59
|
|
|
95
|
-
|
|
60
|
+
They can be used in this way:
|
|
96
61
|
|
|
97
|
-
|
|
62
|
+
1. Define them. Look at [the next section](#settings).
|
|
63
|
+
2. Put `AUTOFRONT_ENV` in your JS source code where it would be injected.
|
|
64
|
+
3. On executing Gulp command, indicate the name of the current one to the flag argument `env`. Defaults to "development" with server tasks and to "production" with `build`.
|
|
98
65
|
|
|
99
|
-
|
|
66
|
+
## Settings
|
|
100
67
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
Idem, but it is also obligatory an extra jointly: `_variables.scss`.
|
|
104
|
-
|
|
105
|
-
### JavaScript
|
|
106
|
-
|
|
107
|
-
Wherever you want.
|
|
108
|
-
|
|
109
|
-
#### [AngularJS](https://angularjs.org)
|
|
110
|
-
|
|
111
|
-
One of modules should to be named "app", ideally the main one.
|
|
112
|
-
|
|
113
|
-
Optionally, to work with [HTML5 mode](https://docs.angularjs.org/api/ng/provider/$locationProvider#html5Mode), invoke it:
|
|
68
|
+
You can configure it typing into Gulp file like this:
|
|
114
69
|
|
|
115
70
|
```js
|
|
116
|
-
|
|
117
|
-
|
|
71
|
+
const autofront = require('autofront');
|
|
72
|
+
|
|
73
|
+
autofront.property = {
|
|
74
|
+
subproperty: value,
|
|
75
|
+
subproperty2: {
|
|
76
|
+
subproperty3: value2,
|
|
77
|
+
// ...
|
|
78
|
+
},
|
|
79
|
+
// ...
|
|
80
|
+
};
|
|
81
|
+
autofront.property2.subproperty4 = value3;
|
|
82
|
+
// ...
|
|
118
83
|
```
|
|
119
84
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
85
|
+
Defining with:
|
|
86
|
+
|
|
87
|
+
| Property | Subprop. | | Type | Details | Default |
|
|
88
|
+
| --- | --- | --- | --- | --- | --- |
|
|
89
|
+
| `html` | `pug` | | Boolean | [Pug](https://pugjs.org) activated? | `false` |
|
|
90
|
+
| `css` | `folder` | | String | Directory that contains CSS files. | `'styles/'` |
|
|
91
|
+
| <!-- 〃 --> | `filename` | | String | Filename of root files. | `'index'` |
|
|
92
|
+
| <!-- 〃 --> | `order` | | Number | Index of order to include content in stylesheet. | `0` |
|
|
93
|
+
| <!-- 〃 --> | `less`[^3] | `order` | Number | Idem for [Less](https://lesscss.org). | `1` |
|
|
94
|
+
| <!-- 〃 --> | `scss`[^3] | `order` | Number | Idem for [SCSS (Sass)](https://sass-lang.com/documentation/syntax#scss). | `2` |
|
|
95
|
+
| <!-- 〃 --> | <!-- 〃 --> | `variables` | String | Filename of variables file. | `_variables` |
|
|
96
|
+
| <!-- 〃 --> | `fonts` | `folder` | String | Location (folder path) of font files from Bower. | `'fonts/'` |
|
|
97
|
+
| <!-- 〃 --> | <!-- 〃 --> | `extensions` | String or array of strings | File extensions to catch. | `['eot', 'otf', 'svg', 'ttf', 'woff', 'woff2']` |
|
|
98
|
+
| `js` | `ng`[^3] | `module` | String | Name of [AngularJS](https://angularjs.org) main module. | `'app'` |
|
|
99
|
+
| <!-- 〃 --> | <!-- 〃 --> | `html5Mode` | Boolean | [HTML5 mode](https://docs.angularjs.org/guide/$location#html5-mode) enabled? | `false` |
|
|
100
|
+
| <!-- 〃 --> | <!-- 〃 --> | `template` | Boolean | Templates loaded by [`$templateCache`](https://docs.angularjs.org/api/ng/service/$templateCache)? | `true` |
|
|
101
|
+
| <!-- 〃 --> | `envs` | | Object | Environment variables list, with names as keys and data (whatever can be JSON parsed) as values. | `{}` |
|
|
102
|
+
|
|
103
|
+
[^3]: It can be disabled assigning a falsy value.
|
package/index.js
CHANGED
|
@@ -1,123 +1,254 @@
|
|
|
1
|
-
|
|
1
|
+
const defSettings = {
|
|
2
|
+
html: { pug: false },
|
|
3
|
+
css: {
|
|
4
|
+
folder: 'styles/',
|
|
5
|
+
filename: 'index',
|
|
6
|
+
order: 0,
|
|
7
|
+
less: { order: 1 },
|
|
8
|
+
scss: {
|
|
9
|
+
order: 2,
|
|
10
|
+
variables: '_variables'
|
|
11
|
+
},
|
|
12
|
+
fonts: {
|
|
13
|
+
folder: 'fonts/',
|
|
14
|
+
extensions: ['eot', 'otf', 'svg', 'ttf', 'woff', 'woff2']
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
js: {
|
|
18
|
+
ng: {
|
|
19
|
+
module: 'app',
|
|
20
|
+
html5Mode: false,
|
|
21
|
+
template: true
|
|
22
|
+
},
|
|
23
|
+
envs: {}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const settings = this;
|
|
27
|
+
for (const name in defSettings)
|
|
28
|
+
settings[name] = { ...defSettings[name] };
|
|
2
29
|
|
|
3
30
|
const gulp = require('gulp'),
|
|
4
|
-
path = require('path'),
|
|
5
|
-
args = require('get-gulp-args')(),
|
|
6
|
-
mergeStream = require('merge-stream'),
|
|
7
|
-
mainBowerFiles = require('main-bower-files'),
|
|
8
31
|
$ = require('gulp-load-plugins')(),
|
|
9
|
-
injStr = $.injectString,
|
|
10
|
-
gulpSass = $.sass(require('sass')),
|
|
11
32
|
notifyError = $.notify.onError(error => error.message),
|
|
33
|
+
gulpFilter = ext => $.filter(getGlob(ext), { restore: true }),
|
|
12
34
|
browserSync = require('browser-sync').create(),
|
|
13
|
-
deleteEmpty = require('delete-empty')
|
|
35
|
+
deleteEmpty = require('delete-empty'),
|
|
36
|
+
gulpHtmlmin = () => $.htmlmin({ collapseWhitespace: true, conservativeCollapse: true }),
|
|
37
|
+
fs = require('fs'),
|
|
38
|
+
hidefile = require('hidefile');
|
|
14
39
|
|
|
15
|
-
let
|
|
40
|
+
let defEnv = 'production',
|
|
41
|
+
envName,
|
|
42
|
+
envValue;
|
|
16
43
|
|
|
17
44
|
const allFiles = getGlob(),
|
|
18
|
-
|
|
45
|
+
indexFile = 'index.html',
|
|
46
|
+
scriptsDir = 'scripts/',
|
|
19
47
|
jsFiles = getGlob('js'),
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
48
|
+
cssComment = '<!-- autofrontcss -->',
|
|
49
|
+
endCssComment = '<!-- endautofrontcss -->',
|
|
50
|
+
jsComment = '<!-- autofrontjs -->',
|
|
51
|
+
html5ModeJsFile = scriptsDir + 'html5-mode.js',
|
|
52
|
+
jsTemplatesFile = scriptsDir + 'templates.js',
|
|
53
|
+
endJsComment = '<!-- endautofrontjs -->',
|
|
54
|
+
cssFile = 'index.css',
|
|
55
|
+
jsFile = 'index.js';
|
|
56
|
+
let stylesDir,
|
|
57
|
+
stylesFilename,
|
|
58
|
+
cssExtensions = [];
|
|
24
59
|
|
|
25
60
|
const globs = {
|
|
26
61
|
src: 'src/',
|
|
27
62
|
tmp: '.tmp/',
|
|
28
63
|
dist: 'dist/'
|
|
29
64
|
};
|
|
30
|
-
globs.
|
|
65
|
+
globs.hiddenDist = '.' + globs.dist;
|
|
66
|
+
globs.srcIndex = globs.src + indexFile;
|
|
31
67
|
globs.srcJs = globs.src + jsFiles;
|
|
32
|
-
globs.
|
|
33
|
-
globs.srcStyles = [globs.src + stylesDir + cssFile, globs.src + getGlob('less'), globs.src + getGlob('scss')];
|
|
34
|
-
globs.srcOthers = [globs.src + allFiles, ...[...globs.srcIndexAndSrcJs, ...globs.srcStyles].map(glob => '!' + glob)];
|
|
68
|
+
globs.srcOthers = [globs.src + allFiles];
|
|
35
69
|
globs.tmpAllFiles = globs.tmp + allFiles;
|
|
70
|
+
globs.distIndexFile = globs.dist + indexFile;
|
|
71
|
+
globs.distTmpls = [globs.dist + getGlob('html'), '!' + globs.distIndexFile];
|
|
36
72
|
|
|
37
|
-
const nl = '\n',
|
|
73
|
+
const nl = '\r\n',
|
|
38
74
|
tab = ' ';
|
|
39
75
|
|
|
40
|
-
function
|
|
41
|
-
|
|
76
|
+
function setDefaultEnv(cb) {
|
|
77
|
+
defEnv = 'development';
|
|
78
|
+
cb();
|
|
42
79
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
setDefaultEnv.displayName = 'set-default-env';
|
|
81
|
+
|
|
82
|
+
function setVariables(cb) {
|
|
83
|
+
stylesDir = getSetting('cssFolder');
|
|
84
|
+
stylesFilename = getSetting('filename');
|
|
85
|
+
|
|
86
|
+
for (const cssExt of [
|
|
87
|
+
{
|
|
88
|
+
name: 'css',
|
|
89
|
+
process: $.cssimport
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'less',
|
|
93
|
+
process: $.less,
|
|
94
|
+
isPreprocessor: true
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'scss',
|
|
98
|
+
process: $.sass(require('sass')),
|
|
99
|
+
getExtraCode: () => {
|
|
100
|
+
const file = globs.src + stylesDir + getSetting('variables') + '.scss';
|
|
101
|
+
return fileExists(file) ? `@import "${file}";` : '';
|
|
102
|
+
},
|
|
103
|
+
isPreprocessor: true
|
|
54
104
|
}
|
|
55
|
-
|
|
105
|
+
]) {
|
|
106
|
+
const name = cssExt.name;
|
|
107
|
+
if (!cssExt.isPreprocessor || getSetting(name))
|
|
108
|
+
cssExtensions.push({ getExtraCode: () => '', ...cssExt, order: getSetting(name + 'Order') });
|
|
109
|
+
}
|
|
110
|
+
cssExtensions = cssExtensions.sort((a, b) => a.order - b.order);
|
|
111
|
+
|
|
112
|
+
const srcStyles = [];
|
|
113
|
+
for (const cssExt of cssExtensions) {
|
|
114
|
+
const glob = globs.src + getGlob(cssExt.name);
|
|
115
|
+
srcStyles.push(glob);
|
|
116
|
+
cssExt.glob = glob;
|
|
56
117
|
}
|
|
57
|
-
|
|
118
|
+
globs.srcOthers.push(...[globs.srcIndex, globs.srcJs, ...srcStyles].map(glob => '!' + glob));
|
|
119
|
+
|
|
120
|
+
cb();
|
|
121
|
+
}
|
|
122
|
+
setVariables.displayName = 'set-variables';
|
|
123
|
+
|
|
124
|
+
function getEnv() {
|
|
125
|
+
envName = require('get-gulp-args')().env || defEnv;
|
|
126
|
+
envValue = getSetting('envs')[envName];
|
|
127
|
+
const isMatched = envValue !== undefined;
|
|
58
128
|
return gulp.src(globs.src, { read: false })
|
|
59
|
-
.pipe($.notify(isMatched ? `Matching
|
|
129
|
+
.pipe($.notify(isMatched ? `Matching environment: "${envName}".` : 'No environment matched.'));
|
|
130
|
+
}
|
|
131
|
+
getEnv.displayName = 'get-env';
|
|
132
|
+
|
|
133
|
+
function removeFolder() {
|
|
134
|
+
return delDir(globs.tmp);
|
|
60
135
|
}
|
|
61
|
-
|
|
136
|
+
removeFolder.displayName = 'remove-folder';
|
|
62
137
|
|
|
63
|
-
function
|
|
64
|
-
return gulp.src(
|
|
65
|
-
.pipe(
|
|
66
|
-
|
|
138
|
+
function createFolder() {
|
|
139
|
+
return gulp.src('*.*', { read: false })
|
|
140
|
+
.pipe(gulp.dest(globs.tmp));
|
|
141
|
+
}
|
|
142
|
+
createFolder.displayName = 'create-folder';
|
|
143
|
+
|
|
144
|
+
function hideFolder(cb) {
|
|
145
|
+
hideDir(globs.tmp);
|
|
146
|
+
cb();
|
|
147
|
+
}
|
|
148
|
+
hideFolder.displayName = 'hide-folder';
|
|
149
|
+
|
|
150
|
+
const addFolder = gulp.series(createFolder, hideFolder);
|
|
151
|
+
|
|
152
|
+
function index() {
|
|
153
|
+
const filename = 'vendor',
|
|
154
|
+
strs = [
|
|
155
|
+
cssComment,
|
|
156
|
+
`<!-- build:css ${stylesDir + filename}.css -->`,
|
|
157
|
+
'<!-- bower:css --><!-- endbower -->',
|
|
158
|
+
'<!-- endbuild -->'
|
|
159
|
+
];
|
|
160
|
+
for (const { name } of cssExtensions)
|
|
161
|
+
strs.push('<link rel="stylesheet" href="' + stylesDir + stylesFilename + (name != 'css' ? '.' + name : '') + '.css' + '">');
|
|
162
|
+
strs.push(
|
|
163
|
+
endCssComment,
|
|
164
|
+
jsComment,
|
|
165
|
+
`<!-- build:js ${scriptsDir + filename}.js defer -->`,
|
|
166
|
+
'<!-- bower:js --><!-- endbower -->',
|
|
167
|
+
'<!-- endbuild -->',
|
|
168
|
+
'<!-- inject:js -->',
|
|
169
|
+
'<!-- endinject -->'
|
|
170
|
+
);
|
|
171
|
+
if (getSetting('html5Mode')) {
|
|
172
|
+
strs.unshift('<base href="/">');
|
|
173
|
+
strs.push(getScriptTag(html5ModeJsFile));
|
|
174
|
+
}
|
|
175
|
+
strs.push(endJsComment);
|
|
176
|
+
|
|
177
|
+
let stream = gulp.src(globs.srcJs);
|
|
178
|
+
if (getSetting('ng'))
|
|
179
|
+
stream = stream.pipe($.angularFilesort());
|
|
180
|
+
|
|
181
|
+
return gulp.src(globs.srcIndex)
|
|
182
|
+
.pipe($.injectString.before('</head>', tab + strs.join(nl + tab) + nl))
|
|
183
|
+
.pipe($.inject(stream, { relative: true, transform: filepath => getScriptTag(filepath) })).on('error', notifyError)
|
|
67
184
|
.pipe($.wiredep())
|
|
68
185
|
.pipe($.useref())
|
|
69
186
|
.pipe(gulp.dest(globs.tmp));
|
|
70
187
|
}
|
|
71
|
-
buildIndex.displayName = 'build-index';
|
|
72
188
|
|
|
73
|
-
function
|
|
74
|
-
return gulp.src(globs.
|
|
75
|
-
.pipe(
|
|
189
|
+
function js() {
|
|
190
|
+
return gulp.src(globs.srcJs)
|
|
191
|
+
.pipe(replace('AUTOFRONT_ENV', JSON.stringify(envValue, undefined, tab)))
|
|
76
192
|
.pipe(gulp.dest(globs.tmp));
|
|
77
193
|
}
|
|
78
|
-
injectDomain.displayName = 'inject-domain';
|
|
79
194
|
|
|
80
|
-
const indexAndJs = gulp.
|
|
195
|
+
const indexAndJs = gulp.parallel(index, js);
|
|
81
196
|
|
|
82
|
-
|
|
83
|
-
return mergeStream(getStream('css'), getStream('less', $.less), getStream('scss', gulpSass, '@import "variables";'))
|
|
84
|
-
.pipe($.concat(cssFile))
|
|
85
|
-
.pipe(gulp.dest(globs.tmp + stylesDir))
|
|
86
|
-
.pipe(browserSync.stream());
|
|
197
|
+
const css = getStylesTask('css');
|
|
87
198
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
199
|
+
const less = getStylesTask('less');
|
|
200
|
+
|
|
201
|
+
const scss = getStylesTask('scss');
|
|
202
|
+
|
|
203
|
+
const styles = gulp.parallel(css, less, scss);
|
|
204
|
+
|
|
205
|
+
function html5Mode(cb) {
|
|
206
|
+
if (getSetting('html5Mode'))
|
|
207
|
+
return $.addFiles([{
|
|
208
|
+
name: html5ModeJsFile,
|
|
209
|
+
content: `(function () {
|
|
210
|
+
angular.module('${getSetting('module')}')
|
|
211
|
+
.config(config);
|
|
212
|
+
|
|
213
|
+
function config($locationProvider) {
|
|
214
|
+
$locationProvider.html5Mode(true);
|
|
96
215
|
}
|
|
216
|
+
})();`
|
|
217
|
+
}])
|
|
218
|
+
.pipe(gulp.dest(globs.tmp));
|
|
219
|
+
|
|
220
|
+
cb();
|
|
97
221
|
}
|
|
222
|
+
html5Mode.displayName = 'html5-mode';
|
|
98
223
|
|
|
99
|
-
function fonts() {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
224
|
+
function fonts(cb) {
|
|
225
|
+
const glob = require('main-bower-files')(getGlob(getSetting('extensions')));
|
|
226
|
+
if (glob.length)
|
|
227
|
+
return gulp.src(glob)
|
|
228
|
+
.pipe(gulp.dest(globs.tmp + getSetting('fontsFolder')));
|
|
229
|
+
|
|
230
|
+
cb();
|
|
103
231
|
}
|
|
104
232
|
|
|
105
233
|
function others() {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.pipe(
|
|
234
|
+
let stream = gulp.src(globs.srcOthers);
|
|
235
|
+
if (getSetting('pug')) {
|
|
236
|
+
const pugFilter = gulpFilter('pug');
|
|
237
|
+
stream = stream.pipe(pugFilter).pipe($.pug()).on('error', notifyError).pipe(pugFilter.restore);
|
|
238
|
+
}
|
|
239
|
+
return stream.pipe(gulp.dest(globs.tmp));
|
|
110
240
|
}
|
|
111
241
|
|
|
112
242
|
function about() {
|
|
113
243
|
return gulp.src('package.json')
|
|
114
|
-
.pipe($.about())
|
|
244
|
+
.pipe($.about({ inject: { environment: envName } }))
|
|
115
245
|
.pipe(gulp.dest(globs.tmp));
|
|
116
246
|
}
|
|
117
247
|
|
|
118
248
|
const buildTmp = gulp.series(
|
|
119
|
-
gulp.parallel(
|
|
120
|
-
|
|
249
|
+
gulp.parallel(getEnv, removeFolder),
|
|
250
|
+
addFolder,
|
|
251
|
+
gulp.parallel(indexAndJs, styles, html5Mode, fonts, others, about)
|
|
121
252
|
);
|
|
122
253
|
|
|
123
254
|
function browser(cb) {
|
|
@@ -125,89 +256,218 @@ function browser(cb) {
|
|
|
125
256
|
cb();
|
|
126
257
|
}
|
|
127
258
|
|
|
259
|
+
function reload(cb) {
|
|
260
|
+
browserSync.reload();
|
|
261
|
+
cb();
|
|
262
|
+
}
|
|
263
|
+
|
|
128
264
|
function watch() {
|
|
129
|
-
gulp.watch(globs.
|
|
130
|
-
gulp.watch(globs.
|
|
131
|
-
|
|
132
|
-
|
|
265
|
+
gulp.watch(globs.srcIndex, index);
|
|
266
|
+
gulp.watch(globs.srcJs)
|
|
267
|
+
.on('add', indexAndJs)
|
|
268
|
+
.on('change', gulp.series(js))
|
|
269
|
+
.on('unlink', gulp.series(index))
|
|
270
|
+
.on('unlink', path => { delFile(path); });
|
|
271
|
+
|
|
272
|
+
for (cssExt of cssExtensions)
|
|
273
|
+
gulp.watch(cssExt.glob, eval(cssExt.name));
|
|
274
|
+
|
|
275
|
+
gulp.watch(globs.srcOthers)
|
|
276
|
+
.on('add', gulp.series(others))
|
|
277
|
+
.on('change', gulp.series(others))
|
|
278
|
+
.on('unlink', path => { delFile(path, replaceExt); });
|
|
279
|
+
|
|
280
|
+
gulp.watch([globs.tmpAllFiles, '!' + globs.tmp + stylesDir + getGlob('css')], reload).on('unlink', () => { deleteEmpty(globs.tmp); });
|
|
281
|
+
|
|
282
|
+
function delFile(path, fn) {
|
|
283
|
+
path = path.replaceAll('\\', '/').replace(globs.src, globs.tmp);
|
|
284
|
+
if (fn)
|
|
285
|
+
path = fn(path);
|
|
286
|
+
gulp.src(path, { read: false })
|
|
133
287
|
.pipe($.clean());
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function replaceExt(path) {
|
|
291
|
+
if (getSetting('pug'))
|
|
292
|
+
return path.replace('.pug', '.html');
|
|
293
|
+
return path;
|
|
294
|
+
}
|
|
140
295
|
}
|
|
141
296
|
|
|
142
|
-
gulp.task('serve', gulp.series(
|
|
297
|
+
gulp.task('serve', gulp.series(
|
|
298
|
+
gulp.parallel(setDefaultEnv, setVariables),
|
|
299
|
+
buildTmp, browser, watch
|
|
300
|
+
));
|
|
143
301
|
|
|
144
|
-
function
|
|
145
|
-
return delDir(globs.dist);
|
|
302
|
+
function removeFolderDist() {
|
|
303
|
+
return delDir([globs.dist, globs.hiddenDist]);
|
|
146
304
|
}
|
|
147
|
-
|
|
305
|
+
removeFolderDist.displayName = 'remove-folder:dist';
|
|
148
306
|
|
|
149
307
|
function copy() {
|
|
150
308
|
return gulp.src(globs.tmpAllFiles)
|
|
309
|
+
.pipe($.size())
|
|
151
310
|
.pipe(gulp.dest(globs.dist));
|
|
152
311
|
}
|
|
153
312
|
|
|
154
|
-
function
|
|
155
|
-
|
|
156
|
-
.pipe(
|
|
157
|
-
|
|
158
|
-
.pipe($.angularTemplatecache(jsTemplatesFile, { module: '
|
|
313
|
+
function templates() {
|
|
314
|
+
let stream = gulp.src(globs.distTmpls)
|
|
315
|
+
.pipe(gulpHtmlmin());
|
|
316
|
+
if (getSetting('template'))
|
|
317
|
+
stream = stream.pipe($.angularTemplatecache(jsTemplatesFile, { module: getSetting('module'), transformUrl: url => url.slice(1) }));
|
|
318
|
+
return stream.pipe(gulp.dest(globs.dist));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function indexDist() {
|
|
322
|
+
const replaces = Object.entries({
|
|
323
|
+
[cssComment]: `<!-- build:css ${cssFile} -->`,
|
|
324
|
+
[endCssComment]: '<!-- endbuild -->',
|
|
325
|
+
[jsComment]: `<!-- build:js ${jsFile} defer -->`,
|
|
326
|
+
[endJsComment]: '<!-- endbuild -->'
|
|
327
|
+
});
|
|
328
|
+
let stream = gulp.src(globs.distIndexFile);
|
|
329
|
+
if (getSetting('template') && fileExists(globs.dist + jsTemplatesFile))
|
|
330
|
+
stream = stream.pipe($.injectString.before(endJsComment, getScriptTag(jsTemplatesFile) + nl + tab));
|
|
331
|
+
for (const [search, str] of replaces)
|
|
332
|
+
stream = stream.pipe($.injectString.replace(search, str));
|
|
333
|
+
return stream
|
|
334
|
+
.pipe($.useref())
|
|
159
335
|
.pipe(gulp.dest(globs.dist));
|
|
160
336
|
}
|
|
161
|
-
|
|
337
|
+
indexDist.displayName = 'index:dist';
|
|
338
|
+
|
|
339
|
+
function rebase() {
|
|
340
|
+
const str = 'url(',
|
|
341
|
+
quotes = ["'", '"'];
|
|
342
|
+
let stream = gulp.src(globs.dist + cssFile)
|
|
343
|
+
.pipe(replace(str + '\\s*', str));
|
|
344
|
+
for (char of ['', ...quotes])
|
|
345
|
+
for (str2 of ['http://', 'https://', '//', '/', 'data:', '#'])
|
|
346
|
+
stream = stream.pipe(replace(str + char + str2, str + tab + char + str2));
|
|
347
|
+
stream = stream
|
|
348
|
+
.pipe(replace(str, str + stylesDir))
|
|
349
|
+
.pipe(replace(str + stylesDir + tab, str));
|
|
350
|
+
for (quote of quotes)
|
|
351
|
+
stream = stream.pipe(replace(str + stylesDir + quote, str + quote + stylesDir));
|
|
352
|
+
return stream.pipe(gulp.dest(globs.dist));
|
|
353
|
+
}
|
|
162
354
|
|
|
163
|
-
function
|
|
355
|
+
function cleanFiles() {
|
|
356
|
+
return gulp.src([
|
|
357
|
+
...(getSetting('template') ? globs.distTmpls : []),
|
|
358
|
+
globs.dist + getGlob('css'), '!' + globs.dist + cssFile,
|
|
359
|
+
globs.dist + jsFiles, '!' + globs.dist + jsFile
|
|
360
|
+
], { read: false })
|
|
361
|
+
.pipe($.clean());
|
|
362
|
+
}
|
|
363
|
+
cleanFiles.displayName = 'clean-files';
|
|
364
|
+
|
|
365
|
+
function cleanFolders() {
|
|
164
366
|
return deleteEmpty(globs.dist);
|
|
165
367
|
}
|
|
166
|
-
|
|
368
|
+
cleanFolders.displayName = 'clean-folders';
|
|
369
|
+
|
|
370
|
+
const clean = gulp.series(cleanFiles, cleanFolders);
|
|
371
|
+
|
|
372
|
+
const rebaseAndClean = gulp.parallel(rebase, clean);
|
|
373
|
+
|
|
374
|
+
const minify = gulp.parallel(
|
|
375
|
+
getMinifyTask('html', stream => stream.pipe(gulpHtmlmin())),
|
|
376
|
+
getMinifyTask('css', stream => stream.pipe($.postcss([require('cssnano')()]))),
|
|
377
|
+
getMinifyTask('js', stream => {
|
|
378
|
+
if (getSetting('ng'))
|
|
379
|
+
stream = stream.pipe($.ngAnnotate());
|
|
380
|
+
return stream.pipe($.terser());
|
|
381
|
+
}),
|
|
382
|
+
getMinifyTask(['png', 'jpg', 'gif', 'svg'], stream => stream.pipe($.imagemin()), 'img'),
|
|
383
|
+
getMinifyTask('json', stream => stream.pipe($.jsonmin()))
|
|
384
|
+
);
|
|
167
385
|
|
|
168
386
|
function finishBuild() {
|
|
169
|
-
const
|
|
170
|
-
cssFilter = filter('css'),
|
|
171
|
-
jsFilter = filter('js'),
|
|
172
|
-
cssAndJsFilter = filter(['css', 'js']),
|
|
173
|
-
imgFilter = filter(['png', 'jpg', 'gif', 'svg']),
|
|
174
|
-
jsonFilter = filter('json');
|
|
387
|
+
const cssAndJsFilter = gulpFilter(['css', 'js']);
|
|
175
388
|
return gulp.src(globs.dist + allFiles)
|
|
176
|
-
.pipe(indexHtmlFilter).pipe(injStr.before('</body>', `<script src="${jsTemplatesFile}"></script>` + nl)).pipe(minifyHtml()).pipe(indexHtmlFilter.restore)
|
|
177
|
-
.pipe(cssFilter).pipe($.cssnano({ zindex: false })).pipe(cssFilter.restore)
|
|
178
|
-
.pipe(jsFilter).pipe($.ngAnnotate()).pipe($.terser()).pipe(jsFilter.restore)
|
|
179
389
|
.pipe(cssAndJsFilter).pipe($.rev()).pipe($.revDeleteOriginal()).pipe(cssAndJsFilter.restore)
|
|
180
390
|
.pipe($.revReplace())
|
|
181
|
-
.pipe(imgFilter).pipe($.imagemin()).pipe(imgFilter.restore)
|
|
182
|
-
.pipe(jsonFilter).pipe($.jsonmin()).pipe(jsonFilter.restore)
|
|
183
391
|
.pipe($.size({ showFiles: true }))
|
|
184
392
|
.pipe(gulp.dest(globs.dist));
|
|
185
393
|
}
|
|
186
394
|
finishBuild.displayName = 'finish-build';
|
|
187
395
|
|
|
188
|
-
gulp.task('build', gulp.series(
|
|
396
|
+
gulp.task('build', gulp.series(
|
|
397
|
+
setVariables,
|
|
398
|
+
gulp.parallel(buildTmp, removeFolderDist),
|
|
399
|
+
copy, templates, indexDist, rebaseAndClean, minify, finishBuild
|
|
400
|
+
));
|
|
401
|
+
|
|
402
|
+
function hideFolderDist(cb) {
|
|
403
|
+
hideDir(globs.dist);
|
|
404
|
+
cb();
|
|
405
|
+
}
|
|
406
|
+
hideFolderDist.displayName = 'hide-folder:dist';
|
|
189
407
|
|
|
190
408
|
function browserDist(cb) {
|
|
191
|
-
browserSyncInit(globs.
|
|
409
|
+
browserSyncInit(globs.hiddenDist);
|
|
192
410
|
cb();
|
|
193
411
|
}
|
|
194
412
|
browserDist.displayName = 'browser:dist';
|
|
195
413
|
|
|
196
|
-
gulp.task('serve:dist', gulp.series('build', browserDist));
|
|
197
|
-
|
|
198
|
-
gulp.task('default', gulp.task('serve'));
|
|
414
|
+
gulp.task('serve:dist', gulp.series(setDefaultEnv, 'build', hideFolderDist, browserDist));
|
|
199
415
|
|
|
200
|
-
|
|
201
|
-
const prefix = '/';
|
|
202
|
-
stylesDir = prefix + stylesDir;
|
|
203
|
-
jsTemplatesFile = prefix + jsTemplatesFile;
|
|
204
|
-
}
|
|
416
|
+
gulp.task('default', gulp.series('serve'));
|
|
205
417
|
|
|
206
418
|
function getGlob(ext = '*') {
|
|
207
419
|
const glob = '**/*.';
|
|
208
420
|
if (typeof ext == 'string')
|
|
209
421
|
return glob + ext;
|
|
210
|
-
return glob + '{' + ext.join() + '}';
|
|
422
|
+
return glob + '{' + ext.join() + ',}';
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function getSetting(name) {
|
|
426
|
+
switch (name) {
|
|
427
|
+
case 'pug':
|
|
428
|
+
return getValue('html');
|
|
429
|
+
case 'cssFolder':
|
|
430
|
+
case 'filename':
|
|
431
|
+
case 'cssOrder':
|
|
432
|
+
return getValue('css');
|
|
433
|
+
case 'less':
|
|
434
|
+
case 'scss':
|
|
435
|
+
return getValue('css', true);
|
|
436
|
+
case 'lessOrder':
|
|
437
|
+
return getValue('css.less', true, true);
|
|
438
|
+
case 'scssOrder':
|
|
439
|
+
case 'variables':
|
|
440
|
+
return getValue('css.scss', true, true);
|
|
441
|
+
case 'fontsFolder':
|
|
442
|
+
case 'extensions':
|
|
443
|
+
return getValue('css.fonts');
|
|
444
|
+
case 'ng':
|
|
445
|
+
return getValue('js', true);
|
|
446
|
+
case 'module':
|
|
447
|
+
case 'html5Mode':
|
|
448
|
+
case 'template':
|
|
449
|
+
return getValue('js.ng', true, true);
|
|
450
|
+
case 'envs':
|
|
451
|
+
return getValue('js');
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function getValue(str, withoutDefault, onlyIfFalsy) {
|
|
455
|
+
for (const str of ['Folder', 'Order'])
|
|
456
|
+
if (name.endsWith(str))
|
|
457
|
+
name = str.toLowerCase();
|
|
458
|
+
|
|
459
|
+
const nameStr = str + '.' + name,
|
|
460
|
+
value = eval('settings.' + nameStr.replaceAll('.', '?.'));
|
|
461
|
+
if (withoutDefault) {
|
|
462
|
+
if (!onlyIfFalsy || !getSetting(str.split('.').pop()))
|
|
463
|
+
return value;
|
|
464
|
+
}
|
|
465
|
+
return value ?? eval('defSettings.' + nameStr);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function fileExists(path) {
|
|
470
|
+
return fs.existsSync(path);
|
|
211
471
|
}
|
|
212
472
|
|
|
213
473
|
function delDir(glob) {
|
|
@@ -215,14 +475,62 @@ function delDir(glob) {
|
|
|
215
475
|
.pipe($.clean());
|
|
216
476
|
}
|
|
217
477
|
|
|
218
|
-
function
|
|
219
|
-
|
|
478
|
+
function hideDir(glob) {
|
|
479
|
+
hidefile.hideSync(glob, error => notifyError(error));
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function getScriptTag(src) {
|
|
483
|
+
return `<script src="${src}" defer></script>`;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function replace(search, str) {
|
|
487
|
+
for (const char of ['$', '.', '/', '('])
|
|
488
|
+
search = search.replaceAll(char, '\\' + char);
|
|
489
|
+
return $.injectString.replace(search, str);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function getStylesTask(ext) {
|
|
493
|
+
const fn = cb => {
|
|
494
|
+
const cssExt = cssExtensions.find(({ name }) => name == ext);
|
|
495
|
+
if (cssExt) {
|
|
496
|
+
const stylesFile = stylesFilename + '.' + ext,
|
|
497
|
+
srcStylesFile = globs.src + stylesDir + stylesFile,
|
|
498
|
+
isPreprocessor = cssExt.isPreprocessor,
|
|
499
|
+
extraCode = cssExt.getExtraCode(),
|
|
500
|
+
sep = nl + nl,
|
|
501
|
+
content = (extraCode ? extraCode + sep : '') + (isPreprocessor ? '// bower:' + ext + nl + '// endbower' : '');
|
|
502
|
+
let stream;
|
|
503
|
+
if (!fileExists(srcStylesFile))
|
|
504
|
+
stream = $.addFiles([{
|
|
505
|
+
name: stylesFile,
|
|
506
|
+
content
|
|
507
|
+
}]);
|
|
508
|
+
else
|
|
509
|
+
stream = gulp.src(srcStylesFile)
|
|
510
|
+
.pipe($.injectString.prepend(content ? content + sep : ''));
|
|
511
|
+
if (isPreprocessor)
|
|
512
|
+
stream = stream.pipe($.wiredep());
|
|
513
|
+
stream = stream.pipe(cssExt.process()).on('error', notifyError);
|
|
514
|
+
if (isPreprocessor)
|
|
515
|
+
stream = stream.pipe($.rename({ suffix: '.' + ext }));
|
|
516
|
+
return stream
|
|
517
|
+
.pipe(gulp.dest(globs.tmp + stylesDir))
|
|
518
|
+
.pipe(browserSync.stream());
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
cb();
|
|
522
|
+
};
|
|
523
|
+
fn.displayName = ext;
|
|
524
|
+
return fn;
|
|
220
525
|
}
|
|
221
526
|
|
|
222
527
|
function browserSyncInit(path) {
|
|
223
528
|
browserSync.init({ server: path });
|
|
224
529
|
}
|
|
225
530
|
|
|
226
|
-
function
|
|
227
|
-
|
|
531
|
+
function getMinifyTask(ext, getProcessedStream, str) {
|
|
532
|
+
const fn = () => getProcessedStream(gulp.src(globs.dist + getGlob(ext)))
|
|
533
|
+
.pipe(gulp.dest(globs.dist));
|
|
534
|
+
fn.displayName = 'minify-' + (str || ext);
|
|
535
|
+
return fn;
|
|
228
536
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autofront",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"description": "Automation of front-end by Gulp and Bower.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"serve": "gulp",
|
|
8
|
-
"serve:dist": "gulp serve:dist",
|
|
9
|
-
"build": "gulp build"
|
|
10
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
"serve:dist": "gulp serve:dist --env=preproduction",
|
|
9
|
+
"build": "gulp build"
|
|
11
10
|
},
|
|
12
11
|
"repository": {
|
|
13
12
|
"type": "git",
|
|
@@ -18,7 +17,7 @@
|
|
|
18
17
|
"pug",
|
|
19
18
|
"css",
|
|
20
19
|
"less",
|
|
21
|
-
"
|
|
20
|
+
"scss",
|
|
22
21
|
"javascript",
|
|
23
22
|
"angularjs"
|
|
24
23
|
],
|
|
@@ -29,47 +28,40 @@
|
|
|
29
28
|
},
|
|
30
29
|
"homepage": "https://github.com/mvicens/autofront#readme",
|
|
31
30
|
"dependencies": {
|
|
32
|
-
"browser-sync": "
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"gulp": "
|
|
36
|
-
"gulp
|
|
37
|
-
"gulp-
|
|
38
|
-
"gulp-
|
|
39
|
-
"gulp-
|
|
40
|
-
"gulp-
|
|
41
|
-
"gulp-
|
|
42
|
-
"gulp-
|
|
43
|
-
"gulp-filter": "
|
|
44
|
-
"gulp-htmlmin": "
|
|
45
|
-
"gulp-imagemin": "
|
|
46
|
-
"gulp-inject": "
|
|
47
|
-
"gulp-inject-string": "
|
|
48
|
-
"gulp-jsonmin": "
|
|
49
|
-
"gulp-less": "
|
|
50
|
-
"gulp-load-plugins": "
|
|
51
|
-
"gulp-ng-annotate": "
|
|
52
|
-
"gulp-notify": "
|
|
53
|
-
"gulp-
|
|
54
|
-
"gulp-
|
|
55
|
-
"gulp-
|
|
56
|
-
"gulp-rev
|
|
57
|
-
"gulp-
|
|
58
|
-
"gulp-
|
|
59
|
-
"gulp-
|
|
60
|
-
"gulp-
|
|
61
|
-
"gulp-
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"local": "http://localhost:8081/",
|
|
68
|
-
"development": "http://dev.mydomain/",
|
|
69
|
-
"production": "http://mydomain/"
|
|
70
|
-
},
|
|
71
|
-
"domainAliases": {
|
|
72
|
-
"prod": "production",
|
|
73
|
-
"dev": "development"
|
|
31
|
+
"browser-sync": "2.27.10",
|
|
32
|
+
"cssnano": "5.1.14",
|
|
33
|
+
"delete-empty": "2.0.0",
|
|
34
|
+
"get-gulp-args": "0.0.1",
|
|
35
|
+
"gulp": "4.0.2",
|
|
36
|
+
"gulp-about": "1.1.0",
|
|
37
|
+
"gulp-add-files": "1.0.0",
|
|
38
|
+
"gulp-angular-filesort": "1.2.1",
|
|
39
|
+
"gulp-angular-templatecache": "3.0.1",
|
|
40
|
+
"gulp-clean": "0.4.0",
|
|
41
|
+
"gulp-cssimport": "7.0.0",
|
|
42
|
+
"gulp-filter": "7.0.0",
|
|
43
|
+
"gulp-htmlmin": "5.0.1",
|
|
44
|
+
"gulp-imagemin": "7.1.0",
|
|
45
|
+
"gulp-inject": "5.0.5",
|
|
46
|
+
"gulp-inject-string": "1.1.2",
|
|
47
|
+
"gulp-jsonmin": "1.2.0",
|
|
48
|
+
"gulp-less": "5.0.0",
|
|
49
|
+
"gulp-load-plugins": "2.0.8",
|
|
50
|
+
"gulp-ng-annotate": "2.1.0",
|
|
51
|
+
"gulp-notify": "4.0.0",
|
|
52
|
+
"gulp-postcss": "9.0.1",
|
|
53
|
+
"gulp-pug": "5.0.0",
|
|
54
|
+
"gulp-rename": "2.0.0",
|
|
55
|
+
"gulp-rev": "9.0.0",
|
|
56
|
+
"gulp-rev-delete-original": "0.2.3",
|
|
57
|
+
"gulp-rev-replace": "0.4.4",
|
|
58
|
+
"gulp-sass": "5.1.0",
|
|
59
|
+
"gulp-size": "4.0.1",
|
|
60
|
+
"gulp-terser": "2.1.0",
|
|
61
|
+
"gulp-useref": "5.0.0",
|
|
62
|
+
"gulp-wiredep": "1.2.0",
|
|
63
|
+
"hidefile": "3.0.0",
|
|
64
|
+
"main-bower-files": "2.13.3",
|
|
65
|
+
"sass": "1.56.1"
|
|
74
66
|
}
|
|
75
67
|
}
|