Skip to content

Commit

Permalink
V_2_2_10 (#30)
Browse files Browse the repository at this point in the history
* refine cache; bugfix

* replace fs sync methods with promises

* update changelog
  • Loading branch information
indooorsman authored Mar 25, 2022
1 parent 1aa49d7 commit cf686d9
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 51 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## V2.2.10
- **[v2]** refine cache logic
- **[v2]** replace fs sync methods to promises

## V2.2.8
- **[v2]** refine some logs
- **[v2]** make hash of outputs stable
Expand Down
38 changes: 21 additions & 17 deletions lib/cache.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,54 @@
const { readFile } = require('fs/promises');
class BuildCache {
/**
* @param {(...args: any[]) => void} log
* @param {import('..').Build} build
*/
constructor(log) {
this.log = log || ((...args) => console.log(...args));
constructor(build) {
this.build = build;
/**
* @type {import('..').Build['context']['log']}
*/
this.log = build.context.log;
/**
* @type {Map<string, {result: import('esbuild').OnLoadResult; input: string}}
*/
this.cache = new Map();
}
/**
* @description key should be absolute path
* @param {string} key
* @param {string} absPath
* @returns {Promise<import('esbuild').OnLoadResult|void>}
*/
async get(key) {
const cachedData = this.cache.get(key);
async get(absPath) {
const cachedData = this.cache.get(absPath);
if (cachedData) {
this.log(`find cache data, check if input changed(${key})...`);
const input = await readFile(key, { encoding: 'utf8' });
this.log(
`find cache data, check if content changed(${this.build.context.relative(absPath)})...`
);
const input = await readFile(absPath, { encoding: 'utf8' });
if (input === cachedData.input) {
this.log(`input not changed, return cache(${key})`);
this.log(`content not changed, return cache(${this.build.context.relative(absPath)})`);
return cachedData.result;
}
this.log(`input changed(${key})`);
this.log(`content changed(${this.build.context.relative(absPath)}), rebuilding...`);
return void 0;
}
this.log(`cache data not found(${key})`);
this.log(`cache data not found(${this.build.context.relative(absPath)}), building...`);
return void 0;
}
/**
* @description key should be absolute path
* @param {string} key
* @param {string} absPath
* @param {import('esbuild').OnLoadResult} result
* @param {string} originContent
* @returns {Promise<void>}
*/
async set(key, result, originContent) {
async set(absPath, result, originContent) {
const m = process.memoryUsage.rss();
if (m / 1024 / 1024 > 250) {
this.log('memory usage > 250M');
this.clear();
}
const input = originContent || (await readFile(key, { encoding: 'utf8' }));
this.cache.set(key, { input, result });
const input = originContent || (await readFile(absPath, { encoding: 'utf8' }));
this.cache.set(absPath, { input, result });
}
clear() {
this.log('clear cache');
Expand Down
58 changes: 33 additions & 25 deletions lib/plugin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const path = require('path');
const { createHash } = require('crypto');
const { readFileSync } = require('fs');
const { readFile, appendFile } = require('fs/promises');
const {
getLogger,
Expand Down Expand Up @@ -105,24 +104,23 @@ export default new Proxy(${classNamesMapString}, {
* @return {Promise<void>}
*/
const prepareBuild = async (build, options) => {
const buildId = getBuildId(build);
const buildId = await getBuildId(build);
build.initialOptions.metafile = true;
const packageRoot = options.root;
const buildRoot = getRootDir(build);
const log = getLogger(build);
const cache = new BuildCache(log);
const relative = (to) => getRelativePath(build, to);

log(`root of this build(#${buildId}):`, buildRoot);

build.context = {
buildId,
buildRoot,
packageRoot,
log,
relative,
cache
relative
};
build.context.cache = new BuildCache(build);

log(`root of this build(#${buildId}):`, buildRoot);
};

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

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

log(`checking cache for`, absPath);
log(`checking cache for`, rpath);
const cached = await cache.get(absPath);
if (cached) {
log('return build cache for', rpath);
Expand Down Expand Up @@ -211,7 +209,7 @@ const onLoadModulesCss = async (build, options, args) => {
loader: 'js'
};
await cache.set(absPath, result, originCss);
log(`add build result to cache for ${absPath}`);
log(`add build result to cache for ${rpath}`);

return result;
};
Expand Down Expand Up @@ -279,10 +277,10 @@ const onLoadBuiltModulesCss = async ({ pluginData }, build) => {
const onEnd = async (build, options, result) => {
const { buildId, buildRoot, cache } = build.context;
const log = getLogger(build);
log('done');

if (options.inject === true || typeof options.inject === 'string') {
const cssContents = [];

const { entryPoints } = build.initialOptions;
let entriesArray = [];
if (Array.isArray(entryPoints)) {
Expand All @@ -295,24 +293,32 @@ const onEnd = async (build, options, result) => {
});
}
const entries = entriesArray.map((p) => (path.isAbsolute(p) ? p : path.resolve(buildRoot, p)));

log('entries:', entries);

let injectTo = null;
Object.keys(result.metafile?.outputs ?? []).forEach((f) => {
if (
!injectTo &&
result.metafile.outputs[f].entryPoint &&
entries.includes(path.resolve(buildRoot, result.metafile.outputs[f].entryPoint)) &&
path.extname(f) === '.js'
) {
injectTo = path.resolve(buildRoot, f);
}
if (path.extname(f) === '.css') {
const fullpath = path.resolve(buildRoot, f);
const css = readFileSync(fullpath);
cssContents.push(`${css}\n`);
}
});
const outputs = Object.keys(result.metafile?.outputs ?? []);

await Promise.all(
outputs.map(async (f) => {
if (
!injectTo &&
result.metafile.outputs[f].entryPoint &&
entries.includes(path.resolve(buildRoot, result.metafile.outputs[f].entryPoint)) &&
path.extname(f) === '.js'
) {
injectTo = path.resolve(buildRoot, f);
}
if (path.extname(f) === '.css') {
const fullpath = path.resolve(buildRoot, f);
const css = await readFile(fullpath, { encoding: 'utf8' });
cssContents.push(`${css}`);
}
})
);

log('inject css to', path.relative(buildRoot, injectTo));

if (injectTo && cssContents.length) {
const allCss = cssContents.join('');
const container = typeof options.inject === 'string' ? options.inject : 'head';
Expand All @@ -321,6 +327,8 @@ const onEnd = async (build, options, result) => {
await appendFile(injectTo, injectedCode, { encoding: 'utf-8' });
}
}

log('finished');
};

/**
Expand Down
20 changes: 11 additions & 9 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const path = require('path');
const { createHash } = require('crypto');
const { readFileSync } = require('fs');
const { readFile } = require('fs/promises');
const pluginName = require('../package.json').name.toLowerCase();
const pluginNamespace = `${pluginName}-namespace`;
const buildingCssSuffix = `?${pluginName}-building`;
Expand Down Expand Up @@ -103,9 +103,9 @@ const getRelativePath = (build, to) => {
* getBuildId
* @description buildId should be stable so that the hash of output files are stable
* @param {import('..').Build} build
* @returns {string}
* @returns {Promise<string>}
*/
const getBuildId = (build) => {
const getBuildId = async (build) => {
const { entryPoints } = build.initialOptions;
const buildRoot = getRootDir(build);
let entries = [];
Expand All @@ -118,12 +118,14 @@ const getBuildId = (build) => {
entries.push(entryPoints[k]);
});
}
const entryContents = entries
.map((p) => {
const absPath = path.isAbsolute(p) ? p : path.resolve(buildRoot, p);
return readFileSync(absPath, { encoding: 'utf8' }).trim();
})
.join('');
const entryContents = (
await Promise.all(
entries.map(async (p) => {
const absPath = path.isAbsolute(p) ? p : path.resolve(buildRoot, p);
return (await readFile(absPath, { encoding: 'utf8' })).trim();
})
)
).join('');
return createHash('sha256').update(entryContents).digest('hex');
};

Expand Down

0 comments on commit cf686d9

Please sign in to comment.