@divriots/jampack 0.12.2 → 0.14.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/dist/cache.d.ts +2 -1
- package/dist/cache.js +32 -12
- package/dist/compress.js +1 -1
- package/dist/compressors/images.js +3 -3
- package/dist/config-default.js +2 -0
- package/dist/config-types.d.ts +3 -1
- package/dist/index.js +12 -2
- package/dist/optimize.js +4 -10
- package/dist/optimizers/img-external.d.ts +1 -1
- package/dist/optimizers/img-external.js +8 -10
- package/dist/packagejson.d.ts +2 -0
- package/dist/{version.js → packagejson.js} +1 -0
- package/package.json +8 -3
- package/dist/version.d.ts +0 -1
package/dist/cache.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
|
|
2
|
+
declare const listOfCategories: readonly ["img", "img-ext"];
|
|
3
|
+
export type Category = (typeof listOfCategories)[number];
|
|
3
4
|
export type CacheData = {
|
|
4
5
|
buffer: Buffer;
|
|
5
6
|
meta: any;
|
package/dist/cache.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import hasha from 'hasha';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import * as fs from 'fs/promises';
|
|
4
|
-
import { VERSION } from './version.js';
|
|
5
4
|
import $state from './state.js';
|
|
5
|
+
import { CACHE_VERSIONS } from './packagejson.js';
|
|
6
|
+
const listOfCategories = ['img', 'img-ext'];
|
|
6
7
|
const CACHE_FOLDER = '.jampack/cache';
|
|
7
|
-
const CACHE_FOLDER_VERSION = CACHE_FOLDER + '/' + VERSION;
|
|
8
8
|
async function cleanCache(full) {
|
|
9
9
|
if (full) {
|
|
10
10
|
try {
|
|
@@ -15,19 +15,36 @@ async function cleanCache(full) {
|
|
|
15
15
|
}
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
|
-
//
|
|
19
|
-
let
|
|
18
|
+
// Delete old cache category
|
|
19
|
+
let catFolders = [];
|
|
20
20
|
try {
|
|
21
|
-
|
|
21
|
+
catFolders = await fs.readdir(CACHE_FOLDER);
|
|
22
22
|
}
|
|
23
23
|
catch (e) {
|
|
24
|
-
//
|
|
25
|
-
|
|
24
|
+
// No problem
|
|
25
|
+
}
|
|
26
|
+
for (const f of catFolders) {
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
if (!listOfCategories.includes(f))
|
|
29
|
+
fs.rm(path.join(CACHE_FOLDER, f), { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
// Loop cache folders
|
|
32
|
+
for (const cat of listOfCategories) {
|
|
33
|
+
const location = path.join(CACHE_FOLDER, cat);
|
|
34
|
+
// List versions in cache
|
|
35
|
+
let folders;
|
|
36
|
+
try {
|
|
37
|
+
folders = await fs.readdir(location);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
// Delete old cache versions
|
|
43
|
+
for (const f of folders) {
|
|
44
|
+
if (f !== CACHE_VERSIONS[cat])
|
|
45
|
+
fs.rm(path.join(location, f), { recursive: true });
|
|
46
|
+
}
|
|
26
47
|
}
|
|
27
|
-
// Delete old cache versions
|
|
28
|
-
await files
|
|
29
|
-
.filter((f) => f !== VERSION)
|
|
30
|
-
.forEach(async (f) => fs.rm(path.join(CACHE_FOLDER, f), { recursive: true }));
|
|
31
48
|
}
|
|
32
49
|
function computeCacheHash(buffer, options) {
|
|
33
50
|
if ($state.args.nocache) {
|
|
@@ -39,8 +56,11 @@ function computeCacheHash(buffer, options) {
|
|
|
39
56
|
}
|
|
40
57
|
return hash;
|
|
41
58
|
}
|
|
59
|
+
function getVersionOfCategory(category) {
|
|
60
|
+
return CACHE_VERSIONS[category];
|
|
61
|
+
}
|
|
42
62
|
function getLocation(hash, category) {
|
|
43
|
-
return path.join(
|
|
63
|
+
return path.join(CACHE_FOLDER, category, getVersionOfCategory(category), hash);
|
|
44
64
|
}
|
|
45
65
|
async function getFromCache(category, hash) {
|
|
46
66
|
if ($state.args.nocache) {
|
package/dist/compress.js
CHANGED
|
@@ -69,7 +69,7 @@ const processFile = async (file, stats) => {
|
|
|
69
69
|
};
|
|
70
70
|
export async function compressFolder(exclude) {
|
|
71
71
|
const spinner = ora(getProgressText()).start();
|
|
72
|
-
const globs = ['**/**'];
|
|
72
|
+
const globs = ['**/**', '!_jampack/**']; // Exclude jampack folder because already compressed
|
|
73
73
|
if (exclude)
|
|
74
74
|
globs.push('!' + exclude);
|
|
75
75
|
const paths = await globby(globs, { cwd: $state.dir, absolute: true });
|
|
@@ -113,10 +113,10 @@ export async function compressImage(data, options) {
|
|
|
113
113
|
if (!outputFormat)
|
|
114
114
|
return undefined;
|
|
115
115
|
// If resize is requested
|
|
116
|
-
if (((_a = options.resize) === null || _a === void 0 ? void 0 : _a.width)
|
|
116
|
+
if (((_a = options.resize) === null || _a === void 0 ? void 0 : _a.width) || ((_b = options.resize) === null || _b === void 0 ? void 0 : _b.height)) {
|
|
117
|
+
const resize = options.resize;
|
|
117
118
|
sharpFile = sharpFile.resize({
|
|
118
|
-
...
|
|
119
|
-
fit: 'fill',
|
|
119
|
+
...resize,
|
|
120
120
|
withoutEnlargement: true,
|
|
121
121
|
});
|
|
122
122
|
}
|
package/dist/config-default.js
CHANGED
package/dist/config-types.d.ts
CHANGED
|
@@ -10,8 +10,10 @@ export type Options = {
|
|
|
10
10
|
image: {
|
|
11
11
|
embed_size: number;
|
|
12
12
|
srcset_min_width: number;
|
|
13
|
+
srcset_max_width: number;
|
|
14
|
+
max_width: number;
|
|
13
15
|
external: {
|
|
14
|
-
process: 'off' | 'download'
|
|
16
|
+
process: 'off' | 'download';
|
|
15
17
|
src_include: RegExp;
|
|
16
18
|
src_exclude: RegExp | null;
|
|
17
19
|
};
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,9 @@ import { printTitle } from './logger.js';
|
|
|
10
10
|
import { exit } from 'process';
|
|
11
11
|
import kleur from 'kleur';
|
|
12
12
|
import { cleanCache } from './cache.js';
|
|
13
|
-
import { VERSION } from './
|
|
13
|
+
import { VERSION } from './packagejson.js';
|
|
14
|
+
import { mkdirSync } from 'fs';
|
|
15
|
+
import { join } from 'path';
|
|
14
16
|
const logo = ` __ __
|
|
15
17
|
|__|____ _____ ___________ ____ | | __
|
|
16
18
|
| \\__ \\ / \\\\____ \\__ \\ _/ ___\\| |/ /
|
|
@@ -53,7 +55,15 @@ program
|
|
|
53
55
|
fast();
|
|
54
56
|
}
|
|
55
57
|
// Clean cache
|
|
56
|
-
cleanCache(options.cleancache);
|
|
58
|
+
await cleanCache(options.cleancache);
|
|
59
|
+
// Make _jampack folder
|
|
60
|
+
try {
|
|
61
|
+
mkdirSync(join(dir, '_jampack'));
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
console.error('Failed to create `_jampack` folder.');
|
|
65
|
+
exit(1);
|
|
66
|
+
}
|
|
57
67
|
if (!options.onlycomp) {
|
|
58
68
|
printTitle('PASS 1 - Optimizing');
|
|
59
69
|
console.time('Done');
|
package/dist/optimize.js
CHANGED
|
@@ -194,8 +194,7 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
|
|
|
194
194
|
return;
|
|
195
195
|
case 'download': // Download external image for local processing
|
|
196
196
|
try {
|
|
197
|
-
|
|
198
|
-
attrib_src = await downloadExternalImage(attrib_src, htmlFolder);
|
|
197
|
+
attrib_src = await downloadExternalImage(htmlfile, attrib_src);
|
|
199
198
|
img.attr('src', attrib_src);
|
|
200
199
|
}
|
|
201
200
|
catch (e) {
|
|
@@ -206,10 +205,6 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
|
|
|
206
205
|
return; // No more processing
|
|
207
206
|
}
|
|
208
207
|
break;
|
|
209
|
-
case 'add-dimensions-only': // Only add dimensions of image
|
|
210
|
-
throw new Error('External images with `add-dimensions-only` is not implemented yet.');
|
|
211
|
-
case 'cdn-srcset-when-possible': // Use unpic to use CDN capabilities
|
|
212
|
-
throw new Error('External images with `cdn-srcset-when-possible` is not implemented yet.');
|
|
213
208
|
}
|
|
214
209
|
}
|
|
215
210
|
/*
|
|
@@ -259,6 +254,7 @@ async function processImage(htmlfile, $, imgElement, isAboveTheFold) {
|
|
|
259
254
|
}
|
|
260
255
|
newImage = await compressImage(await originalImage.getData(), {
|
|
261
256
|
toFormat: srcToFormat,
|
|
257
|
+
resize: { width: config.image.srcset_max_width },
|
|
262
258
|
});
|
|
263
259
|
if ((newImage === null || newImage === void 0 ? void 0 : newImage.data) &&
|
|
264
260
|
(newImage.data.length < (await originalImage.getLen()) ||
|
|
@@ -458,9 +454,8 @@ async function generateSrcSet(htmlfile, originalImage, startSrc, startSrcLength,
|
|
|
458
454
|
}
|
|
459
455
|
// Start reduction
|
|
460
456
|
const step = 300; //px
|
|
461
|
-
const ratio = imageWidth / imageHeight;
|
|
462
457
|
let valueW = !startSrc ? imageWidth : imageWidth - step;
|
|
463
|
-
|
|
458
|
+
valueW = Math.min(valueW, config.image.srcset_max_width);
|
|
464
459
|
let previousImageSize = startSrcLength || Number.MAX_VALUE;
|
|
465
460
|
while (valueW >= config.image.srcset_min_width) {
|
|
466
461
|
const src = imageSrc(`@${valueW}w`);
|
|
@@ -468,7 +463,7 @@ async function generateSrcSet(htmlfile, originalImage, startSrc, startSrcLength,
|
|
|
468
463
|
let doAddToSrcSet = true;
|
|
469
464
|
// Don't generate srcset file twice
|
|
470
465
|
if (!$state.compressedFiles.has(absoluteFilename)) {
|
|
471
|
-
const compressedImage = await compressImage(await originalImage.getData(), { ...options, resize: { width: valueW
|
|
466
|
+
const compressedImage = await compressImage(await originalImage.getData(), { ...options, resize: { width: valueW } });
|
|
472
467
|
if (!(compressedImage === null || compressedImage === void 0 ? void 0 : compressedImage.data) ||
|
|
473
468
|
compressedImage.data.length >= previousImageSize) {
|
|
474
469
|
// New image is not compressed or bigger than previous image in srcset
|
|
@@ -491,7 +486,6 @@ async function generateSrcSet(htmlfile, originalImage, startSrc, startSrcLength,
|
|
|
491
486
|
}
|
|
492
487
|
// reduce size
|
|
493
488
|
valueW -= step;
|
|
494
|
-
valueH = Math.trunc(valueW / ratio);
|
|
495
489
|
}
|
|
496
490
|
if (new_srcset) {
|
|
497
491
|
return startSrc
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '../utils/polyfill-fetch.js';
|
|
2
|
-
export declare function downloadExternalImage(
|
|
2
|
+
export declare function downloadExternalImage(htmlfile: string, href: string): Promise<string>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
|
+
import $state from '../state.js';
|
|
3
4
|
import hasha from 'hasha';
|
|
4
5
|
import { fileTypeFromBuffer } from 'file-type';
|
|
5
6
|
import { addToCache, getFromCache } from '../cache.js';
|
|
6
7
|
import { parse } from '../utils/cache-control-parser.js';
|
|
7
8
|
import '../utils/polyfill-fetch.js';
|
|
8
|
-
export async function downloadExternalImage(
|
|
9
|
+
export async function downloadExternalImage(htmlfile, href) {
|
|
9
10
|
var _a, _b, _c, _d, _e;
|
|
10
11
|
const hash = hasha(href, {
|
|
11
12
|
algorithm: 'md5',
|
|
@@ -90,16 +91,13 @@ export async function downloadExternalImage(href, dir) {
|
|
|
90
91
|
// buffer can't be undefined here
|
|
91
92
|
if (!buffer)
|
|
92
93
|
throw new Error('Buffer is undefined');
|
|
93
|
-
// Construct
|
|
94
|
+
// Construct contenthash
|
|
95
|
+
const contentHash = hasha(buffer, { algorithm: 'md5' });
|
|
96
|
+
// Construct local filename relative to root dir
|
|
94
97
|
if (!ext)
|
|
95
98
|
throw new Error('Unknown image format');
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
catch (e) {
|
|
101
|
-
// Nothing to do - folder is probably already present
|
|
102
|
-
}
|
|
103
|
-
fs.writeFile(path.join(dir, filename), buffer);
|
|
99
|
+
const htmlFolder = path.dirname(htmlfile);
|
|
100
|
+
const filename = path.relative(path.join($state.dir, htmlFolder), path.join($state.dir, `_jampack/${contentHash}.${ext}`));
|
|
101
|
+
await fs.writeFile(path.join($state.dir, htmlFolder, filename), buffer);
|
|
104
102
|
return filename;
|
|
105
103
|
}
|
|
@@ -4,3 +4,4 @@ import { fileURLToPath } from 'url';
|
|
|
4
4
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
5
|
const pkgjson = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json')).toString());
|
|
6
6
|
export const VERSION = pkgjson.version;
|
|
7
|
+
export const CACHE_VERSIONS = pkgjson['cache-version'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@divriots/jampack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"cache-version": {
|
|
5
|
+
"img": "v1",
|
|
6
|
+
"img-ext": "v1"
|
|
7
|
+
},
|
|
4
8
|
"description": "Packer for static websites",
|
|
5
9
|
"author": "Georges Gomes @georges-gomes",
|
|
6
10
|
"bin": {
|
|
@@ -29,7 +33,7 @@
|
|
|
29
33
|
"lightningcss": "^1.20.0",
|
|
30
34
|
"mini-svg-data-uri": "^1.4.4",
|
|
31
35
|
"ora": "^6.3.0",
|
|
32
|
-
"sharp": "^0.32.
|
|
36
|
+
"sharp": "^0.32.5",
|
|
33
37
|
"svgo": "^3.0.2",
|
|
34
38
|
"table": "^6.8.1",
|
|
35
39
|
"undici": "^5.22.1"
|
|
@@ -47,7 +51,8 @@
|
|
|
47
51
|
"try": "shx rm -fr demo && cp -R demo_rf demo && node ./dist/index.js ./demo --nocache --onlyoptim",
|
|
48
52
|
"build": "shx rm -rf dist && tsc -b",
|
|
49
53
|
"lint": "eslint . --ext .ts --config .eslintrc",
|
|
50
|
-
"prepublishOnly": "pnpm build"
|
|
54
|
+
"prepublishOnly": "pnpm build",
|
|
55
|
+
"cleanAllDotJampack": "find -s . | grep '.jampack$' | xargs rm -fr"
|
|
51
56
|
},
|
|
52
57
|
"engines": {
|
|
53
58
|
"node": ">=14.0.0"
|
package/dist/version.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const VERSION: any;
|