Skip to content

Commit cf686d9

Browse files
authored
V_2_2_10 (#30)
* refine cache; bugfix * replace fs sync methods with promises * update changelog
1 parent 1aa49d7 commit cf686d9

File tree

4 files changed

+69
-51
lines changed

4 files changed

+69
-51
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## V2.2.10
2+
- **[v2]** refine cache logic
3+
- **[v2]** replace fs sync methods to promises
4+
15
## V2.2.8
26
- **[v2]** refine some logs
37
- **[v2]** make hash of outputs stable

lib/cache.js

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,54 @@
11
const { readFile } = require('fs/promises');
22
class BuildCache {
33
/**
4-
* @param {(...args: any[]) => void} log
4+
* @param {import('..').Build} build
55
*/
6-
constructor(log) {
7-
this.log = log || ((...args) => console.log(...args));
6+
constructor(build) {
7+
this.build = build;
8+
/**
9+
* @type {import('..').Build['context']['log']}
10+
*/
11+
this.log = build.context.log;
812
/**
913
* @type {Map<string, {result: import('esbuild').OnLoadResult; input: string}}
1014
*/
1115
this.cache = new Map();
1216
}
1317
/**
14-
* @description key should be absolute path
15-
* @param {string} key
18+
* @param {string} absPath
1619
* @returns {Promise<import('esbuild').OnLoadResult|void>}
1720
*/
18-
async get(key) {
19-
const cachedData = this.cache.get(key);
21+
async get(absPath) {
22+
const cachedData = this.cache.get(absPath);
2023
if (cachedData) {
21-
this.log(`find cache data, check if input changed(${key})...`);
22-
const input = await readFile(key, { encoding: 'utf8' });
24+
this.log(
25+
`find cache data, check if content changed(${this.build.context.relative(absPath)})...`
26+
);
27+
const input = await readFile(absPath, { encoding: 'utf8' });
2328
if (input === cachedData.input) {
24-
this.log(`input not changed, return cache(${key})`);
29+
this.log(`content not changed, return cache(${this.build.context.relative(absPath)})`);
2530
return cachedData.result;
2631
}
27-
this.log(`input changed(${key})`);
32+
this.log(`content changed(${this.build.context.relative(absPath)}), rebuilding...`);
2833
return void 0;
2934
}
30-
this.log(`cache data not found(${key})`);
35+
this.log(`cache data not found(${this.build.context.relative(absPath)}), building...`);
3136
return void 0;
3237
}
3338
/**
34-
* @description key should be absolute path
35-
* @param {string} key
39+
* @param {string} absPath
3640
* @param {import('esbuild').OnLoadResult} result
3741
* @param {string} originContent
3842
* @returns {Promise<void>}
3943
*/
40-
async set(key, result, originContent) {
44+
async set(absPath, result, originContent) {
4145
const m = process.memoryUsage.rss();
4246
if (m / 1024 / 1024 > 250) {
4347
this.log('memory usage > 250M');
4448
this.clear();
4549
}
46-
const input = originContent || (await readFile(key, { encoding: 'utf8' }));
47-
this.cache.set(key, { input, result });
50+
const input = originContent || (await readFile(absPath, { encoding: 'utf8' }));
51+
this.cache.set(absPath, { input, result });
4852
}
4953
clear() {
5054
this.log('clear cache');

lib/plugin.js

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const path = require('path');
22
const { createHash } = require('crypto');
3-
const { readFileSync } = require('fs');
43
const { readFile, appendFile } = require('fs/promises');
54
const {
65
getLogger,
@@ -105,24 +104,23 @@ export default new Proxy(${classNamesMapString}, {
105104
* @return {Promise<void>}
106105
*/
107106
const prepareBuild = async (build, options) => {
108-
const buildId = getBuildId(build);
107+
const buildId = await getBuildId(build);
109108
build.initialOptions.metafile = true;
110109
const packageRoot = options.root;
111110
const buildRoot = getRootDir(build);
112111
const log = getLogger(build);
113-
const cache = new BuildCache(log);
114112
const relative = (to) => getRelativePath(build, to);
115113

116-
log(`root of this build(#${buildId}):`, buildRoot);
117-
118114
build.context = {
119115
buildId,
120116
buildRoot,
121117
packageRoot,
122118
log,
123-
relative,
124-
cache
119+
relative
125120
};
121+
build.context.cache = new BuildCache(build);
122+
123+
log(`root of this build(#${buildId}):`, buildRoot);
126124
};
127125

128126
/**
@@ -181,7 +179,7 @@ const onLoadModulesCss = async (build, options, args) => {
181179

182180
log(`loading ${rpath}${args.suffix}`);
183181

184-
log(`checking cache for`, absPath);
182+
log(`checking cache for`, rpath);
185183
const cached = await cache.get(absPath);
186184
if (cached) {
187185
log('return build cache for', rpath);
@@ -211,7 +209,7 @@ const onLoadModulesCss = async (build, options, args) => {
211209
loader: 'js'
212210
};
213211
await cache.set(absPath, result, originCss);
214-
log(`add build result to cache for ${absPath}`);
212+
log(`add build result to cache for ${rpath}`);
215213

216214
return result;
217215
};
@@ -279,10 +277,10 @@ const onLoadBuiltModulesCss = async ({ pluginData }, build) => {
279277
const onEnd = async (build, options, result) => {
280278
const { buildId, buildRoot, cache } = build.context;
281279
const log = getLogger(build);
282-
log('done');
283280

284281
if (options.inject === true || typeof options.inject === 'string') {
285282
const cssContents = [];
283+
286284
const { entryPoints } = build.initialOptions;
287285
let entriesArray = [];
288286
if (Array.isArray(entryPoints)) {
@@ -295,24 +293,32 @@ const onEnd = async (build, options, result) => {
295293
});
296294
}
297295
const entries = entriesArray.map((p) => (path.isAbsolute(p) ? p : path.resolve(buildRoot, p)));
296+
298297
log('entries:', entries);
298+
299299
let injectTo = null;
300-
Object.keys(result.metafile?.outputs ?? []).forEach((f) => {
301-
if (
302-
!injectTo &&
303-
result.metafile.outputs[f].entryPoint &&
304-
entries.includes(path.resolve(buildRoot, result.metafile.outputs[f].entryPoint)) &&
305-
path.extname(f) === '.js'
306-
) {
307-
injectTo = path.resolve(buildRoot, f);
308-
}
309-
if (path.extname(f) === '.css') {
310-
const fullpath = path.resolve(buildRoot, f);
311-
const css = readFileSync(fullpath);
312-
cssContents.push(`${css}\n`);
313-
}
314-
});
300+
const outputs = Object.keys(result.metafile?.outputs ?? []);
301+
302+
await Promise.all(
303+
outputs.map(async (f) => {
304+
if (
305+
!injectTo &&
306+
result.metafile.outputs[f].entryPoint &&
307+
entries.includes(path.resolve(buildRoot, result.metafile.outputs[f].entryPoint)) &&
308+
path.extname(f) === '.js'
309+
) {
310+
injectTo = path.resolve(buildRoot, f);
311+
}
312+
if (path.extname(f) === '.css') {
313+
const fullpath = path.resolve(buildRoot, f);
314+
const css = await readFile(fullpath, { encoding: 'utf8' });
315+
cssContents.push(`${css}`);
316+
}
317+
})
318+
);
319+
315320
log('inject css to', path.relative(buildRoot, injectTo));
321+
316322
if (injectTo && cssContents.length) {
317323
const allCss = cssContents.join('');
318324
const container = typeof options.inject === 'string' ? options.inject : 'head';
@@ -321,6 +327,8 @@ const onEnd = async (build, options, result) => {
321327
await appendFile(injectTo, injectedCode, { encoding: 'utf-8' });
322328
}
323329
}
330+
331+
log('finished');
324332
};
325333

326334
/**

lib/utils.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const path = require('path');
22
const { createHash } = require('crypto');
3-
const { readFileSync } = require('fs');
3+
const { readFile } = require('fs/promises');
44
const pluginName = require('../package.json').name.toLowerCase();
55
const pluginNamespace = `${pluginName}-namespace`;
66
const buildingCssSuffix = `?${pluginName}-building`;
@@ -103,9 +103,9 @@ const getRelativePath = (build, to) => {
103103
* getBuildId
104104
* @description buildId should be stable so that the hash of output files are stable
105105
* @param {import('..').Build} build
106-
* @returns {string}
106+
* @returns {Promise<string>}
107107
*/
108-
const getBuildId = (build) => {
108+
const getBuildId = async (build) => {
109109
const { entryPoints } = build.initialOptions;
110110
const buildRoot = getRootDir(build);
111111
let entries = [];
@@ -118,12 +118,14 @@ const getBuildId = (build) => {
118118
entries.push(entryPoints[k]);
119119
});
120120
}
121-
const entryContents = entries
122-
.map((p) => {
123-
const absPath = path.isAbsolute(p) ? p : path.resolve(buildRoot, p);
124-
return readFileSync(absPath, { encoding: 'utf8' }).trim();
125-
})
126-
.join('');
121+
const entryContents = (
122+
await Promise.all(
123+
entries.map(async (p) => {
124+
const absPath = path.isAbsolute(p) ? p : path.resolve(buildRoot, p);
125+
return (await readFile(absPath, { encoding: 'utf8' })).trim();
126+
})
127+
)
128+
).join('');
127129
return createHash('sha256').update(entryContents).digest('hex');
128130
};
129131

0 commit comments

Comments
 (0)