1 | const path = require('path')
|
2 | const fs = require('fs-extra')
|
3 | const PngQuant = require('pngquant')
|
4 | const through2 = require('through2')
|
5 | const klaw = require('klaw')
|
6 |
|
7 | module.exports = async (srcPath, distPath, opts) => {
|
8 | const { dir, emoji } = opts
|
9 | const distGenericPath = path.join(distPath, dir)
|
10 | const srcGenericPath = path.join(srcPath, dir)
|
11 | const uncompressedFilter = /.*\.(jpg|gif|svg)$/
|
12 | const compressedFilter = /.*\.(png)$/
|
13 | await fs.mkdirs(srcGenericPath)
|
14 | await fs.copy(srcGenericPath, distGenericPath, {
|
15 | clobber: true,
|
16 | filter: (filePath) => {
|
17 | return path.extname(filePath) === '' || uncompressedFilter.test(filePath)
|
18 | }
|
19 | })
|
20 | const relativePaths = []
|
21 | const excludeFilter = through2.obj(function (item, enc, next) {
|
22 | if (item.stats.isFile() && compressedFilter.test(path.extname(item.path))) {
|
23 | this.push(item)
|
24 | }
|
25 | next()
|
26 | })
|
27 | await new Promise((resolve, reject) => {
|
28 | klaw(srcGenericPath)
|
29 | .pipe(excludeFilter)
|
30 | .on('data', (item) => {
|
31 | relativePaths.push(path.relative(srcGenericPath, item.path))
|
32 | })
|
33 | .on('end', resolve)
|
34 | .on('error', reject)
|
35 | })
|
36 | const copyAndCompress = (relativePath) => {
|
37 | return new Promise((resolve, reject) => {
|
38 | fs.createReadStream(path.join(srcGenericPath, relativePath))
|
39 | .on('error', reject)
|
40 | .pipe(new PngQuant([256, '--speed', '1', '--skip-if-larger']))
|
41 | .on('error', reject)
|
42 | .pipe(fs.createWriteStream(path.join(distGenericPath, relativePath)))
|
43 | .on('error', reject)
|
44 | .on('close', resolve)
|
45 | })
|
46 | }
|
47 | await Promise.all(relativePaths.map(copyAndCompress))
|
48 | console.log(`${emoji} Copied ${dir}`)
|
49 | }
|