@videinfra/static-website-builder 2.1.0 → 2.2.0
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/CHANGELOG.md +4 -0
- package/init/test/config/config.js +9 -1
- package/package.json +8 -10
- package/tasks/clean/task.js +2 -2
- package/tasks/icons/preprocess-config.js +1 -8
- package/tasks/icons/task.js +1 -1
- package/tests/build/build.test.js +18 -7
- package/vendor/gulp-sass/index.js +4 -4
- package/vendor/gulp-svgmin/.babelrc +3 -0
- package/vendor/gulp-svgmin/.editorconfig +16 -0
- package/vendor/gulp-svgmin/CHANGELOG.md +80 -0
- package/vendor/gulp-svgmin/LICENSE-MIT +22 -0
- package/vendor/gulp-svgmin/README.md +166 -0
- package/vendor/gulp-svgmin/src/get-svgo-config.js +126 -0
- package/vendor/gulp-svgmin/src/index.js +44 -0
- package/vendor/gulp-twig/index.js +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [2.2.0] - 2026-03-06
|
|
8
|
+
### Changed
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
7
11
|
## [2.1.0] - 2026-03-04
|
|
8
12
|
### Changed
|
|
9
13
|
- Updated gulp-sass to use sass-embedded instead of sass
|
|
@@ -26,7 +26,15 @@ export const javascripts = {
|
|
|
26
26
|
},
|
|
27
27
|
],
|
|
28
28
|
};
|
|
29
|
-
export const stylesheets = {
|
|
29
|
+
export const stylesheets = {
|
|
30
|
+
// Overwriting to test that source maps are generated
|
|
31
|
+
production: {
|
|
32
|
+
sourcemaps: {
|
|
33
|
+
init: {},
|
|
34
|
+
write: {},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
30
38
|
export const sizereport = false;
|
|
31
39
|
|
|
32
40
|
export const plugins = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@videinfra/static-website-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Customizable static site project builder",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -29,14 +29,14 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@csstools/postcss-nested-calc": "^5.0.0",
|
|
31
31
|
"@rollup/plugin-replace": "^6.0.3",
|
|
32
|
-
"autoprefixer": "^10.4.
|
|
32
|
+
"autoprefixer": "^10.4.27",
|
|
33
33
|
"browser-sync": "^3.0.4",
|
|
34
|
-
"chalk": "
|
|
34
|
+
"chalk": "5.6.2",
|
|
35
35
|
"chokidar": "^5.0.0",
|
|
36
36
|
"cross-env": "^10.1.0",
|
|
37
37
|
"cssnano": "^7.1.2",
|
|
38
|
-
"del": "^
|
|
39
|
-
"dotenv": "^17.
|
|
38
|
+
"del": "^8.0.1",
|
|
39
|
+
"dotenv": "^17.3.1",
|
|
40
40
|
"gulp": "^5.0.1",
|
|
41
41
|
"gulp-cached": "^1.1.1",
|
|
42
42
|
"gulp-data": "^1.3.1",
|
|
@@ -46,19 +46,17 @@
|
|
|
46
46
|
"gulp-ignore": "^3.0.0",
|
|
47
47
|
"gulp-plumber": "^1.2.1",
|
|
48
48
|
"gulp-postcss": "^10.0.0",
|
|
49
|
-
"gulp-sass": "^5.1.0",
|
|
50
49
|
"gulp-sitemap": "^8.0.0",
|
|
51
50
|
"gulp-sizereport": "^1.2.1",
|
|
52
|
-
"gulp-sourcemaps": "^
|
|
53
|
-
"gulp-svgmin": "^4.1.0",
|
|
51
|
+
"gulp-sourcemaps": "^3.0.0",
|
|
54
52
|
"gulp-svgstore": "^9.0.0",
|
|
55
53
|
"lodash.clone": "^4.3.2",
|
|
56
54
|
"lodash.some": "^4.2.2",
|
|
57
|
-
"map-stream": "^0.1.0",
|
|
58
55
|
"minimist": "^1.2.8",
|
|
59
56
|
"nano-memoize": "3.0.16",
|
|
60
|
-
"rolldown": "^1.0.0-rc.
|
|
57
|
+
"rolldown": "^1.0.0-rc.7",
|
|
61
58
|
"sass-embedded": "^1.97.3",
|
|
59
|
+
"svgo": "^4.0.1",
|
|
62
60
|
"through": "^2.3.8",
|
|
63
61
|
"twig": "^1.17.1"
|
|
64
62
|
},
|
package/tasks/clean/task.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { deleteAsync } from 'del';
|
|
2
2
|
import { getTaskConfig } from '../../lib/get-config.js';
|
|
3
3
|
|
|
4
4
|
export function beforeBuild(callback) {
|
|
5
5
|
const patterns = getTaskConfig('clean', 'patterns');
|
|
6
|
-
return
|
|
6
|
+
return deleteAsync(patterns, { force: true }).then(() => callback());
|
|
7
7
|
}
|
|
@@ -42,16 +42,9 @@ export default function preprocessIconsConfig (config, fullConfig) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Use function to output svgmin configuration
|
|
45
|
-
// Add ID attribute transformation
|
|
46
45
|
config.svgmin = function getSVGMinOptions (file) {
|
|
47
|
-
var prefix = path.basename(file.relative, path.extname(file.relative));
|
|
48
46
|
return {
|
|
49
|
-
plugins: [
|
|
50
|
-
cleanupIDs: {
|
|
51
|
-
prefix: prefix + '-',
|
|
52
|
-
minify: true
|
|
53
|
-
}
|
|
54
|
-
}].concat(svgmin)
|
|
47
|
+
plugins: [].concat(svgmin)
|
|
55
48
|
}
|
|
56
49
|
};
|
|
57
50
|
}
|
package/tasks/icons/task.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import gulp from 'gulp';
|
|
2
2
|
import gulpif from 'gulp-if';
|
|
3
3
|
import svgstore from 'gulp-svgstore';
|
|
4
|
-
import svgmin from 'gulp-svgmin';
|
|
4
|
+
import svgmin from '../../vendor/gulp-svgmin/src/index.js';
|
|
5
5
|
import nanomemoize from 'nano-memoize';
|
|
6
6
|
|
|
7
7
|
import globs from './../../lib/globs-helper.js';
|
|
@@ -18,40 +18,51 @@ test('Multiple TWIG templates rendered', () => {
|
|
|
18
18
|
|
|
19
19
|
test('SASS variable test', () => {
|
|
20
20
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/variable-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
21
|
-
expect(css
|
|
21
|
+
expect(css.startsWith('main{background:#fff;color:#222}')).toBe(true);
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
test('SASS import test', () => {
|
|
26
26
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/import-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
27
|
-
expect(css
|
|
27
|
+
expect(css.startsWith('.btn{background:#222;color:#fff}')).toBe(true);
|
|
28
28
|
});
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
test('SASS sub-folder import test', () => {
|
|
32
32
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/sub-folder/import-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
33
|
-
expect(css
|
|
33
|
+
expect(css.startsWith('.btn{background:#222;color:#fff}')).toBe(true);
|
|
34
34
|
});
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
test('SASS autoprefixer test', () => {
|
|
38
38
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/autoprefixer-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
39
|
-
expect(css
|
|
39
|
+
expect(css.startsWith('main{clip-path:polygon(0 0,100% 0,100% 100%,0 100%)}')).toBe(true);
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test('CSS nano ignore test', () => {
|
|
44
44
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/ignore-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
45
|
-
expect(css
|
|
45
|
+
expect(css.startsWith(':root{--yes: ;--no:initial}')).toBe(true);
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
|
|
49
49
|
test('CSS nano nested calc test', () => {
|
|
50
50
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/nested-calc-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
51
|
-
expect(css
|
|
51
|
+
expect(css.startsWith('body{padding-top:calc(10vw + 15vh)}')).toBe(true);
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
test('CSS has sourcemap URL', () => {
|
|
56
|
+
return fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/nested-calc-test.css'), { encoding: 'utf8' }).then((css) => {
|
|
57
|
+
expect(css.includes('sourceMappingURL=')).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('CSS sourcemap generated', () => {
|
|
62
|
+
expect.assertions(1);
|
|
63
|
+
return expect(fsPromises.access(path.resolve(publicPath, 'assets/stylesheets/nested-calc-test.css.map'))).resolves.toBe(undefined);
|
|
64
|
+
});
|
|
65
|
+
|
|
55
66
|
test('Font file woff copied', () => {
|
|
56
67
|
expect.assertions(1);
|
|
57
68
|
return expect(fsPromises.access(path.resolve(publicPath, 'assets/fonts/font.woff'))).resolves.toBe(undefined);
|
|
@@ -139,7 +150,7 @@ test('currentPagePath available in templates', () => {
|
|
|
139
150
|
|
|
140
151
|
test('icons generated', () => {
|
|
141
152
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/images/icons.svg'), { encoding: 'utf8' }).then((svg) => {
|
|
142
|
-
expect(svg.indexOf('<symbol id="example-arrow">')).not.toBe(-1);
|
|
153
|
+
expect(svg.indexOf('<symbol id="example-arrow" viewBox="0 0 20 20">')).not.toBe(-1);
|
|
143
154
|
});
|
|
144
155
|
});
|
|
145
156
|
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { Transform } from 'stream';
|
|
8
|
-
import
|
|
8
|
+
import chalk from 'chalk';
|
|
9
9
|
import PluginError from 'plugin-error';
|
|
10
10
|
import replaceExtension from 'replace-ext';
|
|
11
11
|
import stripAnsi from 'strip-ansi';
|
|
12
|
-
import
|
|
12
|
+
import cloneDeep from 'lodash/cloneDeep.js';
|
|
13
13
|
import sassStingify from './sass-stringify.js';
|
|
14
14
|
|
|
15
15
|
const PLUGIN_NAME = 'gulp-sass';
|
|
@@ -36,7 +36,7 @@ const filePush = (file, css, callback) => {
|
|
|
36
36
|
const handleError = (error, file, callback) => {
|
|
37
37
|
const filePath = (error.file === 'stdin' ? file.path : error.file) || file.path;
|
|
38
38
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
39
|
-
const message = `${
|
|
39
|
+
const message = `${chalk.underline(relativePath)}\n${error.formatted}`;
|
|
40
40
|
|
|
41
41
|
error.messageFormatted = message;
|
|
42
42
|
error.messageOriginal = error.message;
|
|
@@ -69,7 +69,7 @@ const gulpSass = (options) => {
|
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const opts =
|
|
72
|
+
const opts = cloneDeep(options || {});
|
|
73
73
|
let source = file.contents.toString();
|
|
74
74
|
|
|
75
75
|
// Stringiyfy variables
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
indent_style = space
|
|
6
|
+
indent_size = 4
|
|
7
|
+
end_of_line = lf
|
|
8
|
+
charset = utf-8
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
insert_final_newline = true
|
|
11
|
+
|
|
12
|
+
[*.md]
|
|
13
|
+
indent_size = 2
|
|
14
|
+
|
|
15
|
+
[package.json]
|
|
16
|
+
indent_size = 2
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 5.0.0
|
|
2
|
+
|
|
3
|
+
* Kaspars Zuks: changed SVGO version to 4.0.0
|
|
4
|
+
|
|
5
|
+
# 4.1.0
|
|
6
|
+
|
|
7
|
+
* Bump svgo to v2.7.0. (thanks to @djphan)
|
|
8
|
+
|
|
9
|
+
# 4.0.1
|
|
10
|
+
|
|
11
|
+
* Move lodash.clonedeep into dependencies, fixes #120 (thanks to @donmahallem)
|
|
12
|
+
|
|
13
|
+
# 4.0.0
|
|
14
|
+
|
|
15
|
+
* Bump svgo to v2.3.1. (thanks to @JohnAlbin)
|
|
16
|
+
* Drop node 10 support.
|
|
17
|
+
* Replace eslint-config-cssnano with xo.
|
|
18
|
+
* Update babel to v7 and ava to v3 (thanks to @JohnAlbin)
|
|
19
|
+
* Update dependencies.
|
|
20
|
+
|
|
21
|
+
# 3.0.0
|
|
22
|
+
|
|
23
|
+
* Bump svgo to v1.3.2.
|
|
24
|
+
* Drop node 8 support.
|
|
25
|
+
* Update dependencies.
|
|
26
|
+
|
|
27
|
+
# 2.2.0
|
|
28
|
+
|
|
29
|
+
* Bump svgo to v1.2.1. (thanks to @ekfuhrmann)
|
|
30
|
+
|
|
31
|
+
# 2.1.0
|
|
32
|
+
|
|
33
|
+
* Bump svgo to v1.1.x.
|
|
34
|
+
* Update babel-dependencies (but not yet to v7).
|
|
35
|
+
|
|
36
|
+
# 2.0.0
|
|
37
|
+
|
|
38
|
+
* Bump svgo to v1.0.x. (thanks to @theverything)
|
|
39
|
+
* Drop dependency on deprecated 'gulp-util'. (thanks to @TheDancingCode)
|
|
40
|
+
* Drop support for old node version.
|
|
41
|
+
|
|
42
|
+
# 1.2.4
|
|
43
|
+
|
|
44
|
+
* Fixed a regression with the per-file options. (thanks to @Odrin)
|
|
45
|
+
|
|
46
|
+
# 1.2.3
|
|
47
|
+
|
|
48
|
+
* Bump svgo to v0.7.x.
|
|
49
|
+
|
|
50
|
+
# 1.2.2
|
|
51
|
+
|
|
52
|
+
* Now compiled with babel 6.
|
|
53
|
+
|
|
54
|
+
# 1.2.1
|
|
55
|
+
|
|
56
|
+
* Bump svgo to v0.6.x.
|
|
57
|
+
|
|
58
|
+
# 1.2.0
|
|
59
|
+
|
|
60
|
+
* Adds the ability to pass per-file objects. (thanks to @w0rm)
|
|
61
|
+
|
|
62
|
+
# 1.1.2
|
|
63
|
+
|
|
64
|
+
* Update code style.
|
|
65
|
+
|
|
66
|
+
# 1.1.1
|
|
67
|
+
|
|
68
|
+
* Update documentation.
|
|
69
|
+
|
|
70
|
+
# 1.1.0
|
|
71
|
+
|
|
72
|
+
* Refactor internals.
|
|
73
|
+
|
|
74
|
+
# 1.0.0
|
|
75
|
+
|
|
76
|
+
* svgmin takes an options object now, instead of a list of plugins.
|
|
77
|
+
|
|
78
|
+
# 0.4.8
|
|
79
|
+
|
|
80
|
+
* Bump svgo to v0.5.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) Ben Briggs <beneb.info@gmail.com> (https://beneb.info)
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
|
4
|
+
obtaining a copy of this software and associated documentation
|
|
5
|
+
files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use,
|
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the
|
|
9
|
+
Software is furnished to do so, subject to the following
|
|
10
|
+
conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# gulp-svgmin
|
|
2
|
+
|
|
3
|
+
[][travis-status]
|
|
4
|
+
[][npm-status]
|
|
5
|
+
[][deps-status]
|
|
6
|
+
|
|
7
|
+
> A [Gulp][gulp-url] plugin to minify SVG files with [svgo-url].
|
|
8
|
+
|
|
9
|
+
*If you have any difficulties with the output of this plugin, please use the [SVGO tracker][svgo-bugs].*
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
With [npm][npm-url] do:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
npm install gulp-svgmin
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
import { src, dest } from 'gulp';
|
|
24
|
+
import svgmin from 'gulp-svgmin';
|
|
25
|
+
|
|
26
|
+
const defaultTask = () =>
|
|
27
|
+
src('logo.svg')
|
|
28
|
+
.pipe(svgmin())
|
|
29
|
+
.pipe(dest('./out'));
|
|
30
|
+
|
|
31
|
+
export default defaultTask;
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration file
|
|
35
|
+
|
|
36
|
+
By default, `gulp-svgmin` loads options from a `svgo.config.js` file in your project. See the [svgo’s configuration docs][svgo-config] for more info on how to write one.
|
|
37
|
+
|
|
38
|
+
You can control which directory `svgo` searches for `svgo.config.js` with the `cwd` option. Or you can use a different file name with the `configFile` option.
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { src, dest } from 'gulp';
|
|
42
|
+
import svgmin from 'gulp-svgmin';
|
|
43
|
+
|
|
44
|
+
const defaultTask = () =>
|
|
45
|
+
src('logo.svg')
|
|
46
|
+
.pipe(svgmin({
|
|
47
|
+
// Specify an absolute directory path to
|
|
48
|
+
// search for the config file.
|
|
49
|
+
cwd: '/users/admin/project/assets',
|
|
50
|
+
// This path is relative to process.cwd()
|
|
51
|
+
// or the 'cwd' option.
|
|
52
|
+
configFile: 'images/svg/config.js',
|
|
53
|
+
}))
|
|
54
|
+
.pipe(dest('./out'));
|
|
55
|
+
|
|
56
|
+
export default defaultTask;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Options
|
|
60
|
+
|
|
61
|
+
Instead of using a config file, you can pass an object of svgo’s options to the `gulp-svgmin` plugin. You will need to provide the config in comma separated objects, like the example below.
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
const defaultTask = () =>
|
|
65
|
+
src('logo.svg')
|
|
66
|
+
.pipe(svgmin({
|
|
67
|
+
// Ensures the best optimization.
|
|
68
|
+
multipass: true,
|
|
69
|
+
js2svg: {
|
|
70
|
+
// Beutifies the SVG output instead of
|
|
71
|
+
// stripping all white space.
|
|
72
|
+
pretty: true,
|
|
73
|
+
indent: 2,
|
|
74
|
+
},
|
|
75
|
+
// Alter the default list of plugins.
|
|
76
|
+
plugins: [
|
|
77
|
+
// You can enable a plugin with just its name.
|
|
78
|
+
'sortAttrs',
|
|
79
|
+
{
|
|
80
|
+
name: 'removeViewBox',
|
|
81
|
+
// Disable a plugin by setting active to false.
|
|
82
|
+
active: false,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'cleanupIDs',
|
|
86
|
+
// Add plugin options.
|
|
87
|
+
params: {
|
|
88
|
+
minify: true,
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
}))
|
|
93
|
+
.pipe(dest('./out'));
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
You can view the [full list of plugins here][svgo-plugins].
|
|
97
|
+
|
|
98
|
+
By default, the plugins list given to the gulp plugin will alter the default list of svgo plugins. Optionally, you can specify your plugins and set the `full` flag to `true` to indicate that your plugins list should not be merged with the default list of plugins.
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
const defaultTask = () =>
|
|
102
|
+
src('logo.svg')
|
|
103
|
+
.pipe(svgmin({
|
|
104
|
+
multipass: true,
|
|
105
|
+
// The plugins list is the full list of plugins
|
|
106
|
+
// to use. The default list is ignored.
|
|
107
|
+
full: true,
|
|
108
|
+
plugins: [
|
|
109
|
+
'removeDoctype',
|
|
110
|
+
'removeComments',
|
|
111
|
+
'sortAttrs',
|
|
112
|
+
// ...
|
|
113
|
+
],
|
|
114
|
+
}))
|
|
115
|
+
.pipe(dest('./out'));
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Per-file options
|
|
119
|
+
|
|
120
|
+
To have per-file options, pass a function, that receives `file` object and
|
|
121
|
+
returns `svgo` options. For example, if you need to prefix ids with filenames
|
|
122
|
+
to make them unique before combining svgs with [gulp-svgstore][gulp-svgostore]:
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const defaultTask = () =>
|
|
126
|
+
src('src/*.svg')
|
|
127
|
+
.pipe(svgmin(function getOptions(file) {
|
|
128
|
+
const prefix = path.basename(
|
|
129
|
+
file.relative,
|
|
130
|
+
path.extname(file.relative)
|
|
131
|
+
);
|
|
132
|
+
return {
|
|
133
|
+
plugins: [
|
|
134
|
+
{
|
|
135
|
+
name: 'cleanupIDs',
|
|
136
|
+
parmas: {
|
|
137
|
+
prefix: prefix + '-',
|
|
138
|
+
minify: true,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
}))
|
|
144
|
+
.pipe(svgstore())
|
|
145
|
+
.pipe(dest('./dest'));
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Contributing
|
|
149
|
+
|
|
150
|
+
Pull requests are welcome. If you add functionality, then please add unit tests to cover it.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT © [Ben Briggs](https://beneb.info)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
[travis-status]: https://travis-ci.org/ben-eb/gulp-svgmin
|
|
158
|
+
[deps-status]: https://david-dm.org/ben-eb/gulp-svgmin
|
|
159
|
+
[npm-status]: https://badge.fury.io/js/gulp-svgmin
|
|
160
|
+
[npm-url]: https://npmjs.org/package/gulp-svgmin
|
|
161
|
+
[gulp-url]: https://github.com/gulpjs/gulp
|
|
162
|
+
[gulp-svgostore]: https://github.com/w0rm/gulp-svgstore
|
|
163
|
+
[svgo-url]: https://github.com/svg/svgo
|
|
164
|
+
[svgo-bugs]: https://github.com/svg/svgo/issues
|
|
165
|
+
[svgo-config]: https://github.com/svg/svgo#configuration
|
|
166
|
+
[svgo-plugins]: https://github.com/svg/svgo#built-in-plugins
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import cloneDeep from 'lodash/cloneDeep.js';
|
|
2
|
+
import {loadConfig} from 'svgo';
|
|
3
|
+
|
|
4
|
+
// To prevent multiple scans of the disk for a svgo.config.js file, keep its
|
|
5
|
+
// data in module scope.
|
|
6
|
+
const cache = {};
|
|
7
|
+
|
|
8
|
+
// Load the config from svgo.config.js.
|
|
9
|
+
const loadConfigFromCache = async (configFile, cwd) => {
|
|
10
|
+
if (configFile !== null) {
|
|
11
|
+
// Look for the config in the specified file. loadConfig() will
|
|
12
|
+
// require() the file, which caches it for us.
|
|
13
|
+
return loadConfig(configFile, cwd);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Since no configFile was given, let loadConfig() find a file for us.
|
|
17
|
+
|
|
18
|
+
// If the config file is not in our module cache, look for it on disk.
|
|
19
|
+
if (!(cwd in cache)) {
|
|
20
|
+
// Any usage of loadConfig() with the same cwd will return the same
|
|
21
|
+
// file's config. Store the resulting config in our module cache.
|
|
22
|
+
cache[cwd] = await loadConfig(null, cwd);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return cache[cwd];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const getSvgoConfig = async function (
|
|
29
|
+
options = null,
|
|
30
|
+
doDeepClone = false
|
|
31
|
+
) {
|
|
32
|
+
// Construct the svgo config from the given options.
|
|
33
|
+
let config = {
|
|
34
|
+
...options,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Get the options that are for this gulp plugin and not for svgo.
|
|
38
|
+
const pluginOptions = {
|
|
39
|
+
full: Boolean(config.full),
|
|
40
|
+
configFile: config.configFile || null,
|
|
41
|
+
cwd: config.cwd || process.cwd(),
|
|
42
|
+
};
|
|
43
|
+
delete config.full;
|
|
44
|
+
delete config.configFile;
|
|
45
|
+
delete config.cwd;
|
|
46
|
+
|
|
47
|
+
// If the options.full flag is specified, then the given options are
|
|
48
|
+
// considered to be the full svgo config.
|
|
49
|
+
if (pluginOptions.full) {
|
|
50
|
+
return config;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Extract the svgo plugins list from the config as we will need to handle
|
|
54
|
+
// them specially later.
|
|
55
|
+
const plugins = config.plugins || [];
|
|
56
|
+
delete config.plugins;
|
|
57
|
+
|
|
58
|
+
const loadedConfig = await loadConfigFromCache(
|
|
59
|
+
pluginOptions.configFile,
|
|
60
|
+
pluginOptions.cwd
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Merge the given config with the config loaded from file. (If no
|
|
64
|
+
// config file was found, svgo's loadConfig() returns null.)
|
|
65
|
+
if (loadedConfig) {
|
|
66
|
+
config = {
|
|
67
|
+
// Since gulp-svgmin allows a function to modify config per-file, we
|
|
68
|
+
// want to prevent that function from making modifications to the
|
|
69
|
+
// returned config object that would bleed into subsequent usages of
|
|
70
|
+
// the config object.
|
|
71
|
+
...(doDeepClone ? cloneDeep(loadedConfig) : loadedConfig),
|
|
72
|
+
...config,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Merge any plugins given in options.plugins.
|
|
77
|
+
if (config.plugins) {
|
|
78
|
+
// If plugins are provided in a config file, they are assumed to be
|
|
79
|
+
// a final list of plugins; according to svgo version 2 docs, the
|
|
80
|
+
// config file is responsible for merging the default plugins list.
|
|
81
|
+
// So we just need to merge the options.plugins into the list loaded
|
|
82
|
+
// from the config file.
|
|
83
|
+
config.plugins = extendLoadedPlugins(config.plugins, plugins);
|
|
84
|
+
} else {
|
|
85
|
+
const pluginConfig = {
|
|
86
|
+
// Default provided per svgo docs in v2.4.0+
|
|
87
|
+
name: 'preset-default',
|
|
88
|
+
params: {
|
|
89
|
+
overrides: {},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Following format assuming plugins settings are for built ins
|
|
94
|
+
for (const plugin of plugins) {
|
|
95
|
+
for (const [key, value] of Object.entries(plugin)) {
|
|
96
|
+
pluginConfig.params.overrides[key] = value;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
config.plugins = [pluginConfig];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return config;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Based on svgo's extendDefaultPlugins().
|
|
107
|
+
const extendLoadedPlugins = (loadedPlugins, plugins) => {
|
|
108
|
+
const pluginsOrder = [];
|
|
109
|
+
const extendedPlugins = loadedPlugins.map((plugin) => {
|
|
110
|
+
pluginsOrder.push(typeof plugin === 'string' ? plugin : plugin.name);
|
|
111
|
+
return plugin;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
for (const plugin of plugins) {
|
|
115
|
+
const index = pluginsOrder.indexOf(
|
|
116
|
+
typeof plugin === 'string' ? plugin : plugin.name
|
|
117
|
+
);
|
|
118
|
+
if (index === -1) {
|
|
119
|
+
extendedPlugins.push(plugin);
|
|
120
|
+
} else {
|
|
121
|
+
extendedPlugins[index] = plugin;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return extendedPlugins;
|
|
126
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import PluginError from 'plugin-error';
|
|
2
|
+
import {Transform} from 'stream';
|
|
3
|
+
import {optimize} from 'svgo';
|
|
4
|
+
import {getSvgoConfig} from './get-svgo-config.js';
|
|
5
|
+
|
|
6
|
+
const PLUGIN_NAME = 'gulp-svgmin';
|
|
7
|
+
|
|
8
|
+
export default function (options) {
|
|
9
|
+
const optionsFunction = typeof options === 'function';
|
|
10
|
+
|
|
11
|
+
const stream = new Transform({objectMode: true});
|
|
12
|
+
stream._transform = function (file, encoding, cb) {
|
|
13
|
+
if (file.isStream()) {
|
|
14
|
+
return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (file.isBuffer()) {
|
|
18
|
+
getSvgoConfig(
|
|
19
|
+
optionsFunction ? options(file) : options,
|
|
20
|
+
optionsFunction
|
|
21
|
+
)
|
|
22
|
+
.then((config) => {
|
|
23
|
+
const result = optimize(String(file.contents), config);
|
|
24
|
+
|
|
25
|
+
// Ignore svgo meta data and return the SVG string.
|
|
26
|
+
if (typeof result.data === 'string') {
|
|
27
|
+
file.contents = Buffer.from(result.data);
|
|
28
|
+
return cb(null, file);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Otherwise, throw an error, even if it is undefined.
|
|
32
|
+
throw result.error;
|
|
33
|
+
})
|
|
34
|
+
.catch((error) => cb(new PluginError(PLUGIN_NAME, error)));
|
|
35
|
+
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Handle all other cases, like file.isNull(), file.isDirectory().
|
|
40
|
+
return cb(null, file);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return stream;
|
|
44
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// 2024-02-13, Kaspars Zuks: added "options.async" support
|
|
2
|
-
|
|
2
|
+
// 2026-03-06, Kaspars Zuks: replaced map-stream with through2
|
|
3
|
+
import through from 'through2';
|
|
3
4
|
import rext from 'replace-ext';
|
|
4
5
|
import log from 'fancy-log';
|
|
5
6
|
import PluginError from 'plugin-error';
|
|
@@ -20,7 +21,7 @@ export default function (options) {
|
|
|
20
21
|
options || {},
|
|
21
22
|
);
|
|
22
23
|
|
|
23
|
-
function modifyContents(file, cb) {
|
|
24
|
+
function modifyContents(file, _enc, cb) {
|
|
24
25
|
var data = file.data || Object.assign({}, options.data);
|
|
25
26
|
|
|
26
27
|
if (file.isNull()) {
|
|
@@ -134,5 +135,5 @@ export default function (options) {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
return
|
|
138
|
+
return through.obj(modifyContents);
|
|
138
139
|
}
|