@videinfra/static-website-builder 1.14.0 → 1.15.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/CHANGELOG.md +4 -0
- package/init/test/.env +2 -0
- package/init/test/.env.local +2 -0
- package/init/test/config/config.js +8 -0
- package/init/test/src/html/env.twig +6 -0
- package/init/test/src/javascripts/main.js +4 -0
- package/init/test/src/stylesheets/env-test.scss +3 -0
- package/package.json +2 -1
- package/plugins/sass-engine/preprocess-config.js +7 -2
- package/tasks/data/get-data.js +3 -2
- package/tasks/env/config.js +23 -0
- package/tasks/env/get-env.js +51 -0
- package/tasks/javascripts/preprocess-config.js +7 -3
- package/tests/build/build.test.js +16 -0
- package/vendor/gulp-sass/CHANGELOG.md +168 -0
- package/vendor/gulp-sass/LICENSE +20 -0
- package/vendor/gulp-sass/README.md +196 -0
- package/vendor/gulp-sass/index.js +225 -0
- package/vendor/gulp-sass/package.json +60 -0
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
|
+
## [1.15.0] - 2025-01-20
|
|
8
|
+
### Added
|
|
9
|
+
- Env file support
|
|
10
|
+
|
|
7
11
|
## [1.14.0] - 2025-01-16
|
|
8
12
|
### Added
|
|
9
13
|
- Fail build process when TWIG task fails
|
package/init/test/.env
ADDED
|
@@ -33,6 +33,13 @@ exports.plugins = [
|
|
|
33
33
|
require('../../../plugins/twig'),
|
|
34
34
|
];
|
|
35
35
|
|
|
36
|
+
exports.env = {
|
|
37
|
+
map: {
|
|
38
|
+
'HOST': 'host',
|
|
39
|
+
'FOO': 'foo',
|
|
40
|
+
'BAR': 'bar',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
36
43
|
|
|
37
44
|
/*
|
|
38
45
|
* Path configuration
|
|
@@ -45,4 +52,5 @@ exports.plugins = [
|
|
|
45
52
|
exports.paths = {
|
|
46
53
|
src: './init/test/src',
|
|
47
54
|
dest: './tests/build/public',
|
|
55
|
+
env: ['./init/test/.env', './init/test/.env.local'],
|
|
48
56
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@videinfra/static-website-builder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"description": "Customizable static site project builder",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"cross-env": "^7.0.3",
|
|
37
37
|
"cssnano": "^6.0.1",
|
|
38
38
|
"del": "^6.0.0",
|
|
39
|
+
"dotenv": "^16.4.7",
|
|
39
40
|
"gulp": "^4.0.2",
|
|
40
41
|
"gulp-cached": "^1.1.1",
|
|
41
42
|
"gulp-data": "^1.3.1",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const paths = require('./../../lib/get-path');
|
|
2
2
|
const getConfig = require('./../../lib/get-config');
|
|
3
3
|
const getPaths = require('./../../lib/get-path');
|
|
4
|
+
const merge = require('./../../lib/merge');
|
|
5
|
+
const getEnvData = require('./../../tasks/env/get-env');
|
|
4
6
|
const assign = require('lodash/assign');
|
|
5
|
-
const gulpSass = require('gulp-sass');
|
|
7
|
+
const gulpSass = require('../../vendor/gulp-sass/index');
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -33,7 +35,10 @@ module.exports = function processSASSConfig (config, fullConfig) {
|
|
|
33
35
|
// Engine is a function which returns a gulp pipe function
|
|
34
36
|
config.engine = function getSASSEngine () {
|
|
35
37
|
const sass = config.legacy ? gulpSass(require('node-sass')) : gulpSass(require('sass'));
|
|
36
|
-
|
|
38
|
+
const sassConfig = getConfig.getTaskConfig('stylesheets', 'sass');
|
|
39
|
+
|
|
40
|
+
sassConfig.data = merge(getEnvData().sass, sassConfig.data || {});
|
|
41
|
+
return sass(sassConfig).on('error', sass.logError)
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
// Main 'dependents' config is shared between all tasks
|
package/tasks/data/get-data.js
CHANGED
|
@@ -8,7 +8,7 @@ const getConfig = require('../../lib/get-config');
|
|
|
8
8
|
const logError = require('../../lib/log-error');
|
|
9
9
|
const getFileNamesSync = require('../../lib/get-file-names');
|
|
10
10
|
const camelizeFileName = require('../../lib/camelize-file-name');
|
|
11
|
-
|
|
11
|
+
const getEnvData = require('../env/get-env');
|
|
12
12
|
|
|
13
13
|
function getData () {
|
|
14
14
|
const folders = getPaths.getSourcePaths('data');
|
|
@@ -61,7 +61,8 @@ function getData () {
|
|
|
61
61
|
return data;
|
|
62
62
|
}, {});
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
// Merge with env variables
|
|
65
|
+
return merge(data, getEnvData().twig);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enviromental variable loading configuration
|
|
3
|
+
* Environment variables are loaded from .env files and remapped so that they can
|
|
4
|
+
* be used in TWIG, SASS and JavaScript:
|
|
5
|
+
* in TWIG `host` is accessible as `host`
|
|
6
|
+
* in SCSS `host` is accessible as `map-get($env, host)`
|
|
7
|
+
* in JS `host` is accessible as `process.env.host`
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
exports.env = {
|
|
11
|
+
// How env variable names should be remapped
|
|
12
|
+
// Example:
|
|
13
|
+
// map: { 'HOST': 'host', 'RECAPTCHA3_PUBLIC_KEY': 'recaptcha3_site_key' }
|
|
14
|
+
map: {}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.paths = {
|
|
18
|
+
// Env files which to load relative to project folder
|
|
19
|
+
env: [
|
|
20
|
+
'../.env',
|
|
21
|
+
'../.env.local',
|
|
22
|
+
],
|
|
23
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const paths = require('../../lib/get-path');
|
|
2
|
+
const dotenv = require('dotenv');
|
|
3
|
+
const getConfig = require('../../lib/get-config');
|
|
4
|
+
|
|
5
|
+
function escapeJSVariable (value) {
|
|
6
|
+
if (value === true || value === false || !isNaN(value)) {
|
|
7
|
+
return value;
|
|
8
|
+
} else {
|
|
9
|
+
// Convert to string
|
|
10
|
+
return "'" + value.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/\n/g, '\\n') + "'";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function getEnvData () {
|
|
15
|
+
const envVariables = {};
|
|
16
|
+
const twigVariables = {};
|
|
17
|
+
const scssVariables = {};
|
|
18
|
+
const jsVariables = {};
|
|
19
|
+
|
|
20
|
+
const envFiles = paths.getPathConfig().env.map((path) => paths.getProjectPath(path));
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
dotenv.config({
|
|
24
|
+
// dotenv file order is reversed, values in first file overwrite all other
|
|
25
|
+
// file values
|
|
26
|
+
path: envFiles.reverse(),
|
|
27
|
+
processEnv: envVariables
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Remap property names
|
|
31
|
+
const map = getConfig.getTaskConfig('env', 'map');
|
|
32
|
+
|
|
33
|
+
Object.keys(map).forEach(key => {
|
|
34
|
+
if (key in envVariables) {
|
|
35
|
+
const value = envVariables[key];
|
|
36
|
+
const camelCase = map[key];
|
|
37
|
+
const kebabCase = map[key].replace(/([a-z])([A-Z])/g, '$1-$2').replace(/_([a-z])/ig, '-$1').toLowerCase();
|
|
38
|
+
twigVariables[camelCase] = value;
|
|
39
|
+
jsVariables[`process.env.${ camelCase }`] = escapeJSVariable(value);
|
|
40
|
+
scssVariables[`env-${ kebabCase }`] = value;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
twig: twigVariables,
|
|
46
|
+
sass: scssVariables,
|
|
47
|
+
js: jsVariables,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = getEnvData;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const paths = require('../../lib/get-path');
|
|
2
2
|
const merge = require('../../lib/merge');
|
|
3
|
+
const getEnvData = require('../env/get-env');
|
|
3
4
|
const get = require('lodash/get');
|
|
4
5
|
const map = require('lodash/map');
|
|
5
6
|
const cloneDeep = require('lodash/cloneDeep');
|
|
@@ -83,6 +84,11 @@ module.exports = function preprocessJavascriptsConfig (config, fullConfig) {
|
|
|
83
84
|
.replace('[folder]/', entry.outpuSubFolder ? entry.outpuSubFolder + '/' : '')
|
|
84
85
|
.replace('[folder]', entry.outpuSubFolder ? entry.outpuSubFolder : '');
|
|
85
86
|
|
|
87
|
+
// Use process.env... variables from .env files
|
|
88
|
+
const envVariables = merge(getEnvData().js, {
|
|
89
|
+
'process.env.NODE_ENV': JSON.stringify(global.production ? 'production' : 'development'),
|
|
90
|
+
});
|
|
91
|
+
|
|
86
92
|
const buildConfig = merge(entryConfig, {
|
|
87
93
|
webpack: {
|
|
88
94
|
mode: global.production ? 'production' : 'development',
|
|
@@ -96,9 +102,7 @@ module.exports = function preprocessJavascriptsConfig (config, fullConfig) {
|
|
|
96
102
|
|
|
97
103
|
// Plugins, add ENV variables
|
|
98
104
|
plugins: [
|
|
99
|
-
new webpack.DefinePlugin(
|
|
100
|
-
'process.env.NODE_ENV': JSON.stringify(global.production ? 'production' : 'development'),
|
|
101
|
-
}),
|
|
105
|
+
new webpack.DefinePlugin(envVariables),
|
|
102
106
|
new WatchExternalFilesPlugin.default({
|
|
103
107
|
verbose: false,
|
|
104
108
|
files: [
|
|
@@ -93,6 +93,22 @@ test('alt/other.js file doesn\'t exist', async () => {
|
|
|
93
93
|
expect(fsPromises.stat(path.resolve(publicPath, 'assets/javascripts/alt/other.js'))).rejects.toThrow();
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
+
test('.env and .env.local files loaded', () => {
|
|
97
|
+
return Promise.all([
|
|
98
|
+
fsPromises.readFile(path.resolve(publicPath, 'assets/javascripts/main.js'), {'encoding': 'utf8'}).then((js) => {
|
|
99
|
+
expect(js.indexOf('console.log("env.host ==","https://test-local.tld")')).not.toBe(-1);
|
|
100
|
+
expect(js.indexOf('console.log("env.foo ==","foo-global")')).not.toBe(-1);
|
|
101
|
+
expect(js.indexOf('console.log("env.bar ==","bar-local")')).not.toBe(-1);
|
|
102
|
+
}),
|
|
103
|
+
fsPromises.readFile(path.resolve(publicPath, 'env.html'), {'encoding': 'utf8'}).then((html) => {
|
|
104
|
+
expect(html.indexOf('<p>HOST: https://test-local.tld</p>')).not.toBe(-1);
|
|
105
|
+
}),
|
|
106
|
+
fsPromises.readFile(path.resolve(publicPath, 'assets/stylesheets/env-test.css'), {'encoding': 'utf8'}).then((css) => {
|
|
107
|
+
expect(css.indexOf('.env-test:before{content:"https://test-local.tld"}')).not.toBe(-1);
|
|
108
|
+
}),
|
|
109
|
+
]);
|
|
110
|
+
});
|
|
111
|
+
|
|
96
112
|
test('icons generated', () => {
|
|
97
113
|
return fsPromises.readFile(path.resolve(publicPath, 'assets/images/icons.svg'), {'encoding': 'utf8'}).then((svg) => {
|
|
98
114
|
expect(svg.indexOf('<symbol id="example-arrow">')).not.toBe(-1);
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# gulp-sass Changelog
|
|
2
|
+
|
|
3
|
+
## v5.0.0
|
|
4
|
+
|
|
5
|
+
**June 25, 2021**
|
|
6
|
+
|
|
7
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v5.0.0>
|
|
8
|
+
|
|
9
|
+
## v4.1.1
|
|
10
|
+
|
|
11
|
+
**June 24, 2021**
|
|
12
|
+
|
|
13
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v4.1.1>
|
|
14
|
+
|
|
15
|
+
## v4.1.0
|
|
16
|
+
|
|
17
|
+
**April 23, 2020**
|
|
18
|
+
|
|
19
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v4.1.0>
|
|
20
|
+
|
|
21
|
+
## v4.0.2
|
|
22
|
+
|
|
23
|
+
**October 16, 2018**
|
|
24
|
+
|
|
25
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v4.0.2>
|
|
26
|
+
|
|
27
|
+
## v4.0.1
|
|
28
|
+
|
|
29
|
+
**Apr 8, 2018**
|
|
30
|
+
|
|
31
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v4.0.1>
|
|
32
|
+
|
|
33
|
+
## v4.0.0
|
|
34
|
+
|
|
35
|
+
**April 5, 2018**
|
|
36
|
+
|
|
37
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v4.0.0>
|
|
38
|
+
|
|
39
|
+
## v3.2.1
|
|
40
|
+
|
|
41
|
+
**March 24, 2018**
|
|
42
|
+
|
|
43
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v3.2.1>
|
|
44
|
+
|
|
45
|
+
## v3.2.0
|
|
46
|
+
|
|
47
|
+
**March 12, 2018**
|
|
48
|
+
|
|
49
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v3.2.0>
|
|
50
|
+
|
|
51
|
+
## v3.1.0
|
|
52
|
+
|
|
53
|
+
**January 9, 2017**
|
|
54
|
+
|
|
55
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v3.1.0>
|
|
56
|
+
|
|
57
|
+
## v3.0.0
|
|
58
|
+
|
|
59
|
+
**January 9, 2017**
|
|
60
|
+
|
|
61
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v3.0.0>
|
|
62
|
+
|
|
63
|
+
## v2.3.2
|
|
64
|
+
|
|
65
|
+
**June 15, 2016**
|
|
66
|
+
|
|
67
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.3.2>
|
|
68
|
+
|
|
69
|
+
## v2.3.1
|
|
70
|
+
|
|
71
|
+
**April 22, 2016**
|
|
72
|
+
|
|
73
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.3.1>
|
|
74
|
+
|
|
75
|
+
## v2.3.0
|
|
76
|
+
|
|
77
|
+
**April 21, 2016**
|
|
78
|
+
|
|
79
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.3.0>
|
|
80
|
+
|
|
81
|
+
## v2.3.0-beta.1
|
|
82
|
+
|
|
83
|
+
**February 4, 2016**
|
|
84
|
+
|
|
85
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.3.0-beta.1>
|
|
86
|
+
|
|
87
|
+
## v2.2.0
|
|
88
|
+
|
|
89
|
+
**February 4, 2016**
|
|
90
|
+
|
|
91
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.2.0>
|
|
92
|
+
|
|
93
|
+
## v2.1.0
|
|
94
|
+
|
|
95
|
+
**November 2, 2015**
|
|
96
|
+
|
|
97
|
+
<https://github.com/dlmanning/gulp-sass/releases/tag/v2.1.0>
|
|
98
|
+
|
|
99
|
+
## v2.1.0-beta
|
|
100
|
+
|
|
101
|
+
**September 21, 2015**
|
|
102
|
+
|
|
103
|
+
* **Change** Updated to `node-sass` 3.4.0-beta1
|
|
104
|
+
|
|
105
|
+
## v2.0.4
|
|
106
|
+
|
|
107
|
+
**July 15, 2015**
|
|
108
|
+
|
|
109
|
+
* **Fix** Relative file path now uses `file.relative` instead of arcane `split('/').pop` magic. Resolves lots of issues with source map paths.
|
|
110
|
+
* **Fix** Empty partials no longer copied to CSS folder
|
|
111
|
+
|
|
112
|
+
## v2.0.3
|
|
113
|
+
|
|
114
|
+
**June 27, 2015**
|
|
115
|
+
|
|
116
|
+
* **Fix** Empty partials are no longer copied to CSS folder
|
|
117
|
+
|
|
118
|
+
## v2.0.2
|
|
119
|
+
|
|
120
|
+
**June 25, 2015**
|
|
121
|
+
|
|
122
|
+
* **Fix** Error in watch stream preventing watch from continuing
|
|
123
|
+
|
|
124
|
+
## v2.0.1
|
|
125
|
+
|
|
126
|
+
**May 13, 2015**
|
|
127
|
+
|
|
128
|
+
* **Fix** Source maps now work as expected with Autoprefixer
|
|
129
|
+
* **Fix** Current file directory `unshift` onto includePaths stack so it's checked first
|
|
130
|
+
* **Fix** Error message returned is unformatted so as to not break other error handling (*i.e.* `gulp-notify`)
|
|
131
|
+
|
|
132
|
+
## v2.0.0
|
|
133
|
+
|
|
134
|
+
**May 6, 2015**
|
|
135
|
+
|
|
136
|
+
* **Change** Updated to `node-sass` 3.0.0
|
|
137
|
+
|
|
138
|
+
## v2.0.0-alpha.1
|
|
139
|
+
|
|
140
|
+
**March 26, 2015**
|
|
141
|
+
|
|
142
|
+
* **New** Added `renderSync` option that can be used through `sass.sync()`
|
|
143
|
+
|
|
144
|
+
### March 24, 2015
|
|
145
|
+
|
|
146
|
+
* **Change** Updated to `node-sass` 3.0.0-alpha.1
|
|
147
|
+
* **New** Added support for `gulp-sourcemaps` including tests
|
|
148
|
+
* **New** Added `.editorconfig` for development consistency
|
|
149
|
+
* **New** Added linting and test for said linting
|
|
150
|
+
* **Change** Updated the README
|
|
151
|
+
* **New** `logError` function to make streaming errors possible instead of breaking the stream
|
|
152
|
+
|
|
153
|
+
### 1.3.3
|
|
154
|
+
|
|
155
|
+
* updated to `node-sass` 2.0 (final)
|
|
156
|
+
* should now work with Node.js 0.12 and io.js
|
|
157
|
+
|
|
158
|
+
### 1.3.2
|
|
159
|
+
|
|
160
|
+
* fixed `errLogToConsole`
|
|
161
|
+
|
|
162
|
+
### 1.3.1
|
|
163
|
+
|
|
164
|
+
* bug fix
|
|
165
|
+
|
|
166
|
+
## Version 1.3.0
|
|
167
|
+
|
|
168
|
+
* Supports `node-sass` 2.0 (thanks laurelnaiad!)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 David Manning
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# gulp-sass  [](https://github.com/dlmanning/gulp-sass/actions?query=workflow%3ACI+branch%3Amaster) [](https://gitter.im/dlmanning/gulp-sass) 
|
|
2
|
+
|
|
3
|
+
Sass plugin for [Gulp](https://github.com/gulpjs/gulp).
|
|
4
|
+
|
|
5
|
+
**_Before filing an issue, please make sure you have [updated to the latest version of `gulp-sass`](https://github.com/dlmanning/gulp-sass/wiki/Update-to-the-latest-Gulp-Sass) and have gone through our [Common Issues and Their Fixes](https://github.com/dlmanning/gulp-sass/wiki/Common-Issues-and-Their-Fixes) section._**
|
|
6
|
+
|
|
7
|
+
**Migrating your existing project to version 5? Please read our (short!) [migration guide](#migrating-to-version-5).**
|
|
8
|
+
|
|
9
|
+
## Support
|
|
10
|
+
|
|
11
|
+
Only [Active LTS and Current releases](https://github.com/nodejs/Release#release-schedule) are supported.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
To use `gulp-sass`, you must install both `gulp-sass` itself *and* a Sass compiler. `gulp-sass` supports both [Dart Sass][] and [Node Sass][], although Node Sass is [deprecated](https://sass-lang.com/blog/libsass-is-deprecated). We recommend that you use Dart Sass for new projects, and migrate Node Sass projects to Dart Sass when possible.
|
|
16
|
+
|
|
17
|
+
Whichever compiler you choose, it's best to install these as dev dependencies:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm install sass gulp-sass --save-dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Importing it into your project
|
|
24
|
+
|
|
25
|
+
`gulp-sass` must be imported into your gulpfile, where you provide it the compiler of your choice. To use `gulp-sass` in a CommonJS module (which is most Node.js environments), do something like this:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
const sass = require('gulp-sass')(require('sass'));
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
To use `gulp-sass` in an ECMAScript module (which is supported in newer Node.js 14 and later), do something like this:
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
import dartSass from 'sass';
|
|
35
|
+
import gulpSass from 'gulp-sass';
|
|
36
|
+
const sass = gulpSass(dartSass);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
**Note:** These examples are written for CommonJS modules and assume you're using Gulp 4. For examples that work with Gulp 3, [check the docs for an earlier version of `gulp-sass`](https://github.com/dlmanning/gulp-sass/tree/v4.1.1).
|
|
42
|
+
|
|
43
|
+
`gulp-sass` must be used in a Gulp task. Your task can call `sass()` (to asynchronously render your CSS), or `sass.sync()` (to synchronously render your CSS). Then, export your task with the `export` keyword. We'll show some examples of how to do that.
|
|
44
|
+
|
|
45
|
+
**⚠️ Note:** When using Dart Sass, **synchronous rendering is twice as fast as asynchronous rendering**. The Sass team is exploring ways to improve asynchronous rendering with Dart Sass, but for now, you will get the best performance from `sass.sync()`. If performance is critical, you can use `node-sass` instead, but bear in mind that `node-sass` may not support modern Sass features you rely on.
|
|
46
|
+
|
|
47
|
+
### Render your CSS
|
|
48
|
+
|
|
49
|
+
To render your CSS with a build task, then watch your files for changes, you might write something like this:
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
'use strict';
|
|
53
|
+
|
|
54
|
+
const gulp = require('gulp');
|
|
55
|
+
const sass = require('gulp-sass')(require('sass'));
|
|
56
|
+
|
|
57
|
+
function buildStyles() {
|
|
58
|
+
return gulp.src('./sass/**/*.scss')
|
|
59
|
+
.pipe(sass().on('error', sass.logError))
|
|
60
|
+
.pipe(gulp.dest('./css'));
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.buildStyles = buildStyles;
|
|
64
|
+
exports.watch = function () {
|
|
65
|
+
gulp.watch('./sass/**/*.scss', ['sass']);
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
With synchronous rendering, that Gulp task looks like this:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
function buildStyles() {
|
|
73
|
+
return gulp.src('./sass/**/*.scss')
|
|
74
|
+
.pipe(sass.sync().on('error', sass.logError))
|
|
75
|
+
.pipe(gulp.dest('./css'));
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Render with options
|
|
80
|
+
|
|
81
|
+
To change the final output of your CSS, you can pass an options object to your renderer. `gulp-sass` supports [Node Sass's render options](https://github.com/sass/node-sass#options), with two unsupported exceptions:
|
|
82
|
+
|
|
83
|
+
- The `data` option, which is used by `gulp-sass` internally.
|
|
84
|
+
- The `file` option, which has undefined behavior that may change without notice.
|
|
85
|
+
|
|
86
|
+
For example, to compress your CSS, you can call `sass({outputStyle: 'compressed'}`. In the context of a Gulp task, that looks like this:
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
function buildStyles() {
|
|
90
|
+
return gulp.src('./sass/**/*.scss')
|
|
91
|
+
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
|
|
92
|
+
.pipe(gulp.dest('./css'));
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
exports.buildStyles = buildStyles;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or this for synchronous rendering:
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
function buildStyles() {
|
|
102
|
+
return gulp.src('./sass/**/*.scss')
|
|
103
|
+
.pipe(sass.sync({outputStyle: 'compressed'}).on('error', sass.logError))
|
|
104
|
+
.pipe(gulp.dest('./css'));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
exports.buildStyles = buildStyles;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Include a source map
|
|
111
|
+
|
|
112
|
+
`gulp-sass` can be used in tandem with [`gulp-sourcemaps`](https://github.com/gulp-sourcemaps/gulp-sourcemaps) to generate source maps for the Sass-to-CSS compilation. You will need to initialize `gulp-sourcemaps` _before_ running `gulp-sass`, and write the source maps after.
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
const sourcemaps = require('gulp-sourcemaps');
|
|
116
|
+
|
|
117
|
+
function buildStyles() {
|
|
118
|
+
return gulp.src('./sass/**/*.scss')
|
|
119
|
+
.pipe(sourcemaps.init())
|
|
120
|
+
.pipe(sass().on('error', sass.logError))
|
|
121
|
+
.pipe(sourcemaps.write())
|
|
122
|
+
.pipe(gulp.dest('./css'));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
exports.buildStyles = buildStyles;
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
By default, `gulp-sourcemaps` writes the source maps inline, in the compiled CSS files. To write them to a separate file, specify a path relative to the `gulp.dest()` destination in the `sourcemaps.write()` function.
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
const sourcemaps = require('gulp-sourcemaps');
|
|
132
|
+
|
|
133
|
+
function buildStyles() {
|
|
134
|
+
return gulp.src('./sass/**/*.scss')
|
|
135
|
+
.pipe(sourcemaps.init())
|
|
136
|
+
.pipe(sass().on('error', sass.logError))
|
|
137
|
+
.pipe(sourcemaps.write('./maps'))
|
|
138
|
+
.pipe(gulp.dest('./css'));
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
exports.buildStyles = buildStyles;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
<h2 id="migrating-to-version-5">Migrating to version 5</h2>
|
|
145
|
+
|
|
146
|
+
`gulp-sass` version 5 requires Node.js 12 or later, and introduces some breaking changes. Additionally, changes in Node.js itself mean that Node fibers can no longer be used to speed up Dart Sass in Node.js 16.
|
|
147
|
+
|
|
148
|
+
### Setting a Sass compiler
|
|
149
|
+
|
|
150
|
+
As of version 5, `gulp-sass` _does not include a default Sass compiler_, so you must install one (either `node-sass` or `sass`) along with `gulp-sass`.
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npm install sass gulp-sass --save-dev
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Then, you must explicitly set that compiler in your gulpfille. Instead of setting a `compiler` prop on the `gulp-sass` instance, you pass the compiler into a function call when instantiating `gulp-sass`.
|
|
157
|
+
|
|
158
|
+
These changes look something like this:
|
|
159
|
+
|
|
160
|
+
```diff
|
|
161
|
+
- const sass = require('gulp-sass'));
|
|
162
|
+
- const compiler = require('sass');
|
|
163
|
+
- sass.compiler = compiler;
|
|
164
|
+
+ const sass = require('gulp-sass')(require('sass'));
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
If you're migrating an ECMAScript module, that'll look something like this:
|
|
168
|
+
|
|
169
|
+
```diff
|
|
170
|
+
import dartSass from 'sass';
|
|
171
|
+
- import sass from 'gulp-sass';
|
|
172
|
+
- sass.compiler = dartSass;
|
|
173
|
+
|
|
174
|
+
import dartSass from 'sass';
|
|
175
|
+
+ import gulpSass from 'gulp-sass';
|
|
176
|
+
+ const sass = gulpSass(dartSass);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### What about fibers?
|
|
180
|
+
|
|
181
|
+
We used to recommend Node fibers as a way to speed up asynchronous rendering with Dart Sass. Unfortunately, [Node fibers are discontinued](https://sass-lang.com/blog/node-fibers-discontinued) and will not work in Node.js 16. The Sass team is exploring its options for future performance improvements, but for now, you will get the best performance from `sass.sync()`.
|
|
182
|
+
|
|
183
|
+
## Issues
|
|
184
|
+
|
|
185
|
+
`gulp-sass` is a light-weight wrapper around either [Dart Sass][] or [Node Sass][] (which in turn is a Node.js binding for [LibSass][]. Because of this, the issue you're having likely isn't a `gulp-sass` issue, but an issue with one those projects or with [Sass][] as a whole.
|
|
186
|
+
|
|
187
|
+
If you have a feature request/question about how Sass works/concerns on how your Sass gets compiled/errors in your compiling, it's likely a Dart Sass or LibSass issue and you should file your issue with one of those projects.
|
|
188
|
+
|
|
189
|
+
If you're having problems with the options you're passing in, it's likely a Dart Sass or Node Sass issue and you should file your issue with one of those projects.
|
|
190
|
+
|
|
191
|
+
We may, in the course of resolving issues, direct you to one of these other projects. If we do so, please follow up by searching that project's issue queue (both open and closed) for your problem and, if it doesn't exist, filing an issue with them.
|
|
192
|
+
|
|
193
|
+
[Dart Sass]: https://sass-lang.com/dart-sass
|
|
194
|
+
[LibSass]: https://sass-lang.com/libsass
|
|
195
|
+
[Node Sass]: https://github.com/sass/node-sass
|
|
196
|
+
[Sass]: https://sass-lang.com
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// 2025-01-20, Kaspars Zuks: added "options.data" support for variables
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { Transform } = require('stream');
|
|
6
|
+
const picocolors = require('picocolors');
|
|
7
|
+
const PluginError = require('plugin-error');
|
|
8
|
+
const replaceExtension = require('replace-ext');
|
|
9
|
+
const stripAnsi = require('strip-ansi');
|
|
10
|
+
const clonedeep = require('lodash.clonedeep');
|
|
11
|
+
const applySourceMap = require('vinyl-sourcemaps-apply');
|
|
12
|
+
|
|
13
|
+
const PLUGIN_NAME = 'gulp-sass';
|
|
14
|
+
|
|
15
|
+
const MISSING_COMPILER_MESSAGE = `
|
|
16
|
+
gulp-sass no longer has a default Sass compiler; please set one yourself.
|
|
17
|
+
Both the "sass" and "node-sass" packages are permitted.
|
|
18
|
+
For example, in your gulpfile:
|
|
19
|
+
|
|
20
|
+
const sass = require('gulp-sass')(require('sass'));
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const transfob = (transform) => new Transform({ transform, objectMode: true });
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Handles returning the file to the stream
|
|
27
|
+
*/
|
|
28
|
+
const filePush = (file, sassObject, callback) => {
|
|
29
|
+
// Build Source Maps!
|
|
30
|
+
if (sassObject.map) {
|
|
31
|
+
// Transform map into JSON
|
|
32
|
+
const sassMap = JSON.parse(sassObject.map.toString());
|
|
33
|
+
// Grab the stdout and transform it into stdin
|
|
34
|
+
const sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin');
|
|
35
|
+
// Grab the base filename that's being worked on
|
|
36
|
+
const sassFileSrc = file.relative;
|
|
37
|
+
// Grab the path portion of the file that's being worked on
|
|
38
|
+
const sassFileSrcPath = path.dirname(sassFileSrc);
|
|
39
|
+
|
|
40
|
+
if (sassFileSrcPath) {
|
|
41
|
+
const sourceFileIndex = sassMap.sources.indexOf(sassMapFile);
|
|
42
|
+
// Prepend the path to all files in the sources array except the file that's being worked on
|
|
43
|
+
sassMap.sources = sassMap.sources.map((source, index) => (
|
|
44
|
+
index === sourceFileIndex
|
|
45
|
+
? source
|
|
46
|
+
: path.join(sassFileSrcPath, source)
|
|
47
|
+
));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Remove 'stdin' from souces and replace with filenames!
|
|
51
|
+
sassMap.sources = sassMap.sources.filter((src) => src !== 'stdin' && src);
|
|
52
|
+
|
|
53
|
+
// Replace the map file with the original filename (but new extension)
|
|
54
|
+
sassMap.file = replaceExtension(sassFileSrc, '.css');
|
|
55
|
+
// Apply the map
|
|
56
|
+
applySourceMap(file, sassMap);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
file.contents = sassObject.css;
|
|
60
|
+
file.path = replaceExtension(file.path, '.css');
|
|
61
|
+
|
|
62
|
+
if (file.stat) {
|
|
63
|
+
file.stat.atime = file.stat.mtime = file.stat.ctime = new Date();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
callback(null, file);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Handles error message
|
|
71
|
+
*/
|
|
72
|
+
const handleError = (error, file, callback) => {
|
|
73
|
+
const filePath = (error.file === 'stdin' ? file.path : error.file) || file.path;
|
|
74
|
+
const relativePath = path.relative(process.cwd(), filePath);
|
|
75
|
+
const message = `${picocolors.underline(relativePath)}\n${error.formatted}`;
|
|
76
|
+
|
|
77
|
+
error.messageFormatted = message;
|
|
78
|
+
error.messageOriginal = error.message;
|
|
79
|
+
error.message = stripAnsi(message);
|
|
80
|
+
error.relativePath = relativePath;
|
|
81
|
+
|
|
82
|
+
return callback(new PluginError(PLUGIN_NAME, error));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Escape SCSS variable value for output in SCSS
|
|
87
|
+
* @param {any} value Value
|
|
88
|
+
* @returns {string} Escaped value
|
|
89
|
+
*/
|
|
90
|
+
const escapeSCSSVariable = (value) => {
|
|
91
|
+
if (value !== '' && (value === true || value === false || !isNaN(value))) {
|
|
92
|
+
return String(value);
|
|
93
|
+
} else {
|
|
94
|
+
// Convert to string
|
|
95
|
+
return "'" + value.toString().replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/\n/g, '\\n') + "'";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Main Gulp Sass function
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
// eslint-disable-next-line arrow-body-style
|
|
104
|
+
const gulpSass = (options, sync) => {
|
|
105
|
+
return transfob((file, encoding, callback) => {
|
|
106
|
+
if (file.isNull()) {
|
|
107
|
+
callback(null, file);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (file.isStream()) {
|
|
112
|
+
callback(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (path.basename(file.path).startsWith('_')) {
|
|
117
|
+
callback();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!file.contents.length) {
|
|
122
|
+
file.path = replaceExtension(file.path, '.css');
|
|
123
|
+
callback(null, file);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const opts = clonedeep(options || {});
|
|
128
|
+
opts.data = file.contents.toString();
|
|
129
|
+
|
|
130
|
+
// Stringiyfy variables
|
|
131
|
+
if (options.data) {
|
|
132
|
+
const scssVariables = [];
|
|
133
|
+
|
|
134
|
+
if (typeof options.data === 'string') {
|
|
135
|
+
// Assume it's valid SCSS
|
|
136
|
+
scssVariables.push(options.data);
|
|
137
|
+
} else {
|
|
138
|
+
for (let key in options.data) {
|
|
139
|
+
const value = escapeSCSSVariable(options.data[key]);
|
|
140
|
+
scssVariables.push(`$${key}: ${value};`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
opts.data = scssVariables.join('') + opts.data;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// We set the file path here so that libsass can correctly resolve import paths
|
|
148
|
+
opts.file = file.path;
|
|
149
|
+
|
|
150
|
+
// Ensure `indentedSyntax` is true if a `.sass` file
|
|
151
|
+
if (path.extname(file.path) === '.sass') {
|
|
152
|
+
opts.indentedSyntax = true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Ensure file's parent directory in the include path
|
|
156
|
+
if (opts.includePaths) {
|
|
157
|
+
if (typeof opts.includePaths === 'string') {
|
|
158
|
+
opts.includePaths = [opts.includePaths];
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
opts.includePaths = [];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
opts.includePaths.unshift(path.dirname(file.path));
|
|
165
|
+
|
|
166
|
+
// Generate Source Maps if the source-map plugin is present
|
|
167
|
+
if (file.sourceMap) {
|
|
168
|
+
opts.sourceMap = file.path;
|
|
169
|
+
opts.omitSourceMapUrl = true;
|
|
170
|
+
opts.sourceMapContents = true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (sync !== true) {
|
|
174
|
+
/**
|
|
175
|
+
* Async Sass render
|
|
176
|
+
*/
|
|
177
|
+
gulpSass.compiler.render(opts, (error, obj) => {
|
|
178
|
+
if (error) {
|
|
179
|
+
handleError(error, file, callback);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
filePush(file, obj, callback);
|
|
184
|
+
});
|
|
185
|
+
} else {
|
|
186
|
+
/**
|
|
187
|
+
* Sync Sass render
|
|
188
|
+
*/
|
|
189
|
+
try {
|
|
190
|
+
filePush(file, gulpSass.compiler.renderSync(opts), callback);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
handleError(error, file, callback);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Sync Sass render
|
|
200
|
+
*/
|
|
201
|
+
gulpSass.sync = (options) => gulpSass(options, true);
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Log errors nicely
|
|
205
|
+
*/
|
|
206
|
+
gulpSass.logError = function logError(error) {
|
|
207
|
+
const message = new PluginError('sass', error.messageFormatted).toString();
|
|
208
|
+
process.stderr.write(`${message}\n`);
|
|
209
|
+
this.emit('end');
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
module.exports = (compiler) => {
|
|
213
|
+
if (!compiler || !compiler.render) {
|
|
214
|
+
const message = new PluginError(
|
|
215
|
+
PLUGIN_NAME,
|
|
216
|
+
MISSING_COMPILER_MESSAGE,
|
|
217
|
+
{ showProperties: false },
|
|
218
|
+
).toString();
|
|
219
|
+
process.stderr.write(`${message}\n`);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
gulpSass.compiler = compiler;
|
|
224
|
+
return gulpSass;
|
|
225
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gulp-sass",
|
|
3
|
+
"version": "5.1.0",
|
|
4
|
+
"description": "Gulp plugin for sass",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=12"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"lint": "eslint --report-unused-disable-directives --ignore-path .gitignore .",
|
|
11
|
+
"fix": "npm run lint -- --fix",
|
|
12
|
+
"mocha": "mocha",
|
|
13
|
+
"test": "npm run test:node-sass && npm run test:dart-sass",
|
|
14
|
+
"test:node-sass": "mocha",
|
|
15
|
+
"test:dart-sass": "mocha -- --sass"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/dlmanning/gulp-sass.git"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"gulpplugin",
|
|
23
|
+
"sass",
|
|
24
|
+
"gulp"
|
|
25
|
+
],
|
|
26
|
+
"author": "David Manning",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/dlmanning/gulp-sass/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/dlmanning/gulp-sass#readme",
|
|
32
|
+
"files": [
|
|
33
|
+
"index.js"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"lodash.clonedeep": "^4.5.0",
|
|
37
|
+
"picocolors": "^1.0.0",
|
|
38
|
+
"plugin-error": "^1.0.1",
|
|
39
|
+
"replace-ext": "^2.0.0",
|
|
40
|
+
"strip-ansi": "^6.0.1",
|
|
41
|
+
"vinyl-sourcemaps-apply": "^0.2.1"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"autoprefixer": "^10.4.0",
|
|
45
|
+
"eslint": "^8.5.0",
|
|
46
|
+
"eslint-config-airbnb-base": "^15.0.0",
|
|
47
|
+
"eslint-plugin-import": "^2.25.3",
|
|
48
|
+
"globule": "^1.3.3",
|
|
49
|
+
"gulp": "^4.0.2",
|
|
50
|
+
"gulp-postcss": "^9.0.1",
|
|
51
|
+
"gulp-sourcemaps": "^3.0.0",
|
|
52
|
+
"gulp-tap": "^2.0.0",
|
|
53
|
+
"mocha": "^9.1.3",
|
|
54
|
+
"node-sass": "^7.0.1",
|
|
55
|
+
"postcss": "^8.4.5",
|
|
56
|
+
"rimraf": "^3.0.2",
|
|
57
|
+
"sass": "^1.45.1",
|
|
58
|
+
"vinyl": "^2.2.1"
|
|
59
|
+
}
|
|
60
|
+
}
|