@divriots/jampack 0.30.3 → 0.31.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/config-default.js +6 -0
- package/dist/config-types.d.ts +6 -0
- package/dist/config.js +1 -1
- package/dist/optimize.js +9 -11
- package/dist/optimizers/prefetch-links.d.ts +1 -1
- package/dist/optimizers/prefetch-links.js +14 -23
- package/dist/optimizers/process-iframe.d.ts +3 -0
- package/dist/optimizers/process-iframe.js +37 -0
- package/dist/proload/error.cjs +27 -0
- package/dist/proload/error.d.cts +11 -0
- package/dist/proload/esm/index.d.mts +27 -0
- package/dist/proload/esm/index.mjs +231 -0
- package/dist/proload/esm/requireOrImport.d.mts +7 -0
- package/dist/proload/esm/requireOrImport.mjs +21 -0
- package/dist/state.d.ts +1 -0
- package/dist/state.js +1 -0
- package/dist/utils/install-dep.d.ts +12 -0
- package/dist/utils/install-dep.js +27 -0
- package/package.json +2 -2
package/dist/config-default.js
CHANGED
package/dist/config-types.d.ts
CHANGED
package/dist/config.js
CHANGED
package/dist/optimize.js
CHANGED
|
@@ -12,6 +12,7 @@ import { isLocal, Resource, translateSrc } from './utils/resource.js';
|
|
|
12
12
|
import { downloadExternalImage } from './optimizers/img-external.js';
|
|
13
13
|
import { inlineCriticalCss } from './optimizers/inline-critical-css.js';
|
|
14
14
|
import { prefetch_links_in_viewport } from './optimizers/prefetch-links.js';
|
|
15
|
+
import { processIframe } from './optimizers/process-iframe.js';
|
|
15
16
|
const UNPIC_DEFAULT_HOST_REGEX = /^https:\/\/n\//g;
|
|
16
17
|
const ABOVE_FOLD_DATA_ATTR = 'data-abovethefold';
|
|
17
18
|
function getIntAttr(img, attr) {
|
|
@@ -25,6 +26,8 @@ function getIntAttr(img, attr) {
|
|
|
25
26
|
}
|
|
26
27
|
async function analyse(state, file) {
|
|
27
28
|
console.log('▶ ' + file);
|
|
29
|
+
// For processes to add into
|
|
30
|
+
const appendToBody = {};
|
|
28
31
|
const html = (await fs.readFile(path.join(state.dir, file))).toString();
|
|
29
32
|
if (!html.includes('<html'))
|
|
30
33
|
return;
|
|
@@ -79,7 +82,7 @@ async function analyse(state, file) {
|
|
|
79
82
|
const isAboveTheFold = isElementAboveTheFold(ifr, ifElement, theFold);
|
|
80
83
|
ifr.removeAttr(ABOVE_FOLD_DATA_ATTR);
|
|
81
84
|
try {
|
|
82
|
-
await processIframe(file, $, ifElement, isAboveTheFold);
|
|
85
|
+
await processIframe(state, file, $, ifElement, isAboveTheFold, appendToBody);
|
|
83
86
|
}
|
|
84
87
|
catch (e) {
|
|
85
88
|
state.reportIssue(file, {
|
|
@@ -142,14 +145,15 @@ async function analyse(state, file) {
|
|
|
142
145
|
}
|
|
143
146
|
// Add to <body>
|
|
144
147
|
//
|
|
145
|
-
let appendToBody = '';
|
|
146
148
|
if (options.misc.prefetch_links === 'in-viewport') {
|
|
147
|
-
|
|
149
|
+
await prefetch_links_in_viewport(state, file, appendToBody);
|
|
148
150
|
}
|
|
149
|
-
|
|
151
|
+
// Custom code
|
|
152
|
+
const keys_to_install = Object.keys(appendToBody);
|
|
153
|
+
if (keys_to_install.length > 0) {
|
|
150
154
|
const body = $('body');
|
|
151
155
|
if (body.length > 0) {
|
|
152
|
-
body.append(appendToBody);
|
|
156
|
+
keys_to_install.forEach((key) => body.append(appendToBody[key]));
|
|
153
157
|
}
|
|
154
158
|
}
|
|
155
159
|
// Render HTML
|
|
@@ -760,12 +764,6 @@ async function setImageSize(state, htmlfile, img, image) {
|
|
|
760
764
|
// Something when wrong
|
|
761
765
|
throw new Error(`Unexpected issue when resolving image size "${image.src}"`);
|
|
762
766
|
}
|
|
763
|
-
async function processIframe(htmlfile, $, imgElement, isAboveTheFold) {
|
|
764
|
-
const iframe = $(imgElement);
|
|
765
|
-
if (!isAboveTheFold) {
|
|
766
|
-
iframe.attr('loading', 'lazy');
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
767
|
export async function optimize(state, include, exclude) {
|
|
770
768
|
const glob = include ? [include] : ['**/*.{htm,html}'];
|
|
771
769
|
if (exclude)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { GlobalState } from '../state.js';
|
|
2
|
-
export declare function prefetch_links_in_viewport(state: GlobalState, html_file: string): Promise<
|
|
2
|
+
export declare function prefetch_links_in_viewport(state: GlobalState, html_file: string, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
import * as fs from 'fs/promises';
|
|
2
|
-
import * as path from 'path';
|
|
3
1
|
import { createRequire } from 'node:module';
|
|
2
|
+
import { install_dependency } from '../utils/install-dep.js';
|
|
4
3
|
const require = createRequire(import.meta.url);
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const code_loader = `import { listen } from "./${src_filename}";
|
|
19
|
-
listen();`;
|
|
20
|
-
await fs.writeFile(path_loader, code_loader);
|
|
21
|
-
// Write quicklink code
|
|
22
|
-
const source = require.resolve(`quicklink/dist/${src_filename}`);
|
|
23
|
-
await fs.copyFile(source, quickLinkDestination);
|
|
24
|
-
}
|
|
25
|
-
return `<script type="module" src="${path.relative(path_html, url_loader)}"></script>`;
|
|
4
|
+
export async function prefetch_links_in_viewport(state, html_file, appendToBody) {
|
|
5
|
+
await install_dependency(state, html_file, {
|
|
6
|
+
source: {
|
|
7
|
+
npm_package_name: 'quicklink',
|
|
8
|
+
absolute_path_to_file: '/dist',
|
|
9
|
+
filename: 'quicklink.mjs',
|
|
10
|
+
},
|
|
11
|
+
destination: {
|
|
12
|
+
folder_name: 'quicklink-2.3.0',
|
|
13
|
+
code_loader: `import { listen } from "./quicklink.mjs";
|
|
14
|
+
listen();`,
|
|
15
|
+
},
|
|
16
|
+
}, appendToBody);
|
|
26
17
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import * as cheerio from '@divriots/cheerio';
|
|
2
|
+
import type { GlobalState } from '../state.js';
|
|
3
|
+
export declare function processIframe(state: GlobalState, htmlfile: string, $: cheerio.CheerioAPI, imgElement: cheerio.Element, isAboveTheFold: boolean, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { install_dependency } from '../utils/install-dep.js';
|
|
2
|
+
export async function processIframe(state, htmlfile, $, imgElement, isAboveTheFold, appendToBody) {
|
|
3
|
+
const iframe = $(imgElement);
|
|
4
|
+
// Reset loading attribute
|
|
5
|
+
iframe.removeAttr('loading');
|
|
6
|
+
const lazyloadOptions = state.options.iframe.lazyload;
|
|
7
|
+
if (lazyloadOptions.when === 'never') {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (lazyloadOptions.when === 'always' ||
|
|
11
|
+
(lazyloadOptions.when === 'below-the-fold' && !isAboveTheFold)) {
|
|
12
|
+
if (lazyloadOptions.how === 'native') {
|
|
13
|
+
iframe.attr('loading', 'lazy');
|
|
14
|
+
}
|
|
15
|
+
else if (lazyloadOptions.how === 'js') {
|
|
16
|
+
const src = iframe.attr('src');
|
|
17
|
+
if (src) {
|
|
18
|
+
iframe.attr('class', 'jampack-lozad');
|
|
19
|
+
iframe.attr('data-src', src);
|
|
20
|
+
iframe.removeAttr('src');
|
|
21
|
+
await install_dependency(state, htmlfile, {
|
|
22
|
+
source: {
|
|
23
|
+
npm_package_name: 'lozad',
|
|
24
|
+
absolute_path_to_file: '/dist',
|
|
25
|
+
filename: 'lozad.es.js',
|
|
26
|
+
},
|
|
27
|
+
destination: {
|
|
28
|
+
folder_name: 'lozad-1.16',
|
|
29
|
+
code_loader: `import lozad from "./lozad.es.js";
|
|
30
|
+
const observer = lozad('.jampack-lozad', { rootMargin: '100px 0px', threshold: [0.1] });
|
|
31
|
+
observer.observe();`,
|
|
32
|
+
},
|
|
33
|
+
}, appendToBody);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @type import('./error.cjs').ProloadError
|
|
5
|
+
*/
|
|
6
|
+
class ProloadError extends Error {
|
|
7
|
+
constructor(opts = {}) {
|
|
8
|
+
super(opts.message);
|
|
9
|
+
this.name = 'ProloadError';
|
|
10
|
+
this.code = opts.code || 'ERR_PROLOAD_INVALID';
|
|
11
|
+
if (Error.captureStackTrace) {
|
|
12
|
+
Error.captureStackTrace(this, this.constructor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @type import('./error.cjs').assert
|
|
18
|
+
*/
|
|
19
|
+
function assert(bool, message, code) {
|
|
20
|
+
if (bool)
|
|
21
|
+
return;
|
|
22
|
+
if (message instanceof Error)
|
|
23
|
+
throw message;
|
|
24
|
+
throw new ProloadError({ message, code });
|
|
25
|
+
}
|
|
26
|
+
module.exports.ProloadError = ProloadError;
|
|
27
|
+
module.exports.assert = assert;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type import('./error.cjs').ProloadError
|
|
3
|
+
*/
|
|
4
|
+
export class ProloadError extends Error {
|
|
5
|
+
constructor(opts?: {});
|
|
6
|
+
code: any;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* @type import('./error.cjs').assert
|
|
10
|
+
*/
|
|
11
|
+
export function assert(bool: any, message: any, code: any): any;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default load;
|
|
2
|
+
import { ProloadError } from "../error.cjs";
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {string} namespace
|
|
6
|
+
* @param {import('../index').LoadOptions} opts
|
|
7
|
+
*/
|
|
8
|
+
declare function load(namespace: string, opts?: any): Promise<{
|
|
9
|
+
filePath: any;
|
|
10
|
+
raw: any;
|
|
11
|
+
value: {};
|
|
12
|
+
} | undefined>;
|
|
13
|
+
declare namespace load {
|
|
14
|
+
export { defaultPlugins as plugins };
|
|
15
|
+
export function use(plugins: any): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param {string} namespace
|
|
20
|
+
* @param {import('../index').LoadOptions} opts
|
|
21
|
+
*/
|
|
22
|
+
declare function resolveConfig(namespace: string, opts?: any): Promise<any>;
|
|
23
|
+
declare const defaultPlugins: {
|
|
24
|
+
name: string;
|
|
25
|
+
transform(mdl: any): any;
|
|
26
|
+
}[];
|
|
27
|
+
export { ProloadError, resolveConfig as resolve };
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import escalade from "escalade";
|
|
2
|
+
import { join, dirname, extname, resolve } from "path";
|
|
3
|
+
import deepmerge from "deepmerge";
|
|
4
|
+
import { existsSync, readdir, readFile, stat } from "fs";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
import requireOrImport from "./requireOrImport.mjs";
|
|
8
|
+
import { assert, ProloadError } from "../error.cjs";
|
|
9
|
+
export { ProloadError };
|
|
10
|
+
const toStats = promisify(stat);
|
|
11
|
+
const toRead = promisify(readdir);
|
|
12
|
+
const toReadFile = promisify(readFile);
|
|
13
|
+
const require = createRequire(import.meta.url);
|
|
14
|
+
let merge = deepmerge;
|
|
15
|
+
const defaultExtensions = ['js', 'cjs', 'mjs'];
|
|
16
|
+
const defaultFileNames = ['[name].config'];
|
|
17
|
+
const validNames = (namespace) => {
|
|
18
|
+
const extensionPlugins = load.plugins.filter(p => Array.isArray(p.extensions));
|
|
19
|
+
const fileNamePlugins = load.plugins.filter(p => Array.isArray(p.fileNames));
|
|
20
|
+
const validExtensions = [...defaultExtensions].concat(...extensionPlugins.map(p => p.extensions));
|
|
21
|
+
const validFileNames = [...defaultFileNames].concat(...fileNamePlugins.map(p => p.fileNames));
|
|
22
|
+
const result = validFileNames
|
|
23
|
+
.map(fileName => fileName.replace('[name]', namespace))
|
|
24
|
+
.reduce((acc, fileName) => {
|
|
25
|
+
return [...acc].concat(...validExtensions.map(ext => `${fileName}${ext ? '.' + ext.replace(/^\./, '') : ''}`));
|
|
26
|
+
}, []);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @param {any} val
|
|
31
|
+
* @returns {val is Record<any, any>}
|
|
32
|
+
*/
|
|
33
|
+
const isObject = (val) => val != null && typeof val === "object" && Array.isArray(val) === false;
|
|
34
|
+
const requireOrImportWithMiddleware = (filePath) => {
|
|
35
|
+
let registerPlugins = load.plugins.filter((plugin) => typeof plugin.register !== "undefined");
|
|
36
|
+
let transformPlugins = load.plugins.filter((plugin) => typeof plugin.transform !== "undefined");
|
|
37
|
+
return requireOrImport(filePath, { middleware: registerPlugins }).then(async (mdl) => Promise.all(transformPlugins.map((plugin) => {
|
|
38
|
+
return Promise.resolve(plugin.transform(mdl)).then((result) => {
|
|
39
|
+
if (result)
|
|
40
|
+
mdl = result;
|
|
41
|
+
});
|
|
42
|
+
})).then(() => mdl));
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param {string} namespace
|
|
47
|
+
* @param {{ filePath: string, extension: string }} opts
|
|
48
|
+
* @returns {Promise<{ filePath: string, value: string }>}
|
|
49
|
+
*/
|
|
50
|
+
async function resolveExtension(namespace, { filePath, extension }) {
|
|
51
|
+
let resolvedPath;
|
|
52
|
+
if (extension.startsWith("./") || extension.startsWith("../")) {
|
|
53
|
+
if (extname(extension) === "") {
|
|
54
|
+
resolvedPath = resolve(dirname(filePath), `${extension}${extname(filePath)}`);
|
|
55
|
+
}
|
|
56
|
+
if (!existsSync(resolvedPath))
|
|
57
|
+
resolvedPath = null;
|
|
58
|
+
if (!resolvedPath) {
|
|
59
|
+
resolvedPath = resolve(dirname(filePath), extension);
|
|
60
|
+
}
|
|
61
|
+
if (!existsSync(resolvedPath))
|
|
62
|
+
resolvedPath = null;
|
|
63
|
+
}
|
|
64
|
+
if (!resolvedPath) {
|
|
65
|
+
const pkg = require.resolve(extension, {
|
|
66
|
+
cwd: dirname(filePath),
|
|
67
|
+
});
|
|
68
|
+
const accepted = validNames(namespace);
|
|
69
|
+
for (const config of accepted) {
|
|
70
|
+
try {
|
|
71
|
+
resolvedPath = `${pkg}/${config}`;
|
|
72
|
+
if (resolvedPath && existsSync(resolvedPath)) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
resolvedPath = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (e) { }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!resolvedPath) {
|
|
83
|
+
resolvedPath = require.resolve(extension, { cwd: dirname(filePath) });
|
|
84
|
+
}
|
|
85
|
+
if (!resolvedPath)
|
|
86
|
+
return;
|
|
87
|
+
const value = await requireOrImportWithMiddleware(resolvedPath);
|
|
88
|
+
return { filePath: resolvedPath, value };
|
|
89
|
+
}
|
|
90
|
+
async function resolveExtensions(namespace, { filePath, value: raw, context }, acc = {}) {
|
|
91
|
+
let value = typeof raw === "function" ? await raw(context) : raw;
|
|
92
|
+
if (Array.isArray(value))
|
|
93
|
+
return value;
|
|
94
|
+
assert(isObject(value), `${namespace} configuration expects an "object" but encountered ${value}`);
|
|
95
|
+
acc = merge(acc, value);
|
|
96
|
+
if (!("extends" in value))
|
|
97
|
+
return acc;
|
|
98
|
+
assert(Array.isArray(value.extends), `${namespace} "extends" must be an array`);
|
|
99
|
+
const configs = await Promise.all(value.extends.map((extension) => resolveExtension(namespace, { filePath, extension }).then((config) => resolveExtensions(namespace, { ...config, context }, acc))));
|
|
100
|
+
for (const config of configs) {
|
|
101
|
+
acc = merge(acc, config);
|
|
102
|
+
}
|
|
103
|
+
delete acc.extends;
|
|
104
|
+
return acc;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
* @param {string} namespace
|
|
109
|
+
* @param {import('../index').LoadOptions} opts
|
|
110
|
+
*/
|
|
111
|
+
async function resolveConfig(namespace, opts = {}) {
|
|
112
|
+
const accepted = validNames(namespace);
|
|
113
|
+
const { context, accept } = opts;
|
|
114
|
+
const input = opts.cwd || process.cwd();
|
|
115
|
+
let mustExist = true;
|
|
116
|
+
if (typeof opts.mustExist !== "undefined") {
|
|
117
|
+
mustExist = opts.mustExist;
|
|
118
|
+
}
|
|
119
|
+
if (typeof opts.merge === "function") {
|
|
120
|
+
merge = opts.merge;
|
|
121
|
+
}
|
|
122
|
+
let filePath;
|
|
123
|
+
if (typeof opts.filePath === "string") {
|
|
124
|
+
const absPath = opts.filePath.startsWith(".")
|
|
125
|
+
? resolve(opts.filePath, input)
|
|
126
|
+
: opts.filePath;
|
|
127
|
+
if (existsSync(absPath)) {
|
|
128
|
+
filePath = absPath;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
filePath = await escalade(input, async (dir, names) => {
|
|
133
|
+
if (accept) {
|
|
134
|
+
for (const n of names) {
|
|
135
|
+
if (accept(n, { directory: dir }) === true)
|
|
136
|
+
return n;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
for (const n of accepted) {
|
|
140
|
+
if (names.includes(n))
|
|
141
|
+
return n;
|
|
142
|
+
}
|
|
143
|
+
if (names.includes("config")) {
|
|
144
|
+
let d = join(dir, "config");
|
|
145
|
+
let _, stats = await toStats(d);
|
|
146
|
+
let entries = [];
|
|
147
|
+
if (stats.isDirectory()) {
|
|
148
|
+
entries = await toRead(d);
|
|
149
|
+
for (const n of accepted) {
|
|
150
|
+
if (entries.includes(n))
|
|
151
|
+
return join("config", n);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (names.includes("package.json")) {
|
|
156
|
+
let file = join(dir, "package.json");
|
|
157
|
+
let _, contents = await toReadFile(file).then((r) => JSON.parse(r.toString()));
|
|
158
|
+
if (contents[namespace])
|
|
159
|
+
return "package.json";
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (mustExist) {
|
|
164
|
+
assert(!!filePath, `Unable to resolve a ${namespace} configuration`, "ERR_PROLOAD_NOT_FOUND");
|
|
165
|
+
}
|
|
166
|
+
else if (!filePath) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
return filePath;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
*
|
|
173
|
+
* @param {string} namespace
|
|
174
|
+
* @param {import('../index').LoadOptions} opts
|
|
175
|
+
*/
|
|
176
|
+
async function load(namespace, opts = {}) {
|
|
177
|
+
const { context } = opts;
|
|
178
|
+
let mustExist = true;
|
|
179
|
+
if (typeof opts.mustExist !== 'undefined') {
|
|
180
|
+
mustExist = opts.mustExist;
|
|
181
|
+
}
|
|
182
|
+
const filePath = await resolveConfig(namespace, opts);
|
|
183
|
+
if (mustExist) {
|
|
184
|
+
assert(!!filePath, `Unable to resolve a ${namespace} configuration`, 'ERR_PROLOAD_NOT_FOUND');
|
|
185
|
+
}
|
|
186
|
+
else if (!filePath) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
let rawValue = await requireOrImportWithMiddleware(filePath);
|
|
190
|
+
if (filePath.endsWith('package.json'))
|
|
191
|
+
rawValue = rawValue[namespace];
|
|
192
|
+
// Important: "empty" config files will be returned as `Module {}`
|
|
193
|
+
// We should handle them here
|
|
194
|
+
if (rawValue && !(rawValue instanceof Object)) {
|
|
195
|
+
if (mustExist) {
|
|
196
|
+
assert(true, `Resolved a ${namespace} configuration, but no configuration was exported`, "ERR_PROLOAD_NOT_FOUND");
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const resolvedValue = await resolveExtensions(namespace, {
|
|
203
|
+
filePath,
|
|
204
|
+
value: rawValue,
|
|
205
|
+
context,
|
|
206
|
+
});
|
|
207
|
+
return {
|
|
208
|
+
filePath,
|
|
209
|
+
raw: rawValue,
|
|
210
|
+
value: resolvedValue,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const defaultPlugins = [
|
|
214
|
+
{
|
|
215
|
+
name: "@proload/extract-default",
|
|
216
|
+
transform(mdl) {
|
|
217
|
+
if (mdl.default && Object.keys(mdl).length === 1) {
|
|
218
|
+
return mdl.default;
|
|
219
|
+
}
|
|
220
|
+
;
|
|
221
|
+
return mdl;
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
];
|
|
225
|
+
/** @type import('../index').Plugin[] */
|
|
226
|
+
load.plugins = defaultPlugins;
|
|
227
|
+
load.use = (plugins) => {
|
|
228
|
+
load.plugins = [...load.plugins, ...plugins];
|
|
229
|
+
};
|
|
230
|
+
export default load;
|
|
231
|
+
export { resolveConfig as resolve };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import { pathToFileURL } from 'url';
|
|
4
|
+
let require = createRequire(import.meta.url);
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} filePath
|
|
8
|
+
*/
|
|
9
|
+
export default async function requireOrImport(filePath, { middleware = [] } = {}) {
|
|
10
|
+
await Promise.all(middleware.map(plugin => plugin.register(filePath)));
|
|
11
|
+
return new Promise(async (resolve, reject) => {
|
|
12
|
+
const fileUrl = pathToFileURL(filePath).toString();
|
|
13
|
+
try {
|
|
14
|
+
const mdl = await import(fileUrl);
|
|
15
|
+
return resolve(mdl);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
reject(e);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
package/dist/state.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class GlobalState {
|
|
|
26
26
|
targets: import("lightningcss").Targets;
|
|
27
27
|
compressedFiles: Set<string>;
|
|
28
28
|
issues: Map<string, Issue[]>;
|
|
29
|
+
installed_dependencies: Set<string>;
|
|
29
30
|
summary: Summary;
|
|
30
31
|
summaryByExtension: Record<string, Summary>;
|
|
31
32
|
reportIssue(sourceFile: string, issue: Issue): void;
|
package/dist/state.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GlobalState } from '../state.js';
|
|
2
|
+
export declare function install_dependency(state: GlobalState, html_file: string, options: {
|
|
3
|
+
source: {
|
|
4
|
+
npm_package_name: string;
|
|
5
|
+
absolute_path_to_file: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
};
|
|
8
|
+
destination: {
|
|
9
|
+
folder_name: string;
|
|
10
|
+
code_loader: string;
|
|
11
|
+
};
|
|
12
|
+
}, appendToBody: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
export async function install_dependency(state, html_file, options, appendToBody) {
|
|
6
|
+
const path_html = path.dirname('/' + html_file);
|
|
7
|
+
const folder = `/_jampack/${options.destination.folder_name}`;
|
|
8
|
+
const src_filename = options.source.filename;
|
|
9
|
+
const url_loader = `${folder}/loader.js`;
|
|
10
|
+
// Install dependency in /_jampack if not done yet
|
|
11
|
+
if (!state.installed_dependencies.has(options.source.npm_package_name)) {
|
|
12
|
+
const quickLinkDestination = path.join(state.dir, folder, src_filename);
|
|
13
|
+
const path_loader = path.join(state.dir, url_loader);
|
|
14
|
+
await fs.mkdir(path.join(state.dir, folder), { recursive: true });
|
|
15
|
+
// Write loader
|
|
16
|
+
const code_loader = options.destination.code_loader;
|
|
17
|
+
await fs.writeFile(path_loader, code_loader);
|
|
18
|
+
// Write quicklink code
|
|
19
|
+
const source = require.resolve(`${options.source.npm_package_name}${options.source.absolute_path_to_file}/${src_filename}`);
|
|
20
|
+
await fs.copyFile(source, quickLinkDestination);
|
|
21
|
+
state.installed_dependencies.add(options.source.npm_package_name);
|
|
22
|
+
}
|
|
23
|
+
// Add custom code to the end of body if not done yet
|
|
24
|
+
if (!(options.source.npm_package_name in appendToBody)) {
|
|
25
|
+
appendToBody[options.source.npm_package_name] = `<script type="module" src="${path.relative(path_html, url_loader)}"></script>`;
|
|
26
|
+
}
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@divriots/jampack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"cache-version": {
|
|
5
5
|
"img": "v1",
|
|
6
6
|
"img-ext": "v1"
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@commander-js/extra-typings": "^12.0.0",
|
|
30
30
|
"@divriots/cheerio": "1.0.0-rc.12",
|
|
31
|
-
"@proload/core": "^0.3.3",
|
|
32
31
|
"@swc/core": "^1.4.16",
|
|
33
32
|
"add": "^2.0.6",
|
|
34
33
|
"browserslist": "^4.23.0",
|
|
@@ -42,6 +41,7 @@
|
|
|
42
41
|
"html-minifier-terser": "^7.2.0",
|
|
43
42
|
"kleur": "^4.1.5",
|
|
44
43
|
"lightningcss": "^1.25.1",
|
|
44
|
+
"lozad": "^1.16.0",
|
|
45
45
|
"mini-svg-data-uri": "^1.4.4",
|
|
46
46
|
"ora": "^8.0.1",
|
|
47
47
|
"quicklink": "^2.3.0",
|