mirror of
https://github.com/citizenfx/cfx-server-data.git
synced 2025-02-13 17:53:16 +08:00
builders: webpack: cache input file state and only rebuild when needing to
This commit is contained in:
parent
2bc68781fc
commit
3c6a2b6859
@ -1,22 +1,68 @@
|
|||||||
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const workerFarm = require('worker-farm');
|
const workerFarm = require('worker-farm');
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
|
||||||
const justBuilt = {};
|
|
||||||
|
|
||||||
const webpackBuildTask = {
|
const webpackBuildTask = {
|
||||||
shouldBuild(resourceName) {
|
shouldBuild(resourceName) {
|
||||||
const numMetaData = GetNumResourceMetadata(resourceName, 'webpack_config');
|
const numMetaData = GetNumResourceMetadata(resourceName, 'webpack_config');
|
||||||
|
|
||||||
if (numMetaData > 0) {
|
if (numMetaData > 0) {
|
||||||
if (!(resourceName in justBuilt)) {
|
for (let i = 0; i < numMetaData; i++) {
|
||||||
return true;
|
const configName = GetResourceMetadata(resourceName, 'webpack_config');
|
||||||
}
|
|
||||||
|
|
||||||
delete justBuilt[resourceName];
|
if (shouldBuild(configName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
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) {
|
build(resourceName, cb) {
|
||||||
@ -30,6 +76,12 @@ const webpackBuildTask = {
|
|||||||
async.forEachOf(configs, (configName, i, acb) => {
|
async.forEachOf(configs, (configName, i, acb) => {
|
||||||
const configPath = GetResourcePath(resourceName) + '/' + configName;
|
const configPath = GetResourcePath(resourceName) + '/' + configName;
|
||||||
|
|
||||||
|
const cachePath = `cache/${resourceName}/${configName.replace(/\//g, '_')}.json`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.dirname(cachePath));
|
||||||
|
} catch {}
|
||||||
|
|
||||||
const config = require(configPath);
|
const config = require(configPath);
|
||||||
|
|
||||||
const workers = workerFarm(require.resolve('./webpack_runner'));
|
const workers = workerFarm(require.resolve('./webpack_runner'));
|
||||||
@ -39,7 +91,8 @@ const webpackBuildTask = {
|
|||||||
|
|
||||||
workers({
|
workers({
|
||||||
configPath,
|
configPath,
|
||||||
resourcePath
|
resourcePath,
|
||||||
|
cachePath
|
||||||
}, (err, outp) => {
|
}, (err, outp) => {
|
||||||
workerFarm.end(workers);
|
workerFarm.end(workers);
|
||||||
|
|
||||||
@ -61,6 +114,8 @@ const webpackBuildTask = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`${resourceName}: built ${configName}`);
|
||||||
|
|
||||||
acb();
|
acb();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -75,8 +130,6 @@ const webpackBuildTask = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
justBuilt[resourceName] = true;
|
|
||||||
|
|
||||||
cb(true);
|
cb(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,48 @@
|
|||||||
const weebpack = require('webpack');
|
const weebpack = require('webpack');
|
||||||
const path = require('path');
|
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) => {
|
module.exports = (inp, callback) => {
|
||||||
const config = require(inp.configPath);
|
const config = require(inp.configPath);
|
||||||
@ -10,6 +53,12 @@ module.exports = (inp, callback) => {
|
|||||||
config.output.path = path.resolve(inp.resourcePath, 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) => {
|
weebpack(config, (err, stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
|
Loading…
Reference in New Issue
Block a user