CacheSerializerFactory.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * A factory wrapper around a webpack compiler plugin to create a serializer
  3. * object that caches a various data hard-source turns into json data without
  4. * circular references.
  5. *
  6. * The wrapper uses a plugin hook on the webpack Compiler called
  7. * `'hard-source-cache-factory'`. It is a waterfall plugin, the returned value
  8. * of one plugin handle is passed to the next as the first argument. This
  9. * plugin is expected to return a factory function that takes one argument. The
  10. * argument passed to the factory function is the info about what kind of cache
  11. * serializer hard-source wants.
  12. *
  13. * The info object contains three fields, `name`, `type`, and `cacheDirPath`.
  14. *
  15. * One example of info might be
  16. *
  17. * ```js
  18. * {
  19. * name: 'asset',
  20. * type: 'file',
  21. * cacheDirPath: '/absolute/path/to/my-project/path/configured/in/hard-source'
  22. * }
  23. * ```
  24. *
  25. * - `name` is the general name of the cache in hard-source.
  26. * - `type` is the type of data contained. The `file` type means it'll be file
  27. * data like large buffers and strings. The `data` type means its generally
  28. * smaller info and serializable with JSON.stringify.
  29. * - `cacheDirPath` is the root of the hard-source disk cache. A serializer
  30. * should add some further element to the path for where it will store its
  31. * info.
  32. *
  33. * So an example plugin handle should take the `factory` argument and return
  34. * its own wrapping factory function. That function will take the `info` data
  35. * and if it wants to returns a serializer. Otherwise its best to call the
  36. * factory passed into the plugin handle.
  37. *
  38. * ```js
  39. * compiler.plugin('hard-source-cache-factory', function(factory) {
  40. * return function(info) {
  41. * if (info.type === 'data') {
  42. * return new MySerializer({
  43. * cacheDirPath: join(info.cacheDirPath, info.name)
  44. * });
  45. * }
  46. * return factory(info);
  47. * };
  48. * });
  49. * ```
  50. *
  51. * @module hard-source-webpack-plugin/cache-serializer-factory
  52. * @author Michael "Z" Goddard <mzgoddard@gmail.com>
  53. */
  54. /**
  55. * @constructor Serializer
  56. * @memberof module:hard-source-webpack-plugin/cache-serializer-factory
  57. */
  58. /**
  59. * @method read
  60. * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~Serializer#
  61. * @returns {Promise} promise that resolves the disk cache's contents
  62. * @resolves {Object} a map of keys to current values stored on disk that has
  63. * previously been cached
  64. */
  65. /**
  66. * @method write
  67. * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~Serializer#
  68. * @param {Array.Object} ops difference of values to be stored in the disk cache
  69. * @param {string} ops.key
  70. * @param ops.value
  71. * @returns {Promise} promise that resolves when writing completes
  72. */
  73. const FileSerializerPlugin = require('./SerializerFilePlugin');
  74. const Append2SerializerPlugin = require('./SerializerAppend2Plugin');
  75. const pluginCompat = require('./util/plugin-compat');
  76. /**
  77. * @constructor CacheSerializerFactory
  78. * @memberof module:hard-source-webpack-plugin/cache-serializer-factory
  79. */
  80. class CacheSerializerFactory {
  81. constructor(compiler) {
  82. this.compiler = compiler;
  83. pluginCompat.register(compiler, 'hardSourceCacheFactory', 'syncWaterfall', [
  84. 'factory',
  85. ]);
  86. pluginCompat.tap(
  87. compiler,
  88. 'hardSourceCacheFactory',
  89. 'default factory',
  90. factory => info => {
  91. // It's best to have plugins to hard-source listed in the config after it
  92. // but to make hard-source easier to use we can call the factory of a
  93. // plugin passed into this default factory.
  94. if (factory) {
  95. serializer = factory(info);
  96. if (serializer) {
  97. return serializer;
  98. }
  99. }
  100. // Otherwise lets return the default serializers.
  101. switch (info.type) {
  102. case 'data':
  103. return CacheSerializerFactory.dataSerializer.createSerializer(info);
  104. break;
  105. case 'file':
  106. return CacheSerializerFactory.fileSerializer.createSerializer(info);
  107. break;
  108. default:
  109. throw new Error(
  110. `Unknown hard-source cache serializer type: ${info.type}`,
  111. );
  112. break;
  113. }
  114. },
  115. );
  116. }
  117. /**
  118. * @method create
  119. * @memberof module:hard-source-webpack-plugin/cache-serializer-factory~CacheSerializerFactory#
  120. * @param {Object} info
  121. * @param {String} info.name
  122. * @param {String} info.type
  123. * @param {String} info.cacheDirPath
  124. * @returns {Serializer}
  125. */
  126. create(info) {
  127. const factory = pluginCompat.call(this.compiler, 'hardSourceCacheFactory', [
  128. null,
  129. ]);
  130. const serializer = factory(info);
  131. return serializer;
  132. }
  133. }
  134. /**
  135. * The default data serializer factory.
  136. */
  137. CacheSerializerFactory.dataSerializer = Append2SerializerPlugin;
  138. /**
  139. * The default file serializer factory.
  140. */
  141. CacheSerializerFactory.fileSerializer = FileSerializerPlugin;
  142. module.exports = CacheSerializerFactory;