1
0
mirror of https://github.com/citizenfx/cfx-server-data.git synced 2025-02-09 06:33:29 +08:00

builders: webpack: cache input file state and only rebuild when needing to

This commit is contained in:
moscovium 2019-01-15 14:00:11 +01:00
parent 2bc68781fc
commit 3c6a2b6859
2 changed files with 111 additions and 9 deletions

View File

@ -1,22 +1,68 @@
const fs = require('fs');
const path = require('path');
const workerFarm = require('worker-farm');
const async = require('async');
const justBuilt = {};
const webpackBuildTask = {
shouldBuild(resourceName) {
const numMetaData = GetNumResourceMetadata(resourceName, 'webpack_config');
if (numMetaData > 0) {
if (!(resourceName in justBuilt)) {
return true;
for (let i = 0; i < numMetaData; i++) {
const configName = GetResourceMetadata(resourceName, 'webpack_config');
if (shouldBuild(configName)) {
return true;
}
}
delete justBuilt[resourceName];
}
return false;
function loadCache(config) {
const cachePath = `cache/${resourceName}/${config.replace(/\//g, '_')}.json`;
try {
return JSON.parse(fs.readFileSync(cachePath, { encoding: 'utf8' }));
} catch {
return null;
}
}
function shouldBuild(config) {
const cache = loadCache(config);
if (!cache) {
return true;
}
for (const file of cache) {
const stats = getStat(file.name);
if (!stats ||
stats.mtime !== file.stats.mtime ||
stats.size !== file.stats.size ||
stats.inode !== file.stats.inode) {
return true;
}
}
return false;
}
function getStat(path) {
try {
const stat = fs.statSync(path);
return stat ? {
mtime: stat.mtimeMs,
size: stat.size,
inode: stat.ino,
} : null;
} catch {
return null;
}
}
},
build(resourceName, cb) {
@ -29,6 +75,12 @@ const webpackBuildTask = {
async.forEachOf(configs, (configName, i, acb) => {
const configPath = GetResourcePath(resourceName) + '/' + configName;
const cachePath = `cache/${resourceName}/${configName.replace(/\//g, '_')}.json`;
try {
fs.mkdirSync(path.dirname(cachePath));
} catch {}
const config = require(configPath);
@ -39,7 +91,8 @@ const webpackBuildTask = {
workers({
configPath,
resourcePath
resourcePath,
cachePath
}, (err, outp) => {
workerFarm.end(workers);
@ -60,6 +113,8 @@ const webpackBuildTask = {
acb("webpack got an error");
return;
}
console.log(`${resourceName}: built ${configName}`);
acb();
});
@ -75,8 +130,6 @@ const webpackBuildTask = {
return;
}
justBuilt[resourceName] = true;
cb(true);
});
});

View File

@ -1,5 +1,48 @@
const weebpack = require('webpack');
const path = require('path');
const fs = require('fs');
function getStat(path) {
try {
const stat = fs.statSync(path);
return stat ? {
mtime: stat.mtimeMs,
size: stat.size,
inode: stat.ino,
} : null;
} catch {
return null;
}
}
class SaveStatePlugin {
constructor(inp) {
this.cache = [];
this.cachePath = inp.cachePath;
}
apply(compiler) {
compiler.hooks.afterCompile.tap('SaveStatePlugin', (compilation) => {
for (const file of compilation.fileDependencies) {
this.cache.push({
name: file,
stats: getStat(file)
});
}
});
compiler.hooks.done.tap('SaveStatePlugin', (stats) => {
if (stats.hasErrors()) {
return;
}
fs.writeFile(this.cachePath, JSON.stringify(this.cache), () => {
});
});
}
}
module.exports = (inp, callback) => {
const config = require(inp.configPath);
@ -9,6 +52,12 @@ module.exports = (inp, callback) => {
if (config.output && config.output.path) {
config.output.path = path.resolve(inp.resourcePath, config.output.path);
}
if (!config.plugins) {
config.plugins = [];
}
config.plugins.push(new SaveStatePlugin(inp));
weebpack(config, (err, stats) => {
if (err) {