@videinfra/static-website-builder 2.0.10 → 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 +9 -0
- package/init/test/config/config.js +9 -1
- package/init/test/src/stylesheets/env-test.scss +7 -5
- package/package.json +9 -11
- package/plugins/sass-engine/preprocess-config.js +14 -3
- package/tasks/clean/task.js +2 -2
- package/tasks/icons/preprocess-config.js +1 -8
- package/tasks/icons/task.js +1 -1
- package/tasks/stylesheets/task.js +10 -5
- package/tests/build/build.test.js +18 -7
- package/vendor/gulp-sass/index.js +29 -109
- package/vendor/gulp-sass/package.json +1 -1
- 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,15 @@ 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
|
+
|
|
11
|
+
## [2.1.0] - 2026-03-04
|
|
12
|
+
### Changed
|
|
13
|
+
- Updated gulp-sass to use sass-embedded instead of sass
|
|
14
|
+
- Updated gulp-sass to remove legacy code and use only sync mode
|
|
15
|
+
|
|
7
16
|
## [2.0.9] - 2026-02-19
|
|
8
17
|
### Fixed
|
|
9
18
|
- Removed file extension from the sitemap URLs
|
|
@@ -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 = [
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
|
|
1
3
|
.env-test:before {
|
|
2
|
-
content: map
|
|
4
|
+
content: map.get($env, host);
|
|
3
5
|
}
|
|
4
6
|
|
|
5
7
|
:root {
|
|
6
|
-
#{ --env-test-type-number }: map
|
|
7
|
-
#{ --env-test-type-empty }: map
|
|
8
|
+
#{ --env-test-type-number }: map.get($env, typeNumber);
|
|
9
|
+
#{ --env-test-type-empty }: map.get($env, typeEmpty);
|
|
8
10
|
}
|
|
9
11
|
|
|
10
|
-
@if map
|
|
12
|
+
@if map.get($env, typeBoolTrue) {
|
|
11
13
|
:root {
|
|
12
14
|
--env-test-bool-true: true;
|
|
13
15
|
}
|
|
@@ -17,7 +19,7 @@
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
@if map
|
|
22
|
+
@if map.get($env, typeBoolFalse) {
|
|
21
23
|
:root {
|
|
22
24
|
--env-test-bool-false: true;
|
|
23
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@videinfra/static-website-builder",
|
|
3
|
-
"version": "2.0
|
|
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.
|
|
61
|
-
"sass": "^1.97.3",
|
|
57
|
+
"rolldown": "^1.0.0-rc.7",
|
|
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
|
},
|
|
@@ -4,7 +4,7 @@ import merge from './../../lib/merge.js';
|
|
|
4
4
|
import getEnvData from './../../tasks/env/get-env.js';
|
|
5
5
|
import gulpSass from '../../vendor/gulp-sass/index.js';
|
|
6
6
|
import assign from 'lodash/assign.js';
|
|
7
|
-
import * as sass from 'sass';
|
|
7
|
+
import * as sass from 'sass-embedded';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Modify configuration
|
|
@@ -32,7 +32,15 @@ export default function processSASSConfig(config, fullConfig) {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
// Engine is a function which returns a gulp pipe function
|
|
35
|
-
config.
|
|
35
|
+
config._engineCache = null;
|
|
36
|
+
config.engine = function getSASSEngine(disposeOnly = false) {
|
|
37
|
+
if (config._engineCache) {
|
|
38
|
+
config._engineCache.dispose();
|
|
39
|
+
}
|
|
40
|
+
if (disposeOnly) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
const sassEngine = gulpSass(sass);
|
|
37
45
|
const sassConfig = getTaskConfig('stylesheets', 'sass');
|
|
38
46
|
|
|
@@ -41,7 +49,10 @@ export default function processSASSConfig(config, fullConfig) {
|
|
|
41
49
|
}
|
|
42
50
|
|
|
43
51
|
sassConfig.data = merge(getEnvData().sass, sassConfig.data || {});
|
|
44
|
-
|
|
52
|
+
config._engineCache = sassEngine(sassConfig).on('error', sassEngine.logError);
|
|
53
|
+
config._engineCache.dispose = sassEngine.dispose;
|
|
54
|
+
|
|
55
|
+
return config._engineCache;
|
|
45
56
|
};
|
|
46
57
|
|
|
47
58
|
// Main 'dependents' config is shared between all tasks
|
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';
|
|
@@ -33,13 +33,13 @@ const getGlobPaths = nanomemoize.nanomemoize(function () {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
const getEngine = function () {
|
|
36
|
+
const getEngine = function (disposeOnly = false) {
|
|
37
37
|
const engine = getTaskConfig('stylesheets', 'engine');
|
|
38
|
-
return engine ? engine() : (() => {});
|
|
38
|
+
return engine ? engine(disposeOnly) : (() => {});
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
function
|
|
42
|
+
function stylesheetsBuild () {
|
|
43
43
|
return gulp.src(getGlobPaths())
|
|
44
44
|
.pipe(taskStart())
|
|
45
45
|
|
|
@@ -65,9 +65,14 @@ function stylesheets () {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function stylesheetsWatch () {
|
|
68
|
-
return taskWatch(getWatchGlobPaths(true),
|
|
68
|
+
return taskWatch(getWatchGlobPaths(true), stylesheetsBuild);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function stylesheetsBuildEnd () {
|
|
72
|
+
getEngine(true);
|
|
73
|
+
return Promise.resolve();
|
|
69
74
|
}
|
|
70
75
|
|
|
71
76
|
|
|
72
|
-
export const build =
|
|
77
|
+
export const build = gulp.series(stylesheetsBuild, stylesheetsBuildEnd);
|
|
73
78
|
export const watch = stylesheetsWatch;
|
|
@@ -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
|
|
|
@@ -1,61 +1,26 @@
|
|
|
1
1
|
// 2025-01-20, Kaspars Zuks: added "options.data" support for variables
|
|
2
|
+
// 2026-03-04, Kaspars Zuks: updated to use "compileString" instead of "renderSync"
|
|
3
|
+
// 2026-03-04, Kaspars Zuks: removed async version
|
|
2
4
|
'use strict';
|
|
3
5
|
|
|
4
6
|
import path from 'path';
|
|
5
7
|
import { Transform } from 'stream';
|
|
6
|
-
import
|
|
8
|
+
import chalk from 'chalk';
|
|
7
9
|
import PluginError from 'plugin-error';
|
|
8
10
|
import replaceExtension from 'replace-ext';
|
|
9
11
|
import stripAnsi from 'strip-ansi';
|
|
10
|
-
import
|
|
11
|
-
import applySourceMap from 'vinyl-sourcemaps-apply';
|
|
12
|
+
import cloneDeep from 'lodash/cloneDeep.js';
|
|
12
13
|
import sassStingify from './sass-stringify.js';
|
|
13
14
|
|
|
14
15
|
const PLUGIN_NAME = 'gulp-sass';
|
|
15
16
|
|
|
16
|
-
const MISSING_COMPILER_MESSAGE = `
|
|
17
|
-
gulp-sass no longer has a default Sass compiler; please set one yourself.
|
|
18
|
-
Both the "sass" and "node-sass" packages are permitted.
|
|
19
|
-
For example, in your gulpfile:
|
|
20
|
-
|
|
21
|
-
import * as sass from 'sass';
|
|
22
|
-
import gulpSass from 'gulp-sass';
|
|
23
|
-
const instance = gulpSass(sass);
|
|
24
|
-
`;
|
|
25
|
-
|
|
26
17
|
const transfob = (transform) => new Transform({ transform, objectMode: true });
|
|
27
18
|
|
|
28
19
|
/**
|
|
29
20
|
* Handles returning the file to the stream
|
|
30
21
|
*/
|
|
31
|
-
const filePush = (file,
|
|
32
|
-
|
|
33
|
-
if (sassObject.map) {
|
|
34
|
-
// Transform map into JSON
|
|
35
|
-
const sassMap = JSON.parse(sassObject.map.toString());
|
|
36
|
-
// Grab the stdout and transform it into stdin
|
|
37
|
-
const sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin');
|
|
38
|
-
// Grab the base filename that's being worked on
|
|
39
|
-
const sassFileSrc = file.relative;
|
|
40
|
-
// Grab the path portion of the file that's being worked on
|
|
41
|
-
const sassFileSrcPath = path.dirname(sassFileSrc);
|
|
42
|
-
|
|
43
|
-
if (sassFileSrcPath) {
|
|
44
|
-
const sourceFileIndex = sassMap.sources.indexOf(sassMapFile);
|
|
45
|
-
// Prepend the path to all files in the sources array except the file that's being worked on
|
|
46
|
-
sassMap.sources = sassMap.sources.map((source, index) => (index === sourceFileIndex ? source : path.join(sassFileSrcPath, source)));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Remove 'stdin' from souces and replace with filenames!
|
|
50
|
-
sassMap.sources = sassMap.sources.filter((src) => src !== 'stdin' && src);
|
|
51
|
-
|
|
52
|
-
// Replace the map file with the original filename (but new extension)
|
|
53
|
-
sassMap.file = replaceExtension(sassFileSrc, '.css');
|
|
54
|
-
// Apply the map
|
|
55
|
-
applySourceMap(file, sassMap);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
file.contents = sassObject.css;
|
|
22
|
+
const filePush = (file, css, callback) => {
|
|
23
|
+
file.contents = css;
|
|
59
24
|
file.path = replaceExtension(file.path, '.css');
|
|
60
25
|
|
|
61
26
|
if (file.stat) {
|
|
@@ -71,7 +36,7 @@ const filePush = (file, sassObject, callback) => {
|
|
|
71
36
|
const handleError = (error, file, callback) => {
|
|
72
37
|
const filePath = (error.file === 'stdin' ? file.path : error.file) || file.path;
|
|
73
38
|
const relativePath = path.relative(process.cwd(), filePath);
|
|
74
|
-
const message = `${
|
|
39
|
+
const message = `${chalk.underline(relativePath)}\n${error.formatted}`;
|
|
75
40
|
|
|
76
41
|
error.messageFormatted = message;
|
|
77
42
|
error.messageOriginal = error.message;
|
|
@@ -81,32 +46,13 @@ const handleError = (error, file, callback) => {
|
|
|
81
46
|
return callback(new PluginError(PLUGIN_NAME, error));
|
|
82
47
|
};
|
|
83
48
|
|
|
84
|
-
/**
|
|
85
|
-
* Escape SCSS variable value for output in SCSS
|
|
86
|
-
* @param {any} value Value
|
|
87
|
-
* @returns {string} Escaped value
|
|
88
|
-
*/
|
|
89
|
-
const escapeSCSSVariable = (value) => {
|
|
90
|
-
if (value !== '' && (value === true || value === false || !isNaN(value))) {
|
|
91
|
-
return String(value);
|
|
92
|
-
} else {
|
|
93
|
-
// Convert to string
|
|
94
|
-
return "'" + value.toString().replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\n/g, '\\n') + "'";
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
49
|
/**
|
|
99
50
|
* Main Gulp Sass function
|
|
100
51
|
*/
|
|
101
52
|
|
|
102
53
|
// eslint-disable-next-line arrow-body-style
|
|
103
|
-
const gulpSass = (options
|
|
54
|
+
const gulpSass = (options) => {
|
|
104
55
|
return transfob((file, encoding, callback) => {
|
|
105
|
-
if (file.isNull()) {
|
|
106
|
-
callback(null, file);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
56
|
if (file.isStream()) {
|
|
111
57
|
callback(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
|
|
112
58
|
return;
|
|
@@ -117,23 +63,21 @@ const gulpSass = (options, sync) => {
|
|
|
117
63
|
return;
|
|
118
64
|
}
|
|
119
65
|
|
|
120
|
-
if (!file.contents.length) {
|
|
66
|
+
if (file.contents && !file.contents.length) {
|
|
121
67
|
file.path = replaceExtension(file.path, '.css');
|
|
122
68
|
callback(null, file);
|
|
123
69
|
return;
|
|
124
70
|
}
|
|
125
71
|
|
|
126
|
-
const opts =
|
|
127
|
-
|
|
72
|
+
const opts = cloneDeep(options || {});
|
|
73
|
+
let source = file.contents.toString();
|
|
128
74
|
|
|
129
75
|
// Stringiyfy variables
|
|
130
|
-
if (
|
|
131
|
-
|
|
76
|
+
if (opts.data) {
|
|
77
|
+
source = sassStingify(opts.data) + source;
|
|
78
|
+
delete(opts.data);
|
|
132
79
|
}
|
|
133
80
|
|
|
134
|
-
// We set the file path here so that libsass can correctly resolve import paths
|
|
135
|
-
opts.file = file.path;
|
|
136
|
-
|
|
137
81
|
// Ensure `indentedSyntax` is true if a `.sass` file
|
|
138
82
|
if (path.extname(file.path) === '.sass') {
|
|
139
83
|
opts.indentedSyntax = true;
|
|
@@ -150,59 +94,35 @@ const gulpSass = (options, sync) => {
|
|
|
150
94
|
|
|
151
95
|
opts.includePaths.unshift(path.dirname(file.path));
|
|
152
96
|
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
opts.omitSourceMapUrl = true;
|
|
157
|
-
opts.sourceMapContents = true;
|
|
158
|
-
}
|
|
97
|
+
// Rename `includePaths` to `loadPaths`
|
|
98
|
+
opts.loadPaths = opts.includePaths;
|
|
99
|
+
delete(opts.includePaths);
|
|
159
100
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (error) {
|
|
166
|
-
handleError(error, file, callback);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
filePush(file, obj, callback);
|
|
171
|
-
});
|
|
172
|
-
} else {
|
|
173
|
-
/**
|
|
174
|
-
* Sync Sass render
|
|
175
|
-
*/
|
|
176
|
-
try {
|
|
177
|
-
filePush(file, gulpSass.compiler.renderSync(opts), callback);
|
|
178
|
-
} catch (error) {
|
|
179
|
-
handleError(error, file, callback);
|
|
180
|
-
}
|
|
101
|
+
try {
|
|
102
|
+
const result = gulpSass.compiler.compileString(source, opts);
|
|
103
|
+
filePush(file, Buffer.from(result.css, 'utf8'), callback);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
handleError(error, file, callback);
|
|
181
106
|
}
|
|
182
107
|
});
|
|
183
108
|
};
|
|
184
109
|
|
|
185
|
-
/**
|
|
186
|
-
* Sync Sass render
|
|
187
|
-
*/
|
|
188
|
-
gulpSass.sync = (options) => gulpSass(options, true);
|
|
189
|
-
|
|
190
110
|
/**
|
|
191
111
|
* Log errors nicely
|
|
192
112
|
*/
|
|
193
113
|
gulpSass.logError = function logError(error) {
|
|
194
|
-
const message = new PluginError('sass', error.messageFormatted).toString();
|
|
114
|
+
const message = new PluginError('sass', error.messageFormatted || error.message).toString();
|
|
195
115
|
process.stderr.write(`${message}\n`);
|
|
196
116
|
this.emit('end');
|
|
197
117
|
};
|
|
198
118
|
|
|
199
|
-
|
|
200
|
-
if (
|
|
201
|
-
|
|
202
|
-
process.stderr.write(`${message}\n`);
|
|
203
|
-
process.exit(1);
|
|
119
|
+
gulpSass.dispose = function () {
|
|
120
|
+
if (gulpSass.compiler.dispose) {
|
|
121
|
+
gulpSass.compiler.dispose();
|
|
204
122
|
}
|
|
123
|
+
}
|
|
205
124
|
|
|
206
|
-
|
|
125
|
+
export default (compiler) => {
|
|
126
|
+
gulpSass.compiler = compiler.initCompiler();
|
|
207
127
|
return gulpSass;
|
|
208
128
|
};
|
|
@@ -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
|
}
|