client-plugin.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use strict';
  2. /* */
  3. var isJS = function (file) { return /\.js(\?[^.]+)?$/.test(file); };
  4. var isCSS = function (file) { return /\.css(\?[^.]+)?$/.test(file); };
  5. var ref = require('chalk');
  6. var red = ref.red;
  7. var yellow = ref.yellow;
  8. var prefix = "[vue-server-renderer-webpack-plugin]";
  9. var warn = exports.warn = function (msg) { return console.error(red((prefix + " " + msg + "\n"))); };
  10. var tip = exports.tip = function (msg) { return console.log(yellow((prefix + " " + msg + "\n"))); };
  11. var onEmit = function (compiler, name, hook) {
  12. if (compiler.hooks) {
  13. // Webpack >= 4.0.0
  14. compiler.hooks.emit.tapAsync(name, hook);
  15. } else {
  16. // Webpack < 4.0.0
  17. compiler.plugin('emit', hook);
  18. }
  19. };
  20. var hash = require('hash-sum');
  21. var uniq = require('lodash.uniq');
  22. var VueSSRClientPlugin = function VueSSRClientPlugin (options) {
  23. if ( options === void 0 ) options = {};
  24. this.options = Object.assign({
  25. filename: 'vue-ssr-client-manifest.json'
  26. }, options);
  27. };
  28. VueSSRClientPlugin.prototype.apply = function apply (compiler) {
  29. var this$1 = this;
  30. onEmit(compiler, 'vue-client-plugin', function (compilation, cb) {
  31. var stats = compilation.getStats().toJson();
  32. var allFiles = uniq(stats.assets
  33. .map(function (a) { return a.name; }));
  34. var initialFiles = uniq(Object.keys(stats.entrypoints)
  35. .map(function (name) { return stats.entrypoints[name].assets; })
  36. .reduce(function (assets, all) { return all.concat(assets); }, [])
  37. .filter(function (file) { return isJS(file) || isCSS(file); }));
  38. var asyncFiles = allFiles
  39. .filter(function (file) { return isJS(file) || isCSS(file); })
  40. .filter(function (file) { return initialFiles.indexOf(file) < 0; });
  41. var manifest = {
  42. publicPath: stats.publicPath,
  43. all: allFiles,
  44. initial: initialFiles,
  45. async: asyncFiles,
  46. modules: { /* [identifier: string]: Array<index: number> */ }
  47. };
  48. var assetModules = stats.modules.filter(function (m) { return m.assets.length; });
  49. var fileToIndex = function (file) { return manifest.all.indexOf(file); };
  50. stats.modules.forEach(function (m) {
  51. // ignore modules duplicated in multiple chunks
  52. if (m.chunks.length === 1) {
  53. var cid = m.chunks[0];
  54. var chunk = stats.chunks.find(function (c) { return c.id === cid; });
  55. if (!chunk || !chunk.files) {
  56. return
  57. }
  58. var id = m.identifier.replace(/\s\w+$/, ''); // remove appended hash
  59. var files = manifest.modules[hash(id)] = chunk.files.map(fileToIndex);
  60. // find all asset modules associated with the same chunk
  61. assetModules.forEach(function (m) {
  62. if (m.chunks.some(function (id) { return id === cid; })) {
  63. files.push.apply(files, m.assets.map(fileToIndex));
  64. }
  65. });
  66. }
  67. });
  68. var json = JSON.stringify(manifest, null, 2);
  69. compilation.assets[this$1.options.filename] = {
  70. source: function () { return json; },
  71. size: function () { return json.length; }
  72. };
  73. cb();
  74. });
  75. };
  76. module.exports = VueSSRClientPlugin;