CacheModule.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. const pluginCompat = require('./util/plugin-compat');
  2. const relateContext = require('./util/relate-context');
  3. const { parityCacheFromCache, pushParityWriteOps } = require('./util/parity');
  4. const relateNormalPath = relateContext.relateNormalPath;
  5. function relateNormalRequest(compiler, key) {
  6. return key
  7. .split('!')
  8. .map(subkey => relateNormalPath(compiler, subkey))
  9. .join('!');
  10. }
  11. function relateNormalModuleId(compiler, id) {
  12. return id.substring(0, 24) + relateNormalRequest(compiler, id.substring(24));
  13. }
  14. class ModuleCache {
  15. apply(compiler) {
  16. const compilerHooks = pluginCompat.hooks(compiler);
  17. let moduleCache = {};
  18. let parityCache = {};
  19. const moduleArchetypeCache = {
  20. _ops: [],
  21. get(id) {
  22. if (moduleCache[id] && !moduleCache[id].invalid) {
  23. if (typeof moduleCache[id] === 'string') {
  24. moduleCache[id] = JSON.parse(moduleCache[id]);
  25. }
  26. return moduleCache[id];
  27. }
  28. },
  29. set(id, item) {
  30. moduleCache[id] = item;
  31. if (item) {
  32. this._ops.push(id);
  33. } else if (moduleCache[id]) {
  34. if (typeof moduleCache[id] === 'string') {
  35. moduleCache[id] = JSON.parse(moduleCache[id]);
  36. }
  37. moduleCache[id].invalid = true;
  38. moduleCache[id].invalidReason = 'overwritten';
  39. this._ops.push(id);
  40. }
  41. },
  42. operations() {
  43. const _this = this;
  44. const ops = this._ops.map(id => ({
  45. key: relateNormalModuleId(compiler, id),
  46. value: _this.get(id) || null,
  47. }));
  48. this._ops.length = 0;
  49. return ops;
  50. },
  51. };
  52. compilerHooks._hardSourceArchetypeRegister.call(
  53. 'Module',
  54. moduleArchetypeCache,
  55. );
  56. let moduleCacheSerializer;
  57. compilerHooks._hardSourceCreateSerializer.tap(
  58. 'HardSource - ModuleCache',
  59. (cacheSerializerFactory, cacheDirPath) => {
  60. moduleCacheSerializer = cacheSerializerFactory.create({
  61. name: 'module',
  62. type: 'data',
  63. cacheDirPath,
  64. autoParse: true,
  65. });
  66. },
  67. );
  68. compilerHooks._hardSourceResetCache.tap('HardSource - ModuleCache', () => {
  69. moduleCache = {};
  70. });
  71. compilerHooks._hardSourceReadCache.tapPromise(
  72. 'HardSource - ModuleCache',
  73. ({ contextKeys, contextNormalModuleId, copyWithDeser }) =>
  74. moduleCacheSerializer
  75. .read()
  76. .then(_moduleCache => {
  77. Object.keys(_moduleCache).forEach(key => {
  78. if (key.startsWith('__hardSource_parityToken')) {
  79. parityCache[key] = _moduleCache[key];
  80. delete _moduleCache[key];
  81. }
  82. });
  83. return _moduleCache;
  84. })
  85. .then(contextKeys(compiler, contextNormalModuleId))
  86. .then(copyWithDeser.bind(null, moduleCache)),
  87. );
  88. compilerHooks._hardSourceParityCache.tap(
  89. 'HardSource - ModuleCache',
  90. parityRoot => {
  91. parityCacheFromCache('Module', parityRoot, parityCache);
  92. },
  93. );
  94. compilerHooks.compilation.tap('HardSource - ModuleCache', compilation => {
  95. compilation.__hardSourceModuleCache = moduleCache;
  96. });
  97. compilerHooks._hardSourceWriteCache.tapPromise(
  98. 'HardSource - ModuleCache',
  99. compilation => {
  100. const moduleOps = moduleArchetypeCache.operations();
  101. if (!compilation.compiler.parentCompilation) {
  102. // Add ops to remove no longer valid modules. If they were replaced with a
  103. // up to date module, they will already have replaced this item so we
  104. // won't accidentally delete up to date modules.
  105. Object.keys(moduleCache).forEach(key => {
  106. const cacheItem = moduleCache[key];
  107. if (cacheItem && cacheItem.invalid) {
  108. // console.log('invalid', cacheItem.invalidReason);
  109. moduleCache[key] = null;
  110. moduleOps.push({
  111. key,
  112. value: null,
  113. });
  114. }
  115. });
  116. }
  117. pushParityWriteOps(compilation, moduleOps);
  118. return moduleCacheSerializer.write(moduleOps);
  119. },
  120. );
  121. }
  122. }
  123. module.exports = ModuleCache;