sdc-build-wp 4.1.4 → 4.3.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/README.md +1 -0
- package/index.js +22 -252
- package/lib/components/base.js +47 -0
- package/lib/components/blocks.js +112 -0
- package/lib/components/fonts.js +41 -0
- package/lib/components/images.js +60 -0
- package/lib/components/index.js +7 -0
- package/lib/components/php.js +107 -0
- package/lib/components/scripts.js +87 -0
- package/lib/components/server.js +70 -0
- package/lib/components/style.js +198 -0
- package/lib/project.js +35 -2
- package/lib/utils.js +60 -0
- package/package.json +2 -2
- package/lib/blocks.js +0 -63
- package/lib/browsersync.js +0 -55
- package/lib/fonts.js +0 -19
- package/lib/images.js +0 -22
- package/lib/php.js +0 -71
- package/lib/scripts.js +0 -49
- package/lib/style.js +0 -155
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -1,276 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import project from './lib/project.js';
|
|
4
2
|
import parseArgs from 'minimist';
|
|
5
3
|
const argv = parseArgs(process.argv.slice(2));
|
|
6
|
-
import
|
|
7
|
-
import { glob, readdir } from 'node:fs/promises';
|
|
8
|
-
import { existsSync } from 'node:fs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
9
5
|
import { Tail } from 'tail';
|
|
10
|
-
|
|
6
|
+
import project from './lib/project.js';
|
|
11
7
|
import log from './lib/logging.js';
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
json: `${project.path}/theme.json`,
|
|
23
|
-
scss: `${project.path}/_src/style/partials/_theme.scss`
|
|
24
|
-
},
|
|
25
|
-
nodeModules: `${project.path}/node_modules`,
|
|
26
|
-
composer: {
|
|
27
|
-
vendor: `${project.path}/vendor`
|
|
28
|
-
},
|
|
29
|
-
images: project.package?.sdc?.imagesPath || `${project.path}/_src/images`,
|
|
30
|
-
errorLog: process.env.ERROR_LOG_PATH || project.package.sdc?.error_log_path || '../../../../../logs/php/error.log'
|
|
8
|
+
import * as LibComponents from './lib/components/index.js';
|
|
9
|
+
|
|
10
|
+
project.components = {
|
|
11
|
+
style: new LibComponents.style(),
|
|
12
|
+
scripts: new LibComponents.scripts(),
|
|
13
|
+
blocks: new LibComponents.blocks(),
|
|
14
|
+
images: new LibComponents.images(),
|
|
15
|
+
fonts: new LibComponents.fonts(),
|
|
16
|
+
php: new LibComponents.php(),
|
|
17
|
+
server: new LibComponents.server()
|
|
31
18
|
};
|
|
32
19
|
|
|
33
|
-
let
|
|
34
|
-
ignoreInitial: true,
|
|
35
|
-
ignored: [
|
|
36
|
-
paths.nodeModules,
|
|
37
|
-
paths.composer.vendor,
|
|
38
|
-
paths.theme.scss
|
|
39
|
-
]
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
let globs = {};
|
|
43
|
-
let entries = {};
|
|
44
|
-
let filesSass = [];
|
|
45
|
-
let filesJS = [];
|
|
46
|
-
|
|
47
|
-
let builds = argv.builds ? argv.builds.split(',') : [
|
|
48
|
-
'sass',
|
|
49
|
-
'js',
|
|
50
|
-
'blocks',
|
|
51
|
-
'images',
|
|
52
|
-
'fonts',
|
|
53
|
-
'php'
|
|
54
|
-
];
|
|
20
|
+
let builds = argv.builds ? argv.builds.split(',') : Object.keys(project.components).map(key => project.components[key].slug);
|
|
55
21
|
|
|
56
22
|
(async() => {
|
|
57
23
|
|
|
58
24
|
let initialBuildTimerStart = Date.now();
|
|
59
25
|
log('info', `Starting initial build`);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
globs.sass = await Array.fromAsync(
|
|
63
|
-
glob(project.package?.sdc?.sassGlobPath ||
|
|
64
|
-
`${project.path}{/_src/style,/blocks}/**/*.scss`)
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
if (builds.includes('js')) {
|
|
68
|
-
globs.js = await Array.fromAsync(
|
|
69
|
-
glob(project.package?.sdc?.jsGlobPath ||
|
|
70
|
-
`${project.path}/_src/scripts/**/*.js`)
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
if (builds.includes('blocks')) {
|
|
74
|
-
globs.blocks = await Array.fromAsync(
|
|
75
|
-
glob(`${project.path}/blocks/*`)
|
|
76
|
-
);
|
|
77
|
-
globs.blocksSass = await Array.fromAsync(
|
|
78
|
-
glob(`${project.path}/blocks/*/src/*.scss`)
|
|
79
|
-
);
|
|
80
|
-
// for (var filename of globs.blocksSass) {
|
|
81
|
-
// entries[`blocks/${path.basename(path.dirname(filename))}/style`] = [ filename ];
|
|
82
|
-
// }
|
|
26
|
+
for (let build of builds) {
|
|
27
|
+
await project.components[build].init();
|
|
83
28
|
}
|
|
84
|
-
if (builds.includes('images')) {
|
|
85
|
-
globs.images = await Array.fromAsync(
|
|
86
|
-
glob(project.package?.sdc?.imagesPath ||
|
|
87
|
-
`${paths.images}/**/*`)
|
|
88
|
-
);
|
|
89
|
-
globs.imageDirectories = [
|
|
90
|
-
paths.images,
|
|
91
|
-
...await getAllSubdirectories(paths.images)
|
|
92
|
-
];
|
|
93
|
-
}
|
|
94
|
-
if (builds.includes('php')) {
|
|
95
|
-
globs.php = await Array.fromAsync(
|
|
96
|
-
glob(project.package?.sdc?.jsGlobPath ||
|
|
97
|
-
`${project.path}/**/*.php`)
|
|
98
|
-
);
|
|
99
|
-
globs.blocksPHP = await Array.fromAsync(
|
|
100
|
-
glob(`${project.path}/blocks/*/build/*.php`)
|
|
101
|
-
);
|
|
102
|
-
chokidarOpts.ignored = [
|
|
103
|
-
...chokidarOpts.ignored,
|
|
104
|
-
...globs.blocksPHP
|
|
105
|
-
];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
for (const [name, files] of Object.entries(project.package.sdc.entries)) {
|
|
109
|
-
entries[name] = [];
|
|
110
|
-
files.forEach(function(file) {
|
|
111
|
-
entries[name].push(project.path + file);
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
for (const [name, files] of Object.entries(entries)) {
|
|
116
|
-
files.forEach(function(file) {
|
|
117
|
-
switch (path.parse(file).ext) {
|
|
118
|
-
case '.scss':
|
|
119
|
-
if (builds.includes('sass')) {
|
|
120
|
-
filesSass.push({
|
|
121
|
-
'name': name,
|
|
122
|
-
'file': file
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
case '.js':
|
|
127
|
-
if (builds.includes('js')) {
|
|
128
|
-
filesJS.push({
|
|
129
|
-
'name': name,
|
|
130
|
-
'file': file
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (builds.includes('sass')) {
|
|
139
|
-
await runSass(null, true);
|
|
140
|
-
}
|
|
141
|
-
if (builds.includes('js')) {
|
|
142
|
-
await runJS();
|
|
143
|
-
}
|
|
144
|
-
if (builds.includes('blocks')) {
|
|
145
|
-
await runBlocks();
|
|
146
|
-
}
|
|
147
|
-
if (builds.includes('images')) {
|
|
148
|
-
await frontrunImages();
|
|
149
|
-
}
|
|
150
|
-
if (builds.includes('fonts')) {
|
|
151
|
-
await buildFonts(project.path + '/_src/fonts');
|
|
152
|
-
}
|
|
153
|
-
// if (builds.includes('php') && shouldPHPLint) {
|
|
154
|
-
// await runPHP(null, 'warn'); // this errors "Fatal error: Allowed memory size"
|
|
155
|
-
// }
|
|
156
|
-
|
|
157
29
|
log('info', `Finished initial build in ${Math.round((Date.now() - initialBuildTimerStart) / 1000)} seconds`);
|
|
158
30
|
|
|
159
31
|
if (argv.watch) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (builds.includes('sass')) {
|
|
164
|
-
chokidar.watch([
|
|
165
|
-
...[paths.theme.json],
|
|
166
|
-
globs.sass
|
|
167
|
-
], {
|
|
168
|
-
...chokidarOpts
|
|
169
|
-
}).on('all', (event, path) => {
|
|
170
|
-
let hasRanSingle = false;
|
|
171
|
-
for (var block of filesSass) {
|
|
172
|
-
if (path == block.file || getImportedFilesSass(block.file).includes(path)) {
|
|
173
|
-
runSass(block.file, path == paths.theme.json);
|
|
174
|
-
hasRanSingle = true;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (!hasRanSingle) {
|
|
178
|
-
runSass(null, path == paths.theme.json);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (builds.includes('js')) {
|
|
184
|
-
chokidar.watch(globs.js, {
|
|
185
|
-
...chokidarOpts
|
|
186
|
-
}).on('all', (event, path) => {
|
|
187
|
-
runJS();
|
|
188
|
-
});
|
|
32
|
+
for (let build of builds) {
|
|
33
|
+
await project.components[build].watch();
|
|
189
34
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
chokidar.watch(`${block}/src`, {
|
|
194
|
-
...chokidarOpts
|
|
195
|
-
}).on('all', (event, path) => {
|
|
196
|
-
runBlocks(block);
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (builds.includes('images')) {
|
|
202
|
-
chokidar.watch(paths.images, chokidarOpts).on('all', (event, path) => {
|
|
203
|
-
frontrunImages();
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (builds.includes('php') && shouldPHPLint) {
|
|
208
|
-
chokidar.watch(globs.php, {
|
|
209
|
-
...chokidarOpts
|
|
210
|
-
}).on('all', (event, path) => {
|
|
211
|
-
runPHP(path);
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (existsSync(paths.errorLog)) {
|
|
216
|
-
let errorLogTail = new Tail(paths.errorLog);
|
|
35
|
+
try {
|
|
36
|
+
await fs.access(project.paths.errorLog);
|
|
37
|
+
let errorLogTail = new Tail(project.paths.errorLog);
|
|
217
38
|
errorLogTail.on('line', function(data) {
|
|
218
39
|
log('php', data);
|
|
219
40
|
});
|
|
220
|
-
}
|
|
221
|
-
log('info', `Cannot find error log @ ${paths.errorLog}. Skipping watching php error logs`);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
log('info', `Cannot find error log @ ${project.paths.errorLog}. Skipping watching php error logs`);
|
|
222
43
|
}
|
|
223
44
|
}
|
|
224
45
|
|
|
225
46
|
})();
|
|
226
|
-
|
|
227
|
-
async function frontrunImages() {
|
|
228
|
-
const promisesImages = globs.imageDirectories.map(directory => buildImages(directory));
|
|
229
|
-
await Promise.all(promisesImages);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
async function runBlocks(singleBlock) {
|
|
233
|
-
if (singleBlock) {
|
|
234
|
-
await buildBlock(singleBlock);
|
|
235
|
-
} else {
|
|
236
|
-
const promisesBlocks = globs.blocks.map(block => buildBlock(block));
|
|
237
|
-
await Promise.all(promisesBlocks);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function runSass(singleEntry, buildTheme = true) {
|
|
242
|
-
if (buildTheme) {
|
|
243
|
-
await buildSassTheme();
|
|
244
|
-
}
|
|
245
|
-
for (var block of filesSass) {
|
|
246
|
-
if (!singleEntry || singleEntry == block.file) {
|
|
247
|
-
await buildSass(block.file, block.name, globs.sass);
|
|
248
|
-
if (singleEntry == block.file) {
|
|
249
|
-
break;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
async function runJS() {
|
|
256
|
-
const promisesJS = filesJS.map(block => buildJS(block.file, block.name, globs.js));
|
|
257
|
-
await Promise.all(promisesJS);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
async function runPHP(file, method) {
|
|
261
|
-
await buildPHP(file, method);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
async function getAllSubdirectories(dir) {
|
|
265
|
-
let subdirectories = [];
|
|
266
|
-
const subdirectoriesEntries = await readdir(dir, { withFileTypes: true });
|
|
267
|
-
for (const subdirectoriesEntry of subdirectoriesEntries) {
|
|
268
|
-
if (subdirectoriesEntry.isDirectory()) {
|
|
269
|
-
const subdirPath = path.join(dir, subdirectoriesEntry.name);
|
|
270
|
-
subdirectories.push(subdirPath);
|
|
271
|
-
const nestedSubdirs = await getAllSubdirectories(subdirPath);
|
|
272
|
-
subdirectories = subdirectories.concat(nestedSubdirs);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return subdirectories;
|
|
276
|
-
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import * as utils from '../utils.js';
|
|
3
|
+
import project from '../project.js';
|
|
4
|
+
import log from '../logging.js';
|
|
5
|
+
import chokidar from 'chokidar';
|
|
6
|
+
import { glob } from 'node:fs/promises';
|
|
7
|
+
|
|
8
|
+
class BaseComponent {
|
|
9
|
+
|
|
10
|
+
constructor() {
|
|
11
|
+
this.timer = null;
|
|
12
|
+
this.path = path;
|
|
13
|
+
this.utils = utils;
|
|
14
|
+
this.project = project;
|
|
15
|
+
this.log = log;
|
|
16
|
+
this.chokidar = chokidar;
|
|
17
|
+
this.glob = glob;
|
|
18
|
+
this.files = [];
|
|
19
|
+
this.globs = [];
|
|
20
|
+
this.slug = 'base';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async init() {
|
|
24
|
+
//
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
start() {
|
|
28
|
+
this.timer = Date.now();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
end(options) {
|
|
32
|
+
options = Object.assign({}, {
|
|
33
|
+
verb: 'Built',
|
|
34
|
+
itemLabel: null,
|
|
35
|
+
timerStart: this.timer,
|
|
36
|
+
timerEnd: Date.now()
|
|
37
|
+
}, options);
|
|
38
|
+
this.log('success', `${options.verb}${options.itemLabel ? ` ${options.itemLabel}` : ''} in ${options.timerEnd - options.timerStart}ms`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async watch() {
|
|
42
|
+
//
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { BaseComponent as default }
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import BaseComponent from './base.js';
|
|
2
|
+
import { stat } from 'fs/promises';
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
import process from 'process';
|
|
5
|
+
|
|
6
|
+
class BlocksComponent extends BaseComponent {
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.slug = 'blocks';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async init() {
|
|
14
|
+
this.globs = await Array.fromAsync(
|
|
15
|
+
this.glob(`${this.project.path}/blocks/*`)
|
|
16
|
+
);
|
|
17
|
+
this.globsSass = await Array.fromAsync(
|
|
18
|
+
this.glob(`${this.project.path}/blocks/*/src/*.scss`)
|
|
19
|
+
);
|
|
20
|
+
// for (var filename of this.globsSass) {
|
|
21
|
+
// this.project.entries[`blocks/${this.path.basename(this.path.dirname(filename))}/style`] = [ filename ];
|
|
22
|
+
// }
|
|
23
|
+
await this.process();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async build(entry, options) {
|
|
27
|
+
options = Object.assign({}, {}, options);
|
|
28
|
+
let entryLabel = entry.replace(this.project.path, '');
|
|
29
|
+
|
|
30
|
+
let timerStart = Date.now();
|
|
31
|
+
|
|
32
|
+
this.start();
|
|
33
|
+
|
|
34
|
+
let workingBlockJson = null;
|
|
35
|
+
let potentialBlockJsonLocations = [
|
|
36
|
+
`${entry}/src/block.json`,
|
|
37
|
+
// `${entry}/block.json`
|
|
38
|
+
];
|
|
39
|
+
for (var location of potentialBlockJsonLocations) {
|
|
40
|
+
try {
|
|
41
|
+
await stat(location);
|
|
42
|
+
workingBlockJson = location
|
|
43
|
+
break;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
//
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (workingBlockJson === null) {
|
|
49
|
+
this.log('error', `Failed building ${entry} blocks - no block.json found.`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
let cmds = [
|
|
53
|
+
`${this.project.path}/node_modules/@wordpress/scripts/bin/wp-scripts.js`,
|
|
54
|
+
`build`,
|
|
55
|
+
`--source-path=.${entry.replace(this.project.path, '')}/src`,
|
|
56
|
+
`--output-path=.${entry.replace(this.project.path, '')}/build`,
|
|
57
|
+
`--webpack-copy-php`
|
|
58
|
+
];
|
|
59
|
+
await cmd(cmds, { entryLabel: entryLabel });
|
|
60
|
+
|
|
61
|
+
this.end({
|
|
62
|
+
itemLabel: entryLabel,
|
|
63
|
+
timerStart: timerStart,
|
|
64
|
+
timerEnd: Date.now()
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async process(entry) {
|
|
69
|
+
if (entry) {
|
|
70
|
+
await this.build(entry);
|
|
71
|
+
} else {
|
|
72
|
+
const promisesBlocks = this.globs.map(block => this.build(block));
|
|
73
|
+
await Promise.all(promisesBlocks);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
watch() {
|
|
78
|
+
for (let block of this.globs) {
|
|
79
|
+
this.chokidar.watch(`${block}/src`, {
|
|
80
|
+
...this.project.chokidarOpts
|
|
81
|
+
}).on('all', (event, path) => {
|
|
82
|
+
this.process(block);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function cmd(commands) {
|
|
90
|
+
let p = spawn(commands[0], commands.slice(1), {
|
|
91
|
+
shell: true
|
|
92
|
+
});
|
|
93
|
+
return new Promise((resolveFunc) => {
|
|
94
|
+
p.stdout.on('data', (x) => {
|
|
95
|
+
if (x.toString().includes('Error:')) {
|
|
96
|
+
process.stdout.write(x.toString());
|
|
97
|
+
log('error', `Failed building ${entryLabel} block - See above error.`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
p.stderr.on('data', (x) => {
|
|
101
|
+
if (x.toString().includes('Error:')) {
|
|
102
|
+
process.stderr.write(x.toString());
|
|
103
|
+
log('error', `Failed building ${entryLabel} block - See above error.`);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
p.on('exit', (code) => {
|
|
107
|
+
resolveFunc(code);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { BlocksComponent as default }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import BaseComponent from './base.js';
|
|
2
|
+
import { readdir } from 'fs/promises';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
|
|
5
|
+
class FontsComponent extends BaseComponent {
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
super();
|
|
9
|
+
this.slug = 'fonts';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async init() {
|
|
13
|
+
await this.process();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async build(entry) {
|
|
17
|
+
let entryLabel = `/dist/fonts`;
|
|
18
|
+
|
|
19
|
+
this.start();
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
const fontsDir = await readdir(entry);
|
|
23
|
+
if (fontsDir.length == 0) { throw new Error('No files present'); }
|
|
24
|
+
await fs.copy(entry, `${this.project.path}${entryLabel}`);
|
|
25
|
+
} catch(error) {
|
|
26
|
+
this.log('info', `${error} at ${entry.replace(this.project.path, '')}/. Skipping font copy`);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.end({
|
|
31
|
+
itemLabel: entryLabel
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async process() {
|
|
36
|
+
await this.build(`${this.project.path}/_src/fonts`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { FontsComponent as default }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import BaseComponent from './base.js';
|
|
2
|
+
import imagemin from 'imagemin';
|
|
3
|
+
import imageminJpegtran from 'imagemin-jpegtran';
|
|
4
|
+
import imageminPngquant from 'imagemin-pngquant';
|
|
5
|
+
import imageminSvgo from 'imagemin-svgo';
|
|
6
|
+
|
|
7
|
+
class ImagesComponent extends BaseComponent {
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
this.slug = 'images';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async init() {
|
|
15
|
+
this.globs = await Array.fromAsync(
|
|
16
|
+
this.glob(this.project.package?.sdc?.imagesPath ||
|
|
17
|
+
`${this.project.paths.images}/**/*`)
|
|
18
|
+
);
|
|
19
|
+
this.globsDirectories = [
|
|
20
|
+
this.project.paths.images,
|
|
21
|
+
...await this.utils.getAllSubdirectories(this.project.paths.images)
|
|
22
|
+
];
|
|
23
|
+
await this.process();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async build(entry, options) {
|
|
27
|
+
let timerStart = Date.now();
|
|
28
|
+
let dest = entry.replace('_src/images', 'dist/images');
|
|
29
|
+
const files = await imagemin([entry + '/*'], {
|
|
30
|
+
destination: dest,
|
|
31
|
+
plugins: [
|
|
32
|
+
imageminJpegtran(),
|
|
33
|
+
imageminPngquant(),
|
|
34
|
+
imageminSvgo()
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
this.end({
|
|
39
|
+
itemLabel: `${dest.replace(this.project.path, '')} (${files.length} image${files.length == 1 ? '' : 's'})`,
|
|
40
|
+
timerStart: timerStart,
|
|
41
|
+
timerEnd: Date.now()
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async process() {
|
|
46
|
+
const promisesImages = this.globsDirectories.map(directory => this.build(directory));
|
|
47
|
+
await Promise.all(promisesImages);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
watch() {
|
|
51
|
+
this.chokidar.watch(this.project.paths.images, {
|
|
52
|
+
...this.project.chokidarOpts
|
|
53
|
+
}).on('all', (event, path) => {
|
|
54
|
+
this.process();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { ImagesComponent as default }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as style } from './style.js';
|
|
2
|
+
export { default as scripts } from './scripts.js';
|
|
3
|
+
export { default as blocks } from './blocks.js';
|
|
4
|
+
export { default as images } from './images.js';
|
|
5
|
+
export { default as fonts } from './fonts.js';
|
|
6
|
+
export { default as php } from './php.js';
|
|
7
|
+
export { default as server } from './server.js';
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import BaseComponent from './base.js';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
|
|
6
|
+
class PHPComponent extends BaseComponent {
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.slug = 'php';
|
|
11
|
+
this.execPromise = promisify(exec);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async init() {
|
|
15
|
+
this.globs = await Array.fromAsync(
|
|
16
|
+
this.glob(this.project.package?.sdc?.phpGlobPath ||
|
|
17
|
+
`${this.project.path}/**/*.php`)
|
|
18
|
+
);
|
|
19
|
+
this.globsBlocks = await Array.fromAsync(
|
|
20
|
+
this.glob(`${this.project.path}/blocks/*/build/*.php`)
|
|
21
|
+
);
|
|
22
|
+
this.project.chokidarOpts.ignored = [
|
|
23
|
+
...this.project.chokidarOpts.ignored,
|
|
24
|
+
...this.globsBlocks
|
|
25
|
+
];
|
|
26
|
+
// await this.process(null, { lintType: 'warn' }); // this errors "Fatal error: Allowed memory size"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async build(entry, options) {
|
|
30
|
+
options = Object.assign({}, {
|
|
31
|
+
lintType: 'fix'
|
|
32
|
+
}, options);
|
|
33
|
+
let entryLabel = `all PHP files`;
|
|
34
|
+
|
|
35
|
+
this.start();
|
|
36
|
+
let workingLintBin = 'phpcbf';
|
|
37
|
+
if (options.lintType == 'warn') {
|
|
38
|
+
workingLintBin = 'phpcs';
|
|
39
|
+
}
|
|
40
|
+
let phpFiles = '.';
|
|
41
|
+
let additionalFlags = '';
|
|
42
|
+
if (entry) {
|
|
43
|
+
phpFiles = entry;
|
|
44
|
+
entryLabel = entry.replace(this.project.path, '');
|
|
45
|
+
} else {
|
|
46
|
+
additionalFlags += ' -d memory_limit=2G'; // FIXME: this doesn't solve error issue "Fatal error: Allowed memory size"
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const cmds = [
|
|
50
|
+
`vendor/bin/${workingLintBin}`,
|
|
51
|
+
`--parallel=5`,
|
|
52
|
+
`--error-severity=1`,
|
|
53
|
+
`--warning-severity=1`,
|
|
54
|
+
`--colors`,
|
|
55
|
+
`--basepath=${this.project.path}`,
|
|
56
|
+
phpFiles,
|
|
57
|
+
additionalFlags
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const { stdout, stderr } = await this.execPromise(cmds.join(' '), {
|
|
61
|
+
cwd: this.path.resolve(this.path.dirname(fileURLToPath(import.meta.url)), '../../')
|
|
62
|
+
}); // returns an error if any violations are found, so we can't rely on the try/catch as usual
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (
|
|
65
|
+
error.stderr?.length ||
|
|
66
|
+
(
|
|
67
|
+
error.stdout?.length &&
|
|
68
|
+
(
|
|
69
|
+
error.stdout.startsWith('ERROR:') ||
|
|
70
|
+
error.stdout.includes('FAILED TO FIX')
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
) {
|
|
74
|
+
console.error(error.stderr?.length ? error.stderr : error.stdout);
|
|
75
|
+
this.log('error', `Failed linting ${entryLabel.replace(this.project.path, '')} - See above error.`);
|
|
76
|
+
return false;
|
|
77
|
+
} else {
|
|
78
|
+
if (error.stdout?.length) {
|
|
79
|
+
console.log(error.stdout);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (this.project.components.server?.server) {
|
|
84
|
+
this.project.components.server?.server.reload();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.end({
|
|
88
|
+
itemLabel: entryLabel,
|
|
89
|
+
verb: `Linted (${options.lintType})`
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async process(entry, options) {
|
|
94
|
+
await this.build(entry, options);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
watch() {
|
|
98
|
+
this.chokidar.watch(this.globs, {
|
|
99
|
+
...this.project.chokidarOpts
|
|
100
|
+
}).on('all', (event, path) => {
|
|
101
|
+
this.process(path);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { PHPComponent as default }
|