CacheAsset.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. const crypto = require('crypto');
  2. const pluginCompat = require('./util/plugin-compat');
  3. const relateContext = require('./util/relate-context');
  4. const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');
  5. function requestHash(request) {
  6. return crypto
  7. .createHash('sha1')
  8. .update(request)
  9. .digest()
  10. .hexSlice();
  11. }
  12. const relateNormalRequest = relateContext.relateNormalRequest;
  13. class AssetCache {
  14. apply(compiler) {
  15. const compilerHooks = pluginCompat.hooks(compiler);
  16. let assetCache = {};
  17. let parityCache = {};
  18. const assetArchetypeCache = {
  19. _ops: [],
  20. get(id) {
  21. const hashId = requestHash(relateNormalRequest(compiler, id));
  22. if (assetCache[hashId]) {
  23. if (typeof assetCache[hashId] === 'string') {
  24. assetCache[hashId] = JSON.parse(assetCache[hashId]);
  25. }
  26. return assetCache[hashId];
  27. }
  28. },
  29. set(id, item) {
  30. const hashId = requestHash(relateNormalRequest(compiler, id));
  31. if (item) {
  32. assetCache[hashId] = item;
  33. this._ops.push({
  34. key: hashId,
  35. value: item,
  36. });
  37. } else {
  38. assetCache[hashId] = null;
  39. this._ops.push({
  40. key: hashId,
  41. value: null,
  42. });
  43. }
  44. },
  45. operations() {
  46. const ops = this._ops.slice();
  47. this._ops.length = 0;
  48. return ops;
  49. },
  50. };
  51. compilerHooks._hardSourceArchetypeRegister.call(
  52. 'Asset',
  53. assetArchetypeCache,
  54. );
  55. let assetCacheSerializer;
  56. let assetParityCacheSerializer;
  57. compilerHooks._hardSourceCreateSerializer.tap(
  58. 'HardSource - AssetCache',
  59. (cacheSerializerFactory, cacheDirPath) => {
  60. assetCacheSerializer = cacheSerializerFactory.create({
  61. name: 'assets',
  62. type: 'file',
  63. cacheDirPath,
  64. });
  65. assetParityCacheSerializer = cacheSerializerFactory.create({
  66. name: 'assets-parity',
  67. type: 'data',
  68. cacheDirPath,
  69. });
  70. },
  71. );
  72. compilerHooks._hardSourceResetCache.tap('HardSource - AssetCache', () => {
  73. assetCache = {};
  74. parityCache = {};
  75. });
  76. compilerHooks._hardSourceReadCache.tapPromise(
  77. 'HardSource - AssetCache',
  78. () =>
  79. Promise.all([
  80. assetCacheSerializer.read().then(_assetCache => {
  81. assetCache = _assetCache;
  82. }),
  83. assetParityCacheSerializer.read().then(_parityCache => {
  84. parityCache = _parityCache;
  85. }),
  86. ]),
  87. );
  88. compilerHooks._hardSourceParityCache.tap(
  89. 'HardSource - AssetCache',
  90. parityRoot => {
  91. parityCacheFromCache('Asset', parityRoot, parityCache);
  92. },
  93. );
  94. compilerHooks._hardSourceWriteCache.tapPromise(
  95. 'HardSource - AssetCache',
  96. compilation => {
  97. const assetOps = assetArchetypeCache.operations();
  98. const parityOps = [];
  99. pushParityWriteOps(compilation, parityOps);
  100. return Promise.all([
  101. assetCacheSerializer.write(assetOps),
  102. assetParityCacheSerializer.write(parityOps),
  103. ]);
  104. },
  105. );
  106. }
  107. }
  108. module.exports = AssetCache;