From 6d3b6edd8a84ce0f90f47c2bb7baff3a03a3498d Mon Sep 17 00:00:00 2001 From: HF Date: Tue, 12 Dec 2023 16:29:16 +0100 Subject: [PATCH] cache all language builds in the same folder write custom webpack loader to invalidate language specific files choose most recent asset based on mtime rather than birthtime --- scripts/TtagNonCacheableLoader.js | 20 ++++++++++++++++++ src/core/assets.js | 10 ++++----- webpack.config.client.js | 35 +++++++++++++------------------ 3 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 scripts/TtagNonCacheableLoader.js diff --git a/scripts/TtagNonCacheableLoader.js b/scripts/TtagNonCacheableLoader.js new file mode 100644 index 00000000..b8329b4b --- /dev/null +++ b/scripts/TtagNonCacheableLoader.js @@ -0,0 +1,20 @@ +/* + * webpack loader that + * marks modules that include ttag as non-cachable + */ +const filtered = {}; + +module.exports = function (source) { + if (filtered.hasOwnProperty(this.resourcePath)) { + if (filtered[this.resourcePath]) { + this.cacheable(false); + } + return source; + } + const hasTtag = source.slice(0, 400).includes('ttag'); + filtered[this.resourcePath] = hasTtag; + if (hasTtag) { + this.cacheable(false); + } + return source; +} diff --git a/src/core/assets.js b/src/core/assets.js index c1068263..ee2b392f 100644 --- a/src/core/assets.js +++ b/src/core/assets.js @@ -28,7 +28,7 @@ function checkAssets() { css: {}, }; const assetFiles = fs.readdirSync(assetDir); - const birthtimes = {}; + const mtimes = {}; for (const filename of assetFiles) { const parts = filename.split('.'); @@ -38,13 +38,13 @@ function checkAssets() { continue; } // if multiple candidates exist, take most recent created file - const birthtime = fs.statSync(path.resolve(assetDir, filename)) - .birthtime.getTime(); + const mtime = fs.statSync(path.resolve(assetDir, filename)) + .mtime.getTime(); const ident = parts.filter((a, ind) => ind !== parts.length - 2).join('.'); - if (birthtimes[ident] && birthtimes[ident] > birthtime) { + if (mtimes[ident] && mtimes[ident] > mtime) { continue; } - birthtimes[ident] = birthtime; + mtimes[ident] = mtime; const ext = parts[parts.length - 1]; const relPath = `${ASSET_DIR}/${filename}`; diff --git a/webpack.config.client.js b/webpack.config.client.js index d71ab274..cee4fc59 100644 --- a/webpack.config.client.js +++ b/webpack.config.client.js @@ -37,14 +37,6 @@ function buildWebpackClientConfig( ['ttag', ttag], ]; - // cache invalidates if .po file changed - const buildDependencies = { - config: [__filename], - } - if (locale !== 'default') { - buildDependencies.i18n = [ttag.resolve.translations]; - } - return { name: 'client', target: 'web', @@ -69,6 +61,7 @@ function buildWebpackClientConfig( ? '[name].[chunkhash:8].js' : `[name].${locale}.[chunkhash:8].js`, chunkFilename: `[name].${locale}.[chunkhash:8].js`, + clean: true, }, resolve: { @@ -91,9 +84,7 @@ function buildWebpackClientConfig( { test: /\.svg$/, use: [ - { - loader: 'babel-loader', - }, + 'babel-loader', { loader: 'react-svg-loader', options: { @@ -114,16 +105,21 @@ function buildWebpackClientConfig( }, { test: /\.(js|jsx)$/, - loader: 'babel-loader', + use: [ + { + loader: 'babel-loader', + options: { + plugins: babelPlugins, + }, + }, + path.resolve('scripts/TtagNonCacheableLoader.js'), + ], include: [ path.resolve('src'), ...['image-q'].map((moduleName) => ( path.resolve('node_modules', moduleName) )), ], - options: { - plugins: babelPlugins, - }, }, ], }, @@ -168,7 +164,7 @@ function buildWebpackClientConfig( }, }, - recordsPath: path.join(__dirname, 'records.json'), + recordsPath: path.resolve('records.json'), stats: { colors: true, @@ -179,20 +175,19 @@ function buildWebpackClientConfig( }, cache: (extract) ? false - : { + : { type: 'filesystem', - name: (development) ? `${locale}-dev` : locale, - buildDependencies, }, }; } function getAllAvailableLocals() { + // return ['default', 'de', 'tr']; const langDir = path.resolve('i18n'); const langs = fs.readdirSync(langDir) .filter((e) => (e.endsWith('.po') && !e.startsWith('ssr'))) .map((l) => l.slice(0, -3)); - langs.push('default'); + langs.unshift('default'); return langs; }