cbad74709ad886a4ab07cc95c8e8daa7e5ee69ac2929c28e48e8f2ae75c0e35801fb39e38d2ce6f4b6e73bb0cafa23ef356cea995bcc45318b3f8252b76d6d 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /* @flow */
  2. /**
  3. * Creates a mapper that maps components used during a server-side render
  4. * to async chunk files in the client-side build, so that we can inline them
  5. * directly in the rendered HTML to avoid waterfall requests.
  6. */
  7. import type { ClientManifest } from './index'
  8. export type AsyncFileMapper = (files: Array<string>) => Array<string>;
  9. export function createMapper (
  10. clientManifest: ClientManifest
  11. ): AsyncFileMapper {
  12. const map = createMap(clientManifest)
  13. // map server-side moduleIds to client-side files
  14. return function mapper (moduleIds: Array<string>): Array<string> {
  15. const res = new Set()
  16. for (let i = 0; i < moduleIds.length; i++) {
  17. const mapped = map.get(moduleIds[i])
  18. if (mapped) {
  19. for (let j = 0; j < mapped.length; j++) {
  20. res.add(mapped[j])
  21. }
  22. }
  23. }
  24. return Array.from(res)
  25. }
  26. }
  27. function createMap (clientManifest) {
  28. const map = new Map()
  29. Object.keys(clientManifest.modules).forEach(id => {
  30. map.set(id, mapIdToFile(id, clientManifest))
  31. })
  32. return map
  33. }
  34. function mapIdToFile (id, clientManifest) {
  35. const files = []
  36. const fileIndices = clientManifest.modules[id]
  37. if (fileIndices) {
  38. fileIndices.forEach(index => {
  39. const file = clientManifest.all[index]
  40. // only include async files or non-js, non-css assets
  41. if (clientManifest.async.indexOf(file) > -1 || !(/\.(js|css)($|\?)/.test(file))) {
  42. files.push(file)
  43. }
  44. })
  45. }
  46. return files
  47. }