diff --git a/package.json b/package.json index cbe573e..17d320b 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "dependencies": { "debug": "^4.1.1", "find-cache-dir": "^3.3.1", - "flat-cache": "^3.0.4", + "flat-cache": "^6.1.7", "micromatch": "^4.0.2", "react-docgen-typescript": "^2.2.2", "tslib": "^2.6.2" diff --git a/src/plugin.ts b/src/plugin.ts index 39cbed2..6b31058 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -5,7 +5,7 @@ import * as docGen from "react-docgen-typescript"; import { matcher } from "micromatch"; import * as webpack from "webpack"; import findCacheDir from "find-cache-dir"; -import flatCache from "flat-cache"; +import { FlatCache } from 'flat-cache'; import crypto from "crypto"; import { LoaderOptions } from "./types"; @@ -62,10 +62,16 @@ const matchGlob = (globs?: string[]) => { Boolean(filename && matchers.find((match) => match(filename))); }; -// The cache is used only with webpack 4 for now as webpack 5 comes with caching of its own +// Create cache instance with modern options const cacheId = "ts-docgen"; const cacheDir = findCacheDir({ name: cacheId }); -const cache = flatCache.load(cacheId, cacheDir); +const cache = new FlatCache({ + cacheId, + cacheDir, + ttl: 24 * 60 * 60 * 1000, // 24 hours + lruSize: 10000, // Limit cache size + persistInterval: 5 * 60 * 1000 // Save every 5 minutes +}); /** Run the docgen parser and inject the result into the output */ /** This is used for webpack 4 or earlier */ @@ -86,7 +92,8 @@ function processModule( // eslint-disable-next-line .update(webpackModule._source._value) .digest("hex"); - const cached = cache.getKey(hash); + + const cached = cache.get(hash); if (cached) { // eslint-disable-next-line @@ -130,6 +137,9 @@ function processModule( // @ts-ignore: Webpack 4 type // eslint-disable-next-line webpackModule._source._value = sourceWithDocs; + + // Cache is auto-persisted via persistInterval + cache.set(hash, sourceWithDocs); } /** Inject typescript docgen information into modules at the end of a build */ @@ -148,6 +158,11 @@ export default class DocgenPlugin implements webpack.WebpackPluginInstance { } apply(compiler: webpack.Compiler): void { + // Add cleanup hook + compiler.hooks.done.tap(this.name, () => { + cache.destroy(); + }); + // Property compiler.version is set only starting from webpack 5 const webpackVersion = compiler.webpack?.version || ""; const isWebpack5 = parseInt(webpackVersion.split(".")[0], 10) >= 5; @@ -363,8 +378,6 @@ export default class DocgenPlugin implements webpack.WebpackPluginInstance { typePropName: "type", }) ); - - cache.save(); }); }); } diff --git a/yarn.lock b/yarn.lock index 19f872b..0a9607b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -942,6 +942,13 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@keyv/serialize@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@keyv/serialize/-/serialize-1.0.3.tgz#e0fe3710e2a379cb0490cd41e5a5ffa2bab58bf6" + integrity sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g== + dependencies: + buffer "^6.0.3" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -2132,6 +2139,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + before-after-hook@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" @@ -2209,11 +2221,27 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +cacheable@^1.8.9: + version "1.8.9" + resolved "https://registry.yarnpkg.com/cacheable/-/cacheable-1.8.9.tgz#f5498999567ae1015761d805bd8bbecd8393fbd4" + integrity sha512-FicwAUyWnrtnd4QqYAoRlNs44/a1jTL7XDKqm5gJ90wz1DQPlC7U2Rd1Tydpv+E7WAr4sQHuw8Q8M3nZMAyecQ== + dependencies: + hookified "^1.7.1" + keyv "^5.3.1" + call-bind@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" @@ -3432,11 +3460,25 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" +flat-cache@^6.1.7: + version "6.1.7" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-6.1.7.tgz#c04b08316739ad7ef997e1b9ea363443fc2fcb38" + integrity sha512-qwZ4xf1v1m7Rc9XiORly31YaChvKt6oNVHuqqZcoED/7O+ToyNVGobKsIAopY9ODcWpEDKEBAbrSOCBHtNQvew== + dependencies: + cacheable "^1.8.9" + flatted "^3.3.3" + hookified "^1.7.1" + flatted@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== +flatted@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -3734,6 +3776,11 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: dependencies: function-bind "^1.1.2" +hookified@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/hookified/-/hookified-1.7.1.tgz#b08228173e06e9e8767bae1dffb216b8c6171b41" + integrity sha512-OXcdHsXeOiD7OJ5zvWj8Oy/6RCdLwntAX+wUrfemNcMGn6sux4xbEHi2QXwqePYhjQ/yvxxq2MvCRirdlHscBw== + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -3764,6 +3811,11 @@ iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -4676,6 +4728,13 @@ jsx-ast-utils@^3.3.5: object.assign "^4.1.4" object.values "^1.1.6" +keyv@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-5.3.1.tgz#d3acebeecedafd4bf2b929e8866bcd79db071f1e" + integrity sha512-13hQT2q2VIwOoaJdJa7nY3J8UVbYtMTJFHnwm9LI+SaQRfUiM6Em9KZeOVTCKbMnGcRIL3NSUFpAdjZCq24nLQ== + dependencies: + "@keyv/serialize" "^1.0.3" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"