[
  {
    "path": ".eslintignore",
    "content": "node_modules/\n/coverage/\ndist/\nlib/\nbuild/\n/website/.cache/\n/website/public/\n__testfixtures__/"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"root\": true,\n  \"parser\": \"babel-eslint\",\n  \"extends\": [\"airbnb\", \"prettier\"],\n  \"env\": {\n    \"jest\": true\n  },\n  \"rules\": {\n    \"react/jsx-one-expression-per-line\": \"off\",\n    \"no-plusplus\": \"off\",\n    \"no-param-reassign\": \"off\",\n    \"no-nested-ternary\": \"off\",\n    \"react/jsx-filename-extension\": [\"error\", { \"extensions\": [\".js\"] }],\n    \"react/jsx-wrap-multilines\": \"off\",\n    \"react/no-unused-state\": \"off\",\n    \"react/destructuring-assignment\": \"off\",\n    \"react/prop-types\": \"off\",\n    \"react/sort-comp\": \"off\",\n    \"react/jsx-props-no-spreading\": \"off\",\n    \"react/state-in-constructor\": \"off\",\n    \"import/extensions\": \"off\",\n    \"import/prefer-default-export\": \"off\"\n  }\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: gregberge\nopen_collective: loadable\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug.md",
    "content": "---\nname: 🐛 Bug report\nabout: Create a report to help us improve\n---\n\n## 🐛 Bug Report\n\nA clear and concise description of what the bug is.\n\n## To Reproduce\n\nSteps to reproduce the behavior:\n\n## Expected behavior\n\nA clear and concise description of what you expected to happen.\n\n## Link to repl or repo (highly encouraged)\n\nPlease provide a minimal repository on GitHub.\n\nIssues without a reproduction link are likely to stall.\n\n## Run `npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard`\n\nPaste the results here:\n\n```bash\n\n```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature.md",
    "content": "---\nname: 🚀 Feature Proposal\nabout: Submit a proposal for a new feature\n---\n\n## 🚀 Feature Proposal\n\nA clear and concise description of what the feature is.\n\n## Motivation\n\nPlease outline the motivation for the proposal.\n\n## Example\n\nPlease provide an example for how this feature would be used.\n\n## Pitch\n\nWhy does this feature belong in the Loadable Component ecosystem?\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "content": "---\nname: 💬 Questions / Help\nabout: If you have questions, please read full readme first\n---\n\n## 💬 Questions and Help\n\nLoadable Components project is young, but please before asking your question:\n\n- Read carefully the README of the project\n- Search if your answer has already been answered in old issues\n\nAfter you can submit your question and we will be happy to help you!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/regression.md",
    "content": "---\nname: 💥 Regression Report\nabout: Report unexpected behavior that worked in previous versions\n---\n\n## 💥 Regression Report\n\nA clear and concise description of what the regression is.\n\n## Last working version\n\nWorked up to version:\n\nStopped working in version:\n\n## To Reproduce\n\nSteps to reproduce the behavior:\n\n## Expected behavior\n\nA clear and concise description of what you expected to happen.\n\n## Link to repl or repo (highly encouraged)\n\nPlease provide a minimal repository on GitHub.\n\nIssues without a reproduction link are likely to stall.\n\n## Run `npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard`\n\nPaste the results here:\n\n```bash\n\n```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "## 👉 [Please follow one of these issue templates](https://github.com/gregberge/loadable-components/issues/new/choose) 👈\n\nNote: to keep the backlog clean and actionable, issues may be immediately closed if they do not follow one of the above issue templates.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. The two fields below are mandatory. -->\n\n## Summary\n\n<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->\n\n## Test plan\n\n<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI. -->\n"
  },
  {
    "path": ".github/SUPPORT.md",
    "content": "Please read carefully the README before asking questions.\n"
  },
  {
    "path": ".github/opencollective.yml",
    "content": "collective: loadable\ntiers:\n  - tiers: '*'\n    labels: ['backer']\n    message: |\n      Hey <author> :wave:,\n      Thank you so much for supporting us on [Open Collective](<link>) :heart:.\n      We'll give a special attention to this issue.\n      <link>\ninvitation: |\n  Hey <author> :wave:,\n  Thank you for opening an issue. We'll get back to you as soon as we can.\n  Please, consider supporting us on [Open Collective](<link>). We give a special attention to issues opened by backers.\n  If you use Loadable at work, you can also ask your company to sponsor us :heart:.\n  <link>\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 60\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. Thank you\n  for your contributions.\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules/\ndist/\nlib/\n/coverage/\nexamples/*/yarn.lock"
  },
  {
    "path": ".npmignore",
    "content": "/*\n!/babel.js\n!/server.js\n!/server.d.ts\n!/dist/**/*.js\n!/src/**/*.js\n!/types/index.d.ts\n!/types/tsconfig.json\n__fixtures__\n*.test.js\n.size-snapshot.json\n"
  },
  {
    "path": ".npmrc",
    "content": "registry=https://registry.npmjs.org"
  },
  {
    "path": ".nvmrc",
    "content": "20\nregistry=https://registry.npmjs.org"
  },
  {
    "path": ".prettierignore",
    "content": "node_modules/\n/coverage/\n/dist/\n__fixtures__/\nCHANGELOG.md\npackage.json\nlerna.json\n/website/.cache/\n/website/public/\n__testfixtures__/\nexamples/*/public\n**/dist/\n**/lib/"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"semi\": false\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - 12\n\nnotifications:\n  email: false\n\ncache:\n  yarn: true\n  directories:\n    - '.eslintcache'\n    - 'node_modules'\n\ngit:\n  depth: 5\n\nbranches:\n  only:\n  - master\n  - stable\n\nscript:\n  - yarn ci\n  - yarn --cwd examples/typescript && yarn --cwd examples/typescript build\n  - yarn --cwd examples/webpack/webpack4 && yarn --cwd examples/webpack/webpack4 build\n  - yarn --cwd examples/webpack/webpack5 && yarn --cwd examples/webpack/webpack5 build\n\n\nnotifications:\n  email: false\n"
  },
  {
    "path": "BACKERS.md",
    "content": "# Sponsors & Backers\n\n<p class=\"description\">Support Loadable Components development through donations.</p>\n\nLoadable Components is an MIT-licensed open source project. It is created an maintained by a single person: Greg Bergé.\n\n- [Sponsor me on GitHub ❤️](https://github.com/sponsors/gregberge).\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.16.7](https://github.com/gregberge/loadable-components/compare/v5.16.6...v5.16.7) (2025-05-18)\n\n**Note:** Version bump only for package loadable-components\n\n\n\n\n\n## [5.16.6](https://github.com/gregberge/loadable-components/compare/v5.16.5...v5.16.6) (2025-05-18)\n\n**Note:** Version bump only for package loadable-components\n\n\n\n\n\n## [5.16.5](https://github.com/smooth-code/loadable-components/compare/v5.16.4...v5.16.5) (2024-04-20)\n\n**Note:** Version bump only for package loadable-components\n\n\n\n\n\n## [5.16.4](https://github.com/smooth-code/loadable-components/compare/v5.16.3...v5.16.4) (2024-04-20)\n\n\n### Bug Fixes\n\n* correct esm configuration for loadable/server, fixes: [#999](https://github.com/smooth-code/loadable-components/issues/999) ([#1004](https://github.com/smooth-code/loadable-components/issues/1004)) ([114cea2](https://github.com/smooth-code/loadable-components/commit/114cea2b61ef644d3b794a9b5f48df69f0f5400b))\n\n\n\n\n\n## [5.16.3](https://github.com/smooth-code/loadable-components/compare/v5.16.2...v5.16.3) (2023-12-26)\n\n\n### Bug Fixes\n\n* correct react-is for mjs export; remove isValidComponent check ([#991](https://github.com/smooth-code/loadable-components/issues/991)) ([9d381c3](https://github.com/smooth-code/loadable-components/commit/9d381c35b7fc1f8f9122caac25e8e255871ebab6))\n\n\n\n\n\n## [5.16.2](https://github.com/smooth-code/loadable-components/compare/v5.16.1...v5.16.2) (2023-12-15)\n\n\n### Bug Fixes\n\n* add esm exports to package.json and change esm bundle extension to .mjs to allow node.js to properly import esm version of package. ([#989](https://github.com/smooth-code/loadable-components/issues/989)) ([e4a3718](https://github.com/smooth-code/loadable-components/commit/e4a37188b804e6a5bc66f39c23c738006bc0e284))\n\n\n\n\n\n## [5.16.1](https://github.com/smooth-code/loadable-components/compare/v5.16.0...v5.16.1) (2023-07-20)\n\n\n### Bug Fixes\n\n* correct babel plugin default signature to allow any source of 'loadable' ([#972](https://github.com/smooth-code/loadable-components/issues/972)) ([19849b6](https://github.com/smooth-code/loadable-components/commit/19849b6ba738fe19c18e61ed3402ee82ba934760)), closes [#971](https://github.com/smooth-code/loadable-components/issues/971)\n\n\n\n\n\n# [5.16.0](https://github.com/smooth-code/loadable-components/compare/v5.15.3...v5.16.0) (2023-07-09)\n\n\n### Features\n\n* Allow additional identifiers to be passed in to the babel plugin ([#966](https://github.com/smooth-code/loadable-components/issues/966)) ([e18e37a](https://github.com/smooth-code/loadable-components/commit/e18e37afd8b30455d3a786b9b0dae5f3bd0d442b))\n\n\n\n\n\n## [5.15.3](https://github.com/smooth-code/loadable-components/compare/v5.15.2...v5.15.3) (2023-01-28)\n\n\n### Bug Fixes\n\n* add React 17 and 18 to package dependencies, fixes [#718](https://github.com/smooth-code/loadable-components/issues/718) ([66edc37](https://github.com/smooth-code/loadable-components/commit/66edc37a731a8ec655deffd3ad454fd96e909ba3))\n\n\n\n\n\n## [5.15.2](https://github.com/smooth-code/loadable-components/compare/v5.15.1...v5.15.2) (2021-12-12)\n\n\n### Bug Fixes\n\n* Clear correct cache when compiling with Webpack ([#838](https://github.com/smooth-code/loadable-components/issues/838)) ([3b9cb20](https://github.com/smooth-code/loadable-components/commit/3b9cb202a09365e67c08ec18455d82bedf62f4db))\n* loadAsync Loadable should copy statics ([#839](https://github.com/smooth-code/loadable-components/issues/839)) ([9ff6693](https://github.com/smooth-code/loadable-components/commit/9ff66939ee6fd622922f71128a30b5d3f43f63b0))\n* use stable promises for load/preload/React ([#858](https://github.com/smooth-code/loadable-components/issues/858)) ([45f2d91](https://github.com/smooth-code/loadable-components/commit/45f2d9133c8234fec9cbe36e5a162a61f24e4aae))\n\n\n\n\n\n## [5.15.1](https://github.com/smooth-code/loadable-components/compare/v5.15.0...v5.15.1) (2021-08-17)\n\n\n### Bug Fixes\n\n* add cachedAssets to stats options ([#779](https://github.com/smooth-code/loadable-components/issues/779)) ([73b17fd](https://github.com/smooth-code/loadable-components/commit/73b17fd067579b1c5d38eba00e157964e0930a94)), closes [#770](https://github.com/smooth-code/loadable-components/issues/770)\n* SubResourceIntegrity ([#803](https://github.com/smooth-code/loadable-components/issues/803)) ([9b34195](https://github.com/smooth-code/loadable-components/commit/9b34195627c65372a7c834311c32dfcbd5b7fedd))\n\n\n\n\n\n# [5.15.0](https://github.com/smooth-code/loadable-components/compare/v5.14.2...v5.15.0) (2021-05-08)\n\n\n### Bug Fixes\n\n* add displayNames to generated components ([#731](https://github.com/smooth-code/loadable-components/issues/731)) ([b640c82](https://github.com/smooth-code/loadable-components/commit/b640c82a742ffbccc423439e2e205d1becdf5491))\n\n\n### Features\n\n* support multiple Webpack runtimes ([#701](https://github.com/smooth-code/loadable-components/issues/701)) ([d351367](https://github.com/smooth-code/loadable-components/commit/d3513679ed680e46967ca18555116c06e5a4b341))\n* webpack plugin doesn't need all chunk info ([#735](https://github.com/smooth-code/loadable-components/issues/735)) ([cea9f24](https://github.com/smooth-code/loadable-components/commit/cea9f249f7550a1154cf88bcfa3812ebb78a500f))\n\n\n\n\n\n## [5.14.2](https://github.com/smooth-code/loadable-components/compare/v5.14.1...v5.14.2) (2021-01-31)\n\n\n### Bug Fixes\n\n* ignore css chunk ([#689](https://github.com/smooth-code/loadable-components/issues/689)) ([6926e19](https://github.com/smooth-code/loadable-components/commit/6926e190c80f525467980fffbbded0bf933f27ed))\n* remove main asset path query ([#686](https://github.com/smooth-code/loadable-components/issues/686)) ([dde2252](https://github.com/smooth-code/loadable-components/commit/dde2252136a2d7f3ff635f85deff429948130883))\n* update hooks for webpack 5 ([#676](https://github.com/smooth-code/loadable-components/issues/676)) ([671ef52](https://github.com/smooth-code/loadable-components/commit/671ef527e7a37c459df616ee74dc92e106e8245e))\n\n\n\n\n\n## [5.14.1](https://github.com/smooth-code/loadable-components/compare/v5.14.0...v5.14.1) (2020-10-22)\n\n**Note:** Version bump only for package loadable-components\n\n\n\n\n\n# [5.14.0](https://github.com/smooth-code/loadable-components/compare/v5.13.2...v5.14.0) (2020-10-20)\n\n\n### Bug Fixes\n\n* add key to chunks script elements ([#631](https://github.com/smooth-code/loadable-components/issues/631)) ([25b532e](https://github.com/smooth-code/loadable-components/commit/25b532eb53a2841229dbc8a9c91f24112a46b93f)), closes [#628](https://github.com/smooth-code/loadable-components/issues/628)\n* do not derive cache key if component is static, fixes [#629](https://github.com/smooth-code/loadable-components/issues/629) ([#630](https://github.com/smooth-code/loadable-components/issues/630)) ([b4151d8](https://github.com/smooth-code/loadable-components/commit/b4151d85b3ba0f57e9fab48ec88f5e57e4d0b544))\n* treat mjs as script ([575fe2b](https://github.com/smooth-code/loadable-components/commit/575fe2b3f58b18c17416f238780b9bab85110706))\n\n\n### Features\n\n* make packages webpack 5 compatible ([#638](https://github.com/smooth-code/loadable-components/issues/638)) ([e882e4d](https://github.com/smooth-code/loadable-components/commit/e882e4d812e714066eba19a11dd119193e7a9e01))\n\n\n\n\n\n## [5.13.2](https://github.com/smooth-code/loadable-components/compare/v5.13.1...v5.13.2) (2020-09-14)\n\n\n### Bug Fixes\n\n* Fixed lazy usage with Suspense and Error Boundary together ([#521](https://github.com/smooth-code/loadable-components/issues/521)) ([42fbdd0](https://github.com/smooth-code/loadable-components/commit/42fbdd0d552551b18ed0781383bb0073e1cd8640))\n* human readable errors ([b86bb82](https://github.com/smooth-code/loadable-components/commit/b86bb82417ad098ed73037159886c4d0481ba34e))\n* spread nested required chunks array ([95e6ecb](https://github.com/smooth-code/loadable-components/commit/95e6ecb0dd9be3cf18ded934cca433a660fa3543))\n* typo ([bebb828](https://github.com/smooth-code/loadable-components/commit/bebb82811e25475e91f9fadf64fda004b6b649b0))\n\n\n\n\n\n## [5.13.1](https://github.com/smooth-code/loadable-components/compare/v5.13.0...v5.13.1) (2020-07-02)\n\n\n### Bug Fixes\n\n* expose used chunkNames from a server. Fixes [#587](https://github.com/smooth-code/loadable-components/issues/587) ([831aec0](https://github.com/smooth-code/loadable-components/commit/831aec03154ab16007db0d78fbf3559583c000fe))\n\n\n\n\n\n# [5.13.0](https://github.com/smooth-code/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n\n### Bug Fixes\n\n* allow webpack cache is ready only for initial chunks, fixes [#558](https://github.com/smooth-code/loadable-components/issues/558) ([61f8b75](https://github.com/smooth-code/loadable-components/commit/61f8b75b54612368c88807d73abb7dc7add720ad))\n* memory leak in module cache management, fixes [#560](https://github.com/smooth-code/loadable-components/issues/560) ([6c11703](https://github.com/smooth-code/loadable-components/commit/6c11703cbc5446fc61d10c47b64e84a00cf899c3))\n* use make-dir instead of mkdirp ([#544](https://github.com/smooth-code/loadable-components/issues/544)) ([5a9c33b](https://github.com/smooth-code/loadable-components/commit/5a9c33b222fecb320dc02b643122fbe717aa6fc8))\n* **babel-plugin:** add missing peer dependency ([#524](https://github.com/smooth-code/loadable-components/issues/524)) ([03a79b6](https://github.com/smooth-code/loadable-components/commit/03a79b66defc78f150436acd6a9d3e029bb1d470))\n\n\n### Features\n\n* add `resolveComponent` option ([a47d3d9](https://github.com/smooth-code/loadable-components/commit/a47d3d9021ee6b12c1209bf41069dc133cb1fa7c))\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Bug Fixes\n\n* apply loadable transformations before any other, fixes [#466](https://github.com/gregberge/loadable-components/issues/466) ([ac5ba45](https://github.com/gregberge/loadable-components/commit/ac5ba45862bad68b971a969e6e8713874add51a6))\n\n\n### Features\n\n* add codemods to migrate from react-loadable ([#463](https://github.com/gregberge/loadable-components/issues/463)) ([a82d5ad](https://github.com/gregberge/loadable-components/commit/a82d5ad1e17cd64d3579aa207abfc18346ff0107))\n* avoid synchronous loading on client if options.ssr is false ([#346](https://github.com/gregberge/loadable-components/issues/346)) ([338bf55](https://github.com/gregberge/loadable-components/commit/338bf555adc68986b12c8dd4e304875425119ca2))\n* loadable-components.com ([e515b0e](https://github.com/gregberge/loadable-components/commit/e515b0e1a73a240fae1ab32f5abd6df23d35efcf))\n\n\n### Performance Improvements\n\n* avoid calling stats.toJson if possible ([87698de](https://github.com/gregberge/loadable-components/commit/87698de079cb742317a4f6570430ccd5cd526d3e))\n\n\n\n\n\n# [5.11.0](https://github.com/smooth-code/loadable-components/compare/v5.10.3...v5.11.0) (2019-12-02)\n\n\n### Bug Fixes\n\n* fix isReady problem ([#445](https://github.com/smooth-code/loadable-components/issues/445)) ([3024348](https://github.com/smooth-code/loadable-components/commit/30243482be917e89515d057e2368e7278e34696c)), closes [#400](https://github.com/smooth-code/loadable-components/issues/400)\n* **server:** use require instead of module.require ([#457](https://github.com/smooth-code/loadable-components/issues/457)) ([064b4f8](https://github.com/smooth-code/loadable-components/commit/064b4f83b291e8a7d73bc44fe4196dc9ddc81fe8)), closes [#455](https://github.com/smooth-code/loadable-components/issues/455)\n\n\n### Features\n\n* add support for SRI (integrity) (with webpack-subresource-integrity) ([#436](https://github.com/smooth-code/loadable-components/issues/436)) ([586ad0a](https://github.com/smooth-code/loadable-components/commit/586ad0af6e172e3a0bffdbe0c8ab682c0d8b0eab))\n\n\n\n\n\n## [5.10.3](https://github.com/smooth-code/loadable-components/compare/v5.10.2...v5.10.3) (2019-09-24)\n\n\n### Bug Fixes\n\n* empty cache on each server reload ([#431](https://github.com/smooth-code/loadable-components/issues/431)) ([d4428c6](https://github.com/smooth-code/loadable-components/commit/d4428c6)), closes [#230](https://github.com/smooth-code/loadable-components/issues/230)\n* support IE 11 without polyfill ([#416](https://github.com/smooth-code/loadable-components/issues/416)) ([80ee809](https://github.com/smooth-code/loadable-components/commit/80ee809)), closes [#397](https://github.com/smooth-code/loadable-components/issues/397)\n* **babel-plugin:** fix bug when using + concatenation instead of a template literal ([#425](https://github.com/smooth-code/loadable-components/issues/425)) ([d98dd27](https://github.com/smooth-code/loadable-components/commit/d98dd27))\n\n\n\n\n\n## [5.10.2](https://github.com/smooth-code/loadable-components/compare/v5.10.1...v5.10.2) (2019-07-15)\n\n\n### Bug Fixes\n\n* use === instead of Object.is ([c88cd82](https://github.com/smooth-code/loadable-components/commit/c88cd82)), closes [#371](https://github.com/smooth-code/loadable-components/issues/371)\n\n\n### Performance Improvements\n\n* use more performant url join impl ([#353](https://github.com/smooth-code/loadable-components/issues/353)) ([c3fbbef](https://github.com/smooth-code/loadable-components/commit/c3fbbef))\n\n\n\n\n\n## [5.10.1](https://github.com/smooth-code/loadable-components/compare/v5.10.0...v5.10.1) (2019-05-14)\n\n\n### Bug Fixes\n\n* add @babel/preset-env in rollup config ([#336](https://github.com/smooth-code/loadable-components/issues/336)) ([8b50c94](https://github.com/smooth-code/loadable-components/commit/8b50c94)), closes [#335](https://github.com/smooth-code/loadable-components/issues/335)\n\n\n\n\n\n# [5.10.0](https://github.com/smooth-code/loadable-components/compare/v5.9.0...v5.10.0) (2019-05-13)\n\n\n### Bug Fixes\n\n* fix chunkname mismatch ([#332](https://github.com/smooth-code/loadable-components/issues/332)) ([7ffaa4c](https://github.com/smooth-code/loadable-components/commit/7ffaa4c)), closes [#331](https://github.com/smooth-code/loadable-components/issues/331)\n\n\n### Features\n\n* add `load` method that returns a Promise ([#329](https://github.com/smooth-code/loadable-components/issues/329)) ([a10a9d5](https://github.com/smooth-code/loadable-components/commit/a10a9d5)), closes [#226](https://github.com/smooth-code/loadable-components/issues/226)\n* support reactive dynamic loadable ([#330](https://github.com/smooth-code/loadable-components/issues/330)) ([d65c5bb](https://github.com/smooth-code/loadable-components/commit/d65c5bb)), closes [#284](https://github.com/smooth-code/loadable-components/issues/284)\n\n\n### Performance Improvements\n\n* optimize rollup config ([c94760b](https://github.com/smooth-code/loadable-components/commit/c94760b))\n\n\n\n\n\n# [5.9.0](https://github.com/smooth-code/loadable-components/compare/v5.8.0...v5.9.0) (2019-04-23)\n\n\n### Features\n\n* support multiple react apps ([#317](https://github.com/smooth-code/loadable-components/issues/317)) ([dc54050](https://github.com/smooth-code/loadable-components/commit/dc54050)), closes [#311](https://github.com/smooth-code/loadable-components/issues/311)\n* **server:** authorize custom filesystem ([#318](https://github.com/smooth-code/loadable-components/issues/318)) ([f2a6bbd](https://github.com/smooth-code/loadable-components/commit/f2a6bbd)), closes [#315](https://github.com/smooth-code/loadable-components/issues/315)\n\n\n\n\n\n# [5.8.0](https://github.com/smooth-code/loadable-components/compare/v5.7.2...v5.8.0) (2019-04-10)\n\n\n### Bug Fixes\n\n* **babel-plugin:** Use require.resolve instead of relative path resolution ([#303](https://github.com/smooth-code/loadable-components/issues/303)) ([bad7f1f](https://github.com/smooth-code/loadable-components/commit/bad7f1f))\n\n\n### Features\n\n* **ChunkExtractor:** support publicPath override ([#292](https://github.com/smooth-code/loadable-components/issues/292)) ([9731e9c](https://github.com/smooth-code/loadable-components/commit/9731e9c))\n* **server:** support function in attributes ([#277](https://github.com/smooth-code/loadable-components/issues/277)) ([c172324](https://github.com/smooth-code/loadable-components/commit/c172324))\n\n\n### Performance Improvements\n\n* **server:** improve lodash imports for serverless bundles ([#298](https://github.com/smooth-code/loadable-components/issues/298)) ([96841f2](https://github.com/smooth-code/loadable-components/commit/96841f2))\n\n\n\n\n\n## [5.7.2](https://github.com/smooth-code/loadable-components/compare/v5.7.1...v5.7.2) (2019-03-20)\n\n\n### Bug Fixes\n\n* **babel-plugin:** handle \"-\" at the end of request ([c0f325b](https://github.com/smooth-code/loadable-components/commit/c0f325b))\n\n\n\n\n\n## [5.7.1](https://github.com/smooth-code/loadable-components/compare/v5.7.0...v5.7.1) (2019-03-19)\n\n\n### Bug Fixes\n\n* **babel-plugin:** handle special chars in file names ([#279](https://github.com/smooth-code/loadable-components/issues/279)) ([4da39ff](https://github.com/smooth-code/loadable-components/commit/4da39ff))\n* **webpack-plugin:** create output folder with mkdirp ([#273](https://github.com/smooth-code/loadable-components/issues/273)) ([3767f28](https://github.com/smooth-code/loadable-components/commit/3767f28))\n\n\n\n\n\n# [5.7.0](https://github.com/smooth-code/loadable-components/compare/v5.6.1...v5.7.0) (2019-03-14)\n\n\n### Bug Fixes\n\n* **component:** fix warning message about babel ([#255](https://github.com/smooth-code/loadable-components/issues/255)) ([7cb68a1](https://github.com/smooth-code/loadable-components/commit/7cb68a1)), closes [#253](https://github.com/smooth-code/loadable-components/issues/253)\n* **server:** fix loading order of assets ([#266](https://github.com/smooth-code/loadable-components/issues/266)) ([4c8ae60](https://github.com/smooth-code/loadable-components/commit/4c8ae60))\n\n\n### Features\n\n* use inline JSON to enabling CSP without `unsafe-inline` ([05e5500](https://github.com/smooth-code/loadable-components/commit/05e5500))\n\n\n### Performance Improvements\n\n* **build:** add build target for Node ([#267](https://github.com/smooth-code/loadable-components/issues/267)) ([97ff6ac](https://github.com/smooth-code/loadable-components/commit/97ff6ac))\n\n\n\n\n\n## [5.6.1](https://github.com/smooth-code/loadable-components/compare/v5.6.0...v5.6.1) (2019-02-25)\n\n\n### Bug Fixes\n\n* **component:** better ES Modules handling ([#228](https://github.com/smooth-code/loadable-components/issues/228)) ([3628363](https://github.com/smooth-code/loadable-components/commit/3628363))\n* **server:** allow query-param cache busting in chunk names ([#229](https://github.com/smooth-code/loadable-components/issues/229)) ([71f7bcd](https://github.com/smooth-code/loadable-components/commit/71f7bcd))\n* **server:** use `eval` to prevent webpack warning ([#240](https://github.com/smooth-code/loadable-components/issues/240)) ([948165d](https://github.com/smooth-code/loadable-components/commit/948165d)), closes [#234](https://github.com/smooth-code/loadable-components/issues/234)\n* **suspense:** fix suspense mode in React v16.8+ ([#251](https://github.com/smooth-code/loadable-components/issues/251)) ([d04e1c9](https://github.com/smooth-code/loadable-components/commit/d04e1c9))\n\n\n\n\n\n# [5.6.0](https://github.com/smooth-code/loadable-components/compare/v5.5.0...v5.6.0) (2019-02-05)\n\n\n### Bug Fixes\n\n* Add extra props option for links ([#212](https://github.com/smooth-code/loadable-components/issues/212)) ([6714d2a](https://github.com/smooth-code/loadable-components/commit/6714d2a))\n* **server:** fix chunkName resolving ([#219](https://github.com/smooth-code/loadable-components/issues/219)) ([ef11e11](https://github.com/smooth-code/loadable-components/commit/ef11e11))\n\n\n### Features\n\n* **babel-plugin:** transform code annotated with magic comment ([4f832dc](https://github.com/smooth-code/loadable-components/commit/4f832dc)), closes [#192](https://github.com/smooth-code/loadable-components/issues/192)\n* **component:** add preload method ([#224](https://github.com/smooth-code/loadable-components/issues/224)) ([4a67ace](https://github.com/smooth-code/loadable-components/commit/4a67ace)), closes [#196](https://github.com/smooth-code/loadable-components/issues/196)\n* **server:** add option to disable SSR ([#223](https://github.com/smooth-code/loadable-components/issues/223)) ([4cab4f9](https://github.com/smooth-code/loadable-components/commit/4cab4f9)), closes [#195](https://github.com/smooth-code/loadable-components/issues/195)\n\n\n\n\n\n# [5.5.0](https://github.com/smooth-code/loadable-components/compare/v5.4.0...v5.5.0) (2019-01-22)\n\n\n### Features\n\n* allow to specify extra attributes in getScriptTags & others ([#210](https://github.com/smooth-code/loadable-components/issues/210)) ([8a3d067](https://github.com/smooth-code/loadable-components/commit/8a3d067))\n\n\n\n\n\n# [5.4.0](https://github.com/smooth-code/loadable-components/compare/v5.3.0...v5.4.0) (2019-01-17)\n\n\n### Features\n\n* **webpack-plugin:** support custom path in writeToDisk option ([#187](https://github.com/smooth-code/loadable-components/issues/187)) ([4a6f84f](https://github.com/smooth-code/loadable-components/commit/4a6f84f))\n\n\n\n\n\n# [5.3.0](https://github.com/smooth-code/loadable-components/compare/v5.2.2...v5.3.0) (2019-01-11)\n\n\n### Features\n\n* support inline CSS ([#190](https://github.com/smooth-code/loadable-components/issues/190)) ([2caf676](https://github.com/smooth-code/loadable-components/commit/2caf676))\n\n\n\n\n\n## [5.2.2](https://github.com/smooth-code/loadable-components/compare/v5.2.1...v5.2.2) (2018-12-12)\n\n\n### Bug Fixes\n\n* **babel-plugin:** fix chunkName with aggressive code splitting ([e974933](https://github.com/smooth-code/loadable-components/commit/e974933)), closes [#182](https://github.com/smooth-code/loadable-components/issues/182)\n* ensure that component is mounted before calling `setState` ([#184](https://github.com/smooth-code/loadable-components/issues/184)) ([fe0f47f](https://github.com/smooth-code/loadable-components/commit/fe0f47f)), closes [#180](https://github.com/smooth-code/loadable-components/issues/180)\n* **server:** fix usage when compiled using webpack ([#185](https://github.com/smooth-code/loadable-components/issues/185)) ([5e28870](https://github.com/smooth-code/loadable-components/commit/5e28870)), closes [#181](https://github.com/smooth-code/loadable-components/issues/181)\n\n\n\n\n\n## [5.2.1](https://github.com/smooth-code/loadable-components/compare/v5.2.0...v5.2.1) (2018-11-27)\n\n\n### Bug Fixes\n\n* **webpack-plugin:** fix TypeError when set writeToDisk true ([#170](https://github.com/smooth-code/loadable-components/issues/170)) ([2d1fb11](https://github.com/smooth-code/loadable-components/commit/2d1fb11))\n* upgrade hoist-non-react-statics@3.2.0 ([122b1ce](https://github.com/smooth-code/loadable-components/commit/122b1ce))\n\n\n\n\n\n# [5.2.0](https://github.com/smooth-code/loadable-components/compare/v5.1.3...v5.2.0) (2018-11-23)\n\n\n### Bug Fixes\n\n* **server:** fix url join ([#166](https://github.com/smooth-code/loadable-components/issues/166)) ([ba90289](https://github.com/smooth-code/loadable-components/commit/ba90289))\n* **server:** support protocol free paths ([#163](https://github.com/smooth-code/loadable-components/issues/163)) ([3b5b115](https://github.com/smooth-code/loadable-components/commit/3b5b115))\n\n\n### Features\n\n* **webpack-plugin:** add writeToDisk option ([#161](https://github.com/smooth-code/loadable-components/issues/161)) ([6b5ba21](https://github.com/smooth-code/loadable-components/commit/6b5ba21))\n\n\n\n\n\n## [5.1.3](https://github.com/smooth-code/loadable-components/compare/v5.1.2...v5.1.3) (2018-11-20)\n\n\n### Bug Fixes\n\n* **server:** exclude http and https from regex ([#155](https://github.com/smooth-code/loadable-components/issues/155)) ([0bb2ad9](https://github.com/smooth-code/loadable-components/commit/0bb2ad9)), closes [#153](https://github.com/smooth-code/loadable-components/issues/153)\n* **server:** ignore *.hot-update.js ([edcd2c8](https://github.com/smooth-code/loadable-components/commit/edcd2c8)), closes [#148](https://github.com/smooth-code/loadable-components/issues/148)\n\n\n\n\n\n## [5.1.2](https://github.com/smooth-code/loadable-components/compare/v5.1.1...v5.1.2) (2018-11-13)\n\n\n### Bug Fixes\n\n* fix ref handler in `loadable.lib` ([da05d87](https://github.com/smooth-code/loadable-components/commit/da05d87))\n\n\n\n\n\n## [5.1.1](https://github.com/smooth-code/loadable-components/compare/v5.1.0...v5.1.1) (2018-11-13)\n\n\n### Bug Fixes\n\n* **server:** ignore source maps ([9991bbd](https://github.com/smooth-code/loadable-components/commit/9991bbd)), closes [#128](https://github.com/smooth-code/loadable-components/issues/128)\n\n\n\n\n\n# [5.1.0](https://github.com/smooth-code/loadable-components/compare/v5.0.2...v5.1.0) (2018-11-10)\n\n\n### Features\n\n* **server:** add outputPath option in ChunkExtractor ([aac26b3](https://github.com/smooth-code/loadable-components/commit/aac26b3))\n\n\n\n\n\n## [5.0.2](https://github.com/smooth-code/loadable-components/compare/v5.0.1...v5.0.2) (2018-11-10)\n\n\n### Bug Fixes\n\n* update peer dependencies ([b0363dc](https://github.com/smooth-code/loadable-components/commit/b0363dc))\n\n\n\n\n\n# [5.0.0](https://github.com/smooth-code/loadable-components/compare/v4.0.5...v5.0.0) (2018-11-10)\n\n\n### Bug Fixes\n\n* fix loadableReady ([59693bb](https://github.com/smooth-code/loadable-components/commit/59693bb))\n\n\n### Features\n\n* improve SSR support ([eb1cfe8](https://github.com/smooth-code/loadable-components/commit/eb1cfe8))\n\n\n### BREAKING CHANGES\n\n* - SSR has been rewritten from scratch, if you use it, please follow the\nnew guide.\n- Prefetch component and prefetch functions have been removed, please\nuse `webpackPrefetch` instead.\n\n\n\n\n\n## [4.0.5](https://github.com/smooth-code/loadable-components/compare/v4.0.4...v4.0.5) (2018-11-01)\n\n\n### Bug Fixes\n\n* **server:** fix getScriptElements ([ba424e0](https://github.com/smooth-code/loadable-components/commit/ba424e0))\n\n\n\n\n\n## [4.0.4](https://github.com/smooth-code/loadable-components/compare/v4.0.3...v4.0.4) (2018-10-31)\n\n\n### Bug Fixes\n\n* fix peer dependencies ([6816e8c](https://github.com/smooth-code/loadable-components/commit/6816e8c))\n\n\n\n\n\n## [4.0.3](https://github.com/smooth-code/loadable-components/compare/v4.0.2...v4.0.3) (2018-10-31)\n\n\n### Bug Fixes\n\n* **server:** disable common chunks optim ([78e7b28](https://github.com/smooth-code/loadable-components/commit/78e7b28))\n\n\n\n\n\n## [4.0.2](https://github.com/smooth-code/loadable-components/compare/v4.0.1...v4.0.2) (2018-10-31)\n\n\n### Bug Fixes\n\n* **babel-plugin:** transform into friendly chunk name ([54422cb](https://github.com/smooth-code/loadable-components/commit/54422cb))\n* **component:** fix lazy usage ([d711ee0](https://github.com/smooth-code/loadable-components/commit/d711ee0))\n\n\n\n\n\n## [4.0.1](https://github.com/smooth-code/loadable-components/compare/v4.0.0...v4.0.1) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** do not call ref several times ([8cf3190](https://github.com/smooth-code/loadable-components/commit/8cf3190))\n\n\n\n\n\n# [4.0.0](https://github.com/smooth-code/loadable-components/compare/v3.0.2...v4.0.0) (2018-10-30)\n\n\n### Features\n\n* add new loadable.lib, change API ([94b2e87](https://github.com/smooth-code/loadable-components/commit/94b2e87))\n\n\n### BREAKING CHANGES\n\n* - `ErrorComponent` is ignored, please use Error Boundaries to handle errors.\n- `lazy` is no longer exported\n- `LoadingComponent` is replaced by `fallback` option\n- `ref` are now forwarded\n\n\n\n\n\n## [3.0.2](https://github.com/smooth-code/loadable-components/compare/v3.0.1...v3.0.2) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** fix loadComponent (typo) ([a410cb2](https://github.com/smooth-code/loadable-components/commit/a410cb2))\n\n\n\n\n\n## [3.0.1](https://github.com/smooth-code/loadable-components/compare/v3.0.0...v3.0.1) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** fix loadComponents ([bd2220c](https://github.com/smooth-code/loadable-components/commit/bd2220c))\n\n\n\n\n\n# [3.0.0](https://github.com/smooth-code/loadable-components/compare/v2.2.3...v3.0.0) (2018-10-29)\n\n\n### Bug Fixes\n\n* **typescript:** restore types ([#113](https://github.com/smooth-code/loadable-components/issues/113)) ([240bb8f](https://github.com/smooth-code/loadable-components/commit/240bb8f))\n\n\n### Features\n\n* welcome loadable ([4dffad7](https://github.com/smooth-code/loadable-components/commit/4dffad7))\n\n\n### BREAKING CHANGES\n\n* API has completely changed, see documentation.\n\n\n\n\n\n# Change Log\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n\n<a name=\"2.2.3\"></a>\n## [2.2.3](https://github.com/smooth-code/loadable-components/compare/v2.2.2...v2.2.3) (2018-08-16)\n\n\n### Bug Fixes\n\n* fix type definitions (#95) ([8402c19](https://github.com/smooth-code/loadable-components/commit/8402c19)), closes [#95](https://github.com/smooth-code/loadable-components/issues/95)\n* support non-ES modules (#104) ([2a82314](https://github.com/smooth-code/loadable-components/commit/2a82314))\n\n\n\n<a name=\"2.2.2\"></a>\n## [2.2.2](https://github.com/smooth-code/loadable-components/compare/v2.2.1...v2.2.2) (2018-05-25)\n\n\n### Bug Fixes\n\n* fix error handling in loadComponents (#87) ([d32c74c](https://github.com/smooth-code/loadable-components/commit/d32c74c)), closes [#87](https://github.com/smooth-code/loadable-components/issues/87)\n\n\n\n<a name=\"2.2.1\"></a>\n## [2.2.1](https://github.com/smooth-code/loadable-components/compare/v2.2.0...v2.2.1) (2018-05-23)\n\n\n\n<a name=\"2.2.0\"></a>\n# [2.2.0](https://github.com/smooth-code/loadable-components/compare/v2.1.0...v2.2.0) (2018-05-23)\n\n\n### Bug Fixes\n\n* fix SSR with HMR #85 ([20138e1](https://github.com/smooth-code/loadable-components/commit/20138e1)), closes [#85](https://github.com/smooth-code/loadable-components/issues/85)\n\n\n### Features\n\n* experimental suspense 🤩 ([57ce712](https://github.com/smooth-code/loadable-components/commit/57ce712))\n\n\n\n<a name=\"2.1.0\"></a>\n# [2.1.0](https://github.com/smooth-code/loadable-components/compare/v2.0.1...v2.1.0) (2018-05-13)\n\n\n### Features\n\n* add TypeScript definitions (#80) ([db19796](https://github.com/smooth-code/loadable-components/commit/db19796))\n\n\n\n<a name=\"2.0.1\"></a>\n## [2.0.1](https://github.com/smooth-code/loadable-components/compare/v2.0.0...v2.0.1) (2018-05-12)\n\n\n### Bug Fixes\n\n* fix module resolving ([10318b0](https://github.com/smooth-code/loadable-components/commit/10318b0)), closes [#59](https://github.com/smooth-code/loadable-components/issues/59)\n\n\n\n<a name=\"2.0.0\"></a>\n# [2.0.0](https://github.com/smooth-code/loadable-components/compare/v1.4.0...v2.0.0) (2018-05-10)\n\n\n### Bug Fixes\n\n* do not propagate componentId ([fff1248](https://github.com/smooth-code/loadable-components/commit/fff1248))\n\n\n### Code Refactoring\n\n* remove HMR relative code ([ef0817c](https://github.com/smooth-code/loadable-components/commit/ef0817c))\n\n\n### BREAKING CHANGES\n\n* `setConfig` is no longer available.\n\n\n\n<a name=\"1.4.0\"></a>\n# [1.4.0](https://github.com/smooth-code/loadable-components/compare/v1.3.0...v1.4.0) (2018-04-18)\n\n\n### Bug Fixes\n\n* set correct loading state if component is already loaded. (#64) ([9b0cae2](https://github.com/smooth-code/loadable-components/commit/9b0cae2))\n\n\n### Features\n\n* support React.createContext API (#65) ([289ad67](https://github.com/smooth-code/loadable-components/commit/289ad67))\n\n\n\n<a name=\"1.3.0\"></a>\n# [1.3.0](https://github.com/smooth-code/loadable-components/compare/v1.2.0...v1.3.0) (2018-04-06)\n\n\n### Bug Fixes\n\n* circular structure in error object (#60) ([96333ca](https://github.com/smooth-code/loadable-components/commit/96333ca))\n* React 16.3 compatibility ([abd7963](https://github.com/smooth-code/loadable-components/commit/abd7963)), closes [#57](https://github.com/smooth-code/loadable-components/issues/57)\n\n\n### Features\n\n* attach static properties on load ([d383fab](https://github.com/smooth-code/loadable-components/commit/d383fab)), closes [#58](https://github.com/smooth-code/loadable-components/issues/58)\n\n\n\n<a name=\"1.2.0\"></a>\n# [1.2.0](https://github.com/smooth-code/loadable-components/compare/v1.1.1...v1.2.0) (2018-03-25)\n\n\n### Features\n\n* add Hot Reload support ([c79085e](https://github.com/smooth-code/loadable-components/commit/c79085e))\n\n\n\n<a name=\"1.1.1\"></a>\n## [1.1.1](https://github.com/smooth-code/loadable-components/compare/v1.1.0...v1.1.1) (2018-02-06)\n\n\n### Bug Fixes\n\n* **snapshot:** fix snap usage ([3445bea](https://github.com/smooth-code/loadable-components/commit/3445bea)), closes [#40](https://github.com/smooth-code/loadable-components/issues/40)\n\n\n\n<a name=\"1.1.0\"></a>\n# [1.1.0](https://github.com/smooth-code/loadable-components/compare/v1.0.2...v1.1.0) (2018-02-04)\n\n\n### Features\n\n* ship a single js file ([99e08c0](https://github.com/smooth-code/loadable-components/commit/99e08c0))\n\n\n\n<a name=\"1.0.2\"></a>\n## [1.0.2](https://github.com/smooth-code/loadable-components/compare/v1.0.1...v1.0.2) (2018-02-04)\n\n\n### Bug Fixes\n\n* state could have no children ([a47c410](https://github.com/smooth-code/loadable-components/commit/a47c410)), closes [#36](https://github.com/smooth-code/loadable-components/issues/36)\n\n\n\n<a name=\"1.0.1\"></a>\n## [1.0.1](https://github.com/smooth-code/loadable-components/compare/v1.0.0...v1.0.1) (2018-02-03)\n\n\n### Bug Fixes\n\n* fix loadComponents without valid state ([35f81a6](https://github.com/smooth-code/loadable-components/commit/35f81a6)), closes [#34](https://github.com/smooth-code/loadable-components/issues/34)\n\n\n\n<a name=\"1.0.0\"></a>\n# [1.0.0](https://github.com/smooth-code/loadable-components/compare/v0.4.0...v1.0.0) (2018-02-02)\n\n\n### Features\n\n* stable version 1 ([601bd34](https://github.com/smooth-code/loadable-components/commit/601bd34))\n\n\n### BREAKING CHANGES\n\n* loadable-components/babel is now required if you do server side rendering.\n* ErrorComponent now receive `ownProps` instead of `props`.\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project author at hey@gregberge.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to Contribute\n\nLoadable Components is a small project, it is widely used but has not a lot of contributors. We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and answers some questions that you may have.\n\n## [Code of Conduct](https://github.com/gregberge/loadable-components/blob/master/CODE_OF_CONDUCT.md)\n\nWe expect project participants to adhere to our Code of Conduct. Please read [the full text](https://github.com/gregberge/loadable-components/blob/master/CODE_OF_CONDUCT.md) so that you can understand what actions will and will not be tolerated.\n\n## Open Development\n\nAll work on Loadable Components happens directly on [GitHub](/). Both core team members and external contributors send pull requests which go through the same review process.\n\n### Workflow and Pull Requests\n\n_Before_ submitting a pull request, please make sure the following is done…\n\n1.  Fork the repo and create your branch from `master`. A guide on how to fork a repository: https://help.github.com/articles/fork-a-repo/\n\n    Open terminal (e.g. Terminal, iTerm, Git Bash or Git Shell) and type:\n\n    ```sh-session\n    $ git clone https://github.com/<your_username>/loadable-components\n    $ cd loadable-components\n    $ git checkout -b my_branch\n    ```\n\n    Note: Replace `<your_username>` with your GitHub username\n\n2.  Loadable Components uses [Yarn](https://code.fb.com/web/yarn-a-new-package-manager-for-javascript/) for running development scripts. If you haven't already done so, please [install yarn](https://yarnpkg.com/en/docs/install).\n\n3.  Run `yarn install`. On Windows: To install [Yarn](https://yarnpkg.com/en/docs/install#windows-tab) on Windows you may need to download either node.js or Chocolatey<br />\n\n    ```sh\n    yarn install\n    ```\n\n    To check your version of Yarn and ensure it's installed you can type:\n\n    ```sh\n    yarn --version\n    ```\n\n4.  Run `yarn build` to bootstrap packages.\n\n    ```sh\n    yarn build\n    ```\n\n5.  If you've added code that should be tested, add tests. You can use watch mode that continuously transforms changed files to make your life easier.\n\n    ```sh\n    # in the background\n    yarn run dev\n    ```\n\n6.  If you've changed APIs, update the documentation.\n\n7.  Ensure the linting is good via `yarn lint`.\n\n    ```sh-session\n    $ yarn lint\n    ```\n\n8.  Ensure the test suite passes via `yarn test`.\n\n    ```sh-session\n    $ yarn test:prepare # build example and generate fixtures before running tests\n    $ yarn test\n    ```\n\n#### Testing with your own project\n\nYou can use `yarn run release-to-git` to create releases as tags on github. This requires that:\n\n- Your git remote (where you want to publish the tags) is `origin`\n- Your commit messages follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. For example: `feat: add timeout option`.\n\n## Bugs\n\n### Where to Find Known Issues\n\nWe will be using GitHub Issues for our public bugs. We will keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new issue, try to make sure your problem doesn't already exist.\n\n### Reporting New Issues\n\nThe best way to get your bug fixed is to provide a reduced test case. Please provide a public repository with a runnable example.\n\n## Code Conventions\n\nPlease follow the `.prettierrc` in the project.\n\n## License\n\nBy contributing to Loadable Components, you agree that your contributions will be licensed under its MIT license.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2019 Greg Bergé\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/gregberge/loadable-components/master/resources/loadable-components.png\" alt=\"loadable-components\" title=\"loadable-components\" width=\"300\">\n</h1>\n<p align=\"center\" style=\"font-size: 1.2rem;\">React code splitting made easy. Reduce your bundle size without stress ✂️✨.</p>\n\n[![License](https://img.shields.io/npm/l/@loadable/component.svg)](https://github.com/gregberge/loadable-components/blob/master/LICENSE)\n[![npm package](https://img.shields.io/npm/v/@loadable/component/latest.svg)](https://www.npmjs.com/package/@loadable/component)\n[![npm downloads](https://img.shields.io/npm/dm/@loadable/component.svg)](https://www.npmjs.com/package/@loadable/component)\n[![Build Status](https://img.shields.io/travis/gregberge/loadable-components.svg)](https://travis-ci.org/gregberge/loadable-components)\n![Code style](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)\n[![Dependencies](https://img.shields.io/david/gregberge/loadable-components.svg?path=packages%2Fcomponent)](https://david-dm.org/gregberge/loadable-components?path=packages/component)\n[![DevDependencies](https://img.shields.io/david/dev/gregberge/loadable-components.svg)](https://david-dm.org/gregberge/loadable-components?type=dev)\n[![Small size](https://img.badgesize.io/https://unpkg.com/@loadable/component/dist/loadable.min.js?compression=gzip)](https://unpkg.com/@loadable/component/dist/loadable.min.js)\n\n```bash\nnpm install @loadable/component\n```\n\n## [Docs](https://loadable-components.com)\n\n**See the documentation at [loadable-components.com](https://loadable-components.com)** for more information about using Loadable Components!\n\nQuicklinks to some of the most-visited pages:\n\n- [**Getting started**](https://loadable-components.com/docs/getting-started/)\n- [Comparison with React.lazy](https://loadable-components.com/docs/loadable-vs-react-lazy/)\n- [Server Side Rendering](https://loadable-components.com/docs/server-side-rendering/)\n\n## Example\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent />\n    </div>\n  )\n}\n```\n\n## Supporting Loadable Components\n\nLoadable Components is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to the support of these awesome [backers](/BACKERS.md). If you'd like to join them, please consider:\n\n- [Sponsor me on GitHub ❤️](https://github.com/sponsors/gregberge).\n\n## License\n\nLicensed under the MIT License, Copyright © 2017-present Greg Bergé.\n\nSee [LICENSE](./LICENSE) for more information.\n"
  },
  {
    "path": "babel.config.js",
    "content": "function getTargets() {\n  if (process.env.BUILD_TARGET === 'node') {\n    return { node: '8' }\n  }\n  return undefined\n}\n\nfunction getModules() {\n  if (process.env.MODULE_TARGET === 'cjs') {\n    return 'cjs'\n  }\n  if (process.env.MODULE_TARGET === 'esm') {\n    return false\n  }\n  return 'auto'\n}\n\nmodule.exports = {\n  presets: [\n    ['@babel/preset-react', { useBuiltIns: true }],\n    [\n      '@babel/preset-env',\n      { loose: true, targets: getTargets(), modules: getModules() },\n    ],\n  ],\n  plugins: ['@babel/plugin-proposal-class-properties'],\n}\n"
  },
  {
    "path": "examples/client-side/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/client-side/README.md",
    "content": "# Get the client-side example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/client-side\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run\n\n```bash\nyarn dev\n# or\nyarn start\n```\n"
  },
  {
    "path": "examples/client-side/babel.config.js",
    "content": "module.exports = {\n  presets: ['@babel/preset-react'],\n  plugins: ['@babel/plugin-syntax-dynamic-import'],\n}\n"
  },
  {
    "path": "examples/client-side/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"webpack-dev-server\",\n    \"dev\": \"webpack-dev-server\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.2.0\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.4\",\n    \"html-webpack-plugin\": \"^3.2.0\",\n    \"webpack\": \"^4.30.0\",\n    \"webpack-cli\": \"^3.3.2\",\n    \"webpack-dev-server\": \"^3.3.1\"\n  },\n  \"dependencies\": {\n    \"@loadable/component\": \"^5.10.3\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/client-side/src/A.js",
    "content": "export default () => 'A'\n"
  },
  {
    "path": "examples/client-side/src/B.js",
    "content": "export default () => 'B'\n"
  },
  {
    "path": "examples/client-side/src/Hello.js",
    "content": "export default () => 'Hello'\n"
  },
  {
    "path": "examples/client-side/src/index.js",
    "content": "import React, { useState } from 'react'\nimport { render } from 'react-dom'\nimport loadable from '@loadable/component'\n\nconst Hello = loadable(() => import('./Hello'))\nconst Dynamic = loadable(p => import(`./${p.name}`), {\n  cacheKey: p => p.name,\n})\nconst Moment = loadable.lib(() => import('moment'))\n\nfunction App() {\n  const [name, setName] = useState(null)\n\n  return (\n    <div>\n      <button type=\"button\" onClick={() => setName('A')}>\n        Go to A\n      </button>\n      <button type=\"button\" onClick={() => setName('B')}>\n        Go to B\n      </button>\n      {name && <Dynamic name={name} />}\n      <Hello />\n      <Moment>{({ default: moment }) => moment().format('HH:mm')}</Moment>\n    </div>\n  )\n}\n\nconst root = document.createElement('div')\ndocument.body.append(root)\n\nrender(<App />, root)\n"
  },
  {
    "path": "examples/client-side/webpack.config.js",
    "content": "const HtmlWebpackPlugin = require('html-webpack-plugin')\n\nmodule.exports = {\n  mode: 'development',\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: 'babel-loader',\n      },\n    ],\n  },\n  plugins: [new HtmlWebpackPlugin()],\n}\n"
  },
  {
    "path": "examples/razzle/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/razzle/.gitignore",
    "content": "logs\n*.log\nnpm-debug.log*\n.DS_Store\n\ncoverage\nnode_modules\nbuild\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local"
  },
  {
    "path": "examples/razzle/README.md",
    "content": "# Get the razzle example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/razzle\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run locally or build and serve\n\n```bash\nyarn dev\n# or\nyarn build\nyarn start:prod\n```\n"
  },
  {
    "path": "examples/razzle/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"razzle start\",\n    \"build\": \"razzle build\",\n    \"test\": \"razzle test --env=jsdom\",\n    \"start:prod\": \"NODE_ENV=production node build/server.js\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.1.5\",\n    \"@loadable/component\": \"^5.10.2\",\n    \"@loadable/server\": \"^5.10.2\",\n    \"@reach/router\": \"^1.2.1\",\n    \"babel-jest\": \"^24.8.0\",\n    \"common-tags\": \"^1.8.0\",\n    \"express\": \"^4.16.2\",\n    \"normalize.css\": \"^8.0.1\",\n    \"razzle\": \"^3.0.0-alpha.0\",\n    \"react\": \"^16.0.0\",\n    \"react-dom\": \"^16.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/template\": \"^7.4.4\",\n    \"@loadable/babel-plugin\": \"^5.10.0\",\n    \"@loadable/webpack-plugin\": \"^5.7.1\",\n    \"check-prop-types\": \"^1.1.2\"\n  }\n}\n"
  },
  {
    "path": "examples/razzle/public/robots.txt",
    "content": "User-agent: *\n\n"
  },
  {
    "path": "examples/razzle/razzle.config.js",
    "content": "/* eslint-disable prefer-object-spread */\nconst path = require('path')\nconst LoadableWebpackPlugin = require('@loadable/webpack-plugin')\nconst LoadableBabelPlugin = require('@loadable/babel-plugin')\nconst babelPresetRazzle = require('razzle/babel')\n\nmodule.exports = {\n  modify: (config, { dev, target }) => {\n    const appConfig = Object.assign({}, config)\n\n    if (target === 'web') {\n      const filename = path.resolve(__dirname, 'build')\n\n      appConfig.plugins = [\n        ...appConfig.plugins,\n        new LoadableWebpackPlugin({\n          outputAsset: false,\n          writeToDisk: { filename },\n        }),\n      ]\n\n      appConfig.output.filename = dev\n        ? 'static/js/[name].js'\n        : 'static/js/[name].[chunkhash:8].js'\n\n      appConfig.node = { fs: 'empty' } // fix \"Cannot find module 'fs'\" problem.\n\n      appConfig.optimization = Object.assign({}, appConfig.optimization, {\n        runtimeChunk: true,\n        splitChunks: {\n          chunks: 'all',\n          name: dev,\n        },\n      })\n    }\n\n    return appConfig\n  },\n\n  modifyBabelOptions: () => ({\n    babelrc: false,\n    presets: [babelPresetRazzle],\n    plugins: [LoadableBabelPlugin],\n  }),\n}\n"
  },
  {
    "path": "examples/razzle/src/About/index.js",
    "content": "import React from 'react'\n\nconst About = () => <div>About page</div>\n\nexport default About\n"
  },
  {
    "path": "examples/razzle/src/App.css",
    "content": "body {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n}"
  },
  {
    "path": "examples/razzle/src/App.js",
    "content": "import React from 'react'\nimport { Router, Link } from '@reach/router'\nimport loadable from '@loadable/component'\nimport './App.css'\n\nconst NotFound = loadable(() => import('./NotFound'))\nconst Home = loadable(() => import('./Home'))\nconst About = loadable(() => import('./About'))\nconst Contact = loadable(() => import('./Contact'))\n\nconst App = () => (\n  <>\n    <Link to=\"/\">Home</Link>\n    <Link to=\"/about\">About</Link>\n    <Link to=\"/contact\">Contact</Link>\n    <Router>\n      <NotFound default fallback={<div>loading...</div>} />\n      <Home path=\"/\" fallback={<div>loading...</div>} />\n      <About path=\"/about\" fallback={<div>loading...</div>} />\n      <Contact path=\"/contact\" fallback={<div>loading...</div>} />\n    </Router>\n  </>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/razzle/src/Contact/index.js",
    "content": "import React from 'react'\n\nconst Contact = () => <div>Contact page</div>\n\nexport default Contact\n"
  },
  {
    "path": "examples/razzle/src/Home/Home.css",
    "content": ".Home {\n  text-align: center;\n}\n\n.Home-logo {\n  animation: Home-logo-spin infinite 20s linear;\n  height: 80px;\n}\n\n.Home-header {\n  background-color: #222;\n  height: 150px;\n  padding: 20px;\n  color: white;\n}\n\n.Home-intro {\n  font-size: large;\n}\n\n.Home-resources {\n  list-style: none;\n}\n\n.Home-resources > li {\n  display: inline-block;\n  padding: 1rem;\n}\n\n@keyframes Home-logo-spin {\n  from { transform: rotate(0deg); }\n  to { transform: rotate(360deg); }\n}"
  },
  {
    "path": "examples/razzle/src/Home/Intro.js",
    "content": "/* eslint-disable react/jsx-one-expression-per-line */\nimport React from 'react'\n\nconst Intro = () => (\n  <p className=\"Home-intro\">\n    To get started, edit <code>src/App.js</code> or <code>src/Home.js</code> and\n    save to reload.\n  </p>\n)\n\nexport default Intro\n"
  },
  {
    "path": "examples/razzle/src/Home/Logo.js",
    "content": "import React from 'react'\nimport logo from './react.svg'\n\nconst Logo = () => <img src={logo} className=\"Home-logo\" alt=\"logo\" />\n\nexport default Logo\n"
  },
  {
    "path": "examples/razzle/src/Home/Welcome.js",
    "content": "import React from 'react'\n\nconst Welcome = () => <h2>Welcome to Razzle</h2>\n\nexport default Welcome\n"
  },
  {
    "path": "examples/razzle/src/Home/index.js",
    "content": "import React from 'react'\nimport loadable from '@loadable/component'\nimport './Home.css'\n\nconst Intro = loadable(() => import('./Intro'))\nconst Welcome = loadable(() => import('./Welcome'))\nconst Logo = loadable(() => import('./Logo'))\n\nconst Home = () => (\n  <div className=\"Home\">\n    <div className=\"Home-header\">\n      <Logo />\n      <Welcome />\n    </div>\n    <Intro />\n    <ul className=\"Home-resources\">\n      <li>\n        <a href=\"https://github.com/jaredpalmer/razzle\">Docs</a>\n      </li>\n      <li>\n        <a href=\"https://github.com/jaredpalmer/razzle/issues\">Issues</a>\n      </li>\n      <li>\n        <a href=\"https://palmer.chat\">Community Slack</a>\n      </li>\n    </ul>\n  </div>\n)\n\nexport default Home\n"
  },
  {
    "path": "examples/razzle/src/NotFound/index.js",
    "content": "import React from 'react'\n\nconst NotFound = () => <div>Page could not be found</div>\n\nexport default NotFound\n"
  },
  {
    "path": "examples/razzle/src/client.js",
    "content": "import 'normalize.css'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\nimport { loadableReady } from '@loadable/component'\nimport App from './App'\n\nconst root = document.getElementById('root')\n\nloadableReady(() => {\n  hydrate(<App />, root)\n})\n\nif (module.hot) {\n  module.hot.accept()\n}\n"
  },
  {
    "path": "examples/razzle/src/index.js",
    "content": "/* eslint-disable no-console, global-require */\n\nimport http from 'http'\n\nlet app = require('./server').default\n\nconst server = http.createServer(app)\n\nlet currentApp = app\n\nserver.listen(process.env.PORT || 3000, error => {\n  if (error) {\n    console.log(error)\n  }\n\n  console.log('🚀 started')\n})\n\nif (module.hot) {\n  console.log('✅  Server-side HMR Enabled!')\n\n  module.hot.accept('./server', () => {\n    console.log('🔁  HMR Reloading `./server`...')\n\n    try {\n      app = require('./server').default\n      server.removeListener('request', currentApp)\n      server.on('request', app)\n      currentApp = app\n    } catch (error) {\n      console.error(error)\n    }\n  })\n}\n"
  },
  {
    "path": "examples/razzle/src/server.js",
    "content": "import path from 'path'\nimport React from 'react'\nimport express from 'express'\nimport { html as htmlTemplate, oneLineTrim } from 'common-tags'\nimport { renderToString } from 'react-dom/server'\nimport { ServerLocation } from '@reach/router'\nimport { ChunkExtractor, ChunkExtractorManager } from '@loadable/server'\nimport App from './App'\n\nconst server = express()\nserver\n  .disable('x-powered-by')\n  .use(express.static(process.env.RAZZLE_PUBLIC_DIR))\n  .get('/*', (req, res) => {\n    const extractor = new ChunkExtractor({\n      statsFile: path.resolve('build/loadable-stats.json'),\n      entrypoints: ['client'],\n    })\n\n    const html = renderToString(\n      <ChunkExtractorManager extractor={extractor}>\n        <ServerLocation url={req.url}>\n          <App />\n        </ServerLocation>\n      </ChunkExtractorManager>,\n    )\n\n    res.status(200).send(\n      oneLineTrim(htmlTemplate`\n      <!doctype html>\n      <html lang=\"\">\n        <head>\n          <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n          <meta charSet='utf-8' />\n          <title>Welcome to Razzle</title>\n          <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n          ${extractor.getLinkTags()}\n          ${extractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"root\">${html}</div>\n          ${extractor.getScriptTags()}\n        </body>\n      </html>\n    `),\n    )\n  })\n\nexport default server\n"
  },
  {
    "path": "examples/server-side-rendering/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering/.gitignore",
    "content": "public/dist"
  },
  {
    "path": "examples/server-side-rendering/README.md",
    "content": "# Get the SSR example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. Install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n3. Install libary dependencies and build library\n\n```bash\nyarn\nyarn build\n```\n\n4. Move into example directory\n\n```bash\ncd ./loadable-components/examples/server-side-rendering\n```\n\n5. Install project dependencies\n\n```bash\nyarn\n```\n\n5. Run locally or build and serve\n\n```bash\nyarn dev\n\n# Or\n\nyarn build\nyarn start\n```\n\n🍻\n"
  },
  {
    "path": "examples/server-side-rendering/babel.config.js",
    "content": "function isWebTarget(caller) {\n  return Boolean(caller && caller.target === 'web')\n}\n\nfunction isWebpack(caller) {\n  return Boolean(caller && caller.name === 'babel-loader')\n}\n\nmodule.exports = api => {\n  const web = api.caller(isWebTarget)\n  const webpack = api.caller(isWebpack)\n\n  return {\n    presets: [\n      '@babel/preset-react',\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: web ? 'entry' : undefined,\n          corejs: web ? 'core-js@3' : false,\n          targets: !web ? { node: 'current' } : undefined,\n          modules: webpack ? false : 'commonjs',\n        },\n      ],\n    ],\n    plugins: ['@babel/plugin-syntax-dynamic-import', '@loadable/babel-plugin'],\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering/nodemon.json",
    "content": "{\n  \"ignore\": [\"client\", \"public\"],\n  \"execMap\": {\n    \"js\": \"babel-node\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"nodemon src/server/main.js\",\n    \"build\": \"rm -Rf ./public && NODE_ENV=production yarn build:webpack && yarn build:lib\",\n    \"build:webpack\": \"webpack\",\n    \"build:lib\": \"babel -d lib src\",\n    \"start\": \"NODE_ENV=production node lib/server/main.js\",\n    \"link:all\": \"yarn link @loadable/babel-plugin && yarn link @loadable/server && yarn link @loadable/component\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.4.4\",\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.6.2\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@loadable/babel-plugin\": \"file:./../../packages/babel-plugin\",\n    \"@loadable/component\": \"file:./../../packages/component\",\n    \"@loadable/server\": \"file:./../../packages/server\",\n    \"@loadable/webpack-plugin\": \"file:./../../packages/webpack-plugin\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^2.1.1\",\n    \"mini-css-extract-plugin\": \"^0.6.0\",\n    \"nodemon\": \"^1.19.0\",\n    \"webpack\": \"^4.31.0\",\n    \"webpack-cli\": \"^3.3.2\",\n    \"webpack-dev-middleware\": \"^3.6.2\",\n    \"webpack-node-externals\": \"^1.7.2\"\n  },\n  \"dependencies\": {\n    \"core-js\": \"^3.0.1\",\n    \"express\": \"^4.16.4\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/App.js",
    "content": "import React from 'react'\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport loadable from '@loadable/component'\nimport './main.css'\n\nconst A = loadable(() => import('./letters/A'))\nconst B = loadable(() => import('./letters/B'))\nconst C = loadable(() => import(/* webpackPreload: true */ './letters/C'))\nconst D = loadable(() => import(/* webpackPrefetch: true */ './letters/D'))\nconst E = loadable(() => import('./letters/E?param'), { ssr: false })\nconst X = loadable(props => import(`./letters/${props.letter}`))\nconst Sub = loadable(props => import(`./letters/${props.letter}/file`))\nconst RootSub = loadable(props => import(`./${props.letter}/file`))\n\n// Load the 'G' component twice: once in SSR and once fully client-side\nconst GClient = loadable(() => import('./letters/G'), {\n  ssr: false,\n  fallback: <span className=\"loading-state\">ssr: false - Loading...</span>,\n})\nconst GServer = loadable(() => import('./letters/G'), {\n  ssr: true,\n  fallback: <span className=\"loading-state\">ssr: true - Loading...</span>,\n})\n\n// We keep some references to prevent uglify remove\nA.C = C\nA.D = D\n\nconst Moment = loadable.lib(() => import('moment'), {\n  resolveComponent: moment => moment.default || moment,\n})\n\nconst App = () => (\n  <div>\n    <A />\n    <br />\n    <B />\n    <br />\n    <X letter=\"A\" />\n    <br />\n    <X letter=\"F\" />\n    <br />\n    <E />\n    <br />\n    <GClient prefix=\"ssr: false\" />\n    <br />\n    <GServer prefix=\"ssr: true\" />\n    <br />\n    <Sub letter=\"Z\" />\n    <br />\n    <RootSub letter=\"Y\" />\n    <br />\n    <Moment>{moment => moment().format('HH:mm')}</Moment>\n  </div>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/Y/file.js",
    "content": "export default () => 'Y'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/A.css",
    "content": "/* A CSS */\nbody {\n    background: pink;\n}"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/A.js",
    "content": "// We simulate that \"moment\" is called in \"A\" and \"B\"\nimport moment from 'moment'\nimport './A.css'\n\nconst A = () => 'A'\n\n// We keep a reference to prevent uglify remove\nA.moment = moment\n\nexport default A\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/B.js",
    "content": "// We simulate that \"moment\" is called in \"A\" and \"B\"\nimport moment from 'moment'\n\nconst B = () => 'B'\n\n// We keep a reference to prevent uglify remove\nB.moment = moment\n\nexport default B\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/C.js",
    "content": "export default () => 'C'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/D.js",
    "content": "export default () => 'D'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/E.js",
    "content": "export default () => 'E'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/F.js",
    "content": "export default () => 'F'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/G.js",
    "content": "import React from 'react'\n\nconst G = ({ prefix }) => <span className=\"my-cool-class\">{prefix} - G</span>\n\nexport default G\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/letters/Z/file.js",
    "content": "export default () => 'Z'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/main-node.js",
    "content": "export { default } from './App'\n\nexport const hello = 'hello'\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/main-web.js",
    "content": "import 'core-js'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { loadableReady } from '@loadable/component'\nimport App from './App'\n\nloadableReady(() => {\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n"
  },
  {
    "path": "examples/server-side-rendering/src/client/main.css",
    "content": "/* Main CSS */\nh1 {\n    color: cyan;\n}"
  },
  {
    "path": "examples/server-side-rendering/src/server/main.js",
    "content": "import path from 'path'\nimport express from 'express'\nimport React from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst app = express()\n\napp.use(express.static(path.join(__dirname, '../../public')))\n\nif (process.env.NODE_ENV !== 'production') {\n  /* eslint-disable global-require, import/no-extraneous-dependencies */\n  const { default: webpackConfig } = require('../../webpack.config.babel')\n  const webpackDevMiddleware = require('webpack-dev-middleware')\n  const webpack = require('webpack')\n  /* eslint-enable global-require, import/no-extraneous-dependencies */\n\n  const compiler = webpack(webpackConfig)\n\n  app.use(\n    webpackDevMiddleware(compiler, {\n      logLevel: 'silent',\n      publicPath: '/dist/web',\n      writeToDisk(filePath) {\n        return /dist\\/node\\//.test(filePath) || /loadable-stats/.test(filePath)\n      },\n    }),\n  )\n}\n\nconst nodeStats = path.resolve(\n  __dirname,\n  '../../public/dist/node/loadable-stats.json',\n)\n\nconst webStats = path.resolve(\n  __dirname,\n  '../../public/dist/web/loadable-stats.json',\n)\n\napp.get('*', (req, res) => {\n  const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats })\n  const { default: App } = nodeExtractor.requireEntrypoint()\n\n  const webExtractor = new ChunkExtractor({ statsFile: webStats })\n  const jsx = webExtractor.collectChunks(<App />)\n\n  const html = renderToString(jsx)\n\n  res.set('content-type', 'text/html')\n  res.send(`\n      <!DOCTYPE html>\n      <html>\n        <head>\n        ${webExtractor.getLinkTags()}\n        ${webExtractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"main\">${html}</div>\n          ${webExtractor.getScriptTags()}\n        </body>\n      </html>\n    `)\n})\n\n// eslint-disable-next-line no-console\napp.listen(9000, () => console.log('Server started http://localhost:9000'))\n"
  },
  {
    "path": "examples/server-side-rendering/webpack.config.babel.js",
    "content": "import path from 'path'\nimport nodeExternals from 'webpack-node-externals'\nimport LoadablePlugin from '@loadable/webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n\nconst DIST_PATH = path.resolve(__dirname, 'public/dist')\nconst production = process.env.NODE_ENV === 'production'\nconst development =\n  !process.env.NODE_ENV || process.env.NODE_ENV === 'development'\n\nconst getConfig = target => ({\n  name: target,\n  mode: development ? 'development' : 'production',\n  target,\n  entry: `./src/client/main-${target}.js`,\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            caller: { target },\n          },\n        },\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: MiniCssExtractPlugin.loader,\n          },\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  optimization: {\n    moduleIds: 'named',\n    chunkIds: 'named',\n  },\n  externals:\n    target === 'node' ? ['@loadable/component', nodeExternals()] : undefined,\n  output: {\n    path: path.join(DIST_PATH, target),\n    // filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',\n    filename: production ? '[name].js' : '[name].js',\n    publicPath: `/dist/${target}/`,\n    libraryTarget: target === 'node' ? 'commonjs2' : undefined,\n  },\n  plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],\n})\n\nexport default [getConfig('web'), getConfig('node')]\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/.gitignore",
    "content": "public/dist"
  },
  {
    "path": "examples/server-side-rendering-async-node/README.md",
    "content": "> WORK IN PROGRESS\n\n# Get the SSR example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/server-side-rendering-async-node\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run locally or build and serve\n\n```bash\nyarn dev\n\n# Or\n\nyarn build\nyarn start\n```\n\n🍻\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/babel.config.js",
    "content": "function isWebTarget(caller) {\n  return Boolean(caller && caller.target === 'web')\n}\n\nfunction isWebpack(caller) {\n  return Boolean(caller && caller.name === 'babel-loader')\n}\n\nmodule.exports = api => {\n  const web = api.caller(isWebTarget)\n  const webpack = api.caller(isWebpack)\n\n  return {\n    presets: [\n      '@babel/preset-react',\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: web ? 'entry' : undefined,\n          corejs: web ? 'core-js@3' : false,\n          targets: !web ? { node: 'current' } : undefined,\n          modules: webpack ? false : 'commonjs',\n        },\n      ],\n    ],\n    plugins: ['@babel/plugin-syntax-dynamic-import', '@loadable/babel-plugin'],\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/nodemon.json",
    "content": "{\n  \"ignore\": [\"client\", \"public\"],\n  \"execMap\": {\n    \"js\": \"babel-node\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"nodemon src/server/main.js\",\n    \"build\": \"NODE_ENV=production yarn build:webpack && yarn build:lib\",\n    \"build:webpack\": \"webpack\",\n    \"build:lib\": \"babel -d lib src\",\n    \"start\": \"NODE_ENV=production node lib/server/main.js\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.4.4\",\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.6.2\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@loadable/babel-plugin\": \"^5.10.3\",\n    \"@loadable/component\": \"^5.10.3\",\n    \"@loadable/server\": \"^5.10.3\",\n    \"@loadable/webpack-plugin\": \"^5.7.1\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^2.1.1\",\n    \"mini-css-extract-plugin\": \"^0.6.0\",\n    \"nodemon\": \"^1.19.0\",\n    \"webpack\": \"^5.0.0-beta.16\",\n    \"webpack-cli\": \"^3.3.2\",\n    \"webpack-dev-middleware\": \"^3.6.2\",\n    \"webpack-node-externals\": \"^1.7.2\"\n  },\n  \"dependencies\": {\n    \"core-js\": \"^3.0.1\",\n    \"express\": \"^4.16.4\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/App.js",
    "content": "import React from 'react'\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport loadable from '@loadable/component'\nimport './main.css'\n\nconst A = loadable(() => import('./letters/A'))\nconst B = loadable(() => import('./letters/B'))\nconst C = loadable(() => import(/* webpackPreload: true */ './letters/C'))\nconst D = loadable(() => import(/* webpackPrefetch: true */ './letters/D'))\nconst E = loadable(() => import('./letters/E'), { ssr: false })\nconst X = loadable(props => import(`./letters/${props.letter}`))\nconst Sub = loadable(props => import(`./letters/${props.letter}/file`))\nconst RootSub = loadable(props => import(`./${props.letter}/file`))\n\n// Load the 'G' component twice: once in SSR and once fully client-side\nconst GClient = loadable(() => import('./letters/G'), {\n  ssr: false,\n  fallback: <span className=\"loading-state\">ssr: false - Loading...</span>,\n})\nconst GServer = loadable(() => import('./letters/G'), {\n  ssr: true,\n  fallback: <span className=\"loading-state\">ssr: true - Loading...</span>,\n})\n\n// We keep some references to prevent uglify remove\nA.C = C\nA.D = D\n\nconst Moment = loadable.lib(() => import('moment'))\n\nconst App = () => (\n  <div>\n    <A />\n    <br />\n    <B />\n    <br />\n    <X letter=\"A\" />\n    <br />\n    <X letter=\"F\" />\n    <br />\n    <E />\n    <br />\n    <GClient prefix=\"ssr: false\" />\n    <br />\n    <GServer prefix=\"ssr: true\" />\n    <br />\n    <Sub letter=\"Z\" />\n    <br />\n    <RootSub letter=\"Y\" />\n    <br />\n    <Moment>{moment => moment().format('HH:mm')}</Moment>\n  </div>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/Y/file.js",
    "content": "export default () => 'Y'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/A.css",
    "content": "/* A CSS */\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/A.js",
    "content": "// We simulate that \"moment\" is called in \"A\" and \"B\"\nimport moment from 'moment'\nimport './A.css'\n\nconst A = () => 'A'\n\n// We keep a reference to prevent uglify remove\nA.moment = moment\n\nexport default A\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/B.js",
    "content": "// We simulate that \"moment\" is called in \"A\" and \"B\"\nimport moment from 'moment'\n\nconst B = () => 'B'\n\n// We keep a reference to prevent uglify remove\nB.moment = moment\n\nexport default B\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/C.js",
    "content": "export default () => 'C'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/D.js",
    "content": "export default () => 'D'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/E.js",
    "content": "export default () => 'E'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/F.js",
    "content": "export default () => 'F'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/G.js",
    "content": "import React from 'react'\n\nconst G = ({ prefix }) => <span className=\"my-cool-class\">{prefix} - G</span>\n\nexport default G\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/letters/Z/file.js",
    "content": "export default () => 'Z'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/main-async-node.js",
    "content": "export { default } from './App'\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/main-web.js",
    "content": "import 'core-js'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { loadableReady } from '@loadable/component'\nimport App from './App'\n\nloadableReady(() => {\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/client/main.css",
    "content": "/* Main CSS */\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/src/server/main.js",
    "content": "import path from 'path'\nimport express from 'express'\nimport React from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst app = express()\n\napp.use(express.static(path.join(__dirname, '../../public')))\n\nif (process.env.NODE_ENV !== 'production') {\n  /* eslint-disable global-require, import/no-extraneous-dependencies */\n  const { default: webpackConfig } = require('../../webpack.config.babel')\n  const webpackDevMiddleware = require('webpack-dev-middleware')\n  const webpack = require('webpack')\n  /* eslint-enable global-require, import/no-extraneous-dependencies */\n\n  const compiler = webpack(webpackConfig)\n\n  app.use(\n    webpackDevMiddleware(compiler, {\n      logLevel: 'silent',\n      publicPath: '/dist/web',\n      writeToDisk(filePath) {\n        return /dist\\/node\\//.test(filePath) || /loadable-stats/.test(filePath)\n      },\n    }),\n  )\n}\n\nconst nodeStats = path.resolve(\n  __dirname,\n  '../../public/dist/async-node/loadable-stats.json',\n)\n\nconst webStats = path.resolve(\n  __dirname,\n  '../../public/dist/web/loadable-stats.json',\n)\n\napp.get('*', (req, res) => {\n  const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats })\n  const { default: App } = nodeExtractor.requireEntrypoint()\n\n  const webExtractor = new ChunkExtractor({ statsFile: webStats })\n  const jsx = webExtractor.collectChunks(<App />)\n\n  const html = renderToString(jsx)\n\n  res.set('content-type', 'text/html')\n  res.send(`\n      <!DOCTYPE html>\n      <html>\n        <head>\n        ${webExtractor.getLinkTags()}\n        ${webExtractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"main\">${html}</div>\n          ${webExtractor.getScriptTags()}\n        </body>\n      </html>\n    `)\n})\n\n// eslint-disable-next-line no-console\napp.listen(9000, () => console.log('Server started http://localhost:9000'))\n"
  },
  {
    "path": "examples/server-side-rendering-async-node/webpack.config.babel.js",
    "content": "import path from 'path'\nimport nodeExternals from 'webpack-node-externals'\nimport LoadablePlugin from '@loadable/webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n\nconst DIST_PATH = path.resolve(__dirname, 'public/dist')\nconst production = process.env.NODE_ENV === 'production'\nconst development =\n  !process.env.NODE_ENV || process.env.NODE_ENV === 'development'\n\nconst getConfig = target => ({\n  name: target,\n  mode: development ? 'development' : 'production',\n  target,\n  entry: `./src/client/main-${target}.js`,\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            caller: { target },\n          },\n        },\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: MiniCssExtractPlugin.loader,\n          },\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  externals:\n    target === 'async-node'\n      ? ['@loadable/component', nodeExternals()]\n      : undefined,\n  output: {\n    path: path.join(DIST_PATH, target),\n    filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',\n    publicPath: `/dist/${target}/`,\n    libraryTarget: target === 'async-node' ? 'commonjs2' : undefined,\n  },\n  plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],\n})\n\nexport default [getConfig('web'), getConfig('async-node')]\n"
  },
  {
    "path": "examples/suspense/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/suspense/README.md",
    "content": "# Get the suspense example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/suspense\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run\n\n```bash\nyarn dev\n# or\nyarn start\n```\n"
  },
  {
    "path": "examples/suspense/babel.config.js",
    "content": "module.exports = {\n  presets: ['@babel/preset-react'],\n  plugins: ['@babel/plugin-syntax-dynamic-import'],\n}\n"
  },
  {
    "path": "examples/suspense/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"webpack-dev-server\",\n    \"dev\": \"webpack-dev-server\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.6.4\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.2.0\",\n    \"@babel/preset-react\": \"^7.6.3\",\n    \"babel-loader\": \"^8.0.4\",\n    \"html-webpack-plugin\": \"^3.2.0\",\n    \"webpack\": \"^4.29.5\",\n    \"webpack-cli\": \"^3.2.3\",\n    \"webpack-dev-server\": \"^3.2.0\"\n  },\n  \"dependencies\": {\n    \"@loadable/component\": \"^5.10.3\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.3\",\n    \"react-dom\": \"^16.8.3\"\n  }\n}\n"
  },
  {
    "path": "examples/suspense/src/Hello.js",
    "content": "export default () => 'Hello'\n"
  },
  {
    "path": "examples/suspense/src/index.js",
    "content": "import React, { Suspense } from 'react'\nimport { render } from 'react-dom'\nimport { lazy } from '@loadable/component'\n\nconst Hello = lazy(() => import('./Hello'))\nconst Moment = lazy.lib(() => import('moment'))\n\nconst App = () => (\n  <div>\n    <Suspense fallback={<div>Loading...</div>}>\n      <Hello />\n      <Moment>{({ default: moment }) => moment().format('HH:mm')}</Moment>\n    </Suspense>\n  </div>\n)\n\nconst root = document.createElement('div')\ndocument.body.append(root)\n\nrender(<App />, root)\n"
  },
  {
    "path": "examples/suspense/webpack.config.js",
    "content": "const HtmlWebpackPlugin = require('html-webpack-plugin')\n\nmodule.exports = {\n  mode: 'development',\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: 'babel-loader',\n      },\n    ],\n  },\n  plugins: [new HtmlWebpackPlugin()],\n}\n"
  },
  {
    "path": "examples/typescript/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/typescript/.gitignore",
    "content": "public/dist"
  },
  {
    "path": "examples/typescript/README.md",
    "content": "# Get the SSR example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/server-side-rendering\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run locally or build and serve\n\n```bash\nyarn dev\n\n# Or\n\nyarn build\nyarn start\n```\n\n🍻\n"
  },
  {
    "path": "examples/typescript/babel.config.js",
    "content": "function isWebTarget(caller) {\n  return Boolean(caller && caller.target === 'web')\n}\n\nfunction isWebpack(caller) {\n  return Boolean(caller && caller.name === 'babel-loader')\n}\n\nmodule.exports = api => {\n  const web = api.caller(isWebTarget)\n  const webpack = api.caller(isWebpack)\n\n  return {\n    presets: [\n      '@babel/preset-typescript',\n      '@babel/preset-react',\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: web ? 'entry' : undefined,\n          corejs: web ? 'core-js@3' : false,\n          targets: !web ? { node: 'current' } : undefined,\n          modules: webpack ? false : 'commonjs',\n        },\n      ],\n    ],\n    plugins: ['@babel/plugin-syntax-dynamic-import', '@loadable/babel-plugin'],\n  }\n}\n"
  },
  {
    "path": "examples/typescript/nodemon.json",
    "content": "{\n  \"ignore\": [\"client\", \"public\"],\n  \"execMap\": {\n    \"js\": \"babel-node\"\n  }\n}\n"
  },
  {
    "path": "examples/typescript/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"nodemon src/server/main.js\",\n    \"build\": \"NODE_ENV=production yarn build:webpack && yarn build:lib\",\n    \"build:dev\": \"NODE_ENV=development yarn build:webpack && yarn build:lib\",\n    \"build:webpack\": \"webpack\",\n    \"build:lib\": \"babel -d lib src\",\n    \"start\": \"NODE_ENV=production node lib/server/main.js\",\n    \"start:dev\": \"NODE_ENV=development node -r @babel/register lib/server/main.js\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.4.4\",\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.6.2\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@babel/preset-typescript\": \"^7.12.1\",\n    \"@types/loadable__component\": \"^5.13.1\",\n    \"@types/react\": \"^16.9.53\",\n    \"@types/react-router-dom\": \"^5.1.6\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^2.1.1\",\n    \"mini-css-extract-plugin\": \"^0.6.0\",\n    \"nodemon\": \"^1.19.0\",\n    \"react-router\": \"^5.2.0\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"typescript\": \"^4.0.3\",\n    \"webpack\": \"^4.31.0\",\n    \"webpack-cli\": \"^3.3.2\",\n    \"webpack-dev-middleware\": \"^3.6.2\",\n    \"webpack-node-externals\": \"^1.7.2\"\n  },\n  \"dependencies\": {\n    \"@babel/register\": \"^7.12.1\",\n    \"@loadable/babel-plugin\": \"file:./../../packages/babel-plugin\",\n    \"@loadable/component\": \"file:./../../packages/component\",\n    \"@loadable/server\": \"file:./../../packages/server\",\n    \"@loadable/webpack-plugin\": \"file:./../../packages/webpack-plugin\",\n    \"core-js\": \"^3.0.1\",\n    \"express\": \"^4.16.4\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/typescript/src/client/App.tsx",
    "content": "import * as React from 'react'\nimport loadable from '@loadable/component'\nimport {StaticRouter, Switch, Route} from 'react-router-dom';\n\nconst X = loadable(() => import(`./Page`))\nconst Y = loadable(() => import(`./PageWithParam`))\n\nconst App = () => (\n  <div>\n    <p>\n      Components loaded directly:\n      <X/>\n      <Y x={42}/>\n    </p>\n    <hr/>\n    <div>\n      <StaticRouter>\n        <Switch>\n          <Route component={X}/>\n          <Route path=\"route-accepts-any\" component={Y}/>\n          <Route\n            path=\"otherPath\"\n            render={routeProperties =>\n            // @ts-expect-error routeProperties do not exists on X - it accepts no props at all\n              <X {...routeProperties} />\n            }\n            />\n        </Switch>\n        <hr/>\n        <Switch>\n          <Route component={Y}/>\n        </Switch>\n      </StaticRouter>\n    </div>\n  </div>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/typescript/src/client/Page.tsx",
    "content": "import * as React from 'react';\n\nconst Page:React.FC<{}> = () => (<span>I am lazy page</span>);\n\nexport default Page;"
  },
  {
    "path": "examples/typescript/src/client/PageWithParam.tsx",
    "content": "import * as React from 'react';\n\nconst PageWithParam:React.FC<{x: number}> = ({x}) => (<span>I am lazy page2 -{x||\"missed prop\"}-</span>);\n\nexport default PageWithParam;"
  },
  {
    "path": "examples/typescript/src/client/main-node.js",
    "content": "export { default } from './App.tsx'\n"
  },
  {
    "path": "examples/typescript/src/client/main-web.js",
    "content": "import 'core-js'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\nimport { loadableReady } from '@loadable/component'\nimport App from './App.tsx'\n\nconsole.log('waiting for application ready...')\nloadableReady(() => {\n  console.log('application is ready...')\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n"
  },
  {
    "path": "examples/typescript/src/server/main.js",
    "content": "import path from 'path'\nimport express from 'express'\nimport React from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst app = express()\n\n// https://github.com/gregberge/loadable-components/issues/634\n// app.use('*/runtime~main.js', async (req, res, next) => {\n//   console.log('delaying runtime chunk');\n//   await new Promise(resolve => setTimeout(resolve, 2000));\n//   next();\n// });\n\napp.use(express.static(path.join(__dirname, '../../public')))\n\nif (process.env.NODE_ENV !== 'production') {\n  /* eslint-disable global-require, import/no-extraneous-dependencies */\n  const { default: webpackConfig } = require('../../webpack.config.babel')\n  const webpackDevMiddleware = require('webpack-dev-middleware')\n  const webpack = require('webpack')\n  /* eslint-enable global-require, import/no-extraneous-dependencies */\n\n  const compiler = webpack(webpackConfig)\n\n  app.use(\n    webpackDevMiddleware(compiler, {\n      logLevel: 'silent',\n      publicPath: '/dist/web',\n      writeToDisk(filePath) {\n        return /dist\\/node\\//.test(filePath) || /loadable-stats/.test(filePath)\n      },\n    }),\n  )\n}\n\nconst nodeStats = path.resolve(\n  __dirname,\n  '../../public/dist/node/loadable-stats.json',\n)\n\nconst webStats = path.resolve(\n  __dirname,\n  '../../public/dist/web/loadable-stats.json',\n)\n\napp.get('*', (req, res) => {\n  const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats })\n  const { default: App } = nodeExtractor.requireEntrypoint()\n\n  const webExtractor = new ChunkExtractor({ statsFile: webStats })\n  const jsx = webExtractor.collectChunks(<App />)\n\n  const html = renderToString(jsx)\n\n  res.set('content-type', 'text/html')\n  res.send(`\n      <!DOCTYPE html>\n      <html>\n        <head>        \n        ${webExtractor.getLinkTags()}\n        ${webExtractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"main\">${html}</div>\n          <script>console.log('html is loaded')</script>          \n          ${webExtractor.getScriptTags()}\n          <script>console.log('html is ready')</script>\n        </body>\n      </html>\n    `)\n})\n\n// eslint-disable-next-line no-console\napp.listen(9000, () => console.log('Server started http://localhost:9000'))\n"
  },
  {
    "path": "examples/typescript/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n\n    /* Basic Options */\n    // \"incremental\": true,                   /* Enable incremental compilation */\n    \"target\": \"es5\" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,\n    \"module\": \"commonjs\" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,\n    // \"lib\": [],                             /* Specify library files to be included in the compilation. */\n    // \"allowJs\": true,                       /* Allow javascript files to be compiled. */\n    // \"checkJs\": true,                       /* Report errors in .js files. */\n    // \"jsx\": \"preserve\",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */\n    // \"declaration\": true,                   /* Generates corresponding '.d.ts' file. */\n    // \"declarationMap\": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */\n    // \"sourceMap\": true,                     /* Generates corresponding '.map' file. */\n    // \"outFile\": \"./\",                       /* Concatenate and emit output to single file. */\n    // \"outDir\": \"./\",                        /* Redirect output structure to the directory. */\n    // \"rootDir\": \"./\",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n    // \"composite\": true,                     /* Enable project compilation */\n    // \"tsBuildInfoFile\": \"./\",               /* Specify file to store incremental compilation information */\n    // \"removeComments\": true,                /* Do not emit comments to output. */\n    // \"noEmit\": true,                        /* Do not emit outputs. */\n    // \"importHelpers\": true,                 /* Import emit helpers from 'tslib'. */\n    // \"downlevelIteration\": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n    // \"isolatedModules\": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n\n    /* Strict Type-Checking Options */\n    \"strict\": true /* Enable all strict type-checking options. */,\n    // \"noImplicitAny\": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,              /* Enable strict null checks. */\n    // \"strictFunctionTypes\": true,           /* Enable strict checking of function types. */\n    // \"strictBindCallApply\": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */\n    // \"strictPropertyInitialization\": true,  /* Enable strict checking of property initialization in classes. */\n    // \"noImplicitThis\": true,                /* Raise error on 'this' expressions with an implied 'any' type. */\n    // \"alwaysStrict\": true,                  /* Parse in strict mode and emit \"use strict\" for each source file. */\n\n    /* Additional Checks */\n    // \"noUnusedLocals\": true,                /* Report errors on unused locals. */\n    // \"noUnusedParameters\": true,            /* Report errors on unused parameters. */\n    // \"noImplicitReturns\": true,             /* Report error when not all code paths in function return a value. */\n    // \"noFallthroughCasesInSwitch\": true,    /* Report errors for fallthrough cases in switch statement. */\n\n    /* Module Resolution Options */\n    // \"moduleResolution\": \"node\",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */\n    // \"baseUrl\": \"./\",                       /* Base directory to resolve non-absolute module names. */\n    // \"paths\": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n    // \"rootDirs\": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */\n    // \"typeRoots\": [],                       /* List of folders to include type definitions from. */\n    // \"types\": [],                           /* Type declaration files to be included in compilation. */\n    // \"allowSyntheticDefaultImports\": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n    \"esModuleInterop\": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,\n    // \"preserveSymlinks\": true,              /* Do not resolve the real path of symlinks. */\n    // \"allowUmdGlobalAccess\": true,          /* Allow accessing UMD globals from modules. */\n\n    /* Source Map Options */\n    // \"sourceRoot\": \"\",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */\n    // \"mapRoot\": \"\",                         /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSourceMap\": true,               /* Emit a single file with source maps instead of having a separate file. */\n    // \"inlineSources\": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */\n\n    /* Experimental Options */\n    // \"experimentalDecorators\": true,        /* Enables experimental support for ES7 decorators. */\n    // \"emitDecoratorMetadata\": true,         /* Enables experimental support for emitting type metadata for decorators. */\n\n    /* Advanced Options */\n    \"skipLibCheck\": true /* Skip type checking of declaration files. */,\n    \"forceConsistentCasingInFileNames\": true,\n    /* Disallow inconsistently-cased references to the same file. */\n    \"jsx\": \"react\"\n  }\n}\n"
  },
  {
    "path": "examples/typescript/webpack.config.babel.js",
    "content": "import path from 'path'\nimport nodeExternals from 'webpack-node-externals'\nimport LoadablePlugin from '@loadable/webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n\nconst DIST_PATH = path.resolve(__dirname, 'public/dist')\nconst production = process.env.NODE_ENV === 'production'\nconst development = !production\n\nconst getConfig = target => ({\n  name: target,\n  mode: development ? 'development' : 'production',\n  target,\n  entry: `./src/client/main-${target}.js`,\n  module: {\n    rules: [\n      {\n        test: /\\.([jt])sx?$/,\n        exclude: /node_modules/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            caller: { target },\n          },\n        },\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: MiniCssExtractPlugin.loader,\n          },\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  externals:\n    target === 'node' ? ['@loadable/component', nodeExternals()] : undefined,\n\n  optimization: {\n    runtimeChunk: target !== 'node',\n  },\n\n  resolve: {\n    extensions: ['.tsx', '.ts', '.js', '.css'],\n  },\n\n  output: {\n    path: path.join(DIST_PATH, target),\n    filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',\n    publicPath: `/dist/${target}/`,\n    libraryTarget: target === 'node' ? 'commonjs2' : undefined,\n  },\n  plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],\n})\n\nexport default [getConfig('web'), getConfig('node')]\n"
  },
  {
    "path": "examples/webpack/README.md",
    "content": "these examples are also **tests**\n"
  },
  {
    "path": "examples/webpack/webpack4/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack4/.gitignore",
    "content": "public/dist"
  },
  {
    "path": "examples/webpack/webpack4/README.md",
    "content": "# Get the SSR example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/server-side-rendering\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run locally or build and serve\n\n```bash\nyarn dev\n\n# Or\n\nyarn build\nyarn start\n```\n\n🍻\n"
  },
  {
    "path": "examples/webpack/webpack4/babel.config.js",
    "content": "function isWebTarget(caller) {\n  return Boolean(caller && caller.target === 'web')\n}\n\nfunction isWebpack(caller) {\n  return Boolean(caller && caller.name === 'babel-loader')\n}\n\nmodule.exports = api => {\n  const web = api.caller(isWebTarget)\n  const webpack = api.caller(isWebpack)\n\n  return {\n    presets: [\n      '@babel/preset-react',\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: web ? 'entry' : undefined,\n          corejs: web ? 'core-js@3' : false,\n          targets: !web ? { node: 'current' } : undefined,\n          modules: webpack ? false : 'commonjs',\n        },\n      ],\n    ],\n    plugins: ['@babel/plugin-syntax-dynamic-import', '@loadable/babel-plugin'],\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack4/nodemon.json",
    "content": "{\n  \"ignore\": [\"client\", \"public\"],\n  \"execMap\": {\n    \"js\": \"babel-node\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack4/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"nodemon src/server/main.js\",\n    \"build\": \"NODE_ENV=production yarn build:webpack && yarn build:lib\",\n    \"build:dev\": \"NODE_ENV=development yarn build:webpack && yarn build:lib\",\n    \"build:webpack\": \"webpack\",\n    \"build:lib\": \"babel -d lib src\",\n    \"start\": \"NODE_ENV=production node lib/server/main.js\",\n    \"start:dev\": \"NODE_ENV=development node -r @babel/register lib/server/main.js\",\n    \"update\": \"rm ./node_modules/.yarn-integrity && yarn\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.4.4\",\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.6.2\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"babel-loader\": \"^8.0.6\",\n    \"css-loader\": \"^2.1.1\",\n    \"mini-css-extract-plugin\": \"^0.6.0\",\n    \"nodemon\": \"^1.19.0\",\n    \"webpack\": \"^4.31.0\",\n    \"webpack-cli\": \"^3.3.2\",\n    \"webpack-dev-middleware\": \"^3.6.2\",\n    \"webpack-node-externals\": \"^1.7.2\"\n  },\n  \"dependencies\": {\n    \"@babel/register\": \"^7.12.1\",\n    \"@loadable/babel-plugin\": \"file:./../../../packages/babel-plugin\",\n    \"@loadable/component\": \"file:./../../../packages/component\",\n    \"@loadable/server\": \"file:./../../../packages/server\",\n    \"@loadable/webpack-plugin\": \"file:./../../../packages/webpack-plugin\",\n    \"core-js\": \"^3.0.1\",\n    \"express\": \"^4.16.4\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/App.js",
    "content": "import React from 'react'\nimport loadable from '@loadable/component'\n\nconst X = loadable(props => import(`./letters/${props.letter}`))\n\nconst ClientSideOnly = loadable(props => import(`./letters/${props.letter}`), {\n  ssr: false,\n})\n\nconst Moment = loadable.lib(() => import('moment'), {\n  resolveComponent: moment => moment.default || moment,\n})\n\nconst App = () => (\n  <div>\n    <p>\n      Lazy load letter A:\n      <X letter=\"A\" />\n    </p>\n    <p>\n      Lazy load letter B:\n      <X letter=\"B\" />\n    </p>\n    <p>\n      Lazy load letter <strong>only on Client</strong> C and D:\n      <ClientSideOnly letter=\"C\" /> +\n      <ClientSideOnly letter=\"D\" />\n    </p>\n    <p>\n      lazy load momentjs and format date:\n      <Moment>{moment => `now is : ${moment().format('HH:mm')}`}</Moment>\n    </p>\n  </div>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/letters/A.css",
    "content": "/* A CSS */\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/letters/A.js",
    "content": "import './A.css'\n\nconst A = () => 'Lazy-Letter-A'\n\nexport default A\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/letters/B.js",
    "content": "const B = () => 'Lazy-Letter-B'\n\nexport default B\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/letters/C.js",
    "content": "const C = () => 'Lazy-Letter-C'\n\nexport default C\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/letters/D.js",
    "content": "// named as C\nconst C = () => 'and-D'\n\nexport default C\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/main-node.js",
    "content": "export { default } from './App'\n"
  },
  {
    "path": "examples/webpack/webpack4/src/client/main-web.js",
    "content": "import 'core-js'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\nimport { loadableReady } from '@loadable/component'\nimport App from './App'\n\nconsole.log('waiting for application ready...')\nloadableReady(() => {\n  console.log('application is ready...')\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n"
  },
  {
    "path": "examples/webpack/webpack4/src/server/main.js",
    "content": "import path from 'path'\nimport express from 'express'\nimport React from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst app = express()\n\n// https://github.com/gregberge/loadable-components/issues/634\napp.use('*/runtime~main*.js', async (req, res, next) => {\n  console.log('delaying runtime chunk')\n  await new Promise(resolve => setTimeout(resolve, 2000))\n  next()\n})\n\napp.use('*/letters*.js', async (req, res, next) => {\n  console.log('delaying letters chunk')\n  await new Promise(resolve => setTimeout(resolve, 1000))\n  next()\n})\n\napp.use(express.static(path.join(__dirname, '../../public')))\n\nif (process.env.NODE_ENV !== 'production') {\n  /* eslint-disable global-require, import/no-extraneous-dependencies */\n  const { default: webpackConfig } = require('../../webpack.config.babel')\n  const webpackDevMiddleware = require('webpack-dev-middleware')\n  const webpack = require('webpack')\n  /* eslint-enable global-require, import/no-extraneous-dependencies */\n\n  const compiler = webpack(webpackConfig)\n\n  app.use(\n    webpackDevMiddleware(compiler, {\n      logLevel: 'silent',\n      publicPath: '/dist/web',\n      writeToDisk(filePath) {\n        return /dist\\/node\\//.test(filePath) || /loadable-stats/.test(filePath)\n      },\n    }),\n  )\n}\n\nconst nodeStats = path.resolve(\n  __dirname,\n  '../../public/dist/node/loadable-stats.json',\n)\n\nconst webStats = path.resolve(\n  __dirname,\n  '../../public/dist/web/loadable-stats.json',\n)\n\napp.get('*', (req, res) => {\n  const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats })\n  const { default: App } = nodeExtractor.requireEntrypoint()\n\n  const webExtractor = new ChunkExtractor({ statsFile: webStats })\n  const jsx = webExtractor.collectChunks(<App />)\n\n  const html = renderToString(jsx)\n\n  res.set('content-type', 'text/html')\n  res.send(`\n      <!DOCTYPE html>\n      <html>\n        <head>        \n        ${webExtractor.getLinkTags()}\n        ${webExtractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"main\">${html}</div>\n          <script>console.log('html is loaded')</script>          \n          ${webExtractor.getScriptTags()}\n          <script>console.log('html is ready')</script>\n        </body>\n      </html>\n    `)\n})\n\n// eslint-disable-next-line no-console\napp.listen(9000, () => console.log('Server started http://localhost:9000'))\n"
  },
  {
    "path": "examples/webpack/webpack4/webpack.config.babel.js",
    "content": "import path from 'path'\nimport nodeExternals from 'webpack-node-externals'\nimport LoadablePlugin from '@loadable/webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n\nconst DIST_PATH = path.resolve(__dirname, 'public/dist')\nconst production = process.env.NODE_ENV === 'production'\nconst development = !production\n\nconst getConfig = target => ({\n  name: target,\n  mode: development ? 'development' : 'production',\n  target,\n  entry: `./src/client/main-${target}.js`,\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            caller: { target },\n          },\n        },\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: MiniCssExtractPlugin.loader,\n          },\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  externals:\n    target === 'node' ? ['@loadable/component', nodeExternals()] : undefined,\n\n  optimization: {\n    runtimeChunk: target !== 'node',\n  },\n\n  output: {\n    path: path.join(DIST_PATH, target),\n    filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',\n    publicPath: `/dist/${target}/`,\n    libraryTarget: target === 'node' ? 'commonjs2' : undefined,\n  },\n  plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],\n})\n\nexport default [getConfig('web'), getConfig('node')]\n"
  },
  {
    "path": "examples/webpack/webpack5/.eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true\n  },\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/no-extraneous-dependencies\": \"off\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack5/.gitignore",
    "content": "public/dist"
  },
  {
    "path": "examples/webpack/webpack5/README.md",
    "content": "# Get the SSR example running\n\nSteps:\n\n1. Download repository\n\n```bash\ngit clone https://github.com/gregberge/loadable-components.git\n```\n\n2. move into example directory\n\n```bash\ncd ./loadable-components/examples/server-side-rendering\n```\n\n3. install [https://yarnpkg.com/lang/en/docs/install](yarn) if haven't already\n4. install project dependencies\n\n```bash\nyarn\n```\n\n5. run locally or build and serve\n\n```bash\nyarn dev\n\n# Or\n\nyarn build\nyarn start\n```\n\n🍻\n"
  },
  {
    "path": "examples/webpack/webpack5/babel.config.js",
    "content": "function isWebTarget(caller) {\n  return Boolean(caller && caller.target === 'web')\n}\n\nfunction isWebpack(caller) {\n  return Boolean(caller && caller.name === 'babel-loader')\n}\n\nmodule.exports = api => {\n  const web = api.caller(isWebTarget)\n  const webpack = api.caller(isWebpack)\n\n  return {\n    presets: [\n      '@babel/preset-react',\n      [\n        '@babel/preset-env',\n        {\n          useBuiltIns: web ? 'entry' : undefined,\n          corejs: web ? 'core-js@3' : false,\n          targets: !web ? { node: 'current' } : undefined,\n          modules: webpack ? false : 'commonjs',\n        },\n      ],\n    ],\n    plugins: ['@babel/plugin-syntax-dynamic-import', '@loadable/babel-plugin'],\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack5/nodemon.json",
    "content": "{\n  \"ignore\": [\"client\", \"public\"],\n  \"execMap\": {\n    \"js\": \"babel-node\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack5/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"nodemon src/server/main.js\",\n    \"build\": \"NODE_ENV=production yarn build:webpack && yarn build:lib\",\n    \"build:dev\": \"NODE_ENV=development yarn build:webpack && yarn build:lib\",\n    \"build:webpack\": \"webpack\",\n    \"build:lib\": \"babel -d lib src\",\n    \"start\": \"NODE_ENV=production node lib/server/main.js\",\n    \"start:dev\": \"NODE_ENV=development node -r @babel/register lib/server/main.js\",\n    \"update\": \"rm ./node_modules/.yarn-integrity && yarn\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.4.4\",\n    \"@babel/core\": \"^7.6.2\",\n    \"@babel/node\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.6.2\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"babel-loader\": \"^8.1.0\",\n    \"css-loader\": \"^5.0.0\",\n    \"mini-css-extract-plugin\": \"^1.1.0\",\n    \"nodemon\": \"^1.19.0\",\n    \"webpack\": \"^5.17.0\",\n    \"webpack-cli\": \"^4.1.0\",\n    \"webpack-dev-middleware\": \"^3.7.2\",\n    \"webpack-node-externals\": \"^2.5.2\"\n  },\n  \"dependencies\": {\n    \"@babel/register\": \"^7.12.1\",\n    \"@loadable/babel-plugin\": \"file:./../../../packages/babel-plugin\",\n    \"@loadable/component\": \"file:./../../../packages/component\",\n    \"@loadable/server\": \"file:./../../../packages/server\",\n    \"@loadable/webpack-plugin\": \"file:./../../../packages/webpack-plugin\",\n    \"core-js\": \"^3.0.1\",\n    \"express\": \"^4.16.4\",\n    \"moment\": \"^2.24.0\",\n    \"react\": \"^16.8.6\",\n    \"react-dom\": \"^16.8.6\"\n  }\n}\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/App.js",
    "content": "import React from 'react'\nimport loadable from '@loadable/component'\n\nconst X = loadable(props => import(`./letters/${props.letter}`))\n\nconst ClientSideOnly = loadable(props => import(`./letters/${props.letter}`), {\n  ssr: false,\n})\n\nconst Moment = loadable.lib(() => import('moment'), {\n  resolveComponent: moment => moment.default || moment,\n})\n\nconst App = () => (\n  <div>\n    <p>\n      Lazy load letter A:\n      <X letter=\"A\" />\n    </p>\n    <p>\n      Lazy load letter B:\n      <X letter=\"B\" />\n    </p>\n    <p>\n      Lazy load letter <strong>only on Client</strong> C and D:\n      <ClientSideOnly letter=\"C\" /> +\n      <ClientSideOnly letter=\"D\" />\n    </p>\n    <p>\n      lazy load momentjs and format date:\n      <Moment>{moment => `now is : ${moment().format('HH:mm')}`}</Moment>\n    </p>\n  </div>\n)\n\nexport default App\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/letters/A.css",
    "content": "/* A CSS */\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/letters/A.js",
    "content": "import './A.css'\n\nconst A = () => 'Lazy-Letter-A'\n\nexport default A\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/letters/B.js",
    "content": "const B = () => 'Lazy-Letter-B'\n\nexport default B\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/letters/C.js",
    "content": "const C = () => 'Lazy-Letter-C'\n\nexport default C\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/letters/D.js",
    "content": "// named as C\nconst C = () => 'and-D'\n\nexport default C\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/main-node.js",
    "content": "export { default } from './App'\n"
  },
  {
    "path": "examples/webpack/webpack5/src/client/main-web.js",
    "content": "import 'core-js'\nimport React from 'react'\nimport { hydrate } from 'react-dom'\nimport { loadableReady } from '@loadable/component'\nimport App from './App'\n\nconsole.log('waiting for application ready...')\nloadableReady(() => {\n  console.log('application is ready...')\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n"
  },
  {
    "path": "examples/webpack/webpack5/src/server/main.js",
    "content": "import path from 'path'\nimport express from 'express'\nimport React from 'react'\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst app = express()\n\n// https://github.com/gregberge/loadable-components/issues/634\n// app.use('*/runtime~main.js', async (req, res, next) => {\n//   console.log('delaying runtime chunk');\n//   await new Promise(resolve => setTimeout(resolve, 2000));\n//   next();\n// });\n\napp.use(express.static(path.join(__dirname, '../../public')))\n\nif (process.env.NODE_ENV !== 'production') {\n  /* eslint-disable global-require, import/no-extraneous-dependencies */\n  const { default: webpackConfig } = require('../../webpack.config.babel')\n  const webpackDevMiddleware = require('webpack-dev-middleware')\n  const webpack = require('webpack')\n  /* eslint-enable global-require, import/no-extraneous-dependencies */\n\n  const compiler = webpack(webpackConfig)\n\n  app.use(\n    webpackDevMiddleware(compiler, {\n      logLevel: 'silent',\n      publicPath: '/dist/web',\n      writeToDisk(filePath) {\n        return /dist\\/node\\//.test(filePath) || /loadable-stats/.test(filePath)\n      },\n    }),\n  )\n}\n\nconst nodeStats = path.resolve(\n  __dirname,\n  '../../public/dist/node/loadable-stats.json',\n)\n\nconst webStats = path.resolve(\n  __dirname,\n  '../../public/dist/web/loadable-stats.json',\n)\n\napp.get('*', (req, res) => {\n  const nodeExtractor = new ChunkExtractor({ statsFile: nodeStats })\n  const { default: App } = nodeExtractor.requireEntrypoint()\n\n  const webExtractor = new ChunkExtractor({ statsFile: webStats })\n  const jsx = webExtractor.collectChunks(<App />)\n\n  const html = renderToString(jsx)\n\n  res.set('content-type', 'text/html')\n  res.send(`\n      <!DOCTYPE html>\n      <html>\n        <head>        \n        ${webExtractor.getLinkTags()}\n        ${webExtractor.getStyleTags()}\n        </head>\n        <body>\n          <div id=\"main\">${html}</div>\n          <script>console.log('html is loaded')</script>          \n          ${webExtractor.getScriptTags()}\n          <script>console.log('html is ready')</script>\n        </body>\n      </html>\n    `)\n})\n\n// eslint-disable-next-line no-console\napp.listen(9000, () => console.log('Server started http://localhost:9000'))\n"
  },
  {
    "path": "examples/webpack/webpack5/webpack.config.babel.js",
    "content": "import path from 'path'\nimport nodeExternals from 'webpack-node-externals'\nimport LoadablePlugin from '@loadable/webpack-plugin'\nimport MiniCssExtractPlugin from 'mini-css-extract-plugin'\n\nconst DIST_PATH = path.resolve(__dirname, 'public/dist')\nconst production = process.env.NODE_ENV === 'production'\nconst development = !production\n\nconst getConfig = target => ({\n  name: target,\n  mode: development ? 'development' : 'production',\n  target,\n  entry: `./src/client/main-${target}.js`,\n  module: {\n    rules: [\n      {\n        test: /\\.js?$/,\n        exclude: /node_modules/,\n        use: {\n          loader: 'babel-loader',\n          options: {\n            caller: { target },\n          },\n        },\n      },\n      {\n        test: /\\.css$/,\n        use: [\n          {\n            loader: MiniCssExtractPlugin.loader,\n          },\n          'css-loader',\n        ],\n      },\n    ],\n  },\n  externals:\n    target === 'node' ? ['@loadable/component', nodeExternals()] : undefined,\n\n  optimization: {\n    // this will lead to runtime error\n    runtimeChunk: target !== 'node',\n  },\n\n  output: {\n    path: path.join(DIST_PATH, target),\n    filename: production ? '[name]-bundle-[chunkhash:8].js' : '[name].js',\n    publicPath: `/dist/${target}/`,\n    libraryTarget: target === 'node' ? 'commonjs2' : undefined,\n  },\n  plugins: [new LoadablePlugin(), new MiniCssExtractPlugin()],\n})\n\nexport default [getConfig('web'), getConfig('node')]\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"lerna\": \"2.9.0\",\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"version\": \"5.16.7\",\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true\n}\n"
  },
  {
    "path": "netlify.toml",
    "content": "[build]\t\n  base    = \"website\"\t\n  command = \"yarn build\"\t\n  publish = \"website/public\" "
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"loadable-components\",\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/*\"\n  ],\n  \"bundlesize\": [\n    {\n      \"path\": \"./packages/component/dist/loadable.min.js\",\n      \"maxSize\": \"3.5 kB\"\n    },\n    {\n      \"path\": \"./packages/component/dist/loadable.esm.js\",\n      \"maxSize\": \"4.5 kB\"\n    }\n  ],\n  \"scripts\": {\n    \"build\": \"lerna run build\",\n    \"ci\": \"yarn build && yarn lint && yarn test:prepare && yarn test --ci\",\n    \"dev\": \"WATCH_MODE=true lerna run build --parallel -- --watch\",\n    \"format\": \"prettier --write \\\"**/*.{js,json,md}\\\"\",\n    \"lint\": \"eslint .\",\n    \"release\": \"lerna publish --conventional-commits && conventional-github-releaser --preset angular\",\n    \"release-to-git\": \"./scripts/git-release.sh\",\n    \"test:prepare\": \"./scripts/prepare.sh\",\n    \"test\": \"jest\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.7.7\",\n    \"@babel/core\": \"^7.7.7\",\n    \"@babel/node\": \"^7.7.7\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.7.4\",\n    \"@babel/plugin-transform-runtime\": \"^7.7.6\",\n    \"@babel/preset-env\": \"^7.7.7\",\n    \"@babel/preset-react\": \"^7.7.4\",\n    \"@hedgepigdaniel/npm-publish-git\": \"^0.1.0\",\n    \"@testing-library/jest-dom\": \"^4.2.4\",\n    \"@testing-library/react\": \"^9.4.0\",\n    \"babel-core\": \"^7.0.0-bridge.0\",\n    \"babel-eslint\": \"^10.0.3\",\n    \"babel-jest\": \"^24.9.0\",\n    \"babel-plugin-annotate-pure-calls\": \"^0.4.0\",\n    \"conventional-github-releaser\": \"^3.1.2\",\n    \"cross-env\": \"^6.0.3\",\n    \"eslint\": \"^6.8.0\",\n    \"eslint-config-airbnb\": \"^18.0.1\",\n    \"eslint-config-prettier\": \"^6.9.0\",\n    \"eslint-plugin-import\": \"^2.19.1\",\n    \"eslint-plugin-jsx-a11y\": \"^6.2.1\",\n    \"eslint-plugin-react\": \"^7.17.0\",\n    \"jest\": \"^24.9.0\",\n    \"lerna\": \"^3.20.2\",\n    \"prettier\": \"^1.19.1\",\n    \"react\": \"^16.12.0\",\n    \"react-dom\": \"^16.12.0\",\n    \"regenerator-runtime\": \"^0.13.3\",\n    \"rollup\": \"^1.29.0\",\n    \"rollup-plugin-babel\": \"^4.3.2\",\n    \"rollup-plugin-commonjs\": \"^10.1.0\",\n    \"rollup-plugin-node-resolve\": \"^5.0.1\",\n    \"rollup-plugin-replace\": \"^2.2.0\",\n    \"rollup-plugin-terser\": \"^5.1.3\",\n    \"shx\": \"^0.3.2\"\n  },\n  \"packageManager\": \"yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e\"\n}\n"
  },
  {
    "path": "packages/babel-plugin/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.16.1](https://github.com/gregberge/loadable-components/compare/v5.16.0...v5.16.1) (2023-07-20)\n\n\n### Bug Fixes\n\n* correct babel plugin default signature to allow any source of 'loadable' ([#972](https://github.com/gregberge/loadable-components/issues/972)) ([19849b6](https://github.com/gregberge/loadable-components/commit/19849b6ba738fe19c18e61ed3402ee82ba934760)), closes [#971](https://github.com/gregberge/loadable-components/issues/971)\n\n\n\n\n\n# [5.16.0](https://github.com/gregberge/loadable-components/compare/v5.15.3...v5.16.0) (2023-07-09)\n\n\n### Features\n\n* Allow additional identifiers to be passed in to the babel plugin ([#966](https://github.com/gregberge/loadable-components/issues/966)) ([e18e37a](https://github.com/gregberge/loadable-components/commit/e18e37afd8b30455d3a786b9b0dae5f3bd0d442b))\n\n\n\n\n\n## [5.15.3](https://github.com/gregberge/loadable-components/compare/v5.15.2...v5.15.3) (2023-01-28)\n\n**Note:** Version bump only for package @loadable/babel-plugin\n\n\n\n\n\n## [5.13.2](https://github.com/gregberge/loadable-components/compare/v5.13.1...v5.13.2) (2020-09-14)\n\n**Note:** Version bump only for package @loadable/babel-plugin\n\n\n\n\n\n# [5.13.0](https://github.com/gregberge/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n\n### Bug Fixes\n\n* allow webpack cache is ready only for initial chunks, fixes [#558](https://github.com/gregberge/loadable-components/issues/558) ([61f8b75](https://github.com/gregberge/loadable-components/commit/61f8b75b54612368c88807d73abb7dc7add720ad))\n* **babel-plugin:** add missing peer dependency ([#524](https://github.com/gregberge/loadable-components/issues/524)) ([03a79b6](https://github.com/gregberge/loadable-components/commit/03a79b66defc78f150436acd6a9d3e029bb1d470))\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Bug Fixes\n\n* apply loadable transformations before any other, fixes [#466](https://github.com/gregberge/loadable-components/issues/466) ([ac5ba45](https://github.com/gregberge/loadable-components/commit/ac5ba45862bad68b971a969e6e8713874add51a6))\n\n\n\n\n\n# [5.11.0](https://github.com/smooth-code/loadable-components/compare/v5.10.3...v5.11.0) (2019-12-02)\n\n\n### Bug Fixes\n\n* fix isReady problem ([#445](https://github.com/smooth-code/loadable-components/issues/445)) ([3024348](https://github.com/smooth-code/loadable-components/commit/30243482be917e89515d057e2368e7278e34696c)), closes [#400](https://github.com/smooth-code/loadable-components/issues/400)\n\n\n\n\n\n## [5.10.3](https://github.com/smooth-code/loadable-components/compare/v5.10.2...v5.10.3) (2019-09-24)\n\n\n### Bug Fixes\n\n* **babel-plugin:** fix bug when using + concatenation instead of a template literal ([#425](https://github.com/smooth-code/loadable-components/issues/425)) ([d98dd27](https://github.com/smooth-code/loadable-components/commit/d98dd27))\n\n\n\n\n\n# [5.10.0](https://github.com/smooth-code/loadable-components/compare/v5.9.0...v5.10.0) (2019-05-13)\n\n\n### Bug Fixes\n\n* fix chunkname mismatch ([#332](https://github.com/smooth-code/loadable-components/issues/332)) ([7ffaa4c](https://github.com/smooth-code/loadable-components/commit/7ffaa4c)), closes [#331](https://github.com/smooth-code/loadable-components/issues/331)\n\n\n\n\n\n# [5.8.0](https://github.com/smooth-code/loadable-components/compare/v5.7.2...v5.8.0) (2019-04-10)\n\n\n### Bug Fixes\n\n* **babel-plugin:** Use require.resolve instead of relative path resolution ([#303](https://github.com/smooth-code/loadable-components/issues/303)) ([bad7f1f](https://github.com/smooth-code/loadable-components/commit/bad7f1f))\n\n\n\n\n\n## [5.7.2](https://github.com/smooth-code/loadable-components/compare/v5.7.1...v5.7.2) (2019-03-20)\n\n\n### Bug Fixes\n\n* **babel-plugin:** handle \"-\" at the end of request ([c0f325b](https://github.com/smooth-code/loadable-components/commit/c0f325b))\n\n\n\n\n\n## [5.7.1](https://github.com/smooth-code/loadable-components/compare/v5.7.0...v5.7.1) (2019-03-19)\n\n\n### Bug Fixes\n\n* **babel-plugin:** handle special chars in file names ([#279](https://github.com/smooth-code/loadable-components/issues/279)) ([4da39ff](https://github.com/smooth-code/loadable-components/commit/4da39ff))\n\n\n\n\n\n# [5.7.0](https://github.com/smooth-code/loadable-components/compare/v5.6.1...v5.7.0) (2019-03-14)\n\n\n### Performance Improvements\n\n* **build:** add build target for Node ([#267](https://github.com/smooth-code/loadable-components/issues/267)) ([97ff6ac](https://github.com/smooth-code/loadable-components/commit/97ff6ac))\n\n\n\n\n\n# [5.6.0](https://github.com/smooth-code/loadable-components/compare/v5.5.0...v5.6.0) (2019-02-05)\n\n\n### Bug Fixes\n\n* **server:** fix chunkName resolving ([#219](https://github.com/smooth-code/loadable-components/issues/219)) ([ef11e11](https://github.com/smooth-code/loadable-components/commit/ef11e11))\n\n\n### Features\n\n* **babel-plugin:** transform code annotated with magic comment ([4f832dc](https://github.com/smooth-code/loadable-components/commit/4f832dc)), closes [#192](https://github.com/smooth-code/loadable-components/issues/192)\n\n\n\n\n\n# [5.5.0](https://github.com/smooth-code/loadable-components/compare/v5.4.0...v5.5.0) (2019-01-22)\n\n**Note:** Version bump only for package @loadable/babel-plugin\n\n\n\n\n\n## [5.2.2](https://github.com/smooth-code/loadable-components/compare/v5.2.1...v5.2.2) (2018-12-12)\n\n\n### Bug Fixes\n\n* **babel-plugin:** fix chunkName with aggressive code splitting ([e974933](https://github.com/smooth-code/loadable-components/commit/e974933)), closes [#182](https://github.com/smooth-code/loadable-components/issues/182)\n\n\n\n\n\n# [5.0.0](https://github.com/smooth-code/loadable-components/compare/v4.0.5...v5.0.0) (2018-11-10)\n\n\n### Features\n\n* improve SSR support ([eb1cfe8](https://github.com/smooth-code/loadable-components/commit/eb1cfe8))\n\n\n### BREAKING CHANGES\n\n* - SSR has been rewritten from scratch, if you use it, please follow the\nnew guide.\n- Prefetch component and prefetch functions have been removed, please\nuse `webpackPrefetch` instead.\n\n\n\n\n\n## [4.0.5](https://github.com/smooth-code/loadable-components/compare/v4.0.4...v4.0.5) (2018-11-01)\n\n**Note:** Version bump only for package @loadable/babel-plugin\n\n\n\n\n\n## [4.0.3](https://github.com/smooth-code/loadable-components/compare/v4.0.2...v4.0.3) (2018-10-31)\n\n\n### Bug Fixes\n\n* **server:** disable common chunks optim ([78e7b28](https://github.com/smooth-code/loadable-components/commit/78e7b28))\n\n\n\n\n\n## [4.0.2](https://github.com/smooth-code/loadable-components/compare/v4.0.1...v4.0.2) (2018-10-31)\n\n\n### Bug Fixes\n\n* **babel-plugin:** transform into friendly chunk name ([54422cb](https://github.com/smooth-code/loadable-components/commit/54422cb))\n\n\n\n\n\n# [4.0.0](https://github.com/smooth-code/loadable-components/compare/v3.0.2...v4.0.0) (2018-10-30)\n\n\n### Features\n\n* add new loadable.lib, change API ([94b2e87](https://github.com/smooth-code/loadable-components/commit/94b2e87))\n\n\n### BREAKING CHANGES\n\n* - `ErrorComponent` is ignored, please use Error Boundaries to handle errors.\n- `lazy` is no longer exported\n- `LoadingComponent` is replaced by `fallback` option\n- `ref` are now forwarded\n\n\n\n\n\n# [3.0.0](https://github.com/smooth-code/loadable-components/compare/v2.2.3...v3.0.0) (2018-10-29)\n\n\n### Features\n\n* welcome loadable ([4dffad7](https://github.com/smooth-code/loadable-components/commit/4dffad7))\n\n\n### BREAKING CHANGES\n\n* API has completely changed, see documentation.\n"
  },
  {
    "path": "packages/babel-plugin/README.md",
    "content": "# @loadable/babel-plugin\n\nThis plugin is required only if you use Server Side Rendering in your application. [See `@loadable/server` for more information](https://loadable-components.com/docs/api-loadable-server/).\n\n## Install\n\n```\b\nnpm install --save-dev @loadable/babel-plugin\n```\n\n## Documentation\n\n👉 [See full documentation](https://loadable-components.com/)\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/babel-plugin/package.json",
    "content": "{\n  \"name\": \"@loadable/babel-plugin\",\n  \"description\": \"Babel plugin for loadable (required for SSR).\",\n  \"version\": \"5.16.1\",\n  \"main\": \"lib/index.js\",\n  \"repository\": \"git@github.com:gregberge/loadable-components.git\",\n  \"author\": \"Greg Bergé <berge.greg@gmail.com>\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"keywords\": [\n    \"loadable\"\n  ],\n  \"engines\": {\n    \"node\": \">=8\"\n  },\n  \"funding\": {\n    \"type\": \"github\",\n    \"url\": \"https://github.com/sponsors/gregberge\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"prebuild\": \"shx rm -rf lib\",\n    \"build\": \"BUILD_TARGET=node babel --config-file ../../babel.config.js -d lib --ignore \\\"**/*.test.js\\\" src\",\n    \"prepublishOnly\": \"yarn run build\"\n  },\n  \"dependencies\": {\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.7.4\"\n  },\n  \"peerDependencies\": {\n    \"@babel/core\": \"^7.0.0-0\"\n  }\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/__snapshots__/index.test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`plugin Magic comment should remove only needed comments 1`] = `\n\"const load =\n/* IMPORTANT! */\n{\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"moment\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"moment\\\\\" */\n  'moment'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"moment\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"moment\\\\\");\n  }\n\n};\"\n`;\n\nexports[`plugin Magic comment should transpile arrow functions 1`] = `\n\"const load = {\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"moment\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"moment\\\\\" */\n  'moment'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"moment\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"moment\\\\\");\n  }\n\n};\"\n`;\n\nexports[`plugin Magic comment should transpile function expression 1`] = `\n\"const load = {\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"moment\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: function () {\n    return import(\n    /* webpackChunkName: \\\\\"moment\\\\\" */\n    'moment');\n  },\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"moment\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"moment\\\\\");\n  }\n\n};\"\n`;\n\nexports[`plugin Magic comment should transpile shortand properties 1`] = `\n\"const obj = {\n  load: {\n    resolved: {},\n\n    chunkName() {\n      return \\\\\"moment\\\\\";\n    },\n\n    isReady(props) {\n      const key = this.resolve(props);\n\n      if (this.resolved[key] !== true) {\n        return false;\n      }\n\n      if (typeof __webpack_modules__ !== 'undefined') {\n        return !!__webpack_modules__[key];\n      }\n\n      return false;\n    },\n\n    importAsync: () => {\n      return import(\n      /* webpackChunkName: \\\\\"moment\\\\\" */\n      'moment');\n    },\n\n    requireAsync(props) {\n      const key = this.resolve(props);\n      this.resolved[key] = false;\n      return this.importAsync(props).then(resolved => {\n        this.resolved[key] = true;\n        return resolved;\n      });\n    },\n\n    requireSync(props) {\n      const id = this.resolve(props);\n\n      if (typeof __webpack_require__ !== 'undefined') {\n        return __webpack_require__(id);\n      }\n\n      return eval('module.require')(id);\n    },\n\n    resolve() {\n      if (require.resolveWeak) {\n        return require.resolveWeak(\\\\\"moment\\\\\");\n      }\n\n      return eval('require.resolve')(\\\\\"moment\\\\\");\n    }\n\n  }\n};\"\n`;\n\nexports[`plugin aggressive import should work with destructuration 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName({\n    foo\n  }) {\n    return \\`\\${foo}\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: ({\n    foo\n  }) => import(\n  /* webpackChunkName: \\\\\"[request]\\\\\" */\n  \\`./\\${foo}\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve({\n    foo\n  }) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./\\${foo}\\`);\n    }\n\n    return eval('require.resolve')(\\`./\\${foo}\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin aggressive import with \"webpackChunkName\" should keep it 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName(props) {\n    return \\\\\"pages/\\\\\" + props.path.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: props => import(\n  /* webpackChunkName: \\\\\"pages/[request]\\\\\" */\n  \\`./pages/\\${props.path}\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve(props) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./pages/\\${props.path}\\`);\n    }\n\n    return eval('require.resolve')(\\`./pages/\\${props.path}\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin aggressive import with \"webpackChunkName\" should replace it 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName(props) {\n    return \\`\\${props.foo}\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: props => import(\n  /* webpackChunkName: \\\\\"[request]\\\\\" */\n  \\`./\\${props.foo}\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve(props) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./\\${props.foo}\\`);\n    }\n\n    return eval('require.resolve')(\\`./\\${props.foo}\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin aggressive import without \"webpackChunkName\" should support complex request 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName(props) {\n    return \\`dir-\\${props.foo}-test\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: props => import(\n  /* webpackChunkName: \\\\\"dir-[request]\\\\\" */\n  \\`./dir/\\${props.foo}/test\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve(props) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./dir/\\${props.foo}/test\\`);\n    }\n\n    return eval('require.resolve')(\\`./dir/\\${props.foo}/test\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin aggressive import without \"webpackChunkName\" should support destructuring 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName({\n    foo\n  }) {\n    return \\`dir-\\${foo}-test\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: ({\n    foo\n  }) => import(\n  /* webpackChunkName: \\\\\"dir-[request]\\\\\" */\n  \\`./dir/\\${foo}/test\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve({\n    foo\n  }) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./dir/\\${foo}/test\\`);\n    }\n\n    return eval('require.resolve')(\\`./dir/\\${foo}/test\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin aggressive import without \"webpackChunkName\" should support simple request 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName(props) {\n    return \\`\\${props.foo}\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: props => import(\n  /* webpackChunkName: \\\\\"[request]\\\\\" */\n  \\`./\\${props.foo}\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve(props) {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./\\${props.foo}\\`);\n    }\n\n    return eval('require.resolve')(\\`./\\${props.foo}\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures (default) should support old named import 1`] = `\n\"import loadable from './loadable-utils';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures named signature should not match default import 1`] = `\n\"import myLoadable from 'myLoadablePackage';\nmyLoadable(() => import(\\`./ModA\\`));\"\n`;\n\nexports[`plugin custom signatures should match custom default signature 1`] = `\n\"import myLoadable from 'myLoadablePackage';\nmyLoadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures should match custom named signature 1`] = `\n\"import { myLoadable } from 'myLoadablePackage';\nmyLoadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures should match renamed default import 1`] = `\n\"import renamedLoadable from '@loadable/component';\nrenamedLoadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures should match simple default import 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin custom signatures should not match on undeclared specifiers 1`] = `\n\"import myLoadable from 'myLoadablePackage';\nmyLoadable(() => import(\\`./ModA\\`));\"\n`;\n\nexports[`plugin loadable.lib should be transpiled too 1`] = `\n\"import loadable from '@loadable/component';\nloadable.lib({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"moment\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"moment\\\\\" */\n  'moment'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"moment\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"moment\\\\\");\n  }\n\n});\"\n`;\n\nexports[`plugin simple import in a complex promise should work 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"ModA\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => timeout(import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  './ModA'), 2000),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"./ModA\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"./ModA\\\\\");\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should transform path into \"chunk-friendly\" name 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"foo-bar\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"foo-bar\\\\\" */\n  '../foo/bar'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"../foo/bar\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"../foo/bar\\\\\");\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with * in name 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`foo\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"foo\\\\\" */\n  \\`./foo*\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./foo*\\`);\n    }\n\n    return eval('require.resolve')(\\`./foo*\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with + concatenation 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"\\\\\" */\n  './Mod' + 'A'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak('./Mod' + 'A');\n    }\n\n    return eval('require.resolve')('./Mod' + 'A');\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with lazy if imported 1`] = `\n\"import { lazy } from '@loadable/component';\nlazy({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with renamed lazy specifier 1`] = `\n\"import { lazy as renamedLazy } from '@loadable/component';\nrenamedLazy({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with renamed specifier by default 1`] = `\n\"import renamedLoadable from '@loadable/component';\nrenamedLoadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin simple import should work with template literal 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\`ModA\\`.replace(/[^a-zA-Z0-9_!§$()=\\\\\\\\-^°]+/g, \\\\\"-\\\\\");\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  \\`./ModA\\`),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\`./ModA\\`);\n    }\n\n    return eval('require.resolve')(\\`./ModA\\`);\n  }\n\n});\"\n`;\n\nexports[`plugin simple import with \"webpackChunkName\" comment should use it 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"ChunkA\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ChunkA\\\\\" */\n  './ModA'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"./ModA\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"./ModA\\\\\");\n  }\n\n});\"\n`;\n\nexports[`plugin simple import with \"webpackChunkName\" comment should use it even if comment is separated by \",\" 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"ChunkA\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackPrefetch: true, webpackChunkName: \\\\\"ChunkA\\\\\" */\n  './ModA'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"./ModA\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"./ModA\\\\\");\n  }\n\n});\"\n`;\n\nexports[`plugin simple import without \"webpackChunkName\" comment should add it 1`] = `\n\"import loadable from '@loadable/component';\nloadable({\n  resolved: {},\n\n  chunkName() {\n    return \\\\\"ModA\\\\\";\n  },\n\n  isReady(props) {\n    const key = this.resolve(props);\n\n    if (this.resolved[key] !== true) {\n      return false;\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[key];\n    }\n\n    return false;\n  },\n\n  importAsync: () => import(\n  /* webpackChunkName: \\\\\"ModA\\\\\" */\n  './ModA'),\n\n  requireAsync(props) {\n    const key = this.resolve(props);\n    this.resolved[key] = false;\n    return this.importAsync(props).then(resolved => {\n      this.resolved[key] = true;\n      return resolved;\n    });\n  },\n\n  requireSync(props) {\n    const id = this.resolve(props);\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id);\n    }\n\n    return eval('module.require')(id);\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak(\\\\\"./ModA\\\\\");\n    }\n\n    return eval('require.resolve')(\\\\\"./ModA\\\\\");\n  }\n\n});\"\n`;\n"
  },
  {
    "path": "packages/babel-plugin/src/index.js",
    "content": "import { declare } from \"@babel/helper-plugin-utils\";\nimport syntaxDynamicImport from '@babel/plugin-syntax-dynamic-import'\nimport chunkNameProperty from './properties/chunkName'\nimport isReadyProperty from './properties/isReady'\nimport importAsyncProperty from './properties/importAsync'\nimport requireAsyncProperty from './properties/requireAsync'\nimport requireSyncProperty from './properties/requireSync'\nimport resolveProperty from './properties/resolve'\nimport stateProperty from './properties/state'\n\nconst properties = [\n  stateProperty,\n  chunkNameProperty,\n  isReadyProperty,\n  importAsyncProperty,\n  requireAsyncProperty,\n  requireSyncProperty,\n  resolveProperty,\n]\n\nconst LOADABLE_COMMENT = '#__LOADABLE__'\n\nconst DEFAULT_SIGNATURE = [{name: 'default', from: '@loadable/component'}];\n\nconst loadablePlugin = declare((api, { \n  signatures = DEFAULT_SIGNATURE\n }) => {\n  const { types: t } = api\n\n  function collectImportCallPaths(startPath) {\n    const imports = []\n    startPath.traverse({\n      Import(importPath) {\n        imports.push(importPath.parentPath)\n      },\n    })\n    return imports\n  }\n\n  const propertyFactories = properties.map(init => init(api))\n\n  function isValidIdentifier(path, loadableImportSpecifiers, lazyImportSpecifier) {\n    // loadable signatures\n    if (loadableImportSpecifiers.find(specifier => path.get('callee').isIdentifier({ name: specifier }))) {\n      return true\n    }\n\n    // `lazy()`\n    if (lazyImportSpecifier && path.get('callee').isIdentifier({ name: lazyImportSpecifier })) {\n      return true\n    }\n\n    // `loadable.lib()`\n    return (\n      path.get('callee').isMemberExpression() &&\n      loadableImportSpecifiers.find(specifier => path.get('callee.object').isIdentifier({ name: specifier })) &&\n      path.get('callee.property').isIdentifier({ name: 'lib' })\n    )\n  }\n\n  function hasLoadableComment(path) {\n    const comments = path.get('leadingComments')\n    const comment = comments.find(\n      ({ node }) =>\n        node && node.value && String(node.value).includes(LOADABLE_COMMENT),\n    )\n    if (!comment) return false\n    comment.remove()\n    return true\n  }\n\n  function getFuncPath(path) {\n    const funcPath = path.isCallExpression() ? path.get('arguments.0') : path\n    if (\n      !funcPath.isFunctionExpression() &&\n      !funcPath.isArrowFunctionExpression() &&\n      !funcPath.isObjectMethod()\n    ) {\n      return null\n    }\n    return funcPath\n  }\n\n  function transformImport(path) {\n    const callPaths = collectImportCallPaths(path)\n\n    // Ignore loadable function that does not have any \"import\" call\n    if (callPaths.length === 0) return\n\n    // Multiple imports call is not supported\n    if (callPaths.length > 1) {\n      throw new Error(\n        'loadable: multiple import calls inside `loadable()` function are not supported.',\n      )\n    }\n\n    const [callPath] = callPaths\n\n    const funcPath = getFuncPath(path)\n    if (!funcPath) return\n\n    funcPath.node.params = funcPath.node.params || []\n\n    const object = t.objectExpression(\n      propertyFactories.map(getProperty =>\n        getProperty({ path, callPath, funcPath }),\n      ),\n    )\n\n    if (funcPath.isObjectMethod()) {\n      funcPath.replaceWith(\n        t.objectProperty(funcPath.node.key, object, funcPath.node.computed),\n      )\n    } else {\n      funcPath.replaceWith(object)\n    }\n  }\n\n\n  return {\n    inherits: syntaxDynamicImport,\n    visitor: {\n      Program: {\n        enter(programPath) {\n          let lazyImportSpecifier = false\n          // default to \"loadable\" detection. Remove defaults if signatures are configured\n          const loadableSpecifiers = signatures === DEFAULT_SIGNATURE ? ['loadable']: [];\n\n          programPath.traverse({\n            ImportDefaultSpecifier(path) {\n              const { parent } = path\n              const { local } = path.node\n              if (local && signatures.find(signature => signature.name === 'default' && parent.source.value === signature.from)) {\n                loadableSpecifiers.push(local.name)\n              }\n            },\n            ImportSpecifier(path) {\n              const { parent } = path\n              const { imported, local } = path.node\n              if (!lazyImportSpecifier) {\n                lazyImportSpecifier = parent.source.value == '@loadable/component' &&\n                  imported && imported.name == 'lazy' && local && local.name\n              }\n              if (local && imported && signatures.find(signature => imported.name === signature.name && parent.source.value === signature.from)) {\n                loadableSpecifiers.push(local.name)\n              }\n            },\n            CallExpression(path) {\n              if (!isValidIdentifier(path, loadableSpecifiers, lazyImportSpecifier)) return\n              transformImport(path)\n            },\n            'ArrowFunctionExpression|FunctionExpression|ObjectMethod': path => {\n              if (!hasLoadableComment(path)) return\n              transformImport(path)\n            },\n          })\n        },\n      },\n    },\n  }\n})\n\nexport default loadablePlugin\n"
  },
  {
    "path": "packages/babel-plugin/src/index.test.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\nimport { transform } from '@babel/core'\nimport plugin from '.'\n\nconst testPlugin = (code, options) => {\n  const result = transform(code, {\n    plugins: [[plugin, options]],\n    configFile: false,\n  })\n\n  return result.code\n}\n\ndescribe('plugin', () => {\n  describe('simple import', () => {\n    it('should work with template literal', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(() => import(\\`./ModA\\`))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n    it('should work with lazy if imported', () => {\n      const result = testPlugin(`\n        import { lazy } from '@loadable/component'\n        lazy(() => import(\\`./ModA\\`))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n    it('should not work with lazy if not imported', () => {\n      const result = testPlugin(`\n        import React, { lazy } from 'react'\n        lazy(() => import(\\`./ModA\\`))\n      `)\n\n      expect(result).toMatchInlineSnapshot(`\n        \"import React, { lazy } from 'react';\n        lazy(() => import(\\`./ModA\\`));\"\n      `)\n    })\n    it('should work with renamed specifier by default', () => {\n      const result = testPlugin(`\n        import renamedLoadable from '@loadable/component'\n        renamedLoadable(() => import(\\`./ModA\\`))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n    it('should work with renamed lazy specifier', () => {\n      const result = testPlugin(`\n        import { lazy as renamedLazy } from '@loadable/component'\n        renamedLazy(() => import(\\`./ModA\\`))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n    it('should work with + concatenation', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(() => import('./Mod' + 'A'))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n\n    it('should work with * in name', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(() => import(\\`./foo*\\`))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n\n    it('should transform path into \"chunk-friendly\" name', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(() => import('../foo/bar'))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n\n    describe('with \"webpackChunkName\" comment', () => {\n      it('should use it', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(() => import(/* webpackChunkName: \"ChunkA\" */ './ModA'))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n\n      it('should use it even if comment is separated by \",\"', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(() => import(/* webpackPrefetch: true, webpackChunkName: \"ChunkA\" */ './ModA'))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n    })\n\n    describe('without \"webpackChunkName\" comment', () => {\n      it('should add it', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(() => import('./ModA'))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n    })\n\n    describe('in a complex promise', () => {\n      it('should work', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(() => timeout(import('./ModA'), 2000))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n    })\n  })\n\n  describe('aggressive import', () => {\n    it('should work with destructuration', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(({ foo }) => import(/* webpackChunkName: \"Pages\" */ \\`./\\${foo}\\`))\n      `)\n      expect(result).toMatchSnapshot()\n    })\n\n    describe('with \"webpackChunkName\"', () => {\n      it('should replace it', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(props => import(/* webpackChunkName: \"Pages\" */ \\`./\\${props.foo}\\`))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n\n      it('should keep it', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(props => import(/* webpackChunkName: \"pages/[request]\" */ \\`./pages/\\${props.path}\\`))\n        `)\n\n        expect(result).toMatchSnapshot()\n        expect(result).toEqual(\n          expect.stringContaining('return \"pages/\" + props.path.replace'),\n        )\n        expect(result).toEqual(\n          expect.stringContaining('/* webpackChunkName: \"pages/[request]\"'),\n        )\n      })\n    })\n\n    describe('without \"webpackChunkName\"', () => {\n      it('should support simple request', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(props => import(\\`./\\${props.foo}\\`))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n\n      it('should support complex request', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(props => import(\\`./dir/\\${props.foo}/test\\`))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n\n      it('should support destructuring', () => {\n        const result = testPlugin(`\n          import loadable from '@loadable/component'\n          loadable(({ foo }) => import(\\`./dir/\\${foo}/test\\`))\n        `)\n\n        expect(result).toMatchSnapshot()\n      })\n    })\n  })\n\n  describe('loadable.lib', () => {\n    it('should be transpiled too', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable.lib(() => import('moment'))\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n  })\n\n  describe('custom signatures', () => {\n    it('(default) should support old named import', () => {\n      const result = testPlugin(`\n        import loadable from './loadable-utils'\n        loadable(() => import(\\`./ModA\\`))\n      `)\n      expect(result).toMatchSnapshot()\n    });\n    it('should match simple default import', () => {\n      const result = testPlugin(`\n        import loadable from '@loadable/component'\n        loadable(() => import(\\`./ModA\\`))\n      `, { signatures: [{ name: 'default', from: '@loadable/component' }]})\n      expect(result).toMatchSnapshot()\n    })\n    it('should match renamed default import', () => {\n      const result = testPlugin(`\n        import renamedLoadable from '@loadable/component'\n        renamedLoadable(() => import(\\`./ModA\\`))\n      `, { signatures: [{ name: 'default', from: '@loadable/component' }]})\n      expect(result).toMatchSnapshot()\n    })\n    it('should match custom default signature', () => {\n      const result = testPlugin(`\n        import myLoadable from 'myLoadablePackage'\n        myLoadable(() => import(\\`./ModA\\`))\n      `, { signatures: [{ name: 'default', from: 'myLoadablePackage' }]})\n      expect(result).toMatchSnapshot()\n    })\n    it('should match custom named signature', () => {\n      const result = testPlugin(`\n        import { myLoadable } from 'myLoadablePackage'\n        myLoadable(() => import(\\`./ModA\\`))\n      `, { signatures: [{ name: 'myLoadable', from: 'myLoadablePackage' }]})\n      expect(result).toMatchSnapshot()\n    })\n    it('named signature should not match default import', () => {\n      const result = testPlugin(`\n        import myLoadable from 'myLoadablePackage'\n        myLoadable(() => import(\\`./ModA\\`))\n      `, { signatures: [{ name: 'myLoadable', from: 'myLoadablePackage' }]})\n      expect(result).toMatchSnapshot()\n    })\n    it('should not match on undeclared specifiers', () => {\n      const result = testPlugin(`\n        import myLoadable from 'myLoadablePackage'\n        myLoadable(() => import(\\`./ModA\\`))\n      `)\n      expect(result).toMatchSnapshot()\n    })\n  })\n\n  describe('Magic comment', () => {\n    it('should transpile shortand properties', () => {\n      const result = testPlugin(`\n        const obj = {\n          /* #__LOADABLE__ */\n          load() {\n            return import('moment')\n          }\n        }\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n\n    it('should transpile arrow functions', () => {\n      const result = testPlugin(`\n        const load = /* #__LOADABLE__ */ () => import('moment')\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n\n    it('should transpile function expression', () => {\n      const result = testPlugin(`\n        const load = /* #__LOADABLE__ */ function () {\n          return import('moment')\n        }\n      `)\n      expect(result).toMatchSnapshot()\n    })\n\n    it('should remove only needed comments', () => {\n      const result = testPlugin(`\n        const load = /* #__LOADABLE__ */ /* IMPORTANT! */ () => import('moment')\n      `)\n\n      expect(result).toMatchSnapshot()\n    })\n  })\n})\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/chunkName.js",
    "content": "import vm from 'vm'\nimport { getImportArg } from '../util'\n\nconst JS_PATH_REGEXP = /^[./]+|(\\.js$)/g\nconst MATCH_LEFT_HYPHENS_REPLACE_REGEX = /^-/g\n// https://github.com/webpack/webpack/blob/master/lib/Template.js\nconst WEBPACK_CHUNK_NAME_REGEXP = /webpackChunkName/\nconst WEBPACK_PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\\-^°]+/g\nconst WEBPACK_MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g\n\nfunction readWebpackCommentValues(str) {\n  try {\n    const values = vm.runInNewContext(`(function(){return {${str}};})()`)\n    return values\n  } catch (e) {\n    throw Error(`compilation error while processing: /*${str}*/: ${e.message}`)\n  }\n}\n\nfunction writeWebpackCommentValues(values) {\n  try {\n    const str = Object.keys(values)\n      .map(key => `${key}: ${JSON.stringify(values[key])}`)\n      .join(', ')\n    return ` ${str} `\n  } catch (e) {\n    throw Error(\n      `compilation error while processing: /*${values}*/: ${e.message}`,\n    )\n  }\n}\n\nfunction getChunkNameComment(importArg) {\n  if (!importArg.has('leadingComments')) return null\n  return importArg\n    .get('leadingComments')\n    .find(comment => comment.node.value.match(WEBPACK_CHUNK_NAME_REGEXP))\n}\n\nfunction getRawChunkNameFromCommments(importArg) {\n  const chunkNameComment = getChunkNameComment(importArg)\n  if (!chunkNameComment) return null\n  return readWebpackCommentValues(chunkNameComment.node.value)\n}\n\nfunction moduleToChunk(str) {\n  if (typeof str !== 'string') return ''\n  return str\n    .replace(JS_PATH_REGEXP, '')\n    .replace(WEBPACK_PATH_NAME_NORMALIZE_REPLACE_REGEX, '-')\n    .replace(WEBPACK_MATCH_PADDED_HYPHENS_REPLACE_REGEX, '')\n}\n\nfunction replaceQuasi(str, stripLeftHyphen) {\n  if (!str) return ''\n  const result = str.replace(WEBPACK_PATH_NAME_NORMALIZE_REPLACE_REGEX, '-')\n  if (!stripLeftHyphen) return result\n  return result.replace(MATCH_LEFT_HYPHENS_REPLACE_REGEX, '')\n}\n\nexport default function chunkNameProperty({ types: t }) {\n  function transformQuasi(quasi, first, single) {\n    return t.templateElement(\n      {\n        raw: single\n          ? moduleToChunk(quasi.value.raw)\n          : replaceQuasi(quasi.value.raw, first),\n        cooked: single\n          ? moduleToChunk(quasi.value.cooked)\n          : replaceQuasi(quasi.value.cooked, first),\n      },\n      quasi.tail,\n    )\n  }\n\n  function sanitizeChunkNameTemplateLiteral(node) {\n    return t.callExpression(t.memberExpression(node, t.identifier('replace')), [\n      t.regExpLiteral(WEBPACK_PATH_NAME_NORMALIZE_REPLACE_REGEX.source, 'g'),\n      t.stringLiteral('-'),\n    ])\n  }\n\n  function combineExpressions(node) {\n    const { expressions } = node\n    const { length } = expressions\n\n    if (length === 1) {\n      return expressions[0]\n    }\n\n    return expressions\n      .slice(1)\n      .reduce((r, p) => t.binaryExpression('+', r, p), expressions[0])\n  }\n\n  function generateChunkNameNode(callPath, prefix) {\n    const importArg = getImportArg(callPath)\n    if (importArg.isTemplateLiteral()) {\n      return prefix\n        ? t.binaryExpression(\n            '+',\n            t.stringLiteral(prefix),\n            sanitizeChunkNameTemplateLiteral(\n              combineExpressions(importArg.node),\n            ),\n          )\n        : t.templateLiteral(\n            importArg.node.quasis.map((quasi, index) =>\n              transformQuasi(\n                quasi,\n                index === 0,\n                importArg.node.quasis.length === 1,\n              ),\n            ),\n            importArg.node.expressions,\n          )\n    }\n    return t.stringLiteral(moduleToChunk(importArg.node.value))\n  }\n\n  function getExistingChunkNameComment(callPath) {\n    const importArg = getImportArg(callPath)\n    const values = getRawChunkNameFromCommments(importArg)\n    return values\n  }\n\n  function isAgressiveImport(callPath) {\n    const importArg = getImportArg(callPath)\n    return (\n      importArg.isTemplateLiteral() && importArg.node.expressions.length > 0\n    )\n  }\n\n  function addOrReplaceChunkNameComment(callPath, values) {\n    const importArg = getImportArg(callPath)\n    const chunkNameComment = getChunkNameComment(importArg)\n    if (chunkNameComment) {\n      chunkNameComment.remove()\n    }\n\n    importArg.addComment('leading', writeWebpackCommentValues(values))\n  }\n\n  function chunkNameFromTemplateLiteral(node) {\n    const [q1] = node.quasis\n    const v1 = q1 ? q1.value.cooked : ''\n    if (!node.expressions.length) return v1\n    return `${v1}[request]`\n  }\n\n  function getChunkNamePrefix(chunkName) {\n    if (typeof chunkName !== 'string') return ''\n    const match = chunkName.match(/(.+?)\\[(request|index)\\]$/)\n    return match ? match[1] : ''\n  }\n\n  function replaceChunkName(callPath) {\n    const agressiveImport = isAgressiveImport(callPath)\n    const values = getExistingChunkNameComment(callPath)\n    let { webpackChunkName } = values || {}\n\n    if (!agressiveImport && values) {\n      addOrReplaceChunkNameComment(callPath, values)\n      return t.stringLiteral(webpackChunkName)\n    }\n\n    let chunkNameNode = generateChunkNameNode(\n      callPath,\n      getChunkNamePrefix(webpackChunkName),\n    )\n\n    if (t.isTemplateLiteral(chunkNameNode)) {\n      webpackChunkName = chunkNameFromTemplateLiteral(chunkNameNode)\n      chunkNameNode = sanitizeChunkNameTemplateLiteral(chunkNameNode)\n    } else if (t.isStringLiteral(chunkNameNode)) {\n      webpackChunkName = chunkNameNode.value\n    }\n\n    addOrReplaceChunkNameComment(callPath, { ...values, webpackChunkName })\n    return chunkNameNode\n  }\n\n  return ({ callPath, funcPath }) => {\n    const chunkName = replaceChunkName(callPath)\n\n    return t.objectMethod(\n      'method',\n      t.identifier('chunkName'),\n      funcPath.node.params,\n      t.blockStatement([t.returnStatement(chunkName)]),\n    )\n  }\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/importAsync.js",
    "content": "export default function requireAsyncProperty({ types: t }) {\n  function getFunc(funcPath) {\n    if (funcPath.isObjectMethod()) {\n      const { params, body, async } = funcPath.node\n      return t.arrowFunctionExpression(params, body, async)\n    }\n\n    return funcPath.node\n  }\n\n  return ({ funcPath }) =>\n    t.objectProperty(t.identifier('importAsync'), getFunc(funcPath))\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/isReady.js",
    "content": "export default function isReadyProperty({ types: t, template }) {\n  const statements = template.ast(`\n    const key=this.resolve(props)\n    if (this.resolved[key] !== true) {\n      return false\n    }\n\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!(__webpack_modules__[key])\n    }\n\n    return false\n  `)\n\n  return () =>\n    t.objectMethod(\n      'method',\n      t.identifier('isReady'),\n      [t.identifier('props')],\n      t.blockStatement(statements),\n    )\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/requireAsync.js",
    "content": "export default function requireAsyncProperty({ types: t, template }) {\n  const tracking = template.ast(`\n    const key = this.resolve(props)\n    this.resolved[key] = false\n    return this.importAsync(props).then(resolved => {\n     this.resolved[key] = true\n     return resolved;\n    });        \n  `)\n\n  return () =>\n    t.objectMethod(\n      'method',\n      t.identifier('requireAsync'),\n      [t.identifier('props')],\n      t.blockStatement(tracking),\n    )\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/requireSync.js",
    "content": "export default function requireSyncProperty({ types: t, template }) {\n  const statements = template.ast(`\n    const id = this.resolve(props)\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id)\n    }\n\n    return eval('module.require')(id)\n  `)\n\n  return () =>\n    t.objectMethod(\n      'method',\n      t.identifier('requireSync'),\n      [t.identifier('props')],\n      t.blockStatement(statements),\n    )\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/resolve.js",
    "content": "import { getImportArg } from '../util'\n\nexport default function resolveProperty({ types: t, template }) {\n  const buildStatements = template`\n    if (require.resolveWeak) {\n      return require.resolveWeak(ID)\n    }\n\n    return eval('require.resolve')(ID)\n  `\n\n  function getCallValue(callPath) {\n    const importArg = getImportArg(callPath)\n    if (importArg.isTemplateLiteral()) {\n      return t.templateLiteral(\n        importArg.node.quasis,\n        importArg.node.expressions,\n      )\n    }\n    if (importArg.isBinaryExpression()) {\n      return t.BinaryExpression(\n        importArg.node.operator,\n        importArg.node.left,\n        importArg.node.right,\n      )\n    }\n    return t.stringLiteral(importArg.node.value)\n  }\n\n  return ({ callPath, funcPath }) =>\n    t.objectMethod(\n      'method',\n      t.identifier('resolve'),\n      funcPath.node.params,\n      t.blockStatement(buildStatements({ ID: getCallValue(callPath) })),\n    )\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/properties/state.js",
    "content": "export default function requireAsyncProperty({ types: t }) {\n  return () =>\n    t.objectProperty(t.identifier('resolved'), t.objectExpression([]))\n}\n"
  },
  {
    "path": "packages/babel-plugin/src/util.js",
    "content": "/* eslint-disable import/prefer-default-export */\n\nexport function getImportArg(callPath) {\n  return callPath.get('arguments.0')\n}\n"
  },
  {
    "path": "packages/codemod/.npmignore",
    "content": "transforms/__testfixtures__\ntransforms/__tests__"
  },
  {
    "path": "packages/codemod/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.13.2](https://github.com/gregberge/loadable-components/compare/v5.13.1...v5.13.2) (2020-09-14)\n\n**Note:** Version bump only for package loadable-codemod\n\n\n\n\n\n## [5.13.1](https://github.com/gregberge/loadable-components/compare/v5.13.0...v5.13.1) (2020-07-02)\n\n\n### Bug Fixes\n\n* expose used chunkNames from a server. Fixes [#587](https://github.com/gregberge/loadable-components/issues/587) ([831aec0](https://github.com/gregberge/loadable-components/commit/831aec03154ab16007db0d78fbf3559583c000fe))\n\n\n\n\n\n# [5.13.0](https://github.com/gregberge/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n**Note:** Version bump only for package loadable-codemod\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Features\n\n* add codemods to migrate from react-loadable ([#463](https://github.com/gregberge/loadable-components/issues/463)) ([a82d5ad](https://github.com/gregberge/loadable-components/commit/a82d5ad1e17cd64d3579aa207abfc18346ff0107))\n"
  },
  {
    "path": "packages/codemod/README.md",
    "content": "# @loadable/codemod\n\nThis package is a collection of codemod that can be used to help making big changes easier to a project, for example: migrating from `react-loadable` to `@loadable/component`\n\n## Notes about `react-loadable-to-loadable-component` transform\n\n`react-loadable-to-loadable-component` transform will help codemod all of your `Loadable()` declaration to `loadable()` with mostly equivalent params, barring some behavior that do not exist in `@loadable/component` such as `Loadable.Map()`, `timeout`, `delay`, etc.\n\nAfter running the codemod, you will still need to update some of your code manually, namely:\n\n1. Using `loadableReady` to hydrate your app on the client side.\n2. Updating your webpack configuration to use `@loadable`\n3. Updating your server side rendering code to use `ChunkExtractor`\n"
  },
  {
    "path": "packages/codemod/bin/main.js",
    "content": "#!/usr/bin/env node\n\n/* eslint-disable no-console */\nconst yargs = require('yargs')\nconst execa = require('execa')\nconst path = require('path')\nconst fs = require('fs')\nconst chalk = require('chalk')\nconst CodemodError = require('./utils/CodemodError')\n\nconst jscodeshiftExecutable = require.resolve('.bin/jscodeshift')\nconst transformsDir = path.resolve(__dirname, '../transforms')\n\nconst { argv } = yargs\n\ntry {\n  const selectedCodemod = argv._[0]\n  const directoryToApplyTo = argv._[1]\n\n  if (!selectedCodemod || !directoryToApplyTo) {\n    throw new CodemodError({\n      type: 'Invalid params',\n    })\n  }\n\n  const availableTransforms = fs\n    .readdirSync(transformsDir)\n    .filter(v => v !== '__tests__' && v !== '__testfixtures__')\n    .map(v => v.replace('.js', ''))\n\n  if (!availableTransforms.some(t => t === selectedCodemod)) {\n    throw new CodemodError({\n      type: 'Unrecognised transform',\n      payload: selectedCodemod,\n    })\n  }\n\n  const result = execa.commandSync(\n    `${jscodeshiftExecutable} -t ${transformsDir}/${selectedCodemod}.js ${directoryToApplyTo}`,\n    {\n      stdio: 'inherit',\n      stripEof: false,\n    },\n  )\n\n  if (result.error) {\n    throw result.error\n  }\n} catch (err) {\n  if (err.type === 'Invalid params') {\n    console.error(chalk.red('Invalid params passed!'))\n    console.error(\n      chalk.red(\n        'loadable-codemod requires 2 params to be passed, the name of the codemod, and a directory to apply the codemod to.',\n      ),\n    )\n    console.error(\n      chalk.red(\n        'Example: npx loadable-codemod react-loadable-to-loadable-component ./src/client',\n      ),\n    )\n\n    process.exit(1)\n  }\n\n  if (err.type === 'Unrecognised transform') {\n    console.error(chalk.red(`Unrecognised transform passed: '${err.payload}'`))\n\n    process.exit(2)\n  }\n\n  // For other errors, just re-throw it\n  throw err\n}\n"
  },
  {
    "path": "packages/codemod/bin/utils/CodemodError.js",
    "content": "class CodemodError extends Error {\n  constructor(args) {\n    super(args)\n    this.type = args.type\n    this.payload = args.payload\n  }\n}\n\nmodule.exports = CodemodError\n"
  },
  {
    "path": "packages/codemod/package.json",
    "content": "{\n  \"name\": \"loadable-codemod\",\n  \"description\": \"Various codemods related to @loadable/components for easier migration/upgrades.\",\n  \"version\": \"5.13.2\",\n  \"repository\": \"git@github.com:gregberge/loadable-components.git\",\n  \"author\": \"Jacky Efendi <jacky.efendi1@gmail.com>\",\n  \"bin\": {\n    \"loadable-codemod\": \"./bin/main.js\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"ssr\",\n    \"webpack\",\n    \"code-splitting\",\n    \"react-router\",\n    \"server-side-rendering\",\n    \"dynamic-import\",\n    \"react-loadable\",\n    \"react-async-components\",\n    \"codemod\"\n  ],\n  \"engines\": {\n    \"node\": \">=8\"\n  },\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"chalk\": \"^3.0.0\",\n    \"execa\": \"^4.0.0\",\n    \"jscodeshift\": \"0.7.0\",\n    \"yargs\": \"^15.1.0\"\n  }\n}\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_arrow-no-params.input.js",
    "content": "/* eslint-disable */\nimport Loadable from 'react-loadable'\n\nconst CustomLinkLoadable = Loadable({\n  loader: () =>\n    import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'),\n  loading: () => <div>loading...</div>,\n  delay: 0,\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_arrow-no-params.output.js",
    "content": "/* eslint-disable */\nimport loadable from '@loadable/component'\n\nconst CustomLinkLoadable = loadable(() =>\n  import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'), {\n  fallback: (() => <div>loading...</div>)(),\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_arrow-w-params.input.js",
    "content": "/* eslint-disable */\nimport Loadable from 'react-loadable'\n\nconst CustomLinkLoadable = Loadable({\n  loader: () =>\n    import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'),\n  loading: (props) => {\n    if (props.error || props.timedOut) {\n      throw new Error('Failed to load custom link chunk')\n    } else if (props.loading) {\n      return <div>loading...</div>;\n    }\n  },\n  delay: 0,\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_arrow-w-params.output.js",
    "content": "/* eslint-disable */\nimport loadable from '@loadable/component'\n\nconst CustomLinkLoadable = loadable(() =>\n  import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'), {\n  fallback: (props => {\n    if (props.error || props.timedOut) {\n      throw new Error('Failed to load custom link chunk')\n    } else if (props.loading) {\n      return <div>loading...</div>;\n    }\n  })({\n    pastDelay: true,\n    error: false,\n    timedOut: false,\n  }),\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_expr.input.js",
    "content": "/* eslint-disable */\nimport Loadable from 'react-loadable'\n\nconst Loading = props => {\n  if (props.error || props.timedOut) {\n    throw new Error('Failed to load custom link chunk')\n  } else {\n    return null\n  }\n}\n\nconst CustomLinkLoadable = Loadable({\n  loader: () =>\n    import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'),\n  loading: Loading,\n  delay: 0,\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__testfixtures__/react-loadable-to-loadable-component_expr.output.js",
    "content": "/* eslint-disable */\nimport loadable from '@loadable/component'\n\nconst Loading = props => {\n  if (props.error || props.timedOut) {\n    throw new Error('Failed to load custom link chunk')\n  } else {\n    return null\n  }\n}\n\nconst CustomLinkLoadable = loadable(() =>\n  import(/* webpackChunkName: \"custom-link\" */ '@components/CustomLink/Link'), {\n  fallback: Loading({\n    pastDelay: true,\n    error: false,\n    timedOut: false,\n  }),\n})\n"
  },
  {
    "path": "packages/codemod/transforms/__tests__/react-loadable-to-loadable-component-test.js",
    "content": "jest.autoMockOff()\n\nconst { defineTest } = require('jscodeshift/dist/testUtils')\n\ndefineTest(\n  __dirname,\n  'react-loadable-to-loadable-component',\n  null,\n  'react-loadable-to-loadable-component_expr',\n)\ndefineTest(\n  __dirname,\n  'react-loadable-to-loadable-component',\n  null,\n  'react-loadable-to-loadable-component_arrow-no-params',\n)\ndefineTest(\n  __dirname,\n  'react-loadable-to-loadable-component',\n  null,\n  'react-loadable-to-loadable-component_arrow-w-params',\n)\n"
  },
  {
    "path": "packages/codemod/transforms/react-loadable-to-loadable-component.js",
    "content": "/* eslint-disable no-param-reassign */\n/* eslint-disable no-console */\nconst chalk = require('chalk')\n\nconst invokeWithMockedUpProp = (jscodeshift, file, prop) => {\n  // We invoke the function previously passed as `loading` to react-loadable with this props\n  // {\n  //   pastDelay: true,\n  //   error: false,\n  //   timedOut: false,\n  // }\n  const j = jscodeshift\n\n  const defaultPropsObjProperties = []\n\n  defaultPropsObjProperties.push(\n    j.objectProperty(j.identifier('pastDelay'), j.booleanLiteral(true)),\n  )\n  defaultPropsObjProperties.push(\n    j.objectProperty(j.identifier('error'), j.booleanLiteral(false)),\n  )\n  defaultPropsObjProperties.push(\n    j.objectProperty(j.identifier('timedOut'), j.booleanLiteral(false)),\n  )\n\n  const defaultPropsObj = j.objectExpression(defaultPropsObjProperties)\n\n  const callExpr = j.callExpression(prop.value, [defaultPropsObj])\n\n  prop.value = callExpr\n\n  console.warn(\n    chalk.yellow(\n      `[WARN] '${file.path}' has some react-loadable specific logic in it. We could not codemod while keeping all the behaviors the same. Please check this file manually.`,\n    ),\n  )\n}\n\nmodule.exports = (file, api) => {\n  const { source } = file\n  const { jscodeshift: j } = api\n\n  const root = j(source)\n\n  // Rename `import Loadable from 'react-loadable';` to `import loadable from '@loadable/component';\n  root.find(j.ImportDeclaration).forEach(({ node }) => {\n    if (\n      node.specifiers[0] &&\n      node.specifiers[0].local.name === 'Loadable' &&\n      node.source.value === 'react-loadable'\n    ) {\n      node.specifiers[0].local.name = 'loadable'\n      node.source.value = '@loadable/component'\n    }\n  })\n\n  // Change Loadable({ ... }) invocation to loadable(() => {}, { ... }) invocation\n  root\n    .find(j.CallExpression, { callee: { name: 'Loadable' } })\n    .forEach(path => {\n      const { node } = path\n      const initialArgsProps = node.arguments[0].properties\n      let loader // this will be a function returning a dynamic import promise\n\n      // loop through the first argument (object) passed to `Loadable({ ... })`\n      const newProps = initialArgsProps\n        .map(prop => {\n          if (prop.key.name === 'loader') {\n            /**\n             * In react-loadable, this is the function that returns a dynamic import\n             * We'll keep it to `loader` variable for now, and remove it from the arg object\n             */\n            loader = prop.value\n\n            return undefined\n          }\n\n          if (prop.key.name === 'loading') {\n            prop.key.name = 'fallback' // rename to fallback\n\n            /**\n             * react-loadable accepts a Function that returns JSX as the `loading` arg.\n             * @loadable/component accepts a React.Element (what returned from React.createElement() calls)\n             *\n             */\n            if (prop.value.type === 'ArrowFunctionExpression') {\n              // if it's an ArrowFunctionExpression like `() => <div>loading...</div>`,\n\n              if (\n                (prop.value.params && prop.value.params.length > 0) ||\n                prop.value.type === 'Identifier'\n              ) {\n                // If the function accept props, we can invoke it and pass it a mocked-up props to get the component to\n                // a should-be-acceptable default state, while also logs out a warning.\n                // {\n                //   pastDelay: true,\n                //   error: false,\n                //   timedOut: false,\n                // }\n\n                invokeWithMockedUpProp(j, file, prop)\n              } else {\n                // If the function doesn't accept any params, we can safely just invoke it directly\n                // we can change it to `(() => <div>loading...</div>)()`\n                const callExpr = j.callExpression(prop.value, [])\n\n                prop.value = callExpr\n              }\n            } else if (prop.value.type === 'Identifier') {\n              // if it's an identifier like `Loading`, let's just invoke it with a mocked-up props\n              invokeWithMockedUpProp(j, file, prop)\n            }\n\n            return prop\n          }\n\n          // for all other props, just remove them\n          return undefined\n        })\n        .filter(Boolean)\n\n      // add the function that return a dynamic import we stored earlier as the first argument to `loadable()` call\n      node.arguments.unshift(loader)\n      node.arguments[1].properties = newProps\n      node.callee.name = 'loadable'\n    })\n\n  return root.toSource({ quote: 'single', trailingComma: true })\n}\n\nmodule.exports.parser = 'babylon'\n"
  },
  {
    "path": "packages/component/.npmignore",
    "content": "src/\n.*\nrollup.config.js"
  },
  {
    "path": "packages/component/.size-snapshot.json",
    "content": "{\n  \"dist/cjs/loadable.cjs.js\": {\n    \"bundled\": 16900,\n    \"minified\": 7226,\n    \"gzipped\": 2545\n  },\n  \"dist/esm/loadable.esm.mjs\": {\n    \"bundled\": 16517,\n    \"minified\": 6917,\n    \"gzipped\": 2490,\n    \"treeshaked\": {\n      \"rollup\": {\n        \"code\": 259,\n        \"import_statements\": 259\n      },\n      \"webpack\": {\n        \"code\": 5764\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/component/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.16.7](https://github.com/gregberge/loadable-components/compare/v5.16.6...v5.16.7) (2025-05-18)\n\n**Note:** Version bump only for package @loadable/component\n\n\n\n\n\n## [5.16.6](https://github.com/gregberge/loadable-components/compare/v5.16.5...v5.16.6) (2025-05-18)\n\n**Note:** Version bump only for package @loadable/component\n\n\n\n\n\n## [5.16.4](https://github.com/gregberge/loadable-components/compare/v5.16.3...v5.16.4) (2024-04-20)\n\n\n### Bug Fixes\n\n* correct esm configuration for loadable/server, fixes: [#999](https://github.com/gregberge/loadable-components/issues/999) ([#1004](https://github.com/gregberge/loadable-components/issues/1004)) ([114cea2](https://github.com/gregberge/loadable-components/commit/114cea2b61ef644d3b794a9b5f48df69f0f5400b))\n\n\n\n\n\n## [5.16.3](https://github.com/gregberge/loadable-components/compare/v5.16.2...v5.16.3) (2023-12-26)\n\n\n### Bug Fixes\n\n* correct react-is for mjs export; remove isValidComponent check ([#991](https://github.com/gregberge/loadable-components/issues/991)) ([9d381c3](https://github.com/gregberge/loadable-components/commit/9d381c35b7fc1f8f9122caac25e8e255871ebab6))\n\n\n\n\n\n## [5.16.2](https://github.com/gregberge/loadable-components/compare/v5.16.1...v5.16.2) (2023-12-15)\n\n\n### Bug Fixes\n\n* add esm exports to package.json and change esm bundle extension to .mjs to allow node.js to properly import esm version of package. ([#989](https://github.com/gregberge/loadable-components/issues/989)) ([e4a3718](https://github.com/gregberge/loadable-components/commit/e4a37188b804e6a5bc66f39c23c738006bc0e284))\n\n\n\n\n\n## [5.15.3](https://github.com/gregberge/loadable-components/compare/v5.15.2...v5.15.3) (2023-01-28)\n\n\n### Bug Fixes\n\n* add React 17 and 18 to package dependencies, fixes [#718](https://github.com/gregberge/loadable-components/issues/718) ([66edc37](https://github.com/gregberge/loadable-components/commit/66edc37a731a8ec655deffd3ad454fd96e909ba3))\n\n\n\n\n\n## [5.15.2](https://github.com/gregberge/loadable-components/compare/v5.15.1...v5.15.2) (2021-12-12)\n\n\n### Bug Fixes\n\n* loadAsync Loadable should copy statics ([#839](https://github.com/gregberge/loadable-components/issues/839)) ([9ff6693](https://github.com/gregberge/loadable-components/commit/9ff66939ee6fd622922f71128a30b5d3f43f63b0))\n* use stable promises for load/preload/React ([#858](https://github.com/gregberge/loadable-components/issues/858)) ([45f2d91](https://github.com/gregberge/loadable-components/commit/45f2d9133c8234fec9cbe36e5a162a61f24e4aae))\n\n\n\n\n\n# [5.15.0](https://github.com/gregberge/loadable-components/compare/v5.14.2...v5.15.0) (2021-05-08)\n\n\n### Bug Fixes\n\n* add displayNames to generated components ([#731](https://github.com/gregberge/loadable-components/issues/731)) ([b640c82](https://github.com/gregberge/loadable-components/commit/b640c82a742ffbccc423439e2e205d1becdf5491))\n\n\n### Features\n\n* support multiple Webpack runtimes ([#701](https://github.com/gregberge/loadable-components/issues/701)) ([d351367](https://github.com/gregberge/loadable-components/commit/d3513679ed680e46967ca18555116c06e5a4b341))\n\n\n\n\n\n## [5.14.1](https://github.com/gregberge/loadable-components/compare/v5.14.0...v5.14.1) (2020-10-22)\n\n**Note:** Version bump only for package @loadable/component\n\n\n\n\n\n# [5.14.0](https://github.com/gregberge/loadable-components/compare/v5.13.2...v5.14.0) (2020-10-20)\n\n\n### Bug Fixes\n\n* do not derive cache key if component is static, fixes [#629](https://github.com/gregberge/loadable-components/issues/629) ([#630](https://github.com/gregberge/loadable-components/issues/630)) ([b4151d8](https://github.com/gregberge/loadable-components/commit/b4151d85b3ba0f57e9fab48ec88f5e57e4d0b544))\n\n\n### Features\n\n* make packages webpack 5 compatible ([#638](https://github.com/gregberge/loadable-components/issues/638)) ([e882e4d](https://github.com/gregberge/loadable-components/commit/e882e4d812e714066eba19a11dd119193e7a9e01))\n\n\n\n\n\n## [5.13.2](https://github.com/gregberge/loadable-components/compare/v5.13.1...v5.13.2) (2020-09-14)\n\n\n### Bug Fixes\n\n* Fixed lazy usage with Suspense and Error Boundary together ([#521](https://github.com/gregberge/loadable-components/issues/521)) ([42fbdd0](https://github.com/gregberge/loadable-components/commit/42fbdd0d552551b18ed0781383bb0073e1cd8640))\n\n\n\n\n\n## [5.13.1](https://github.com/gregberge/loadable-components/compare/v5.13.0...v5.13.1) (2020-07-02)\n\n\n### Bug Fixes\n\n* expose used chunkNames from a server. Fixes [#587](https://github.com/gregberge/loadable-components/issues/587) ([831aec0](https://github.com/gregberge/loadable-components/commit/831aec03154ab16007db0d78fbf3559583c000fe))\n\n\n\n\n\n# [5.13.0](https://github.com/gregberge/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n\n### Bug Fixes\n\n* allow webpack cache is ready only for initial chunks, fixes [#558](https://github.com/gregberge/loadable-components/issues/558) ([61f8b75](https://github.com/gregberge/loadable-components/commit/61f8b75b54612368c88807d73abb7dc7add720ad))\n\n\n### Features\n\n* add `resolveComponent` option ([a47d3d9](https://github.com/gregberge/loadable-components/commit/a47d3d9021ee6b12c1209bf41069dc133cb1fa7c))\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Bug Fixes\n\n* apply loadable transformations before any other, fixes [#466](https://github.com/gregberge/loadable-components/issues/466) ([ac5ba45](https://github.com/gregberge/loadable-components/commit/ac5ba45862bad68b971a969e6e8713874add51a6))\n\n\n### Features\n\n* avoid synchronous loading on client if options.ssr is false ([#346](https://github.com/gregberge/loadable-components/issues/346)) ([338bf55](https://github.com/gregberge/loadable-components/commit/338bf555adc68986b12c8dd4e304875425119ca2))\n\n\n\n\n\n# [5.11.0](https://github.com/smooth-code/loadable-components/compare/v5.10.3...v5.11.0) (2019-12-02)\n\n\n### Bug Fixes\n\n* fix isReady problem ([#445](https://github.com/smooth-code/loadable-components/issues/445)) ([3024348](https://github.com/smooth-code/loadable-components/commit/30243482be917e89515d057e2368e7278e34696c)), closes [#400](https://github.com/smooth-code/loadable-components/issues/400)\n\n\n\n\n\n## [5.10.3](https://github.com/smooth-code/loadable-components/compare/v5.10.2...v5.10.3) (2019-09-24)\n\n\n### Bug Fixes\n\n* support IE 11 without polyfill ([#416](https://github.com/smooth-code/loadable-components/issues/416)) ([80ee809](https://github.com/smooth-code/loadable-components/commit/80ee809)), closes [#397](https://github.com/smooth-code/loadable-components/issues/397)\n\n\n\n\n\n## [5.10.2](https://github.com/smooth-code/loadable-components/compare/v5.10.1...v5.10.2) (2019-07-15)\n\n\n### Bug Fixes\n\n* use === instead of Object.is ([c88cd82](https://github.com/smooth-code/loadable-components/commit/c88cd82)), closes [#371](https://github.com/smooth-code/loadable-components/issues/371)\n\n\n\n\n\n## [5.10.1](https://github.com/smooth-code/loadable-components/compare/v5.10.0...v5.10.1) (2019-05-14)\n\n\n### Bug Fixes\n\n* add @babel/preset-env in rollup config ([#336](https://github.com/smooth-code/loadable-components/issues/336)) ([8b50c94](https://github.com/smooth-code/loadable-components/commit/8b50c94)), closes [#335](https://github.com/smooth-code/loadable-components/issues/335)\n\n\n\n\n\n# [5.10.0](https://github.com/smooth-code/loadable-components/compare/v5.9.0...v5.10.0) (2019-05-13)\n\n\n### Features\n\n* add `load` method that returns a Promise ([#329](https://github.com/smooth-code/loadable-components/issues/329)) ([a10a9d5](https://github.com/smooth-code/loadable-components/commit/a10a9d5)), closes [#226](https://github.com/smooth-code/loadable-components/issues/226)\n* support reactive dynamic loadable ([#330](https://github.com/smooth-code/loadable-components/issues/330)) ([d65c5bb](https://github.com/smooth-code/loadable-components/commit/d65c5bb)), closes [#284](https://github.com/smooth-code/loadable-components/issues/284)\n\n\n### Performance Improvements\n\n* optimize rollup config ([c94760b](https://github.com/smooth-code/loadable-components/commit/c94760b))\n\n\n\n\n\n# [5.9.0](https://github.com/smooth-code/loadable-components/compare/v5.8.0...v5.9.0) (2019-04-23)\n\n\n### Features\n\n* support multiple react apps ([#317](https://github.com/smooth-code/loadable-components/issues/317)) ([dc54050](https://github.com/smooth-code/loadable-components/commit/dc54050)), closes [#311](https://github.com/smooth-code/loadable-components/issues/311)\n\n\n\n\n\n# [5.7.0](https://github.com/smooth-code/loadable-components/compare/v5.6.1...v5.7.0) (2019-03-14)\n\n\n### Bug Fixes\n\n* **component:** fix warning message about babel ([#255](https://github.com/smooth-code/loadable-components/issues/255)) ([7cb68a1](https://github.com/smooth-code/loadable-components/commit/7cb68a1)), closes [#253](https://github.com/smooth-code/loadable-components/issues/253)\n\n\n### Features\n\n* use inline JSON to enabling CSP without `unsafe-inline` ([05e5500](https://github.com/smooth-code/loadable-components/commit/05e5500))\n\n\n\n\n\n## [5.6.1](https://github.com/smooth-code/loadable-components/compare/v5.6.0...v5.6.1) (2019-02-25)\n\n\n### Bug Fixes\n\n* **component:** better ES Modules handling ([#228](https://github.com/smooth-code/loadable-components/issues/228)) ([3628363](https://github.com/smooth-code/loadable-components/commit/3628363))\n* **suspense:** fix suspense mode in React v16.8+ ([#251](https://github.com/smooth-code/loadable-components/issues/251)) ([d04e1c9](https://github.com/smooth-code/loadable-components/commit/d04e1c9))\n\n\n\n\n\n# [5.6.0](https://github.com/smooth-code/loadable-components/compare/v5.5.0...v5.6.0) (2019-02-05)\n\n\n### Features\n\n* **component:** add preload method ([#224](https://github.com/smooth-code/loadable-components/issues/224)) ([4a67ace](https://github.com/smooth-code/loadable-components/commit/4a67ace)), closes [#196](https://github.com/smooth-code/loadable-components/issues/196)\n* **server:** add option to disable SSR ([#223](https://github.com/smooth-code/loadable-components/issues/223)) ([4cab4f9](https://github.com/smooth-code/loadable-components/commit/4cab4f9)), closes [#195](https://github.com/smooth-code/loadable-components/issues/195)\n\n\n\n\n\n# [5.5.0](https://github.com/smooth-code/loadable-components/compare/v5.4.0...v5.5.0) (2019-01-22)\n\n**Note:** Version bump only for package @loadable/component\n\n\n\n\n\n## [5.2.2](https://github.com/smooth-code/loadable-components/compare/v5.2.1...v5.2.2) (2018-12-12)\n\n\n### Bug Fixes\n\n* ensure that component is mounted before calling `setState` ([#184](https://github.com/smooth-code/loadable-components/issues/184)) ([fe0f47f](https://github.com/smooth-code/loadable-components/commit/fe0f47f)), closes [#180](https://github.com/smooth-code/loadable-components/issues/180)\n\n\n\n\n\n## [5.2.1](https://github.com/smooth-code/loadable-components/compare/v5.2.0...v5.2.1) (2018-11-27)\n\n\n### Bug Fixes\n\n* upgrade hoist-non-react-statics@3.2.0 ([122b1ce](https://github.com/smooth-code/loadable-components/commit/122b1ce))\n\n\n\n\n\n## [5.1.2](https://github.com/smooth-code/loadable-components/compare/v5.1.1...v5.1.2) (2018-11-13)\n\n\n### Bug Fixes\n\n* fix ref handler in `loadable.lib` ([da05d87](https://github.com/smooth-code/loadable-components/commit/da05d87))\n\n\n\n\n\n# [5.0.0](https://github.com/smooth-code/loadable-components/compare/v4.0.5...v5.0.0) (2018-11-10)\n\n\n### Bug Fixes\n\n* fix loadableReady ([59693bb](https://github.com/smooth-code/loadable-components/commit/59693bb))\n\n\n### Features\n\n* improve SSR support ([eb1cfe8](https://github.com/smooth-code/loadable-components/commit/eb1cfe8))\n\n\n### BREAKING CHANGES\n\n* - SSR has been rewritten from scratch, if you use it, please follow the\nnew guide.\n- Prefetch component and prefetch functions have been removed, please\nuse `webpackPrefetch` instead.\n\n\n\n\n\n## [4.0.2](https://github.com/smooth-code/loadable-components/compare/v4.0.1...v4.0.2) (2018-10-31)\n\n\n### Bug Fixes\n\n* **component:** fix lazy usage ([d711ee0](https://github.com/smooth-code/loadable-components/commit/d711ee0))\n\n\n\n\n\n## [4.0.1](https://github.com/smooth-code/loadable-components/compare/v4.0.0...v4.0.1) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** do not call ref several times ([8cf3190](https://github.com/smooth-code/loadable-components/commit/8cf3190))\n\n\n\n\n\n# [4.0.0](https://github.com/smooth-code/loadable-components/compare/v3.0.2...v4.0.0) (2018-10-30)\n\n\n### Features\n\n* add new loadable.lib, change API ([94b2e87](https://github.com/smooth-code/loadable-components/commit/94b2e87))\n\n\n### BREAKING CHANGES\n\n* - `ErrorComponent` is ignored, please use Error Boundaries to handle errors.\n- `lazy` is no longer exported\n- `LoadingComponent` is replaced by `fallback` option\n- `ref` are now forwarded\n\n\n\n\n\n## [3.0.2](https://github.com/smooth-code/loadable-components/compare/v3.0.1...v3.0.2) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** fix loadComponent (typo) ([a410cb2](https://github.com/smooth-code/loadable-components/commit/a410cb2))\n\n\n\n\n\n## [3.0.1](https://github.com/smooth-code/loadable-components/compare/v3.0.0...v3.0.1) (2018-10-30)\n\n\n### Bug Fixes\n\n* **component:** fix loadComponents ([bd2220c](https://github.com/smooth-code/loadable-components/commit/bd2220c))\n\n\n\n\n\n# [3.0.0](https://github.com/smooth-code/loadable-components/compare/v2.2.3...v3.0.0) (2018-10-29)\n\n\n### Features\n\n* welcome loadable ([4dffad7](https://github.com/smooth-code/loadable-components/commit/4dffad7))\n\n\n### BREAKING CHANGES\n\n* API has completely changed, see documentation.\n"
  },
  {
    "path": "packages/component/README.md",
    "content": "# @loadable/component\n\nEnable Code Splitting in your React application.\n\n## Install\n\n```\b\nnpm install @loadable/component\n```\n\n## Documentation\n\n👉 [See full documentation](https://loadable-components.com/)\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/component/package.json",
    "content": "{\n  \"name\": \"@loadable/component\",\n  \"description\": \"React code splitting made easy.\",\n  \"version\": \"5.16.7\",\n  \"main\": \"./dist/cjs/loadable.cjs.js\",\n  \"module\": \"./dist/esm/loadable.esm.mjs\",\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/cjs/loadable.cjs.js\",\n      \"import\": \"./dist/esm/loadable.esm.mjs\",\n      \"default\": \"./dist/cjs/loadable.cjs.js\"\n    }\n  },\n  \"repository\": \"git@github.com:gregberge/loadable-components.git\",\n  \"author\": \"Greg Bergé <berge.greg@gmail.com>\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"keywords\": [\n    \"react\",\n    \"ssr\",\n    \"webpack\",\n    \"code-splitting\",\n    \"react-router\",\n    \"server-side-rendering\",\n    \"dynamic-import\",\n    \"react-loadable\",\n    \"react-async-components\"\n  ],\n  \"engines\": {\n    \"node\": \">=8\"\n  },\n  \"funding\": {\n    \"type\": \"github\",\n    \"url\": \"https://github.com/sponsors/gregberge\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"prebuild\": \"shx rm -rf dist\",\n    \"build\": \"cross-env rollup -c && yarn create-cjs-package-json\",\n    \"create-cjs-package-json\": \"echo '{\\\"type\\\": \\\"commonjs\\\"}' > ./dist/cjs/package.json\",\n    \"prepublishOnly\": \"yarn run build\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.12.18\",\n    \"hoist-non-react-statics\": \"^3.3.1\",\n    \"react-is\": \"^16.12.0\"\n  }\n}\n"
  },
  {
    "path": "packages/component/rollup.config.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\nimport nodeResolve from 'rollup-plugin-node-resolve'\nimport babel from 'rollup-plugin-babel'\nimport replace from 'rollup-plugin-replace'\nimport commonjs from 'rollup-plugin-commonjs'\nimport { terser } from 'rollup-plugin-terser'\nimport pkg from './package.json'\n\nconst input = 'src/index.js'\nconst name = 'loadable'\nconst globals = {\n  react: 'React',\n  'hoist-non-react-statics': 'hoistNonReactStatics',\n}\n\nconst external = id => !id.startsWith('.') && !id.startsWith('/')\n\nconst getBabelOptions = ({ useESModules }) => ({\n  exclude: '**/node_modules/**',\n  runtimeHelpers: true,\n  presets: [\n    ['@babel/preset-env', { loose: true }],\n    ['@babel/preset-react', { useBuiltIns: true }],\n  ],\n  plugins: [\n    '@babel/plugin-proposal-class-properties',\n    'babel-plugin-annotate-pure-calls',\n    ['@babel/plugin-transform-runtime', { useESModules }],\n  ],\n})\n\nexport default [\n  // umd\n  {\n    input,\n    output: {\n      file: `dist/loadable.js`,\n      format: 'umd',\n      name,\n      globals,\n      exports: 'named',\n      sourcemap: false,\n    },\n    external: Object.keys(globals),\n    plugins: [\n      babel(getBabelOptions({ useESModules: true })),\n      nodeResolve(),\n      commonjs(),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),\n    ],\n  },\n  // min\n  {\n    input,\n    output: {\n      file: 'dist/loadable.min.js',\n      format: 'umd',\n      name,\n      globals,\n      exports: 'named',\n      sourcemap: false,\n    },\n    external: Object.keys(globals),\n    plugins: [\n      babel(getBabelOptions({ useESModules: true })),\n      nodeResolve(),\n      commonjs(),\n      replace({ 'process.env.NODE_ENV': JSON.stringify('production') }),\n      terser(),\n    ],\n  },\n  // cjs\n  {\n    input,\n    output: { file: pkg.main, format: 'cjs', exports: 'named' },\n    external,\n    plugins: [babel(getBabelOptions({ useESModules: false }))],\n  },\n  // esm\n  {\n    input,\n    output: { file: pkg.module, format: 'esm' },\n    external,\n    plugins: [babel(getBabelOptions({ useESModules: true }))],\n  },\n]\n"
  },
  {
    "path": "packages/component/src/Context.js",
    "content": "import React from 'react'\n\nexport default React.createContext()\n"
  },
  {
    "path": "packages/component/src/createLoadable.js",
    "content": "/* eslint-disable no-use-before-define, react/no-multi-comp, no-underscore-dangle */\nimport React from 'react'\nimport hoistNonReactStatics from 'hoist-non-react-statics'\nimport { invariant } from './util'\nimport Context from './Context'\nimport { LOADABLE_SHARED } from './shared'\n\nconst STATUS_PENDING = 'PENDING'\nconst STATUS_RESOLVED = 'RESOLVED'\nconst STATUS_REJECTED = 'REJECTED'\n\nfunction resolveConstructor(ctor) {\n  if (typeof ctor === 'function') {\n    return {\n      requireAsync: ctor,\n      resolve() {\n        return undefined\n      },\n      chunkName() {\n        return undefined\n      },\n    }\n  }\n\n  return ctor\n}\n\nconst withChunkExtractor = Component => {\n  const LoadableWithChunkExtractor = props => (\n    <Context.Consumer>\n      {extractor => <Component __chunkExtractor={extractor} {...props} />}\n    </Context.Consumer>\n  )\n  if (Component.displayName) {\n    LoadableWithChunkExtractor.displayName = `${Component.displayName}WithChunkExtractor`\n  }\n  return LoadableWithChunkExtractor\n}\n\nconst identity = v => v\n\nfunction createLoadable({\n  defaultResolveComponent = identity,\n  render,\n  onLoad,\n}) {\n  function loadable(loadableConstructor, options = {}) {\n    const ctor = resolveConstructor(loadableConstructor)\n    const cache = {}\n\n    /**\n     * Cachekey represents the component to be loaded\n     * if key changes - component has to be reloaded\n     * @param props\n     * @returns {null|Component}\n     */\n    function getCacheKey(props) {\n      if (options.cacheKey) {\n        return options.cacheKey(props)\n      }\n      if (ctor.resolve) {\n        return ctor.resolve(props)\n      }\n      return 'static'\n    }\n\n    /**\n     * Resolves loaded `module` to a specific `Component\n     * @param module\n     * @param props\n     * @param Loadable\n     * @returns Component\n     */\n    function resolve(module, props, Loadable) {\n      const Component = options.resolveComponent\n        ? options.resolveComponent(module, props)\n        : defaultResolveComponent(module)\n\n      // FIXME: suppressed due to https://github.com/gregberge/loadable-components/issues/990\n      // if (options.resolveComponent && !ReactIs.isValidElementType(Component)) {\n      //   throw new Error(\n      //     `resolveComponent returned something that is not a React component!`,\n      //   )\n      // }\n      hoistNonReactStatics(Loadable, Component, {\n        preload: true,\n      })\n      return Component\n    }\n\n    const cachedLoad = props => {\n      const cacheKey = getCacheKey(props)\n      let promise = cache[cacheKey]\n\n      if (!promise || promise.status === STATUS_REJECTED) {\n        promise = ctor.requireAsync(props)\n        promise.status = STATUS_PENDING\n\n        cache[cacheKey] = promise\n\n        promise.then(\n          () => {\n            promise.status = STATUS_RESOLVED\n          },\n          error => {\n            console.error(\n              'loadable-components: failed to asynchronously load component',\n              {\n                fileName: ctor.resolve(props),\n                chunkName: ctor.chunkName(props),\n                error: error ? error.message : error,\n              },\n            )\n            promise.status = STATUS_REJECTED\n          },\n        )\n      }\n\n      return promise\n    }\n\n    class InnerLoadable extends React.Component {\n      static getDerivedStateFromProps(props, state) {\n        const cacheKey = getCacheKey(props)\n        return {\n          ...state,\n          cacheKey,\n          // change of a key triggers loading state automatically\n          loading: state.loading || state.cacheKey !== cacheKey,\n        }\n      }\n\n      constructor(props) {\n        super(props)\n\n        this.state = {\n          result: null,\n          error: null,\n          loading: true,\n          cacheKey: getCacheKey(props),\n        }\n\n        invariant(\n          !props.__chunkExtractor || ctor.requireSync,\n          'SSR requires `@loadable/babel-plugin`, please install it',\n        )\n\n        // Server-side\n        if (props.__chunkExtractor) {\n          // This module has been marked with no SSR\n          if (options.ssr === false) {\n            return\n          }\n\n          // We run load function, we assume that it won't fail and that it\n          // triggers a synchronous loading of the module\n          ctor.requireAsync(props).catch(() => null)\n\n          // So we can require now the module synchronously\n          this.loadSync()\n\n          props.__chunkExtractor.addChunk(ctor.chunkName(props))\n          return\n        }\n\n        // Client-side with `isReady` method present (SSR probably)\n        // If module is already loaded, we use a synchronous loading\n        // Only perform this synchronous loading if the component has not\n        // been marked with no SSR, else we risk hydration mismatches\n        if (\n          options.ssr !== false &&\n          // is ready - was loaded in this session\n          ((ctor.isReady && ctor.isReady(props)) ||\n            // is ready - was loaded during SSR process\n            (ctor.chunkName &&\n              LOADABLE_SHARED.initialChunks[ctor.chunkName(props)]))\n        ) {\n          this.loadSync()\n        }\n      }\n\n      componentDidMount() {\n        this.mounted = true\n\n        // retrieve loading promise from a global cache\n        const cachedPromise = this.getCache()\n\n        // if promise exists, but rejected - clear cache\n        if (cachedPromise && cachedPromise.status === STATUS_REJECTED) {\n          this.setCache()\n        }\n\n        // component might be resolved synchronously in the constructor\n        if (this.state.loading) {\n          this.loadAsync()\n        }\n      }\n\n      componentDidUpdate(prevProps, prevState) {\n        // Component has to be reloaded on cacheKey change\n        if (prevState.cacheKey !== this.state.cacheKey) {\n          this.loadAsync()\n        }\n      }\n\n      componentWillUnmount() {\n        this.mounted = false\n      }\n\n      safeSetState(nextState, callback) {\n        if (this.mounted) {\n          this.setState(nextState, callback)\n        }\n      }\n\n      /**\n       * returns a cache key for the current props\n       * @returns {Component|string}\n       */\n      getCacheKey() {\n        return getCacheKey(this.props)\n      }\n\n      /**\n       * access the persistent cache\n       */\n      getCache() {\n        return cache[this.getCacheKey()]\n      }\n\n      /**\n       * sets the cache value. If called without value sets it as undefined\n       */\n      setCache(value = undefined) {\n        cache[this.getCacheKey()] = value\n      }\n\n      triggerOnLoad() {\n        if (onLoad) {\n          setTimeout(() => {\n            onLoad(this.state.result, this.props)\n          })\n        }\n      }\n\n      /**\n       * Synchronously loads component\n       * target module is expected to already exists in the module cache\n       * or be capable to resolve synchronously (webpack target=node)\n       */\n      loadSync() {\n        // load sync is expecting component to be in the \"loading\" state already\n        // sounds weird, but loading=true is the initial state of InnerLoadable\n        if (!this.state.loading) return\n\n        try {\n          const loadedModule = ctor.requireSync(this.props)\n          const result = resolve(loadedModule, this.props, Loadable)\n          this.state.result = result\n          this.state.loading = false\n        } catch (error) {\n          console.error(\n            'loadable-components: failed to synchronously load component, which expected to be available',\n            {\n              fileName: ctor.resolve(this.props),\n              chunkName: ctor.chunkName(this.props),\n              error: error ? error.message : error,\n            },\n          )\n          this.state.error = error\n        }\n      }\n\n      /**\n       * Asynchronously loads a component.\n       */\n      loadAsync() {\n        const promise = this.resolveAsync()\n\n        promise\n          .then(loadedModule => {\n            const result = resolve(loadedModule, this.props, Loadable)\n            this.safeSetState(\n              {\n                result,\n                loading: false,\n              },\n              () => this.triggerOnLoad(),\n            )\n          })\n          .catch(error => this.safeSetState({ error, loading: false }))\n\n        return promise\n      }\n\n      /**\n       * Asynchronously resolves(not loads) a component.\n       * Note - this function does not change the state\n       */\n      resolveAsync() {\n        const { __chunkExtractor, forwardedRef, ...props } = this.props\n\n        return cachedLoad(props)\n      }\n\n      render() {\n        const {\n          forwardedRef,\n          fallback: propFallback,\n          __chunkExtractor,\n          ...props\n        } = this.props\n        const { error, loading, result } = this.state\n\n        if (options.suspense) {\n          const cachedPromise = this.getCache() || this.loadAsync()\n          if (cachedPromise.status === STATUS_PENDING) {\n            throw this.loadAsync()\n          }\n        }\n\n        if (error) {\n          throw error\n        }\n\n        const fallback = propFallback || options.fallback || null\n\n        if (loading) {\n          return fallback\n        }\n\n        return render({\n          fallback,\n          result,\n          options,\n          props: { ...props, ref: forwardedRef },\n        })\n      }\n    }\n\n    const EnhancedInnerLoadable = withChunkExtractor(InnerLoadable)\n    const Loadable = React.forwardRef((props, ref) => (\n      <EnhancedInnerLoadable forwardedRef={ref} {...props} />\n    ))\n\n    Loadable.displayName = 'Loadable'\n\n    // In future, preload could use `<link rel=\"preload\">`\n    Loadable.preload = props => {\n      Loadable.load(props)\n    }\n\n    Loadable.load = props => {\n      return cachedLoad(props)\n    }\n\n    return Loadable\n  }\n\n  function lazy(ctor, options) {\n    return loadable(ctor, { ...options, suspense: true })\n  }\n\n  return { loadable, lazy }\n}\n\nexport default createLoadable\n"
  },
  {
    "path": "packages/component/src/index.js",
    "content": "/* eslint-disable no-underscore-dangle */\nimport * as sharedInternals from './sharedInternals'\nimport * as loadableExports from './loadable'\nimport * as libraryExports from './library'\n\nconst { loadable } = loadableExports\nloadable.lib = libraryExports.loadable\n\nconst { lazy } = loadableExports\nlazy.lib = libraryExports.lazy\n\nexport default loadable\nexport { lazy }\n\nexport { default as loadableReady } from './loadableReady'\nexport const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = sharedInternals\n"
  },
  {
    "path": "packages/component/src/library.js",
    "content": "/* eslint-disable no-use-before-define, react/no-multi-comp */\nimport createLoadable from './createLoadable'\n\nexport const { loadable, lazy } = createLoadable({\n  onLoad(result, props) {\n    if (result && props.forwardedRef) {\n      if (typeof props.forwardedRef === 'function') {\n        props.forwardedRef(result)\n      } else {\n        props.forwardedRef.current = result\n      }\n    }\n  },\n  render({ result, props }) {\n    if (props.children) {\n      return props.children(result)\n    }\n\n    return null\n  },\n})\n"
  },
  {
    "path": "packages/component/src/loadable.js",
    "content": "/* eslint-disable no-use-before-define, react/no-multi-comp */\nimport React from 'react'\nimport createLoadable from './createLoadable'\nimport { defaultResolveComponent } from './resolvers'\n\nexport const { loadable, lazy } = createLoadable({\n  defaultResolveComponent,\n  render({ result: Component, props }) {\n    return <Component {...props} />\n  },\n})\n"
  },
  {
    "path": "packages/component/src/loadable.test.js",
    "content": "/* eslint-disable max-classes-per-file */\n/* eslint-disable import/no-extraneous-dependencies, react/no-multi-comp */\nimport 'regenerator-runtime/runtime'\nimport '@testing-library/jest-dom/extend-expect'\nimport React from 'react'\nimport { render, cleanup, wait } from '@testing-library/react'\nimport loadable, { lazy } from './index'\n\nafterEach(cleanup)\n\nconst unresolvableLoad = jest.fn(() => new Promise(() => {}))\n\nconst resolvedToDefault = value =>\n  jest.fn().mockResolvedValue({ default: value })\n\nfunction mockDelayedResolvedValueOnce(fn, resolvedValue) {\n  return fn.mockImplementationOnce(\n    () =>\n      new Promise(resolve => {\n        setTimeout(() => resolve(resolvedValue), 1000)\n      }),\n  )\n}\n\nclass Catch extends React.Component {\n  state = { error: false }\n\n  static getDerivedStateFromError() {\n    return { error: true }\n  }\n\n  render() {\n    return this.state.error ? 'error' : this.props.children\n  }\n}\n\nclass ErrorBoundary extends React.Component {\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      error: false,\n      retries: props.retries || 0,\n    }\n  }\n\n  componentDidCatch() {\n    this.setState(prevState => ({\n      error: true,\n      retries: prevState.retries - 1,\n    }))\n  }\n\n  render() {\n    const { children, fallback } = this.props\n    const { error, retries } = this.state\n\n    if (error) {\n      return (retries >= 0 && children) || fallback || null\n    }\n\n    return children || null\n  }\n}\n\ndescribe('#loadable', () => {\n  beforeEach(() => {\n    jest.spyOn(console, 'error').mockImplementation(() => {})\n  })\n\n  afterEach(() => {\n    jest.restoreAllMocks();\n  })\n\n  it('renders nothing without a fallback', () => {\n    const Component = loadable(unresolvableLoad)\n    const { container } = render(<Component />)\n    expect(container).toBeEmpty()\n  })\n\n  it('uses option fallback if specified', () => {\n    const Component = loadable(unresolvableLoad, { fallback: 'progress' })\n    const { container } = render(<Component />)\n    expect(container).toHaveTextContent('progress')\n  })\n\n  it('uses props fallback if specified', () => {\n    const Component = loadable(unresolvableLoad)\n    const { container } = render(<Component fallback=\"progress\" />)\n    expect(container).toHaveTextContent('progress')\n  })\n\n  it('should use props fallback instead of option fallback if specified', () => {\n    const Component = loadable(unresolvableLoad, { fallback: 'opt fallback' })\n    const { container } = render(<Component fallback=\"prop fallback\" />)\n    expect(container).toHaveTextContent('prop fallback')\n  })\n\n  it('mounts component when loaded', async () => {\n    const load = resolvedToDefault(() => 'loaded')\n    const Component = loadable(load)\n    const { container } = render(<Component />)\n    expect(container).toBeEmpty()\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n  })\n\n  it('supports preload', async () => {\n    const load = resolvedToDefault(() => 'loaded')\n    const Component = loadable(load)\n    expect(load).not.toHaveBeenCalled()\n    Component.preload({ foo: 'bar' })\n    expect(load).toHaveBeenCalledWith({ foo: 'bar' })\n    expect(load).toHaveBeenCalledTimes(1)\n    const { container } = render(<Component />)\n    expect(container).toBeEmpty()\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n    expect(load).toHaveBeenCalledTimes(1)\n  })\n\n  it('supports commonjs default export', async () => {\n    const load = resolvedToDefault(() => 'loaded')\n    const Component = loadable(load)\n    const { container } = render(<Component />)\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n  })\n\n  it('supports non-default export via resolveComponent', async () => {\n    const importedModule = { exported: () => 'loaded' }\n    const load = jest.fn().mockResolvedValue(importedModule)\n    const resolveComponent = jest.fn(({ exported: component }) => component)\n    const Component = loadable(load, {\n      resolveComponent,\n    })\n    const { container } = render(<Component someProp=\"123\" />)\n\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n    expect(resolveComponent).toHaveBeenCalledWith(importedModule, {\n      someProp: '123',\n      __chunkExtractor: undefined,\n      forwardedRef: null,\n    })\n  })\n\n  it('forwards props', async () => {\n    const load = resolvedToDefault(({ name }) => name)\n    const Component = loadable(load)\n    const { container } = render(<Component name=\"James Bond\" />)\n    await wait(() => expect(container).toHaveTextContent('James Bond'))\n  })\n\n  it('should update component if props change', async () => {\n    const load = resolvedToDefault(({ value }) => value)\n    const Component = loadable(load)\n    const { container } = render(<Component value=\"first\" />)\n    await wait(() => expect(container).toHaveTextContent('first'))\n    render(<Component value=\"second\" />, { container })\n    await wait(() => expect(container).toHaveTextContent('second'))\n    expect(load).toHaveBeenCalledTimes(1)\n  })\n\n  it('calls load func if cacheKey change', async () => {\n    const load = resolvedToDefault(({ value }) => value)\n    const Component = loadable(load, { cacheKey: ({ value }) => value })\n    const { container } = render(<Component value=\"first\" />)\n    await wait(() => expect(container).toHaveTextContent('first'))\n    expect(load).toHaveBeenCalledTimes(1)\n    render(<Component value=\"second\" />, { container })\n    await wait(() => expect(container).toHaveTextContent('second'))\n    expect(load).toHaveBeenCalledTimes(2)\n  })\n\n  it('calls load func if resolve change', async () => {\n    const load = resolvedToDefault(({ value }) => value)\n    const Component = loadable({\n      requireAsync: load,\n      resolve: ({ value }) => value,\n    })\n    const { container } = render(<Component value=\"first\" />)\n    await wait(() => expect(container).toHaveTextContent('first'))\n    expect(load).toHaveBeenCalledTimes(1)\n    render(<Component value=\"second\" />, { container })\n    await wait(() => expect(container).toHaveTextContent('second'))\n    expect(load).toHaveBeenCalledTimes(2)\n  })\n\n  it('does not call previous component if cacheKey change', async () => {\n    const A = jest.fn(({ id }) => `A-${id}`)\n    const B = jest.fn(({ id }) => `B-${id}`)\n    const components = { A, B }\n    const load = jest.fn(async ({ name }) => {\n      const Component = components[name]\n      return { default: Component }\n    })\n    const Component = loadable(load, { cacheKey: ({ name }) => name })\n    const { container } = render(<Component name=\"A\" id={0} />)\n    await wait(() => expect(container).toHaveTextContent('A-0'))\n    expect(load).toHaveBeenCalledTimes(1)\n    expect(load).toHaveBeenCalledWith({ name: 'A', id: 0 })\n    expect(A).toHaveBeenCalledTimes(1)\n    expect(A).toHaveBeenCalledWith({ name: 'A', id: 0 }, {})\n    render(<Component name=\"A\" id={1} />, { container })\n    await wait(() => expect(container).toHaveTextContent('A-1'))\n    expect(A).toHaveBeenCalledTimes(2)\n    expect(A).toHaveBeenCalledWith({ name: 'A', id: 1 }, {})\n    render(<Component name=\"B\" id={2} />, { container })\n    await wait(() => expect(container).toHaveTextContent('B-2'))\n    expect(load).toHaveBeenCalledTimes(2)\n    expect(load).toHaveBeenCalledWith({ name: 'B', id: 2 })\n    expect(B).toHaveBeenCalledTimes(1)\n    expect(B).toHaveBeenCalledWith({ name: 'B', id: 2 }, {})\n\n    // A should not have been rendered with \"id: 2\"\n    expect(A).toHaveBeenCalledTimes(2)\n  })\n\n  it('forwards ref', async () => {\n    const load = resolvedToDefault(\n      React.forwardRef((props, fref) => <div {...props} ref={fref} />),\n    )\n    const Component = loadable(load)\n    const ref = React.createRef()\n    render(<Component ref={ref} />)\n    await wait(() => expect(ref.current.tagName).toBe('DIV'))\n  })\n\n  it('throws when an error occurs', async () => {\n    const load = jest.fn().mockRejectedValue(new Error('boom'))\n    const Component = loadable(load)\n    const { container } = render(\n      <Catch>\n        <Component />\n      </Catch>,\n    )\n    expect(container).toBeEmpty()\n    await wait(() => expect(container).toHaveTextContent('error'))\n  })\n\n  it('supports retry from Error Boundary', async () => {\n    const load = jest\n      .fn()\n      .mockRejectedValueOnce(new Error('Error Boundary'))\n      .mockResolvedValueOnce({ default: () => 'loaded' })\n\n    const Component = loadable(load)\n    const { container } = render(\n      <ErrorBoundary fallback=\"error\" retries={1}>\n        <Component />\n      </ErrorBoundary>,\n    )\n    expect(container).toBeEmpty()\n\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n  })\n})\n\ndescribe('#lazy', () => {\n  it('supports Suspense', async () => {\n    const load = resolvedToDefault(() => 'loaded')\n    const Component = lazy(load)\n    const { container } = render(\n      <React.Suspense fallback=\"progress\">\n        <Component />\n      </React.Suspense>,\n    )\n    expect(container).toHaveTextContent('progress')\n    await wait(() => expect(container).not.toHaveTextContent('progress'))\n    expect(container).toHaveTextContent('loaded')\n  })\n\n  it('should only render both components when both resolve', async () => {\n    const load = jest\n      .fn()\n      .mockResolvedValueOnce({ default: ({ text }) => text })\n\n    mockDelayedResolvedValueOnce(load, { default: ({ text }) => text })\n\n    const Component = lazy(load)\n\n    const { container } = render(\n      <React.Suspense fallback=\"progress\">\n        <>\n          <Component text=\"A\" />\n          <Component text=\"B\" />\n        </>\n      </React.Suspense>,\n    )\n    expect(container).toHaveTextContent('progress')\n    await wait(() => expect(container).not.toHaveTextContent('progress'))\n    expect(container.textContent).toBe('AB')\n  })\n\n  it(\"should render multiple elements of the same async component under contextual Suspense'\", async () => {\n    const load = resolvedToDefault(({ text }) => text)\n    const Component = lazy(load)\n    const { container } = render(\n      <>\n        <React.Suspense fallback=\"progressA\">\n          <Component text=\"A\" />\n        </React.Suspense>\n        <React.Suspense fallback=\" progressB\">\n          <Component text=\"B\" />\n        </React.Suspense>\n      </>,\n    )\n    expect(container).toHaveTextContent('progressA progressB')\n\n    await wait(() => expect(container).not.toHaveTextContent('progress'))\n    expect(container).toHaveTextContent('AB')\n  })\n\n  it(\"shouldn't trigger nested Suspense for same lazy component\", async () => {\n    const load = resolvedToDefault(({ text }) => text)\n    const Component = lazy(load)\n    const { container } = render(\n      <>\n        <React.Suspense fallback=\"progressA\">\n          <Component text=\"A\" />\n          <React.Suspense fallback=\" progressB\">\n            <Component text=\"B\" />\n          </React.Suspense>\n        </React.Suspense>\n      </>,\n    )\n    expect(container.textContent).toBe('progressA')\n\n    await wait(() => expect(container).not.toHaveTextContent('progressA'))\n    expect(container).toHaveTextContent('AB')\n  })\n\n  it('should support Error Boundary', async () => {\n    const load = jest.fn().mockRejectedValue(new Error('Error Boundary'))\n    const Component = lazy(load)\n    const { container } = render(\n      <ErrorBoundary fallback=\"error\">\n        <React.Suspense fallback=\"progress\">\n          <Component />\n        </React.Suspense>\n      </ErrorBoundary>,\n    )\n    expect(container).toHaveTextContent('progress')\n    await wait(() => expect(container).toHaveTextContent('error'))\n  })\n\n  it('should support retry from Error Boundary', async () => {\n    const load = jest\n      .fn()\n      .mockRejectedValueOnce(new Error('Error Boundary'))\n      .mockResolvedValueOnce({ default: () => 'loaded' })\n\n    const Component = lazy(load)\n    const { container } = render(\n      <ErrorBoundary fallback=\"error\" retries={1}>\n        <React.Suspense fallback=\"progress\">\n          <Component />\n        </React.Suspense>\n      </ErrorBoundary>,\n    )\n    expect(container).toHaveTextContent('progress')\n\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n  })\n})\n\ndescribe('#loadable.lib', () => {\n  it('loads library as render prop', async () => {\n    const library = { it: 'is', a: 'lib' }\n    const load = jest.fn().mockResolvedValue(library)\n    const Lib = loadable.lib(load)\n    const renderFn = jest.fn(() => 'loaded')\n    const { container } = render(<Lib>{renderFn}</Lib>)\n    expect(container).toBeEmpty()\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n    expect(renderFn).toHaveBeenCalledWith(library)\n  })\n})\n\ndescribe('#lazy.lib', () => {\n  it('supports Suspense', async () => {\n    const library = { it: 'is', a: 'lib' }\n    const load = jest.fn().mockResolvedValue(library)\n    const Lib = lazy.lib(load)\n    const renderFn = jest.fn(() => 'loaded')\n    const { container } = render(\n      <React.Suspense fallback=\"progress\">\n        <Lib>{renderFn}</Lib>\n      </React.Suspense>,\n    )\n    expect(container).toHaveTextContent('progress')\n    await wait(() => expect(container).toHaveTextContent('loaded'))\n  })\n\n  it('supports Error Boundary', async () => {\n    const load = jest.fn().mockRejectedValue(new Error('Error Boundary'))\n    const Lib = lazy.lib(load)\n    const renderFn = jest.fn(() => 'loaded')\n    const { container } = render(\n      <ErrorBoundary fallback=\"error\">\n        <React.Suspense fallback=\"progress\">\n          <Lib>{renderFn}</Lib>\n        </React.Suspense>\n      </ErrorBoundary>,\n    )\n    expect(container).toHaveTextContent('progress')\n    await wait(() => expect(container).toHaveTextContent('error'))\n  })\n})\n"
  },
  {
    "path": "packages/component/src/loadableReady.js",
    "content": "/* eslint-disable no-underscore-dangle, camelcase */\n/* eslint-env browser */\nimport { warn } from './util'\nimport { getRequiredChunkKey } from './sharedInternals'\nimport { LOADABLE_SHARED } from './shared'\n\nconst BROWSER = typeof window !== 'undefined'\n\nexport default function loadableReady(\n  done = () => {},\n  { namespace = '', chunkLoadingGlobal = '__LOADABLE_LOADED_CHUNKS__' } = {},\n) {\n  if (!BROWSER) {\n    warn('`loadableReady()` must be called in browser only')\n    done()\n    return Promise.resolve()\n  }\n\n  let requiredChunks = null\n  if (BROWSER) {\n    const id = getRequiredChunkKey(namespace)\n    const dataElement = document.getElementById(id)\n    if (dataElement) {\n      requiredChunks = JSON.parse(dataElement.textContent)\n\n      const extElement = document.getElementById(`${id}_ext`)\n      if (extElement) {\n        const { namedChunks } = JSON.parse(extElement.textContent)\n        namedChunks.forEach(chunkName => {\n          LOADABLE_SHARED.initialChunks[chunkName] = true\n        })\n      } else {\n        // version mismatch\n        throw new Error(\n          'loadable-component: @loadable/server does not match @loadable/component',\n        )\n      }\n    }\n  }\n\n  if (!requiredChunks) {\n    warn(\n      '`loadableReady()` requires state, please use `getScriptTags` or `getScriptElements` server-side',\n    )\n    done()\n    return Promise.resolve()\n  }\n\n  let resolved = false\n\n  return new Promise(resolve => {\n    window[chunkLoadingGlobal] = window[chunkLoadingGlobal] || []\n    const loadedChunks = window[chunkLoadingGlobal]\n    const originalPush = loadedChunks.push.bind(loadedChunks)\n\n    function checkReadyState() {\n      if (\n        requiredChunks.every(chunk =>\n          loadedChunks.some(([chunks]) => chunks.indexOf(chunk) > -1),\n        )\n      ) {\n        if (!resolved) {\n          resolved = true\n          resolve()\n        }\n      }\n    }\n\n    loadedChunks.push = (...args) => {\n      originalPush(...args)\n      checkReadyState()\n    }\n\n    checkReadyState()\n  }).then(done)\n}\n"
  },
  {
    "path": "packages/component/src/resolvers.js",
    "content": "export function defaultResolveComponent(loadedModule) {\n  // eslint-disable-next-line no-underscore-dangle\n  return loadedModule.__esModule\n    ? loadedModule.default\n    : loadedModule.default || loadedModule\n}\n"
  },
  {
    "path": "packages/component/src/shared.js",
    "content": "export const LOADABLE_SHARED = {\n  initialChunks: {},\n}\n"
  },
  {
    "path": "packages/component/src/sharedInternals.js",
    "content": "export { invariant } from './util'\nexport { default as Context } from './Context'\nconst LOADABLE_REQUIRED_CHUNKS_KEY = '__LOADABLE_REQUIRED_CHUNKS__'\nexport function getRequiredChunkKey(namespace) {\n  return `${namespace}${LOADABLE_REQUIRED_CHUNKS_KEY}`\n}\n"
  },
  {
    "path": "packages/component/src/util.js",
    "content": "/* eslint-disable import/prefer-default-export */\n\nexport function invariant(condition, message) {\n  if (condition) return\n  const error = new Error(`loadable: ${message}`)\n  error.framesToPop = 1\n  error.name = 'Invariant Violation'\n  throw error\n}\n\nexport function warn(message) {\n  // eslint-disable-next-line no-console\n  console.warn(`loadable: ${message}`)\n}\n"
  },
  {
    "path": "packages/server/.npmignore",
    "content": "src/\n.*\n__fixtures__"
  },
  {
    "path": "packages/server/.size-snapshot.json",
    "content": "{\n  \"dist/cjs/loadable-server.cjs.js\": {\n    \"bundled\": 18673,\n    \"minified\": 10153,\n    \"gzipped\": 2842\n  },\n  \"dist/esm/loadable-server.esm.mjs\": {\n    \"bundled\": 18308,\n    \"minified\": 9868,\n    \"gzipped\": 2768,\n    \"treeshaked\": {\n      \"rollup\": {\n        \"code\": 288,\n        \"import_statements\": 244\n      },\n      \"webpack\": {\n        \"code\": 13266\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/server/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.16.7](https://github.com/gregberge/loadable-components/compare/v5.16.6...v5.16.7) (2025-05-18)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n## [5.16.6](https://github.com/gregberge/loadable-components/compare/v5.16.5...v5.16.6) (2025-05-18)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n## [5.16.5](https://github.com/gregberge/loadable-components/compare/v5.16.4...v5.16.5) (2024-04-20)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n## [5.16.4](https://github.com/gregberge/loadable-components/compare/v5.16.3...v5.16.4) (2024-04-20)\n\n\n### Bug Fixes\n\n* correct esm configuration for loadable/server, fixes: [#999](https://github.com/gregberge/loadable-components/issues/999) ([#1004](https://github.com/gregberge/loadable-components/issues/1004)) ([114cea2](https://github.com/gregberge/loadable-components/commit/114cea2b61ef644d3b794a9b5f48df69f0f5400b))\n\n\n\n\n\n## [5.16.2](https://github.com/gregberge/loadable-components/compare/v5.16.1...v5.16.2) (2023-12-15)\n\n\n### Bug Fixes\n\n* add esm exports to package.json and change esm bundle extension to .mjs to allow node.js to properly import esm version of package. ([#989](https://github.com/gregberge/loadable-components/issues/989)) ([e4a3718](https://github.com/gregberge/loadable-components/commit/e4a37188b804e6a5bc66f39c23c738006bc0e284))\n\n\n\n\n\n## [5.16.1](https://github.com/gregberge/loadable-components/compare/v5.16.0...v5.16.1) (2023-07-20)\n\n\n### Bug Fixes\n\n* correct babel plugin default signature to allow any source of 'loadable' ([#972](https://github.com/gregberge/loadable-components/issues/972)) ([19849b6](https://github.com/gregberge/loadable-components/commit/19849b6ba738fe19c18e61ed3402ee82ba934760)), closes [#971](https://github.com/gregberge/loadable-components/issues/971)\n\n\n\n\n\n# [5.16.0](https://github.com/gregberge/loadable-components/compare/v5.15.3...v5.16.0) (2023-07-09)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n## [5.15.3](https://github.com/gregberge/loadable-components/compare/v5.15.2...v5.15.3) (2023-01-28)\n\n\n### Bug Fixes\n\n* add React 17 and 18 to package dependencies, fixes [#718](https://github.com/gregberge/loadable-components/issues/718) ([66edc37](https://github.com/gregberge/loadable-components/commit/66edc37a731a8ec655deffd3ad454fd96e909ba3))\n\n\n\n\n\n## [5.15.2](https://github.com/gregberge/loadable-components/compare/v5.15.1...v5.15.2) (2021-12-12)\n\n\n### Bug Fixes\n\n* Clear correct cache when compiling with Webpack ([#838](https://github.com/gregberge/loadable-components/issues/838)) ([3b9cb20](https://github.com/gregberge/loadable-components/commit/3b9cb202a09365e67c08ec18455d82bedf62f4db))\n\n\n\n\n\n## [5.15.1](https://github.com/gregberge/loadable-components/compare/v5.15.0...v5.15.1) (2021-08-17)\n\n\n### Bug Fixes\n\n* SubResourceIntegrity ([#803](https://github.com/gregberge/loadable-components/issues/803)) ([9b34195](https://github.com/gregberge/loadable-components/commit/9b34195627c65372a7c834311c32dfcbd5b7fedd))\n\n\n\n\n\n# [5.15.0](https://github.com/gregberge/loadable-components/compare/v5.14.2...v5.15.0) (2021-05-08)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n## [5.14.2](https://github.com/gregberge/loadable-components/compare/v5.14.1...v5.14.2) (2021-01-31)\n\n\n### Bug Fixes\n\n* ignore css chunk ([#689](https://github.com/gregberge/loadable-components/issues/689)) ([6926e19](https://github.com/gregberge/loadable-components/commit/6926e190c80f525467980fffbbded0bf933f27ed))\n* remove main asset path query ([#686](https://github.com/gregberge/loadable-components/issues/686)) ([dde2252](https://github.com/gregberge/loadable-components/commit/dde2252136a2d7f3ff635f85deff429948130883))\n\n\n\n\n\n# [5.14.0](https://github.com/gregberge/loadable-components/compare/v5.13.2...v5.14.0) (2020-10-20)\n\n\n### Bug Fixes\n\n* add key to chunks script elements ([#631](https://github.com/gregberge/loadable-components/issues/631)) ([25b532e](https://github.com/gregberge/loadable-components/commit/25b532eb53a2841229dbc8a9c91f24112a46b93f)), closes [#628](https://github.com/gregberge/loadable-components/issues/628)\n* treat mjs as script ([575fe2b](https://github.com/gregberge/loadable-components/commit/575fe2b3f58b18c17416f238780b9bab85110706))\n\n\n### Features\n\n* make packages webpack 5 compatible ([#638](https://github.com/gregberge/loadable-components/issues/638)) ([e882e4d](https://github.com/gregberge/loadable-components/commit/e882e4d812e714066eba19a11dd119193e7a9e01))\n\n\n\n\n\n## [5.13.2](https://github.com/gregberge/loadable-components/compare/v5.13.1...v5.13.2) (2020-09-14)\n\n\n### Bug Fixes\n\n* spread nested required chunks array ([95e6ecb](https://github.com/gregberge/loadable-components/commit/95e6ecb0dd9be3cf18ded934cca433a660fa3543))\n\n\n\n\n\n## [5.13.1](https://github.com/gregberge/loadable-components/compare/v5.13.0...v5.13.1) (2020-07-02)\n\n\n### Bug Fixes\n\n* expose used chunkNames from a server. Fixes [#587](https://github.com/gregberge/loadable-components/issues/587) ([831aec0](https://github.com/gregberge/loadable-components/commit/831aec03154ab16007db0d78fbf3559583c000fe))\n\n\n\n\n\n# [5.13.0](https://github.com/gregberge/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n\n### Bug Fixes\n\n* memory leak in module cache management, fixes [#560](https://github.com/gregberge/loadable-components/issues/560) ([6c11703](https://github.com/gregberge/loadable-components/commit/6c11703cbc5446fc61d10c47b64e84a00cf899c3))\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Bug Fixes\n\n* apply loadable transformations before any other, fixes [#466](https://github.com/gregberge/loadable-components/issues/466) ([ac5ba45](https://github.com/gregberge/loadable-components/commit/ac5ba45862bad68b971a969e6e8713874add51a6))\n\n\n\n\n\n# [5.11.0](https://github.com/smooth-code/loadable-components/compare/v5.10.3...v5.11.0) (2019-12-02)\n\n\n### Bug Fixes\n\n* **server:** use require instead of module.require ([#457](https://github.com/smooth-code/loadable-components/issues/457)) ([064b4f8](https://github.com/smooth-code/loadable-components/commit/064b4f83b291e8a7d73bc44fe4196dc9ddc81fe8)), closes [#455](https://github.com/smooth-code/loadable-components/issues/455)\n\n\n### Features\n\n* add support for SRI (integrity) (with webpack-subresource-integrity) ([#436](https://github.com/smooth-code/loadable-components/issues/436)) ([586ad0a](https://github.com/smooth-code/loadable-components/commit/586ad0af6e172e3a0bffdbe0c8ab682c0d8b0eab))\n\n\n\n\n\n## [5.10.3](https://github.com/smooth-code/loadable-components/compare/v5.10.2...v5.10.3) (2019-09-24)\n\n\n### Bug Fixes\n\n* empty cache on each server reload ([#431](https://github.com/smooth-code/loadable-components/issues/431)) ([d4428c6](https://github.com/smooth-code/loadable-components/commit/d4428c6)), closes [#230](https://github.com/smooth-code/loadable-components/issues/230)\n\n\n\n\n\n## [5.10.2](https://github.com/smooth-code/loadable-components/compare/v5.10.1...v5.10.2) (2019-07-15)\n\n\n### Performance Improvements\n\n* use more performant url join impl ([#353](https://github.com/smooth-code/loadable-components/issues/353)) ([c3fbbef](https://github.com/smooth-code/loadable-components/commit/c3fbbef))\n\n\n\n\n\n# [5.9.0](https://github.com/smooth-code/loadable-components/compare/v5.8.0...v5.9.0) (2019-04-23)\n\n\n### Features\n\n* support multiple react apps ([#317](https://github.com/smooth-code/loadable-components/issues/317)) ([dc54050](https://github.com/smooth-code/loadable-components/commit/dc54050)), closes [#311](https://github.com/smooth-code/loadable-components/issues/311)\n* **server:** authorize custom filesystem ([#318](https://github.com/smooth-code/loadable-components/issues/318)) ([f2a6bbd](https://github.com/smooth-code/loadable-components/commit/f2a6bbd)), closes [#315](https://github.com/smooth-code/loadable-components/issues/315)\n\n\n\n\n\n# [5.8.0](https://github.com/smooth-code/loadable-components/compare/v5.7.2...v5.8.0) (2019-04-10)\n\n\n### Features\n\n* **ChunkExtractor:** support publicPath override ([#292](https://github.com/smooth-code/loadable-components/issues/292)) ([9731e9c](https://github.com/smooth-code/loadable-components/commit/9731e9c))\n* **server:** support function in attributes ([#277](https://github.com/smooth-code/loadable-components/issues/277)) ([c172324](https://github.com/smooth-code/loadable-components/commit/c172324))\n\n\n### Performance Improvements\n\n* **server:** improve lodash imports for serverless bundles ([#298](https://github.com/smooth-code/loadable-components/issues/298)) ([96841f2](https://github.com/smooth-code/loadable-components/commit/96841f2))\n\n\n\n\n\n# [5.7.0](https://github.com/smooth-code/loadable-components/compare/v5.6.1...v5.7.0) (2019-03-14)\n\n\n### Bug Fixes\n\n* **server:** fix loading order of assets ([#266](https://github.com/smooth-code/loadable-components/issues/266)) ([4c8ae60](https://github.com/smooth-code/loadable-components/commit/4c8ae60))\n\n\n### Features\n\n* use inline JSON to enabling CSP without `unsafe-inline` ([05e5500](https://github.com/smooth-code/loadable-components/commit/05e5500))\n\n\n### Performance Improvements\n\n* **build:** add build target for Node ([#267](https://github.com/smooth-code/loadable-components/issues/267)) ([97ff6ac](https://github.com/smooth-code/loadable-components/commit/97ff6ac))\n\n\n\n\n\n## [5.6.1](https://github.com/smooth-code/loadable-components/compare/v5.6.0...v5.6.1) (2019-02-25)\n\n\n### Bug Fixes\n\n* **server:** allow query-param cache busting in chunk names ([#229](https://github.com/smooth-code/loadable-components/issues/229)) ([71f7bcd](https://github.com/smooth-code/loadable-components/commit/71f7bcd))\n* **server:** use `eval` to prevent webpack warning ([#240](https://github.com/smooth-code/loadable-components/issues/240)) ([948165d](https://github.com/smooth-code/loadable-components/commit/948165d)), closes [#234](https://github.com/smooth-code/loadable-components/issues/234)\n\n\n\n\n\n# [5.6.0](https://github.com/smooth-code/loadable-components/compare/v5.5.0...v5.6.0) (2019-02-05)\n\n\n### Bug Fixes\n\n* Add extra props option for links ([#212](https://github.com/smooth-code/loadable-components/issues/212)) ([6714d2a](https://github.com/smooth-code/loadable-components/commit/6714d2a))\n\n\n\n\n\n# [5.5.0](https://github.com/smooth-code/loadable-components/compare/v5.4.0...v5.5.0) (2019-01-22)\n\n\n### Features\n\n* allow to specify extra attributes in getScriptTags & others ([#210](https://github.com/smooth-code/loadable-components/issues/210)) ([8a3d067](https://github.com/smooth-code/loadable-components/commit/8a3d067))\n\n\n\n\n\n# [5.4.0](https://github.com/smooth-code/loadable-components/compare/v5.3.0...v5.4.0) (2019-01-17)\n\n\n### Features\n\n* **webpack-plugin:** support custom path in writeToDisk option ([#187](https://github.com/smooth-code/loadable-components/issues/187)) ([4a6f84f](https://github.com/smooth-code/loadable-components/commit/4a6f84f))\n\n\n\n\n\n# [5.3.0](https://github.com/smooth-code/loadable-components/compare/v5.2.2...v5.3.0) (2019-01-11)\n\n\n### Features\n\n* support inline CSS ([#190](https://github.com/smooth-code/loadable-components/issues/190)) ([2caf676](https://github.com/smooth-code/loadable-components/commit/2caf676))\n\n\n\n\n\n## [5.2.2](https://github.com/smooth-code/loadable-components/compare/v5.2.1...v5.2.2) (2018-12-12)\n\n\n### Bug Fixes\n\n* **server:** fix usage when compiled using webpack ([#185](https://github.com/smooth-code/loadable-components/issues/185)) ([5e28870](https://github.com/smooth-code/loadable-components/commit/5e28870)), closes [#181](https://github.com/smooth-code/loadable-components/issues/181)\n\n\n\n\n\n# [5.2.0](https://github.com/smooth-code/loadable-components/compare/v5.1.3...v5.2.0) (2018-11-23)\n\n\n### Bug Fixes\n\n* **server:** fix url join ([#166](https://github.com/smooth-code/loadable-components/issues/166)) ([ba90289](https://github.com/smooth-code/loadable-components/commit/ba90289))\n* **server:** support protocol free paths ([#163](https://github.com/smooth-code/loadable-components/issues/163)) ([3b5b115](https://github.com/smooth-code/loadable-components/commit/3b5b115))\n\n\n\n\n\n## [5.1.3](https://github.com/smooth-code/loadable-components/compare/v5.1.2...v5.1.3) (2018-11-20)\n\n\n### Bug Fixes\n\n* **server:** exclude http and https from regex ([#155](https://github.com/smooth-code/loadable-components/issues/155)) ([0bb2ad9](https://github.com/smooth-code/loadable-components/commit/0bb2ad9)), closes [#153](https://github.com/smooth-code/loadable-components/issues/153)\n* **server:** ignore *.hot-update.js ([edcd2c8](https://github.com/smooth-code/loadable-components/commit/edcd2c8)), closes [#148](https://github.com/smooth-code/loadable-components/issues/148)\n\n\n\n\n\n## [5.1.1](https://github.com/smooth-code/loadable-components/compare/v5.1.0...v5.1.1) (2018-11-13)\n\n\n### Bug Fixes\n\n* **server:** ignore source maps ([9991bbd](https://github.com/smooth-code/loadable-components/commit/9991bbd)), closes [#128](https://github.com/smooth-code/loadable-components/issues/128)\n\n\n\n\n\n# [5.1.0](https://github.com/smooth-code/loadable-components/compare/v5.0.2...v5.1.0) (2018-11-10)\n\n\n### Features\n\n* **server:** add outputPath option in ChunkExtractor ([aac26b3](https://github.com/smooth-code/loadable-components/commit/aac26b3))\n\n\n\n\n\n## [5.0.2](https://github.com/smooth-code/loadable-components/compare/v5.0.1...v5.0.2) (2018-11-10)\n\n\n### Bug Fixes\n\n* update peer dependencies ([b0363dc](https://github.com/smooth-code/loadable-components/commit/b0363dc))\n\n\n\n\n\n# [5.0.0](https://github.com/smooth-code/loadable-components/compare/v4.0.5...v5.0.0) (2018-11-10)\n\n\n### Features\n\n* improve SSR support ([eb1cfe8](https://github.com/smooth-code/loadable-components/commit/eb1cfe8))\n\n\n### BREAKING CHANGES\n\n* - SSR has been rewritten from scratch, if you use it, please follow the\nnew guide.\n- Prefetch component and prefetch functions have been removed, please\nuse `webpackPrefetch` instead.\n\n\n\n\n\n## [4.0.5](https://github.com/smooth-code/loadable-components/compare/v4.0.4...v4.0.5) (2018-11-01)\n\n\n### Bug Fixes\n\n* **server:** fix getScriptElements ([ba424e0](https://github.com/smooth-code/loadable-components/commit/ba424e0))\n\n\n\n\n\n## [4.0.4](https://github.com/smooth-code/loadable-components/compare/v4.0.3...v4.0.4) (2018-10-31)\n\n\n### Bug Fixes\n\n* fix peer dependencies ([6816e8c](https://github.com/smooth-code/loadable-components/commit/6816e8c))\n\n\n\n\n\n## [4.0.3](https://github.com/smooth-code/loadable-components/compare/v4.0.2...v4.0.3) (2018-10-31)\n\n\n### Bug Fixes\n\n* **server:** disable common chunks optim ([78e7b28](https://github.com/smooth-code/loadable-components/commit/78e7b28))\n\n\n\n\n\n# [4.0.0](https://github.com/smooth-code/loadable-components/compare/v3.0.2...v4.0.0) (2018-10-30)\n\n**Note:** Version bump only for package @loadable/server\n\n\n\n\n\n# [3.0.0](https://github.com/smooth-code/loadable-components/compare/v2.2.3...v3.0.0) (2018-10-29)\n\n\n### Features\n\n* welcome loadable ([4dffad7](https://github.com/smooth-code/loadable-components/commit/4dffad7))\n\n\n### BREAKING CHANGES\n\n* API has completely changed, see documentation.\n"
  },
  {
    "path": "packages/server/README.md",
    "content": "# @loadable/server\n\n## Install\n\n```\b\nnpm install @loadable/server\n```\n\n## Documentation\n\n👉 [See full documentation](https://loadable-components.com/)\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/server/__fixtures__/stats.json",
    "content": "{\n  \"errors\": [],\n  \"warnings\": [],\n  \"hash\": \"6cacb38ddc45b9bbd140\",\n  \"publicPath\": \"/dist/node/\",\n  \"outputPath\": \"../../examples/server-side-rendering/public/dist/node\",\n  \"assetsByChunkName\": {\n    \"Y-file\": \"Y-file.js\",\n    \"letters-A\": [\n      \"letters-A.css\",\n      \"letters-A.js\"\n    ],\n    \"letters-A-css\": [\n      \"letters-A-css.css\",\n      \"letters-A-css.js\"\n    ],\n    \"letters-B\": \"letters-B.js\",\n    \"letters-C\": \"letters-C.js\",\n    \"letters-D\": \"letters-D.js\",\n    \"letters-E\": \"letters-E.js\",\n    \"letters-E-param\": \"letters-E-param.js\",\n    \"letters-F\": \"letters-F.js\",\n    \"letters-G\": \"letters-G.js\",\n    \"letters-Z-file\": \"letters-Z-file.js\",\n    \"main\": [\n      \"main.css\",\n      \"main.js\"\n    ]\n  },\n  \"assets\": [\n    {\n      \"name\": \"Y-file.js\",\n      \"size\": 121,\n      \"chunks\": [\n        \"Y-file\"\n      ],\n      \"chunkNames\": [\n        \"Y-file\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-A-css.css\",\n      \"size\": 43,\n      \"chunks\": [\n        \"letters-A-css\"\n      ],\n      \"chunkNames\": [\n        \"letters-A-css\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-A-css.js\",\n      \"size\": 95,\n      \"chunks\": [\n        \"letters-A-css\"\n      ],\n      \"chunkNames\": [\n        \"letters-A-css\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-A.css\",\n      \"size\": 43,\n      \"chunks\": [\n        \"letters-A\",\n        \"letters-A-css\"\n      ],\n      \"chunkNames\": [\n        \"letters-A\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-A.js\",\n      \"size\": 272,\n      \"chunks\": [\n        \"letters-A\",\n        \"letters-A-css\"\n      ],\n      \"chunkNames\": [\n        \"letters-A\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-B.js\",\n      \"size\": 173,\n      \"chunks\": [\n        \"letters-B\"\n      ],\n      \"chunkNames\": [\n        \"letters-B\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-C.js\",\n      \"size\": 127,\n      \"chunks\": [\n        \"letters-C\"\n      ],\n      \"chunkNames\": [\n        \"letters-C\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-D.js\",\n      \"size\": 127,\n      \"chunks\": [\n        \"letters-D\"\n      ],\n      \"chunkNames\": [\n        \"letters-D\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-E-param.js\",\n      \"size\": 139,\n      \"chunks\": [\n        \"letters-E-param\"\n      ],\n      \"chunkNames\": [\n        \"letters-E-param\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-E.js\",\n      \"size\": 127,\n      \"chunks\": [\n        \"letters-E\"\n      ],\n      \"chunkNames\": [\n        \"letters-E\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-F.js\",\n      \"size\": 127,\n      \"chunks\": [\n        \"letters-F\"\n      ],\n      \"chunkNames\": [\n        \"letters-F\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-G.js\",\n      \"size\": 222,\n      \"chunks\": [\n        \"letters-G\"\n      ],\n      \"chunkNames\": [\n        \"letters-G\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"letters-Z-file.js\",\n      \"size\": 137,\n      \"chunks\": [\n        \"letters-Z-file\"\n      ],\n      \"chunkNames\": [\n        \"letters-Z-file\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"main.css\",\n      \"size\": 39,\n      \"chunks\": [\n        \"main\"\n      ],\n      \"chunkNames\": [\n        \"main\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    },\n    {\n      \"name\": \"main.js\",\n      \"size\": 13582,\n      \"chunks\": [\n        \"main\"\n      ],\n      \"chunkNames\": [\n        \"main\"\n      ],\n      \"info\": {},\n      \"emitted\": false\n    }\n  ],\n  \"filteredAssets\": 0,\n  \"namedChunkGroups\": {\n    \"main\": {\n      \"chunks\": [\n        \"main\"\n      ],\n      \"assets\": [\n        \"main.css\",\n        \"main.js\"\n      ],\n      \"children\": {\n        \"preload\": [\n          {\n            \"name\": \"letters-C\",\n            \"chunks\": [\n              \"letters-C\"\n            ],\n            \"assets\": [\n              \"letters-C.js\"\n            ]\n          }\n        ],\n        \"prefetch\": [\n          {\n            \"name\": \"letters-D\",\n            \"chunks\": [\n              \"letters-D\"\n            ],\n            \"assets\": [\n              \"letters-D.js\"\n            ]\n          }\n        ]\n      },\n      \"childAssets\": {\n        \"preload\": [\n          \"letters-C.js\"\n        ],\n        \"prefetch\": [\n          \"letters-D.js\"\n        ]\n      }\n    },\n    \"letters-A\": {\n      \"chunks\": [\n        \"letters-A\"\n      ],\n      \"assets\": [\n        \"letters-A.css\",\n        \"letters-A.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-B\": {\n      \"chunks\": [\n        \"letters-B\"\n      ],\n      \"assets\": [\n        \"letters-B.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-C\": {\n      \"chunks\": [\n        \"letters-C\"\n      ],\n      \"assets\": [\n        \"letters-C.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-D\": {\n      \"chunks\": [\n        \"letters-D\"\n      ],\n      \"assets\": [\n        \"letters-D.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-E-param\": {\n      \"chunks\": [\n        \"letters-E-param\"\n      ],\n      \"assets\": [\n        \"letters-E-param.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-G\": {\n      \"chunks\": [\n        \"letters-G\"\n      ],\n      \"assets\": [\n        \"letters-G.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"moment\": {\n      \"chunks\": [],\n      \"assets\": [],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-A-css\": {\n      \"chunks\": [\n        \"letters-A-css\"\n      ],\n      \"assets\": [\n        \"letters-A-css.css\",\n        \"letters-A-css.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-A-js\": {\n      \"chunks\": [\n        \"letters-A\"\n      ],\n      \"assets\": [\n        \"letters-A.css\",\n        \"letters-A.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-B-js\": {\n      \"chunks\": [\n        \"letters-B\"\n      ],\n      \"assets\": [\n        \"letters-B.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-C-js\": {\n      \"chunks\": [\n        \"letters-C\"\n      ],\n      \"assets\": [\n        \"letters-C.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-D-js\": {\n      \"chunks\": [\n        \"letters-D\"\n      ],\n      \"assets\": [\n        \"letters-D.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-E\": {\n      \"chunks\": [\n        \"letters-E\"\n      ],\n      \"assets\": [\n        \"letters-E.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-E-js\": {\n      \"chunks\": [\n        \"letters-E\"\n      ],\n      \"assets\": [\n        \"letters-E.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-F\": {\n      \"chunks\": [\n        \"letters-F\"\n      ],\n      \"assets\": [\n        \"letters-F.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-F-js\": {\n      \"chunks\": [\n        \"letters-F\"\n      ],\n      \"assets\": [\n        \"letters-F.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-G-js\": {\n      \"chunks\": [\n        \"letters-G\"\n      ],\n      \"assets\": [\n        \"letters-G.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-Z-file\": {\n      \"chunks\": [\n        \"letters-Z-file\"\n      ],\n      \"assets\": [\n        \"letters-Z-file.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"letters-Z-file-js\": {\n      \"chunks\": [\n        \"letters-Z-file\"\n      ],\n      \"assets\": [\n        \"letters-Z-file.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    },\n    \"Y-file\": {\n      \"chunks\": [\n        \"Y-file\"\n      ],\n      \"assets\": [\n        \"Y-file.js\"\n      ],\n      \"children\": {},\n      \"childAssets\": {}\n    }\n  },\n  \"generator\": \"loadable-components\",\n  \"chunks\": [\n    {\n      \"id\": \"Y-file\",\n      \"files\": [\n        \"Y-file.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-A\",\n      \"files\": [\n        \"letters-A.css\",\n        \"letters-A.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-A-css\",\n      \"files\": [\n        \"letters-A-css.css\",\n        \"letters-A-css.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-B\",\n      \"files\": [\n        \"letters-B.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-C\",\n      \"files\": [\n        \"letters-C.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-D\",\n      \"files\": [\n        \"letters-D.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-E\",\n      \"files\": [\n        \"letters-E.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-E-param\",\n      \"files\": [\n        \"letters-E-param.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-F\",\n      \"files\": [\n        \"letters-F.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-G\",\n      \"files\": [\n        \"letters-G.js\"\n      ]\n    },\n    {\n      \"id\": \"letters-Z-file\",\n      \"files\": [\n        \"letters-Z-file.js\"\n      ]\n    },\n    {\n      \"id\": \"main\",\n      \"files\": [\n        \"main.css\",\n        \"main.js\"\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "packages/server/package.json",
    "content": "{\n  \"name\": \"@loadable/server\",\n  \"description\": \"Server utilities for loadable.\",\n  \"version\": \"5.16.7\",\n  \"type\": \"module\",\n  \"main\": \"./dist/cjs/loadable-server.cjs.js\",\n  \"module\": \"./dist/esm/loadable-server.esm.mjs\",\n  \"exports\": {\n    \".\": {\n      \"require\": \"./dist/cjs/loadable-server.cjs.js\",\n      \"import\": \"./dist/esm/loadable-server.esm.mjs\",\n      \"default\": \"./dist/cjs/loadable-server.cjs.js\"\n    }\n  },\n  \"repository\": \"git@github.com:gregberge/loadable-components.git\",\n  \"author\": \"Greg Bergé <berge.greg@gmail.com>\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"keywords\": [\n    \"loadable\"\n  ],\n  \"engines\": {\n    \"node\": \">=8\"\n  },\n  \"funding\": {\n    \"type\": \"github\",\n    \"url\": \"https://github.com/sponsors/gregberge\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"prebuild\": \"shx rm -rf dist\",\n    \"build\": \"cross-env rollup -c && yarn create-cjs-package-json\",\n    \"create-cjs-package-json\": \"echo '{\\\"type\\\": \\\"commonjs\\\"}' > ./dist/cjs/package.json\",\n    \"prepublishOnly\": \"yarn run build\",\n    \"update-fixtures\": \"yarn --cwd ../../examples/__fixtures__ build:webpack && rm -rf ./__fixtures__ && cp -R ../../examples/__fixtures__/target ./__fixtures__ \"\n  },\n  \"peerDependencies\": {\n    \"@loadable/component\": \"^5.0.1\",\n    \"react\": \"^16.3.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n  },\n  \"devDependencies\": {\n    \"@loadable/component\": \"^5.16.7\"\n  },\n  \"dependencies\": {\n    \"lodash\": \"^4.17.15\"\n  }\n}\n"
  },
  {
    "path": "packages/server/rollup.config.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\nimport nodeResolve from 'rollup-plugin-node-resolve'\nimport babel from 'rollup-plugin-babel'\nimport replace from 'rollup-plugin-replace'\nimport commonjs from 'rollup-plugin-commonjs'\nimport { terser } from 'rollup-plugin-terser'\nimport pkg from './package.json'\n\nconst input = 'src/index.js'\nconst name = 'loadable'\nconst globals = {\n  react: 'React',\n  'hoist-non-react-statics': 'hoistNonReactStatics',\n}\n\nconst external = id => !id.startsWith('.') && !id.startsWith('/')\n\nconst getBabelOptions = ({ useESModules }) => ({\n  exclude: '**/node_modules/**',\n  runtimeHelpers: true,\n  presets: [\n    ['@babel/preset-env', { loose: true }],\n    ['@babel/preset-react', { useBuiltIns: true }],\n  ],\n  plugins: [\n    '@babel/plugin-proposal-class-properties',\n    'babel-plugin-annotate-pure-calls',\n    ['@babel/plugin-transform-runtime', { useESModules }],\n  ],\n})\n\nexport default [\n  // cjs\n  {\n    input,\n    output: { file: pkg.main, format: 'cjs', exports: 'named' },\n    external,\n    plugins: [babel(getBabelOptions({ useESModules: false }))],\n  },\n  // esm\n  {\n    input,\n    output: { file: pkg.module, format: 'esm' },\n    external,\n    plugins: [babel(getBabelOptions({ useESModules: true }))],\n  },\n]\n"
  },
  {
    "path": "packages/server/src/ChunkExtractor.js",
    "content": "/* eslint-disable react/no-danger */\nimport path from 'path'\nimport fs from 'fs'\nimport uniq from 'lodash/uniq.js'\nimport uniqBy from 'lodash/uniqBy.js'\nimport flatMap from 'lodash/flatMap.js'\nimport React from 'react'\nimport { invariant, getRequiredChunkKey } from './sharedInternals.js'\nimport ChunkExtractorManager from './ChunkExtractorManager.js'\nimport { smartRequire, joinURLPath, readJsonFileSync } from './util.js'\n\nconst EXTENSION_SCRIPT_TYPES = {\n  '.js': 'script',\n  '.mjs': 'script',\n  '.css': 'style',\n}\n\nfunction extensionToScriptType(extension) {\n  return EXTENSION_SCRIPT_TYPES[extension] || null\n}\n\n/**\n * some files can be references with extra query arguments which have to be removed\n * @param name\n * @returns {*}\n */\nfunction cleanFileName(name) {\n  return name.split('?')[0]\n}\n\nfunction getFileScriptType(fileName) {\n  return extensionToScriptType(\n    cleanFileName(path.extname(fileName)).toLowerCase(),\n  )\n}\n\nfunction isScriptFile(fileName) {\n  return getFileScriptType(fileName) === 'script'\n}\n\nfunction getAssets(chunks, getAsset) {\n  return uniqBy(\n    flatMap(chunks, chunk => getAsset(chunk)),\n    'url',\n  )\n}\n\nfunction handleExtraProps(asset, extraProps) {\n  return typeof extraProps === 'function' ? extraProps(asset) : extraProps\n}\n\nfunction extraPropsToString(asset, extraProps) {\n  return Object.entries(handleExtraProps(asset, extraProps)).reduce(\n    (acc, [key, value]) => `${acc} ${key}=\"${value}\"`,\n    '',\n  )\n}\n\nfunction getSriHtmlAttributes(asset) {\n  if (!asset.integrity) {\n    return ''\n  }\n  return ` integrity=\"${asset.integrity}\"`\n}\n\nfunction assetToScriptTag(asset, extraProps) {\n  return `<script async data-chunk=\"${asset.chunk}\" src=\"${\n    asset.url\n  }\"${getSriHtmlAttributes(asset)}${extraPropsToString(\n    asset,\n    extraProps,\n  )}></script>`\n}\n\nfunction assetToScriptElement(asset, extraProps) {\n  return (\n    <script\n      key={asset.url}\n      async\n      data-chunk={asset.chunk}\n      src={asset.url}\n      {...handleExtraProps(asset, extraProps)}\n    />\n  )\n}\n\nfunction assetToStyleString(asset, { inputFileSystem }) {\n  return new Promise((resolve, reject) => {\n    inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {\n      if (err) {\n        reject(err)\n        return\n      }\n      resolve(data)\n    })\n  })\n}\n\nfunction assetToStyleTag(asset, extraProps) {\n  return `<link data-chunk=\"${asset.chunk}\" rel=\"stylesheet\" href=\"${\n    asset.url\n  }\"${getSriHtmlAttributes(asset)}${extraPropsToString(asset, extraProps)}>`\n}\n\nfunction assetToStyleTagInline(asset, extraProps, { inputFileSystem }) {\n  return new Promise((resolve, reject) => {\n    inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {\n      if (err) {\n        reject(err)\n        return\n      }\n      resolve(\n        `<style type=\"text/css\" data-chunk=\"${asset.chunk}\"${extraPropsToString(\n          asset,\n          extraProps,\n        )}>\n${data}\n</style>`,\n      )\n    })\n  })\n}\n\nfunction assetToStyleElement(asset, extraProps) {\n  return (\n    <link\n      key={asset.url}\n      data-chunk={asset.chunk}\n      rel=\"stylesheet\"\n      href={asset.url}\n      {...handleExtraProps(asset, extraProps)}\n    />\n  )\n}\n\nfunction assetToStyleElementInline(asset, extraProps, { inputFileSystem }) {\n  return new Promise((resolve, reject) => {\n    inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {\n      if (err) {\n        reject(err)\n        return\n      }\n      resolve(\n        <style\n          key={asset.url}\n          data-chunk={asset.chunk}\n          dangerouslySetInnerHTML={{ __html: data }}\n          {...handleExtraProps(asset, extraProps)}\n        />,\n      )\n    })\n  })\n}\n\nconst LINK_ASSET_HINTS = {\n  mainAsset: 'data-chunk',\n  childAsset: 'data-parent-chunk',\n}\n\nfunction assetToLinkTag(asset, extraProps) {\n  const hint = LINK_ASSET_HINTS[asset.type]\n  return `<link ${hint}=\"${asset.chunk}\" rel=\"${asset.linkType}\" as=\"${\n    asset.scriptType\n  }\" href=\"${asset.url}\"${getSriHtmlAttributes(asset)}${extraPropsToString(\n    asset,\n    extraProps,\n  )}>`\n}\n\nfunction assetToLinkElement(asset, extraProps) {\n  const hint = LINK_ASSET_HINTS[asset.type]\n  const props = {\n    key: asset.url,\n    [hint]: asset.chunk,\n    rel: asset.linkType,\n    as: asset.scriptType,\n    href: asset.url,\n    ...handleExtraProps(asset, extraProps),\n  }\n  return <link {...props} />\n}\n\nfunction joinTags(tags) {\n  return tags.join('\\n')\n}\n\nconst HOT_UPDATE_REGEXP = /\\.hot-update\\.js$/\n\nfunction isValidChunkAsset(chunkAsset) {\n  return chunkAsset.scriptType && !HOT_UPDATE_REGEXP.test(chunkAsset.filename)\n}\n\nfunction checkIfChunkIncludesJs(chunkInfo) {\n  return chunkInfo.files.some(file => isScriptFile(file))\n}\n\nclass ChunkExtractor {\n  constructor({\n    statsFile,\n    stats,\n    entrypoints = ['main'],\n    namespace = '',\n    outputPath,\n    publicPath,\n    inputFileSystem = fs,\n  } = {}) {\n    this.namespace = namespace\n    this.stats = stats || readJsonFileSync(inputFileSystem, statsFile)\n    this.publicPath = publicPath || this.stats.publicPath\n    this.outputPath = outputPath || this.stats.outputPath\n    this.statsFile = statsFile\n    this.entrypoints = Array.isArray(entrypoints) ? entrypoints : [entrypoints]\n    this.chunks = []\n    this.inputFileSystem = inputFileSystem\n  }\n\n  resolvePublicUrl(filename) {\n    return joinURLPath(this.publicPath, filename)\n  }\n\n  getChunkGroup(chunk) {\n    const chunkGroup = this.stats.namedChunkGroups[chunk]\n    invariant(chunkGroup, `cannot find ${chunk} in stats`)\n    return chunkGroup\n  }\n\n  getChunkInfo(chunkId) {\n    const chunkInfo = this.stats.chunks.find(chunk => chunk.id === chunkId)\n    invariant(chunkInfo, `cannot find chunk (chunkId: ${chunkId}) in stats`)\n    return chunkInfo\n  }\n\n  createChunkAsset({ filename, chunk, type, linkType }) {\n    const resolvedFilename =\n      typeof filename === 'object' && filename.name ? filename.name : filename\n    const resolvedIntegrity =\n      typeof filename === 'object' && filename.integrity\n        ? filename.integrity\n        : null\n\n    return {\n      filename: resolvedFilename,\n      integrity: resolvedIntegrity,\n      scriptType: getFileScriptType(resolvedFilename),\n      chunk,\n      url: this.resolvePublicUrl(resolvedFilename),\n      path: path.join(this.outputPath, resolvedFilename),\n      type,\n      linkType,\n    }\n  }\n\n  getChunkAssets(chunks) {\n    const one = chunk => {\n      const chunkGroup = this.getChunkGroup(chunk)\n      return chunkGroup.assets\n        .map(filename =>\n          this.createChunkAsset({\n            filename,\n            chunk,\n            type: 'mainAsset',\n            linkType: 'preload',\n          }),\n        )\n        .filter(isValidChunkAsset)\n    }\n\n    if (Array.isArray(chunks)) {\n      return getAssets(chunks, one)\n    }\n\n    return one(chunks)\n  }\n\n  getChunkChildAssets(chunks, type) {\n    const one = chunk => {\n      const chunkGroup = this.getChunkGroup(chunk)\n      const assets = chunkGroup.childAssets[type] || []\n      return assets\n        .map(filename =>\n          this.createChunkAsset({\n            filename,\n            chunk,\n            type: 'childAsset',\n            linkType: type,\n          }),\n        )\n        .filter(isValidChunkAsset)\n    }\n\n    if (Array.isArray(chunks)) {\n      return getAssets(chunks, one)\n    }\n\n    return one(chunks)\n  }\n\n  getChunkDependencies(chunks) {\n    const one = chunk => {\n      const chunkGroup = this.getChunkGroup(chunk)\n\n      // ignore chunk that only contains css files.\n      return chunkGroup.chunks.filter(chunkId => {\n        const chunkInfo = this.getChunkInfo(chunkId)\n\n        if (!chunkInfo) {\n          return false\n        }\n\n        return checkIfChunkIncludesJs(chunkInfo)\n      })\n    }\n\n    if (Array.isArray(chunks)) {\n      return uniq(flatMap(chunks, one))\n    }\n\n    return one(chunks)\n  }\n\n  getRequiredChunksScriptContent() {\n    return JSON.stringify(this.getChunkDependencies(this.chunks))\n  }\n\n  getRequiredChunksNamesScriptContent() {\n    return JSON.stringify({\n      namedChunks: this.chunks,\n    })\n  }\n\n  getRequiredChunksScriptTag(extraProps) {\n    const id = getRequiredChunkKey(this.namespace)\n    const props = `type=\"application/json\"${extraPropsToString(\n      null,\n      extraProps,\n    )}`\n    return [\n      `<script id=\"${id}\" ${props}>${this.getRequiredChunksScriptContent()}</script>`,\n      `<script id=\"${id}_ext\" ${props}>${this.getRequiredChunksNamesScriptContent()}</script>`,\n    ].join('')\n  }\n\n  getRequiredChunksScriptElements(extraProps) {\n    const id = getRequiredChunkKey(this.namespace)\n    const props = {\n      type: 'application/json',\n      ...handleExtraProps(null, extraProps),\n    }\n    return [\n      <script\n        id={id}\n        key={id}\n        dangerouslySetInnerHTML={{\n          __html: this.getRequiredChunksScriptContent(),\n        }}\n        {...props}\n      />,\n      <script\n        id={`${id}_ext`}\n        key={`${id}_ext`}\n        dangerouslySetInnerHTML={{\n          __html: this.getRequiredChunksNamesScriptContent(),\n        }}\n        {...props}\n      />,\n    ]\n  }\n\n  // Public methods\n  // -----------------\n\n  // Collect\n\n  addChunk(chunk) {\n    if (this.chunks.indexOf(chunk) !== -1) return\n    this.chunks.push(chunk)\n  }\n\n  collectChunks(app) {\n    return <ChunkExtractorManager extractor={this}>{app}</ChunkExtractorManager>\n  }\n\n  // Utilities\n\n  requireEntrypoint(entrypoint) {\n    const entrypointPath = this.getEntrypointPath(this.entrypoint)\n\n    this.getAllScriptAssetsPaths()\n      .forEach((assetPath) => {\n        smartRequire(assetPath)\n      })\n\n    return smartRequire(entrypointPath)\n  }\n\n  getEntrypointPath(entrypoint) {\n    entrypoint = entrypoint || this.entrypoints[0]\n    const assets = this.getChunkAssets(entrypoint)\n    const mainAsset = assets.find(asset => asset.scriptType === 'script')\n    invariant(mainAsset, 'asset not found')\n    return cleanFileName(mainAsset.path)\n  }\n\n  getAllScriptAssetsPaths() {\n    return this.stats.assets\n      .filter(({ name }) => isScriptFile(name))\n      .map(({ name }) => {\n        return path.join(this.outputPath, cleanFileName(name))\n      })\n  }\n\n  // Main assets\n\n  getMainAssets(scriptType) {\n    const chunks = [...this.entrypoints, ...this.chunks]\n    const assets = this.getChunkAssets(chunks)\n    if (scriptType) {\n      return assets.filter(asset => asset.scriptType === scriptType)\n    }\n    return assets\n  }\n\n  getScriptTags(extraProps = {}) {\n    const requiredScriptTag = this.getRequiredChunksScriptTag(extraProps)\n    const mainAssets = this.getMainAssets('script')\n    const assetsScriptTags = mainAssets.map(asset =>\n      assetToScriptTag(asset, extraProps),\n    )\n    return joinTags([requiredScriptTag, ...assetsScriptTags])\n  }\n\n  getScriptElements(extraProps = {}) {\n    const requiredScriptElements = this.getRequiredChunksScriptElements(\n      extraProps,\n    )\n    const mainAssets = this.getMainAssets('script')\n    const assetsScriptElements = mainAssets.map(asset =>\n      assetToScriptElement(asset, extraProps),\n    )\n    return [...requiredScriptElements, ...assetsScriptElements]\n  }\n\n  getCssString() {\n    const mainAssets = this.getMainAssets('style')\n    const promises = mainAssets.map(asset =>\n      assetToStyleString(asset, this).then(data => data),\n    )\n    return Promise.all(promises).then(results => joinTags(results))\n  }\n\n  getStyleTags(extraProps = {}) {\n    const mainAssets = this.getMainAssets('style')\n    return joinTags(mainAssets.map(asset => assetToStyleTag(asset, extraProps)))\n  }\n\n  getInlineStyleTags(extraProps = {}) {\n    const mainAssets = this.getMainAssets('style')\n    const promises = mainAssets.map(asset =>\n      assetToStyleTagInline(asset, extraProps, this).then(data => data),\n    )\n    return Promise.all(promises).then(results => joinTags(results))\n  }\n\n  getStyleElements(extraProps = {}) {\n    const mainAssets = this.getMainAssets('style')\n    return mainAssets.map(asset => assetToStyleElement(asset, extraProps))\n  }\n\n  getInlineStyleElements(extraProps = {}) {\n    const mainAssets = this.getMainAssets('style')\n    const promises = mainAssets.map(asset =>\n      assetToStyleElementInline(asset, extraProps, this).then(data => data),\n    )\n    return Promise.all(promises).then(results => results)\n  }\n\n  // Pre assets\n\n  getPreAssets() {\n    const mainAssets = this.getMainAssets()\n    const chunks = [...this.entrypoints, ...this.chunks]\n    const preloadAssets = this.getChunkChildAssets(chunks, 'preload')\n    const prefetchAssets = this.getChunkChildAssets(chunks, 'prefetch')\n    return [...mainAssets, ...preloadAssets, ...prefetchAssets].sort(a =>\n      a.scriptType === 'style' ? -1 : 0,\n    )\n  }\n\n  getLinkTags(extraProps = {}) {\n    const assets = this.getPreAssets()\n    const linkTags = assets.map(asset => assetToLinkTag(asset, extraProps))\n    return joinTags(linkTags)\n  }\n\n  getLinkElements(extraProps = {}) {\n    const assets = this.getPreAssets()\n    return assets.map(asset => assetToLinkElement(asset, extraProps))\n  }\n}\n\nexport default ChunkExtractor\n"
  },
  {
    "path": "packages/server/src/ChunkExtractor.test.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\nimport 'regenerator-runtime/runtime.js'\nimport path from 'path'\nimport stats from '../__fixtures__/stats.json'\nimport ChunkExtractor from './ChunkExtractor.js'\n\nconst targetPath = path.resolve(\n  __dirname,\n  '../../../examples/server-side-rendering/public/dist/node',\n)\n\ndescribe('ChunkExtrator', () => {\n  let extractor\n\n  beforeEach(() => {\n    extractor = new ChunkExtractor({\n      stats,\n      outputPath: targetPath,\n    })\n  })\n\n  describe('#resolvePublicUrl', () => {\n    it('should default to using stats.publicPath', () => {\n      expect(extractor.resolvePublicUrl('main.js')).toEqual(\n        '/dist/node/main.js',\n      )\n    })\n\n    it('should use publicPath from ChunkExtractor options', () => {\n      const testExtractor = new ChunkExtractor({\n        stats,\n        publicPath: 'https://cdn.example.org/v1.1.0/',\n        outputPath: path.resolve(__dirname, '../__fixtures__'),\n      })\n\n      expect(testExtractor.resolvePublicUrl('main.js')).toEqual(\n        'https://cdn.example.org/v1.1.0/main.js',\n      )\n    })\n  })\n\n  describe('#stats', () => {\n    it('should load stats from file', () => {\n      extractor = new ChunkExtractor({\n        statsFile: path.resolve(__dirname, '../__fixtures__/stats.json'),\n      })\n\n      expect(extractor.stats).toEqual(stats)\n    })\n  })\n\n  describe('#addChunk', () => {\n    it('should reference chunk', () => {\n      extractor.addChunk('foo')\n      expect(extractor.chunks).toEqual(['foo'])\n    })\n\n    it('should be uniq', () => {\n      extractor.addChunk('a')\n      extractor.addChunk('b')\n      extractor.addChunk('b')\n      expect(extractor.chunks).toEqual(['a', 'b'])\n    })\n  })\n\n  describe('#getScriptTags', () => {\n    it('should return main script tag without chunk', () => {\n      expect(extractor.getScriptTags()).toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\">[]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\">{\\\\\"namedChunks\\\\\":[]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\"></script>\"\n      `)\n    })\n\n    it('should return main script tag without chunk with namespaced required chunks id', () => {\n      const testExtractor = new ChunkExtractor({\n        namespace: 'testapp',\n        stats,\n        outputPath: path.resolve(__dirname, '../__fixtures__'),\n      })\n      expect(testExtractor.getScriptTags()).toMatchInlineSnapshot(`\n        \"<script id=\\\\\"testapp__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\">[]</script><script id=\\\\\"testapp__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\">{\\\\\"namedChunks\\\\\":[]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\"></script>\"\n      `)\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getScriptTags()).toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\">[\\\\\"letters-A\\\\\"]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\">{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\"></script>\n        <script async data-chunk=\\\\\"letters-A\\\\\" src=\\\\\"/dist/node/letters-A.js\\\\\"></script>\"\n      `)\n    })\n\n    // no longer matching anything\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getScriptTags()).toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\">[4]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\">{\\\\\"namedChunks\\\\\":[\\\\\"letters-E\\\\\"]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\"></script>\n        <script async data-chunk=\\\\\"letters-E\\\\\" src=\\\\\"/dist/node/letters-E.js\\\\\"></script>\"\n      `)\n    })\n\n    it('should add integrity if available in stats', () => {\n      const testExtractor = new ChunkExtractor({\n        stats: {\n          ...stats,\n          namedChunkGroups: {\n            ...stats.namedChunkGroups,\n            main: {\n              ...stats.namedChunkGroups.main,\n              assets: stats.namedChunkGroups.main.assets.map(name => ({\n                name,\n                // pseudo hash - reversed name\n                integrity: name\n                  .split('')\n                  .reverse()\n                  .join(''),\n              })),\n            },\n          },\n        },\n        outputPath: targetPath,\n      })\n      expect(testExtractor.getScriptTags({ crossorigin: 'anonymous' }))\n        .toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\" crossorigin=\\\\\"anonymous\\\\\">[]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\" crossorigin=\\\\\"anonymous\\\\\">{\\\\\"namedChunks\\\\\":[]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\" integrity=\\\\\"sj.niam\\\\\" crossorigin=\\\\\"anonymous\\\\\"></script>\"\n      `)\n    })\n\n    it('should add extra props if specified - object argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getScriptTags({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\" nonce=\\\\\"testnonce\\\\\">[\\\\\"letters-A\\\\\"]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\" nonce=\\\\\"testnonce\\\\\">{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\" nonce=\\\\\"testnonce\\\\\"></script>\n        <script async data-chunk=\\\\\"letters-A\\\\\" src=\\\\\"/dist/node/letters-A.js\\\\\" nonce=\\\\\"testnonce\\\\\"></script>\"\n      `)\n    })\n\n    it('should add extra props if specified - function argument', () => {\n      extractor.addChunk('letters-A')\n      expect(\n        extractor.getScriptTags(asset => {\n          return { nonce: asset ? asset.chunk : 'anonymous' }\n        }),\n      ).toMatchInlineSnapshot(`\n        \"<script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS__\\\\\" type=\\\\\"application/json\\\\\" nonce=\\\\\"anonymous\\\\\">[\\\\\"letters-A\\\\\"]</script><script id=\\\\\"__LOADABLE_REQUIRED_CHUNKS___ext\\\\\" type=\\\\\"application/json\\\\\" nonce=\\\\\"anonymous\\\\\">{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}</script>\n        <script async data-chunk=\\\\\"main\\\\\" src=\\\\\"/dist/node/main.js\\\\\" nonce=\\\\\"main\\\\\"></script>\n        <script async data-chunk=\\\\\"letters-A\\\\\" src=\\\\\"/dist/node/letters-A.js\\\\\" nonce=\\\\\"letters-A\\\\\"></script>\"\n      `)\n    })\n  })\n\n  describe('#getScriptElements', () => {\n    it('should return main script tag without chunk with namespaced id for loadable chunks', () => {\n      const testExtractor = new ChunkExtractor({\n        namespace: 'testapp',\n        stats,\n        outputPath: path.resolve(__dirname, '../__fixtures__'),\n      })\n      expect(testExtractor.getScriptElements()).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[]\",\n              }\n            }\n            id=\"testapp__LOADABLE_REQUIRED_CHUNKS__\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[]}\",\n              }\n            }\n            id=\"testapp__LOADABLE_REQUIRED_CHUNKS___ext\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            src=\"/dist/node/main.js\"\n          />,\n        ]\n      `)\n    })\n\n    it('should return main script tag without chunk', () => {\n      expect(extractor.getScriptElements()).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            src=\"/dist/node/main.js\"\n          />,\n        ]\n      `)\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getScriptElements()).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[\\\\\"letters-A\\\\\"]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            src=\"/dist/node/main.js\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"letters-A\"\n            src=\"/dist/node/letters-A.js\"\n          />,\n        ]\n      `)\n    })\n\n    // params not working\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getScriptElements()).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[\\\\\"letters-E\\\\\"]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[\\\\\"letters-E\\\\\"]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            src=\"/dist/node/main.js\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"letters-E\"\n            src=\"/dist/node/letters-E.js?param\"\n          />,\n        ]\n      `)\n    })\n\n    it('should add extra props if specified - object argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getScriptElements({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[\\\\\"letters-A\\\\\"]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            nonce=\"testnonce\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            nonce=\"testnonce\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            nonce=\"testnonce\"\n            src=\"/dist/node/main.js\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"letters-A\"\n            nonce=\"testnonce\"\n            src=\"/dist/node/letters-A.js\"\n          />,\n        ]\n      `)\n    })\n\n    it('should add extra props if specified - function argument', () => {\n      extractor.addChunk('letters-A')\n      expect(\n        extractor.getScriptElements(asset => {\n          return { nonce: asset ? asset.chunk : 'anonymous' }\n        }),\n      ).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[\\\\\"letters-A\\\\\"]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            nonce=\"anonymous\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[\\\\\"letters-A\\\\\"]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            nonce=\"anonymous\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            nonce=\"main\"\n            src=\"/dist/node/main.js\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"letters-A\"\n            nonce=\"letters-A\"\n            src=\"/dist/node/letters-A.js\"\n          />,\n        ]\n      `)\n    })\n\n    it('should use publicPath from options', () => {\n      const testExtractor = new ChunkExtractor({\n        stats,\n        publicPath: 'https://cdn.example.org/v1.1.0/',\n        outputPath: path.resolve(__dirname, '../__fixtures__'),\n      })\n\n      expect(testExtractor.getScriptElements()).toMatchInlineSnapshot(`\n        Array [\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"[]\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS__\"\n            type=\"application/json\"\n          />,\n          <script\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"{\\\\\"namedChunks\\\\\":[]}\",\n              }\n            }\n            id=\"__LOADABLE_REQUIRED_CHUNKS___ext\"\n            type=\"application/json\"\n          />,\n          <script\n            async={true}\n            data-chunk=\"main\"\n            src=\"https://cdn.example.org/v1.1.0/main.js\"\n          />,\n        ]\n      `)\n    })\n  })\n\n  describe('#getStyleTags', () => {\n    it('should return main style tag without chunk', () => {\n      expect(extractor.getStyleTags()).toMatchInlineSnapshot(\n        `\"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\"`,\n      )\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getStyleTags()).toMatchInlineSnapshot(`\n                \"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\n                <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\">\"\n            `)\n    })\n\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getStyleTags()).toMatchInlineSnapshot(`\n                \"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\n                <link data-chunk=\\\\\"letters-E\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/letters-E.css?param\\\\\">\"\n            `)\n    })\n\n    it('should add extraProps if specified - object argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getStyleTags({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n                \"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/main.css\\\\\" nonce=\\\\\"testnonce\\\\\">\n                <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\" nonce=\\\\\"testnonce\\\\\">\"\n            `)\n    })\n\n    it('should add extraProps if specified - function argument', () => {\n      extractor.addChunk('letters-A')\n      expect(\n        extractor.getStyleTags(asset => ({\n          nonce: asset ? asset.chunk : 'anonymous',\n        })),\n      ).toMatchInlineSnapshot(`\n                \"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/main.css\\\\\" nonce=\\\\\"main\\\\\">\n                <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"stylesheet\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\" nonce=\\\\\"letters-A\\\\\">\"\n            `)\n    })\n  })\n\n  describe('#getInlineStyleTags', () => {\n    it('should return inline style tags as a promise', async () => {\n      extractor.addChunk('letters-A')\n      const data = await extractor.getInlineStyleTags()\n      expect(data).toMatchInlineSnapshot(`\n        \"<style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"main\\\\\">\n        /* Main CSS */\n        h1 {\n            color: cyan;\n        }\n\n        </style>\n        <style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"letters-A\\\\\">\n        /* A CSS */\n        body {\n            background: pink;\n        }\n\n        </style>\"\n      `)\n    })\n\n    it('should add extraProps if specified - object argument', async () => {\n      extractor.addChunk('letters-A')\n      const data = await extractor.getInlineStyleTags({ nonce: 'testnonce' })\n      expect(data).toMatchInlineSnapshot(`\n        \"<style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"main\\\\\" nonce=\\\\\"testnonce\\\\\">\n        /* Main CSS */\n        h1 {\n            color: cyan;\n        }\n\n        </style>\n        <style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"letters-A\\\\\" nonce=\\\\\"testnonce\\\\\">\n        /* A CSS */\n        body {\n            background: pink;\n        }\n\n        </style>\"\n      `)\n    })\n\n    it('should add extraProps if specified - function argument', async () => {\n      extractor.addChunk('letters-A')\n      const data = await extractor.getInlineStyleTags(asset => ({\n        nonce: asset.chunk,\n      }))\n      expect(data).toMatchInlineSnapshot(`\n        \"<style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"main\\\\\" nonce=\\\\\"main\\\\\">\n        /* Main CSS */\n        h1 {\n            color: cyan;\n        }\n\n        </style>\n        <style type=\\\\\"text/css\\\\\" data-chunk=\\\\\"letters-A\\\\\" nonce=\\\\\"letters-A\\\\\">\n        /* A CSS */\n        body {\n            background: pink;\n        }\n\n        </style>\"\n      `)\n    })\n  })\n\n  describe('#getStyleElements', () => {\n    it('should return main style tag without chunk', () => {\n      expect(extractor.getStyleElements()).toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    rel=\"stylesheet\"\n                  />,\n                ]\n            `)\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getStyleElements()).toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    rel=\"stylesheet\"\n                  />,\n                  <link\n                    data-chunk=\"letters-A\"\n                    href=\"/dist/node/letters-A.css\"\n                    rel=\"stylesheet\"\n                  />,\n                ]\n            `)\n    })\n\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getStyleElements()).toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    rel=\"stylesheet\"\n                  />,\n                  <link\n                    data-chunk=\"letters-E\"\n                    href=\"/dist/node/letters-E.css?param\"\n                    rel=\"stylesheet\"\n                  />,\n                ]\n            `)\n    })\n\n    it('should add extraProps if specified - object argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getStyleElements({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    nonce=\"testnonce\"\n                    rel=\"stylesheet\"\n                  />,\n                  <link\n                    data-chunk=\"letters-A\"\n                    href=\"/dist/node/letters-A.css\"\n                    nonce=\"testnonce\"\n                    rel=\"stylesheet\"\n                  />,\n                ]\n            `)\n    })\n\n    it('should add extraProps if specified - function argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getStyleElements(asset => ({ nonce: asset.chunk })))\n        .toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    nonce=\"main\"\n                    rel=\"stylesheet\"\n                  />,\n                  <link\n                    data-chunk=\"letters-A\"\n                    href=\"/dist/node/letters-A.css\"\n                    nonce=\"letters-A\"\n                    rel=\"stylesheet\"\n                  />,\n                ]\n            `)\n    })\n  })\n\n  describe('#getInlineStyleElements', () => {\n    it('should return inline style elements as a promise', async () => {\n      extractor.addChunk('letters-A')\n      const data = await extractor.getInlineStyleElements()\n      expect(data).toMatchInlineSnapshot(`\n        Array [\n          <style\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"/* Main CSS */\n        h1 {\n            color: cyan;\n        }\n        \",\n              }\n            }\n            data-chunk=\"main\"\n          />,\n          <style\n            dangerouslySetInnerHTML={\n              Object {\n                \"__html\": \"/* A CSS */\n        body {\n            background: pink;\n        }\n        \",\n              }\n            }\n            data-chunk=\"letters-A\"\n          />,\n        ]\n      `)\n    })\n  })\n\n  describe('#getCssString', () => {\n    it('should return a string of the referenced css files as a promise', async () => {\n      extractor.addChunk('letters-A')\n      const data = await extractor.getCssString()\n      expect(data).toMatchInlineSnapshot(`\n        \"/* Main CSS */\n        h1 {\n            color: cyan;\n        }\n\n        /* A CSS */\n        body {\n            background: pink;\n        }\n        \"\n      `)\n    })\n\n    it('should work with custom fs', async () => {\n      extractor.inputFileSystem = {\n        readFile: jest.fn((file, encoding, callback) =>\n          callback(null, 'foo\\n'),\n        ),\n      }\n      extractor.addChunk('letters-A')\n      const data = await extractor.getCssString()\n      expect(extractor.inputFileSystem.readFile).toHaveBeenCalledTimes(2)\n      expect(data).toMatchInlineSnapshot(`\n        \"foo\n\n        foo\n        \"\n      `)\n    })\n  })\n\n  describe('#getLinkTags', () => {\n    it('should return main script tag without chunk', () => {\n      expect(extractor.getLinkTags()).toMatchInlineSnapshot(`\n                \"<link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\n                <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/main.js\\\\\">\n                <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-C.js\\\\\">\n                <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"prefetch\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-D.js\\\\\">\"\n            `)\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getLinkTags()).toMatchInlineSnapshot(`\n        \"<link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/main.js\\\\\">\n        <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-A.js\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-C.js\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"prefetch\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-D.js\\\\\">\"\n      `)\n    })\n\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getLinkTags()).toMatchInlineSnapshot(`\n        \"<link data-chunk=\\\\\"letters-E\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/letters-E.css?param\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/main.css\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/main.js\\\\\">\n        <link data-chunk=\\\\\"letters-E\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-E.js?param\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-C.js\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"prefetch\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-D.js\\\\\">\"\n      `)\n    })\n\n    it('should add extraProps if specified - object argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getLinkTags({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n        \"<link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\" nonce=\\\\\"testnonce\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/main.css\\\\\" nonce=\\\\\"testnonce\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/main.js\\\\\" nonce=\\\\\"testnonce\\\\\">\n        <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-A.js\\\\\" nonce=\\\\\"testnonce\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-C.js\\\\\" nonce=\\\\\"testnonce\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"prefetch\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-D.js\\\\\" nonce=\\\\\"testnonce\\\\\">\"\n      `)\n    })\n\n    it('should add extraProps if specified - function argument', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getLinkTags(asset => ({ nonce: asset.chunk })))\n        .toMatchInlineSnapshot(`\n        \"<link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/letters-A.css\\\\\" nonce=\\\\\"letters-A\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"style\\\\\" href=\\\\\"/dist/node/main.css\\\\\" nonce=\\\\\"main\\\\\">\n        <link data-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/main.js\\\\\" nonce=\\\\\"main\\\\\">\n        <link data-chunk=\\\\\"letters-A\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-A.js\\\\\" nonce=\\\\\"letters-A\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"preload\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-C.js\\\\\" nonce=\\\\\"main\\\\\">\n        <link data-parent-chunk=\\\\\"main\\\\\" rel=\\\\\"prefetch\\\\\" as=\\\\\"script\\\\\" href=\\\\\"/dist/node/letters-D.js\\\\\" nonce=\\\\\"main\\\\\">\"\n      `)\n    })\n  })\n\n  describe('#getLinkElements', () => {\n    it('should return main script tag without chunk', () => {\n      expect(extractor.getLinkElements()).toMatchInlineSnapshot(`\n                Array [\n                  <link\n                    as=\"style\"\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.css\"\n                    rel=\"preload\"\n                  />,\n                  <link\n                    as=\"script\"\n                    data-chunk=\"main\"\n                    href=\"/dist/node/main.js\"\n                    rel=\"preload\"\n                  />,\n                  <link\n                    as=\"script\"\n                    data-parent-chunk=\"main\"\n                    href=\"/dist/node/letters-C.js\"\n                    rel=\"preload\"\n                  />,\n                  <link\n                    as=\"script\"\n                    data-parent-chunk=\"main\"\n                    href=\"/dist/node/letters-D.js\"\n                    rel=\"prefetch\"\n                  />,\n                ]\n            `)\n    })\n\n    it('should return other chunks if referenced', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getLinkElements()).toMatchInlineSnapshot(`\n        Array [\n          <link\n            as=\"style\"\n            data-chunk=\"letters-A\"\n            href=\"/dist/node/letters-A.css\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"style\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.css\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.js\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"letters-A\"\n            href=\"/dist/node/letters-A.js\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-C.js\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-D.js\"\n            rel=\"prefetch\"\n          />,\n        ]\n      `)\n    })\n\n    it.skip('should allow for query params in chunk names', () => {\n      extractor.addChunk('letters-E')\n      expect(extractor.getLinkElements()).toMatchInlineSnapshot(`\n        Array [\n          <link\n            as=\"style\"\n            data-chunk=\"letters-E\"\n            href=\"/dist/node/letters-E.css?param\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"style\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.css\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.js\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"letters-E\"\n            href=\"/dist/node/letters-E.js?param\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-C.js\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-D.js\"\n            rel=\"prefetch\"\n          />,\n        ]\n      `)\n    })\n\n    it('should add extraProps if specified', () => {\n      extractor.addChunk('letters-A')\n      expect(extractor.getLinkElements({ nonce: 'testnonce' }))\n        .toMatchInlineSnapshot(`\n        Array [\n          <link\n            as=\"style\"\n            data-chunk=\"letters-A\"\n            href=\"/dist/node/letters-A.css\"\n            nonce=\"testnonce\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"style\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.css\"\n            nonce=\"testnonce\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"main\"\n            href=\"/dist/node/main.js\"\n            nonce=\"testnonce\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-chunk=\"letters-A\"\n            href=\"/dist/node/letters-A.js\"\n            nonce=\"testnonce\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-C.js\"\n            nonce=\"testnonce\"\n            rel=\"preload\"\n          />,\n          <link\n            as=\"script\"\n            data-parent-chunk=\"main\"\n            href=\"/dist/node/letters-D.js\"\n            nonce=\"testnonce\"\n            rel=\"prefetch\"\n          />,\n        ]\n      `)\n    })\n  })\n\n  describe('#requireEntryPoint', () => {\n    it('should load the first entrypoint', () => {\n      const x = extractor.requireEntrypoint()\n      expect(x.hello).toBe('hello')\n    })\n  })\n})\n"
  },
  {
    "path": "packages/server/src/ChunkExtractorManager.js",
    "content": "import React from 'react'\nimport { Context } from './sharedInternals.js'\n\nconst ChunkExtractorManager = ({ extractor, children }) => (\n  <Context.Provider value={extractor}>{children}</Context.Provider>\n)\n\nexport default ChunkExtractorManager\n"
  },
  {
    "path": "packages/server/src/index.js",
    "content": "export { default as ChunkExtractorManager } from './ChunkExtractorManager.js'\nexport { default as ChunkExtractor } from './ChunkExtractor.js'\n"
  },
  {
    "path": "packages/server/src/sharedInternals.js",
    "content": "/* eslint-disable no-underscore-dangle */\nimport { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@loadable/component'\n\nconst {\n  invariant,\n  Context,\n  getRequiredChunkKey,\n} = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n\nexport { invariant, Context, getRequiredChunkKey }\n"
  },
  {
    "path": "packages/server/src/util.js",
    "content": "// Use __non_webpack_require__ to prevent Webpack from compiling it\n// when the server-side code is compiled with Webpack\n// eslint-disable-next-line camelcase, no-undef, global-require, import/no-dynamic-require, no-eval\nconst getRequire = () =>\n  typeof __non_webpack_require__ !== 'undefined'\n    ? __non_webpack_require__\n    : eval('require')\n\nexport const clearModuleCache = moduleName => {\n  const { cache } = getRequire()\n  const m = cache[moduleName]\n  if (m) {\n    // remove self from own parents\n    if (m.parent && m.parent.children) {\n      m.parent.children = m.parent.children.filter(x => x !== m)\n    }\n    // remove self from own children\n    if (m.children) {\n      m.children.forEach(child => {\n        if (child.parent && child.parent === m) {\n          child.parent = null\n        }\n      })\n    }\n    delete cache[moduleName]\n  }\n}\n\nexport const smartRequire = modulePath => {\n  if (process.env.NODE_ENV !== 'production' && module.hot) {\n    clearModuleCache(modulePath)\n  }\n\n  return getRequire()(modulePath)\n}\n\nexport const joinURLPath = (publicPath, filename) => {\n  if (publicPath.substr(-1) === '/') {\n    return `${publicPath}${filename}`\n  }\n\n  return `${publicPath}/${filename}`\n}\n\nexport const readJsonFileSync = (inputFileSystem, jsonFilePath) => {\n  return JSON.parse(inputFileSystem.readFileSync(jsonFilePath))\n}\n"
  },
  {
    "path": "packages/server/src/util.test.js",
    "content": "import { joinURLPath } from './util.js'\n\ndescribe('util', () => {\n  describe('#joinURLPath', () => {\n    it('should join paths with relative public path', () => {\n      expect(joinURLPath('public', 'style.css')).toBe('public/style.css')\n      expect(joinURLPath('public/', 'style.css')).toBe('public/style.css')\n    })\n\n    it('should join paths starting with \"/\"', () => {\n      expect(joinURLPath('/foo', 'style.css')).toBe('/foo/style.css')\n      expect(joinURLPath('/', 'style.css')).toBe('/style.css')\n    })\n\n    it('should join paths with absolute public path', () => {\n      const publicPath = 'http://localhost:3001/public'\n\n      expect(joinURLPath(publicPath, 'style.css')).toBe(\n        `http://localhost:3001/public/style.css`,\n      )\n      expect(joinURLPath(`${publicPath}/`, 'style.css')).toBe(\n        `http://localhost:3001/public/style.css`,\n      )\n    })\n\n    it('should join paths with protocol free public path', () => {\n      const publicPath = '//127.0.0.1/public'\n      expect(joinURLPath(publicPath, 'style.css')).toBe(\n        `//127.0.0.1/public/style.css`,\n      )\n    })\n  })\n})\n"
  },
  {
    "path": "packages/webpack-plugin/.npmignore",
    "content": "src/\n.*\n"
  },
  {
    "path": "packages/webpack-plugin/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [5.15.2](https://github.com/gregberge/loadable-components/compare/v5.15.1...v5.15.2) (2021-12-12)\n\n**Note:** Version bump only for package @loadable/webpack-plugin\n\n\n\n\n\n## [5.15.1](https://github.com/gregberge/loadable-components/compare/v5.15.0...v5.15.1) (2021-08-17)\n\n\n### Bug Fixes\n\n* add cachedAssets to stats options ([#779](https://github.com/gregberge/loadable-components/issues/779)) ([73b17fd](https://github.com/gregberge/loadable-components/commit/73b17fd067579b1c5d38eba00e157964e0930a94)), closes [#770](https://github.com/gregberge/loadable-components/issues/770)\n* SubResourceIntegrity ([#803](https://github.com/gregberge/loadable-components/issues/803)) ([9b34195](https://github.com/gregberge/loadable-components/commit/9b34195627c65372a7c834311c32dfcbd5b7fedd))\n\n\n\n\n\n# [5.15.0](https://github.com/gregberge/loadable-components/compare/v5.14.2...v5.15.0) (2021-05-08)\n\n\n### Features\n\n* support multiple Webpack runtimes ([#701](https://github.com/gregberge/loadable-components/issues/701)) ([d351367](https://github.com/gregberge/loadable-components/commit/d3513679ed680e46967ca18555116c06e5a4b341))\n* webpack plugin doesn't need all chunk info ([#735](https://github.com/gregberge/loadable-components/issues/735)) ([cea9f24](https://github.com/gregberge/loadable-components/commit/cea9f249f7550a1154cf88bcfa3812ebb78a500f))\n\n\n\n\n\n## [5.14.2](https://github.com/gregberge/loadable-components/compare/v5.14.1...v5.14.2) (2021-01-31)\n\n\n### Bug Fixes\n\n* ignore css chunk ([#689](https://github.com/gregberge/loadable-components/issues/689)) ([6926e19](https://github.com/gregberge/loadable-components/commit/6926e190c80f525467980fffbbded0bf933f27ed))\n* update hooks for webpack 5 ([#676](https://github.com/gregberge/loadable-components/issues/676)) ([671ef52](https://github.com/gregberge/loadable-components/commit/671ef527e7a37c459df616ee74dc92e106e8245e))\n\n\n\n\n\n# [5.14.0](https://github.com/gregberge/loadable-components/compare/v5.13.2...v5.14.0) (2020-10-20)\n\n\n### Features\n\n* make packages webpack 5 compatible ([#638](https://github.com/gregberge/loadable-components/issues/638)) ([e882e4d](https://github.com/gregberge/loadable-components/commit/e882e4d812e714066eba19a11dd119193e7a9e01))\n\n\n\n\n\n# [5.13.0](https://github.com/gregberge/loadable-components/compare/v5.12.0...v5.13.0) (2020-06-29)\n\n\n### Bug Fixes\n\n* use make-dir instead of mkdirp ([#544](https://github.com/gregberge/loadable-components/issues/544)) ([5a9c33b](https://github.com/gregberge/loadable-components/commit/5a9c33b222fecb320dc02b643122fbe717aa6fc8))\n\n\n\n\n\n# [5.12.0](https://github.com/gregberge/loadable-components/compare/v5.11.0...v5.12.0) (2020-01-09)\n\n\n### Performance Improvements\n\n* avoid calling stats.toJson if possible ([87698de](https://github.com/gregberge/loadable-components/commit/87698de079cb742317a4f6570430ccd5cd526d3e))\n\n\n\n\n\n## [5.7.1](https://github.com/smooth-code/loadable-components/compare/v5.7.0...v5.7.1) (2019-03-19)\n\n\n### Bug Fixes\n\n* **webpack-plugin:** create output folder with mkdirp ([#273](https://github.com/smooth-code/loadable-components/issues/273)) ([3767f28](https://github.com/smooth-code/loadable-components/commit/3767f28))\n\n\n\n\n\n# [5.7.0](https://github.com/smooth-code/loadable-components/compare/v5.6.1...v5.7.0) (2019-03-14)\n\n\n### Performance Improvements\n\n* **build:** add build target for Node ([#267](https://github.com/smooth-code/loadable-components/issues/267)) ([97ff6ac](https://github.com/smooth-code/loadable-components/commit/97ff6ac))\n\n\n\n\n\n# [5.5.0](https://github.com/smooth-code/loadable-components/compare/v5.4.0...v5.5.0) (2019-01-22)\n\n**Note:** Version bump only for package @loadable/webpack-plugin\n\n\n\n\n\n# [5.4.0](https://github.com/smooth-code/loadable-components/compare/v5.3.0...v5.4.0) (2019-01-17)\n\n\n### Features\n\n* **webpack-plugin:** support custom path in writeToDisk option ([#187](https://github.com/smooth-code/loadable-components/issues/187)) ([4a6f84f](https://github.com/smooth-code/loadable-components/commit/4a6f84f))\n\n\n\n\n\n## [5.2.2](https://github.com/smooth-code/loadable-components/compare/v5.2.1...v5.2.2) (2018-12-12)\n\n**Note:** Version bump only for package @loadable/webpack-plugin\n\n\n\n\n\n## [5.2.1](https://github.com/smooth-code/loadable-components/compare/v5.2.0...v5.2.1) (2018-11-27)\n\n\n### Bug Fixes\n\n* **webpack-plugin:** fix TypeError when set writeToDisk true ([#170](https://github.com/smooth-code/loadable-components/issues/170)) ([2d1fb11](https://github.com/smooth-code/loadable-components/commit/2d1fb11))\n\n\n\n\n\n# [5.2.0](https://github.com/smooth-code/loadable-components/compare/v5.1.3...v5.2.0) (2018-11-23)\n\n\n### Features\n\n* **webpack-plugin:** add writeToDisk option ([#161](https://github.com/smooth-code/loadable-components/issues/161)) ([6b5ba21](https://github.com/smooth-code/loadable-components/commit/6b5ba21))\n\n\n\n\n\n## [5.0.2](https://github.com/smooth-code/loadable-components/compare/v5.0.1...v5.0.2) (2018-11-10)\n\n\n### Bug Fixes\n\n* update peer dependencies ([b0363dc](https://github.com/smooth-code/loadable-components/commit/b0363dc))\n\n\n\n\n\n# [5.0.0](https://github.com/smooth-code/loadable-components/compare/v4.0.5...v5.0.0) (2018-11-10)\n\n\n### Features\n\n* improve SSR support ([eb1cfe8](https://github.com/smooth-code/loadable-components/commit/eb1cfe8))\n\n\n### BREAKING CHANGES\n\n* - SSR has been rewritten from scratch, if you use it, please follow the\nnew guide.\n- Prefetch component and prefetch functions have been removed, please\nuse `webpackPrefetch` instead.\n\n\n\n\n\n## [4.0.5](https://github.com/smooth-code/loadable-components/compare/v4.0.4...v4.0.5) (2018-11-01)\n\n**Note:** Version bump only for package @loadable/webpack-plugin\n\n\n\n\n\n## [4.0.4](https://github.com/smooth-code/loadable-components/compare/v4.0.3...v4.0.4) (2018-10-31)\n\n\n### Bug Fixes\n\n* fix peer dependencies ([6816e8c](https://github.com/smooth-code/loadable-components/commit/6816e8c))\n\n\n\n\n\n## [4.0.3](https://github.com/smooth-code/loadable-components/compare/v4.0.2...v4.0.3) (2018-10-31)\n\n\n### Bug Fixes\n\n* **server:** disable common chunks optim ([78e7b28](https://github.com/smooth-code/loadable-components/commit/78e7b28))\n\n\n\n\n\n# [4.0.0](https://github.com/smooth-code/loadable-components/compare/v3.0.2...v4.0.0) (2018-10-30)\n\n\n### Features\n\n* add new loadable.lib, change API ([94b2e87](https://github.com/smooth-code/loadable-components/commit/94b2e87))\n\n\n### BREAKING CHANGES\n\n* - `ErrorComponent` is ignored, please use Error Boundaries to handle errors.\n- `lazy` is no longer exported\n- `LoadingComponent` is replaced by `fallback` option\n- `ref` are now forwarded\n\n\n\n\n\n# [3.0.0](https://github.com/smooth-code/loadable-components/compare/v2.2.3...v3.0.0) (2018-10-29)\n\n\n### Features\n\n* welcome loadable ([4dffad7](https://github.com/smooth-code/loadable-components/commit/4dffad7))\n\n\n### BREAKING CHANGES\n\n* API has completely changed, see documentation.\n"
  },
  {
    "path": "packages/webpack-plugin/README.md",
    "content": "# @loadable/webpack-plugin\n\nThis plugin is required only if you use Server Side Rendering in your application. [See `@loadable/server` for more information](https://loadable-components.com/docs/api-loadable-server/).\n\n## Install\n\n```\b\nnpm install --save-dev @loadable/webpack-plugin\n```\n\n## Documentation\n\n👉 [See full documentation](https://loadable-components.com/)\n\n## License\n\nMIT\n"
  },
  {
    "path": "packages/webpack-plugin/package.json",
    "content": "{\n  \"name\": \"@loadable/webpack-plugin\",\n  \"description\": \"Webpack plugin for loadable (required for SSR).\",\n  \"version\": \"5.15.2\",\n  \"main\": \"lib/index.js\",\n  \"repository\": \"git@github.com:gregberge/loadable-components.git\",\n  \"author\": \"Greg Bergé <berge.greg@gmail.com>\",\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"keywords\": [\n    \"loadable\"\n  ],\n  \"engines\": {\n    \"node\": \">=8\"\n  },\n  \"funding\": {\n    \"type\": \"github\",\n    \"url\": \"https://github.com/sponsors/gregberge\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"prebuild\": \"shx rm -rf lib\",\n    \"build\": \"BUILD_TARGET=node babel --config-file ../../babel.config.js -d lib --ignore \\\"**/*.test.js\\\" src\",\n    \"prepublishOnly\": \"yarn run build\"\n  },\n  \"peerDependencies\": {\n    \"webpack\": \">=4.6.0\"\n  },\n  \"dependencies\": {\n    \"make-dir\": \"^3.0.2\"\n  }\n}\n"
  },
  {
    "path": "packages/webpack-plugin/src/index.js",
    "content": "const nodePath = require('path')\nconst fs = require('fs')\nconst makeDir = require('make-dir')\n\nconst name = '@loadable/webpack-plugin'\n\nclass LoadablePlugin {\n  constructor({\n    filename = 'loadable-stats.json',\n    path,\n    writeToDisk,\n    outputAsset = true,\n    chunkLoadingGlobal = '__LOADABLE_LOADED_CHUNKS__',\n  } = {}) {\n    this.opts = { filename, writeToDisk, outputAsset, path, chunkLoadingGlobal }\n\n    // The Webpack compiler instance\n    this.compiler = null\n  }\n\n  handleEmit = compilation => {\n    const stats = compilation.getStats().toJson({\n      all: false,\n      assets: true,\n      cachedAssets: true,\n      chunks: false,\n      chunkGroups: true,\n      chunkGroupChildren: true,\n      hash: true,\n      ids: true,\n      outputPath: true,\n      publicPath: true,\n    })\n\n    stats.generator = 'loadable-components'\n\n    // we don't need all chunk information, only a type\n    stats.chunks = [...compilation.chunks].map(chunk => {\n      return {\n        id: chunk.id,\n        files: [...chunk.files],\n      }\n    })\n\n    // update namedChunkGroups with integrity from webpack-subresource-integrity if available\n    Object.values(stats.namedChunkGroups).forEach(namedChunkGroup => {\n      namedChunkGroup.assets.forEach(namedChunkGroupAsset => {\n        if (!namedChunkGroupAsset.integrity) {\n          const asset =\n            stats.assets.find(a => a.name === namedChunkGroupAsset.name) || {}\n          if (asset.integrity) {\n            namedChunkGroupAsset.integrity = asset.integrity\n          }\n        }\n      })\n    })\n\n    const result = JSON.stringify(stats, null, 2)\n\n    if (this.opts.writeToDisk) {\n      this.writeAssetsFile(result)\n    }\n\n    if (this.opts.outputAsset) {\n      return {\n        source() {\n          return result\n        },\n        size() {\n          return result.length\n        },\n      }\n    }\n\n    return null\n  }\n\n  /**\n   * Write Assets Manifest file\n   * @method writeAssetsFile\n   */\n  writeAssetsFile = manifest => {\n    const outputFolder =\n      this.opts.writeToDisk.filename || this.compiler.options.output.path\n\n    const outputFile = nodePath.resolve(outputFolder, this.opts.filename)\n\n    try {\n      if (!fs.existsSync(outputFolder)) {\n        makeDir.sync(outputFolder)\n      }\n    } catch (err) {\n      if (err.code !== 'EEXIST') {\n        throw err\n      }\n    }\n\n    fs.writeFileSync(outputFile, manifest)\n  }\n\n  apply(compiler) {\n    this.compiler = compiler\n\n    const version = 'jsonpFunction' in compiler.options.output ? 4 : 5\n\n    // Add a custom chunk loading callback\n    if (version === 4) {\n      compiler.options.output.jsonpFunction = this.opts.chunkLoadingGlobal\n    } else {\n      compiler.options.output.chunkLoadingGlobal = this.opts.chunkLoadingGlobal\n    }\n\n    if (this.opts.outputAsset || this.opts.writeToDisk) {\n      if (version === 4) {\n        // webpack 4\n        compiler.hooks.emit.tap(name, compilation => {\n          const asset = this.handleEmit(compilation)\n          if (asset) {\n            compilation.assets[this.opts.filename] = asset\n          }\n        })\n      } else {\n        // webpack 5\n        compiler.hooks.make.tap(name, compilation => {\n          compilation.hooks.processAssets.tap(\n            {\n              name,\n              stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT,\n            },\n            () => {\n              const asset = this.handleEmit(compilation)\n              if (asset) {\n                compilation.emitAsset(this.opts.filename, asset)\n              }\n            },\n          )\n        })\n      }\n    }\n  }\n}\n\nmodule.exports = LoadablePlugin\nmodule.exports.default = LoadablePlugin\n"
  },
  {
    "path": "scripts/copy-stats-fixture.js",
    "content": "const fs = require('fs')\nconst path = require('path')\n\nconst stats = fs.readFileSync(\n  '../examples/server-side-rendering/public/dist/node/loadable-stats.json',\n  'utf-8',\n)\nconst localPath = path.resolve(__dirname, '..')\n// write cleaned from PII data\nfs.writeFileSync(\n  '../packages/server/__fixtures__/stats.json',\n  stats.split(localPath).join('../..'),\n)\n"
  },
  {
    "path": "scripts/git-release.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nBRANCH=$(git rev-parse --abbrev-ref HEAD)\n\nyarn run lerna version --conventional-prerelease --preid from-git --no-git-tag-version --no-push --allow-branch $BRANCH --yes\ngit add .\ngit commit -m \"Publish to git\"\n\nfor DIR in $(yarn run -s lerna changed --parseable); do\n  (\n    VERSION=$(cat \"${DIR}/package.json\" | jq -r '.version')\n    NAME=$(cat \"${DIR}/package.json\" | jq -r '.name')\n\n    (\n      cd \"$DIR\"\n      yarn run prepublishOnly\n    )\n    yarn run npm-publish-git --dir \"$DIR\" --tag \"${NAME}/${BRANCH}/${VERSION}\"\n  )\ndone\n"
  },
  {
    "path": "scripts/prepare.sh",
    "content": "#!/usr/bin/env bash\n\nset -xe\n\necho \"building example\"\n(cd \"$( dirname \"${BASH_SOURCE[0]}\" )/../examples/server-side-rendering\" && yarn && yarn build)\n\necho \"generating fixtures\"\n(cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && node ./copy-stats-fixture.js)\n\necho \"done\""
  },
  {
    "path": "website/.eslintignore",
    "content": ".cache/\nnode_modules/\n/public/"
  },
  {
    "path": "website/.eslintrc.json",
    "content": "{\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"import/extensions\": \"off\"\n  }\n}\n"
  },
  {
    "path": "website/.gitignore",
    "content": ".cache/\nnode_modules/\n/public/"
  },
  {
    "path": "website/README.md",
    "content": "# Loadable Components website\n\n[Documentation site](https://loadable-components.com/) for [loadable components](https://github.com/gregberge/loadable-components). This website is running on [gatsbyjs](https://gatsbyjs.com/).\n\n## Getting Started\n\nTo install and run the docs site locally:\n\n```bash\nyarn\nyarn dev\n```\n\nThen, open your favorite browser to [localhost:8000](http://localhost:8000/). GraphiQL runs at [localhost:8000/\\_\\_\\_graphql](http://localhost:8000/___graphql).\n\n## Contributing\n\nBuild the site to test locally.\n\n```bash\nyarn build\n```\n\nServe the build.\n\n```bash\nyarn serve\n```\n\nThen, open your favorite browser to [localhost:9000](http://localhost:9000/) to verify everything looks correct.\n"
  },
  {
    "path": "website/_redirects",
    "content": "https://loadable-components.netlify.com/* https://loadable-components.com/:splat 301!"
  },
  {
    "path": "website/gatsby-config.js",
    "content": "module.exports = {\n  plugins: [\n    {\n      resolve: 'smooth-doc',\n      options: {\n        name: 'Loadable Components',\n        slug: 'loadable-components',\n        author: 'Greg Bergé',\n        description: 'The recommended Code Splitting library for React.',\n        siteUrl: 'https://loadable-components.com',\n        github: 'https://github.com/gregberge/loadable-components',\n        menu: ['Introduction', 'Guides', 'API'],\n        nav: [{ title: 'Docs', url: '/docs/getting-started/' }],\n        carbonAdUrl:\n          '//cdn.carbonads.com/carbon.js?serve=CE7I5K3U&placement=loadable-componentscom',\n        googleAnalytics: 'UA-154156493-1',\n        algoliaDocSearch: {\n          apiKey: 'e6a731577a7b94aefdbb1fb7dcc71e68',\n          indexName: 'smooth-code-loadable-components',\n        },\n      },\n    },\n    {\n      resolve: '@bundle-analyzer/gatsby-plugin',\n      options: {\n        token: '385aa427a43b4e840d763a07f672131a57decf45',\n      },\n    },\n  ],\n}\n"
  },
  {
    "path": "website/gatsby-node.js",
    "content": "module.exports.createPages = ({ actions }) => {\n  actions.createRedirect({\n    fromPath: `/docs/`,\n    toPath: `/docs/getting-started/`,\n    redirectInBrowser: true,\n  })\n}\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"build\": \"gatsby build && cp _redirects public/\",\n    \"dev\": \"gatsby develop\",\n    \"serve\": \"gatsby serve\"\n  },\n  \"dependencies\": {\n    \"@bundle-analyzer/gatsby-plugin\": \"^0.5.1\",\n    \"@xstyled/styled-components\": \"^1.17.1\",\n    \"gatsby\": \"^2.24.2\",\n    \"react\": \"^16.13.1\",\n    \"react-dom\": \"^16.13.1\",\n    \"react-helmet\": \"^6.1.0\",\n    \"smooth-doc\": \"^4.0.3\"\n  }\n}\n"
  },
  {
    "path": "website/src/pages/docs/api-loadable-component.mdx",
    "content": "---\nmenu: API\ntitle: '@loadable/component'\norder: 10\n---\n\n# @loadable/component\n\n## loadable\n\nCreate a loadable component.\n\n| Arguments                  | Description                                                          |\n| -------------------------- | -------------------------------------------------------------------- |\n| `loadFn`                   | The function call to load the component.                             |\n| `options`                  | Optional options.                                                    |\n| `options.resolveComponent` | Function to resolve the imported component from the imported module. |\n| `options.fallback`         | Fallback displayed during the loading.                               |\n| `options.ssr`              | If `false`, it will not be processed server-side. Default to `true`. |\n| `options.cacheKey`         | Cache key function (see [dynamic import](/docs/dynamic-import/))     |\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n```\n\n### `options.resolveComponent`\n\nThis is a function that receives the imported module (what the `import()` call resolves to) and the props, and returns the component.\n\nThe default value assumes that the component is exported as a default export.\nIt can be customized to make a loadable component where the imported component is not the default export, or even where a different export is chosen depending on the props.\nFor example:\n\n```js\n// components.js\n\nexport const Apple = () => 'Apple!'\nexport const Orange = () => 'Orange!'\n```\n\n```js\n// loadable.js\n\nconst LoadableApple = loadable(() => import('./components'), {\n  resolveComponent: components => components.Apple,\n})\n\nconst LoadableOrange = loadable(() => import('./components'), {\n  resolveComponent: components => components.Orange,\n})\n\nconst LoadableFruit = loadable(() => import('./components'), {\n  resolveComponent: (components, props) => components[props.fruit],\n})\n```\n\n**Note:** The default `resolveComponent` breaks Typescript type inference due to CommonJS compatibility.\nTo avoid this, you can specify `resolveComponent` as `(imported) => imported.default`.\nThis requires that the imported components have ES6/Harmony exports.\n\n## lazy\n\nCreate a loadable component \"Suspense\" ready.\n\n| Arguments | Description                              |\n| --------- | ---------------------------------------- |\n| `loadFn`  | The function call to load the component. |\n\n```js\nimport { lazy } from '@loadable/component'\n\nconst OtherComponent = lazy(() => import('./OtherComponent'))\n```\n\n## LoadableComponent\n\nA component created using `loadable` or `lazy`.\n\n| Props      | Description                                       |\n| ---------- | ------------------------------------------------- |\n| `fallback` | Fallback displayed during the loading.            |\n| `...`      | Props are forwarded as first argument of `loadFn` |\n\n## LoadableComponent.preload\n\nTriggers the loading of a component.\n\n| Arguments | Description                        |\n| --------- | ---------------------------------- |\n| `args`    | Props passed to the load function. |\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nOtherComponent.preload()\n```\n\n> This method does not return a Promise intentionally. Use `load` if you need to wait for the component to be loaded.\n\n## LoadableComponent.load\n\nForce the loading of a component synchronously, returns a Promise.\n\n| Arguments | Description                        |\n| --------- | ---------------------------------- |\n| `args`    | Props passed to the load function. |\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nOtherComponent.load().then(() => {\n  console.log('Component is loaded!')\n})\n```\n\n> If you don't need to know when the component will be loaded, you should use `preload` instead.\n\n## loadable.lib\n\nCreate a loadable library.\n\n| Arguments                  | Description                                                          |\n| -------------------------- | -------------------------------------------------------------------- |\n| `loadFn`                   | The function call to load the component.                             |\n| `options`                  | Optional options.                                                    |\n| `options.resolveComponent` | Function to resolve the imported component from the imported module. |\n| `options.fallback`         | Fallback displayed during the loading.                               |\n| `options.ssr`              | If `false`, it will not be processed server-side. Default to `true`. |\n| `options.cacheKey`         | Cache key function (see [dynamic import](/docs/dynamic-import))      |\n\n```js\nimport loadable from '@loadable/component'\n\nconst Moment = loadable.lib(() => import('moment'))\n```\n\n## lazy.lib\n\nCreate a loadable library \"Suspense\" ready.\n\n| Arguments | Description                              |\n| --------- | ---------------------------------------- |\n| `loadFn`  | The function call to load the component. |\n\n```js\nimport { lazy } from '@loadable/component'\n\nconst Moment = lazy.lib(() => import('moment'))\n```\n\n## LoadableLibrary\n\nA component created using `loadable.lib` or `lazy.lib`.\n\n| Props      | Description                                          |\n| ---------- | ---------------------------------------------------- |\n| `children` | Function called when the library is loaded.          |\n| `ref`      | Accepts a ref, populated when the library is loaded. |\n| `fallback` | Fallback displayed during the loading.               |\n| `...`      | Props are forwarded as first argument of `loadFn`    |\n\n## loadableReady\n\nWait for all loadable components to be loaded. This method must only be used with Server Side Rendering, see [Server Side Rendering guide](/docs/server-side-rendering/).\n\n| Arguments                    | Description                                                                               |\n| ---------------------------- | ----------------------------------------------------------------------------------------- |\n| `done`                       | Function called when all components are loaded.                                           |\n| `options`                    | Optional options.                                                                         |\n| `options.namespace`          | Namespace of your application (use only if you have several React apps on the same page). |\n| `options.chunkLoadingGlobal` | A custom `chunkLoadingGlobal` if set in the Webpack plugin                                |\n\n```js\nimport { loadableReady } from '@loadable/component'\n\nloadableReady(() => {\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n```\n"
  },
  {
    "path": "website/src/pages/docs/api-loadable-server.mdx",
    "content": "---\nmenu: API\ntitle: '@loadable/server'\norder: 20\n---\n\n# @loadable/server\n\n## ChunkExtractor\n\nUsed to collect chunks server-side and get them as script tags or script elements.\n\n| Arguments                 | Description                                                                               |\n| ------------------------- | ----------------------------------------------------------------------------------------- |\n| `options`                 | An object options.                                                                        |\n| `options.statsFile`       | Stats file path generated using `@loadable/webpack-plugin`.                               |\n| `options.stats`           | Stats generated using `@loadable/webpack-plugin`.                                         |\n| `options.entrypoints`     | Webpack entrypoints to load (default to `[\"main\"]`).                                      |\n| `options.outputPath`      | Optional output path (for functions using the file system, like `requireEntrypoint`).     |\n| `options.namespace`       | Namespace of your application (use only if you have several React apps on the same page). |\n| `options.inputFileSystem` | File system used to read files (default to `fs`).                                         |\n| `options.publicPath`      | The public path used at runtime.                                                          |\n\nYou must specify either `statsFile` or `stats` to be able to use `ChunkExtractor`.\n\nUsing `statsFile` will automatically reload stats for you if they change.\n\n```js\nimport { ChunkExtractor } from '@loadable/server'\n\nconst statsFile = path.resolve('..', 'dist', 'loadable-stats.json')\nconst chunkExtractor = new ChunkExtractor({ statsFile })\n```\n\n## chunkExtractor.collectChunks\n\nWrap your application in a `ChunkExtractorManager`.\n\n| Arguments | Description                                                  |\n| --------- | ------------------------------------------------------------ |\n| `element` | JSX element that will be wrapped in `ChunkExtractorManager`. |\n\n```js\nconst app = chunkExtractor.collectChunks(<YourApp />)\n```\n\n## chunkExtractor.requireEntrypoint\n\nRequire the entrypoint of your application as a commonjs module.\n\n| Arguments | Description                                                      |\n| --------- | ---------------------------------------------------------------- |\n| `name`    | Optional name the entrypoint, default to the first one (`main`). |\n\n```js\nconst { default: App } = chunkExtractor.requireEntrypoint()\nconst app = <App />\n```\n\n## chunkExtractor.getScriptTags\n\nGet scripts as a string of `<script>` tags.\n\n| Arguments                | Description                                                                                                 |\n| ------------------------ | ----------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to script tags, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nconst body = `<body><div id=\"root\">${html}</div>${chunkExtractor.getScriptTags()}</body>`\n```\n\n## chunkExtractor.getScriptElements\n\nGet scripts as an array of React `<script>` elements.\n\n| Arguments                | Description                                                                                                     |\n| ------------------------ | --------------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to script elements, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nconst body = renderToString(\n  <body>\n    <div id=\"root\" dangerouslySetInnerHtml={{ __html: html }} />\n    {chunkExtractor.getScriptElements()}\n  </body>,\n)\n```\n\n## chunkExtractor.getLinkTags\n\nGet \"prefetch\" and \"preload\" links as a string of `<link>` tags.\n\n| Arguments                | Description                                                                                               |\n| ------------------------ | --------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to link tags, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nconst head = `<head>${chunkExtractor.getLinkTags()}</head>`\n```\n\n## chunkExtractor.getLinkElements\n\nGet \"prefetch\" and \"preload\" links as an array of React `<link>` elements.\n\n| Arguments                | Description                                                                                                   |\n| ------------------------ | ------------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to link elements, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nconst head = renderToString(<head>{chunkExtractor.getLinkElements()}</head>)\n```\n\n## chunkExtractor.getStyleTags\n\nGet style links as a string of `<link>` tags.\n\n| Arguments                | Description                                                                                                |\n| ------------------------ | ---------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to style tags, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nconst head = `<head>${chunkExtractor.getStyleTags()}</head>`\n```\n\n## chunkExtractor.getStyleElements\n\nGet style links as an array of React `<link>` elements.\n\n```js\nconst head = renderToString(<head>{chunkExtractor.getStyleElements()}</head>)\n```\n\n## chunkExtractor.getInlineStyleTags\n\nGet inline styles as a string of `<style>` tags (returns a promise).\n\n| Arguments                | Description                                                                                                |\n| ------------------------ | ---------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to style tags, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nchunkExtractor.getInlineStyleTags()\n.then((styleTags) => {\n  const head = `<head>${styleTags}</head>`\n}\n```\n\n## chunkExtractor.getInlineStyleElements\n\nGet inline styles as an array of React `<style>` elements (returns a promise).\n\n| Arguments                | Description                                                                                                    |\n| ------------------------ | -------------------------------------------------------------------------------------------------------------- |\n| `attributes` or `attrFn` | Optional attributes added to style elements, or a function that receives a `chunk` and returns the attributes. |\n\n```js\nchunkExtractor.getInlineStyleElements()\n.then((styleElements) => {\n  const head = renderToString(<head>{styleElements}</head>)\n}\n```\n\n## chunkExtractor.getCssString\n\nGet css as a raw string for using directly within app (e.g. in custom AMP style tag)\n\n```js\nchunkExtractor.getCssString()\n.then((cssString) => {\n  const head = renderToString(\n    <head>\n      <style\n        dangerouslySetInnerHTML={{ __html: cssString }}\n      />\n    </head>\n  )\n}\n```\n\n## ChunkExtractorManager\n\nUsed to inject a `ChunkExtractor` in the context of your application.\n\n```js\nimport { ChunkExtractor, ChunkExtractorManager } from '@loadable/server'\n\nconst extractor = new ChunkExtractor()\n\nconst app = (\n  <ChunkExtractorManager extractor={extractor}>\n    <YourApp />\n  </ChunkExtractorManager>\n)\n```\n"
  },
  {
    "path": "website/src/pages/docs/api-loadable-webpack-plugin.mdx",
    "content": "---\nmenu: API\ntitle: '@loadable/webpack-plugin'\norder: 30\n---\n\n# @loadable/webpack-plugin\n\n### LoadablePlugin\n\nCreate a webpack loadable plugin.\n\n| Arguments                      | Description                                                                                  |\n| ------------------------------ | -------------------------------------------------------------------------------------------- |\n| `options`                      | Optional options                                                                             |\n| `options.filename`             | Stats filename (default to `loadable-stats.json`)                                            |\n| `options.outputAsset`          | Always write stats file to the `output.path` directory. Defaults to `true`                   |\n| `options.writeToDisk`          | Accepts `boolean` or `object`. Always write stats file to disk. Default to `false`.          |\n| `options.writeToDisk.filename` | Write assets to disk at given `filename` location                                            |\n| `options.chunkLoadingGlobal`   | Overrides Webpack's `chunkLoadingGlobal` allowing multiple Webpack runtimes on the same page |\n\n```js\nnew LoadablePlugin({ filename: 'stats.json', writeToDisk: true })\n```\n\n> Writing file to disk can be useful if you are using `razzle` or `webpack-dev-server`.\n"
  },
  {
    "path": "website/src/pages/docs/babel-plugin.mdx",
    "content": "---\nmenu: Guides\ntitle: Babel plugin\norder: 70\n---\n\n# Babel plugin\n\nThis plugin adds support for [Server Side Rendering](/docs/server-side-rendering) and automatic chunk names.\n\n## Usage\n\nInstall the babel plugin first:\n\n```bash\nnpm install --save-dev @loadable/babel-plugin\n```\n\nThen add it to your babel configuration like so:\n\n```json\n{\n  \"plugins\": [\"@loadable/babel-plugin\"]\n}\n```\n\n## Transformation\n\nThe plugin transforms your code to be ready for Server Side Rendering, it turns a loadable call:\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n```\n\ninto another one with some informations required for Server Side Rendering:\n\n```js\nimport loadable from '@loadable/component'\nconst OtherComponent = loadable({\n  chunkName() {\n    return 'OtherComponent'\n  },\n\n  isReady(props) {\n    if (typeof __webpack_modules__ !== 'undefined') {\n      return !!__webpack_modules__[this.resolve(props)]\n    }\n\n    return false\n  },\n\n  requireAsync: () =>\n    import(/* webpackChunkName: \"OtherComponent\" */\n    './OtherComponent'),\n\n  requireSync(props) {\n    const id = this.resolve(props)\n\n    if (typeof __webpack_require__ !== 'undefined') {\n      return __webpack_require__(id)\n    }\n\n    return eval('module.require')(id)\n  },\n\n  resolve() {\n    if (require.resolveWeak) {\n      return require.resolveWeak('./OtherComponent')\n    }\n\n    return require('path').resolve(__dirname, './OtherComponent')\n  },\n})\n```\n\nAs you can see the \"webpackChunkName\" annotation is automatically added.\n\nOn client side, the two code are completely compatible.\n\nPlease note that babel must not be configured [to strip comments](https://babeljs.io/docs/en/options#comments), since the chunk name is defined in a comment.\n\n## Loadable Configuration (beta)\n> available since 5.16.0\n\nSometimes you need to wrap loadable with your own custom logic. There are many use cases for it, from injecting telemetry to hiding external libraries behind facade.\nBy default `loadable-components` are configured to transform dynamic imports used only inside loadable helpers, but can be configured to instrument any other function of your choice.\n```json\n{\n  \"plugins\": [\"@loadable/babel-plugin\", {\n     \"signatures\": [\n        { \"name\": \"default\", \"from\": \"myLoadableWrapper\" }\n        { \"name\": \"myLoadableHelper\", \"from\": \"myLoadableWrapper\" }\n     ]\n  }]\n}\n```\n```tsx\nimport {myLoadableHelper} from \"myLoadableWrapper\";\nconst Loadable = myLoadableHelper(() => import(\"./MyComponent\"));\n// will behave similar to\nimport loadable from '@loadable/component'\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n```\n\n## Loadable detection (deprecated)\n> Please dont use this feature and prefer Loadable Configuration instead\n\nThe detection of a loadable component is based on the keyword \"loadable\". It is an opinionated choice, it gives you flexibility but it could also be restrictive.\n\nThis code will not be transformed by the babel plugin:\n\n```js\nimport load from '@loadable/component'\nconst OtherComponent = load(() => import('./OtherComponent'))\n```\n\nThe `load` function is not detected, you have to name it `loadable`.\n\nIt is restrictive, yes but it could gives you some flexibility. You can create your own loadable function. In the following example we create a custom loadable function with a custom fallback:\n\n```js\nimport baseLoadable from '@loadable/component'\n\nfunction loadable(func) {\n  return baseLoadable(func, { fallback: <div>Loading...</div> })\n}\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n```\n\n## Magic comments\n\nTo gives you flexibility and portability, the babel plugin supports magic comment. This way you can create portable \"load\" functions. To create a \"load\" function, you have to add `/* #__LOADABLE__ */` comment above the declaration of your function (variable or property):\n\n```js\nconst loadOther = /* #__LOADABLE__ */ () => import('./OtherComponent')\n\nconst OtherComponent = loadable(loadOther)\n```\n\nThe `loadOther` function will be transformed into an object, this way you can manipulate function and it is still portable!\n"
  },
  {
    "path": "website/src/pages/docs/code-splitting.mdx",
    "content": "---\nmenu: Introduction\ntitle: Code Splitting?\norder: 10\n---\n\n# Code Splitting?\n\nCode Splitting is an efficient way to reduce your bundle size: it speeds up the loading of your application and reduces the payload size of your application.\n\nBundling is great, but as your app grows, your bundle will grow too. Especially if you are including large third-party libraries. You need to keep an eye on the code you are including in your bundle so that you don’t accidentally make it so large that your app takes a long time to load.\n\nTo avoid winding up with a large bundle, it’s good to get ahead of the problem and start “splitting” your bundle. Code-Splitting is a feature supported by bundlers like Webpack and Browserify (via factor-bundle) which can create multiple bundles that can be dynamically loaded at runtime.\n\nCode-splitting your app can help you “lazy-load” just the things that are currently needed by the user, which can dramatically improve the performance of your app. While you haven’t reduced the overall amount of code in your app, you’ve avoided loading code that the user may never need, and reduced the amount of code needed during the initial load.\n\n## `import()`\n\nThe best way to introduce code-splitting into your app is through the dynamic `import()` syntax.\n\n**Before:**\n\n```js\nimport { add } from './math'\n\nconsole.log(add(16, 26))\n```\n\n**After:**\n\n```js\nimport('./math').then(math => {\n  console.log(math.add(16, 26))\n})\n```\n\n> Note:\n> The dynamic import() syntax is officially a part of ECMAScript 2020 specification. However to use this syntax in prior language versions you still need to bundle your code with Webpack.\n\nWhen Webpack comes across this syntax, it automatically starts code-splitting your app.\n\nIf you’re setting up Webpack yourself, you’ll probably want to read [Webpack’s guide on code splitting](https://webpack.js.org/guides/code-splitting/).\n\nWhen using Babel, you’ll need to make sure that Babel can parse the dynamic import syntax but is not transforming it. For that you will need [@babel/plugin-syntax-dynamic-import](https://www.npmjs.com/package/@babel/plugin-syntax-dynamic-import).\n\n## Named `import()`\n\nWebpack's default behaviour, is to name them as `x.js` where x is an incremental number depending on how many dynamic\nchunks you are importing in your code.\n\nThis will give a poor view of which file is loading what code.\n\nTo fix that, webpack introduced magic comments, with which a chunk can be named as follows (ie: `math.js`). \n\n```js\nimport(/* webpackChunkName: \"math\" */ './math').then(math => {\n  console.log(math.add(16, 26))\n})\n```\n\n>NOTE: \n>When using [Server Side Rendering](/docs/server-side-rendering/), make sure comment and file path are exactly in the same order as above.\n\n\n## Code Splitting + React\n\nReact supports code splitting out of the box with [`React.lazy`](https://reactjs.org/docs/code-splitting.html#reactlazy). However it has [some limitations](/docs/loadable-vs-react-lazy), this is why `@loadable/component` exists.\n\nIn a React application, most of the time you want to split your components. Splitting a component implies the ability to wait for this component to be loaded (showing a fallback during loading) but also to handle errors.\n\n**Example of component splitting:**\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent />\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "website/src/pages/docs/component-splitting.mdx",
    "content": "---\nmenu: Guides\ntitle: Component Splitting\norder: 5\n---\n\n# Component Splitting\n\n`loadable` lets you easily import components and reuse it in your code.\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent />\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "website/src/pages/docs/delay.mdx",
    "content": "---\nmenu: Guides\ntitle: Delay\norder: 50\n---\n\n# Delay\n\nTo avoid flashing a loader if the loading is very fast, you could implement a minimum delay. There is no built-in API in `@loadable/component` but you could do it using [`p-min-delay`](https://github.com/sindresorhus/p-min-delay).\n\n```js\nimport loadable from '@loadable/component'\nimport pMinDelay from 'p-min-delay'\n\n// Wait a minimum of 200ms before loading home.\nexport const OtherComponent = loadable(() =>\n  pMinDelay(import('./OtherComponent'), 200)\n)\n```\n"
  },
  {
    "path": "website/src/pages/docs/dynamic-import.mdx",
    "content": "---\nmenu: Guides\ntitle: Full dynamic import\norder: 20\n---\n\n# Full dynamic import\n\nWebpack accepts [full dynamic imports](https://webpack.js.org/api/module-methods/#import-), you can use them to create a reusable Loadable Component.\n\n```js\nimport loadable from '@loadable/component'\n\nconst AsyncPage = loadable(props => import(`./${props.page}`))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <AsyncPage page=\"Home\" />\n      <AsyncPage page=\"Contact\" />\n    </div>\n  )\n}\n```\n\n## Use a dynamic property\n\nIf you use [Babel plugin](/docs/babel-plugin/), dynamic properties are supported out of the box. Else you have to add `cacheKey` function: it takes props and returns a cache key.\n\n```js\nimport loadable from '@loadable/component'\n\nconst AsyncPage = loadable(props => import(`./${props.page}`), {\n  cacheKey: props => props.page,\n})\n\nfunction MyComponent() {\n  const [page, setPage] = useState('Home')\n  return (\n    <div>\n      <button onClick={() => setPage('Home')}>Go to home</button>\n      <button onClick={() => setPage('Contact')}>Go to contact</button>\n      {page && <AsyncPage page={page} />}\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "website/src/pages/docs/error-boundaries.mdx",
    "content": "---\nmenu: Guides\ntitle: Error boundaries\norder: 45\n---\n\n# Error Boundaries\n\nIf the other module fails to load (for example, due to network failure), it will trigger an error. You can handle these errors to show a nice user experience and manage recovery with [Error Boundaries](https://reactjs.org/docs/error-boundaries.html). Once you’ve created your Error Boundary, you can use it anywhere above your lazy components to display an error state when there’s a network error.\n\n```js\nimport MyErrorBoundary from './MyErrorBoundary'\nconst OtherComponent = loadable(() => import('./OtherComponent'))\nconst AnotherComponent = loadable(() => import('./AnotherComponent'))\n\nconst MyComponent = () => (\n  <div>\n    <MyErrorBoundary>\n      <section>\n        <OtherComponent />\n        <AnotherComponent />\n      </section>\n    </MyErrorBoundary>\n  </div>\n)\n```\n"
  },
  {
    "path": "website/src/pages/docs/fallback.mdx",
    "content": "---\nmenu: Guides\ntitle: Fallback without Suspense\norder: 40\n---\n\n# Fallback without Suspense\n\nYou can specify a `fallback` in `loadable` options.\n\n```js\nconst OtherComponent = loadable(() => import('./OtherComponent'), {\n  fallback: <div>Loading...</div>,\n})\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent />\n    </div>\n  )\n}\n```\n\nYou can also specify a `fallback` in props:\n\n```js\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent fallback={<div>Loading...</div>} />\n    </div>\n  )\n}\n```\n"
  },
  {
    "path": "website/src/pages/docs/faq.mdx",
    "content": "---\nmenu: Guides\ntitle: Frequently Asked Questions\norder: 80\n---\n\n# Frequently Asked Questions\n\n## Which react versions are supported?\n\nAs defined in peer dependencies, Loadable Components supports React v16.3+.\n\n## Which webpack versions are supported?\n\nAs defined in peer dependencies, Loadable Components supports webpack v4.6+.\n\n## Which browsers are supported?\n\nLoadable Components supports the same set of browsers as the current React version.\n\n- v5.x (React v16.3+): IE11, IE 9+ (with Map + Set polyfills), all evergreen browsers\n\nEvergreen browsers include Chrome and Firefox (and derivatives) as they can be updated regardless of operating system version. Edge and Safari should both also work fine since all versions for the last several years support the relevant APIs.\n\n## Can I use Loadable Components with server-side rendering of React on top of Ruby on Rails?\n\nYes. It works with [React on Rails](https://github.com/shakacode/react_on_rails), but it requires [React on Rails Pro](https://www.shakacode.com/react-on-rails-pro/). High traffic sites using React on Rails Pro with Loadable Components are [popmenu.com](https://get.popmenu.com/) and [egghead.io](https://egghead.io/).\n"
  },
  {
    "path": "website/src/pages/docs/getting-started.mdx",
    "content": "---\nmenu: Introduction\ntitle: Getting Started\norder: 5\n---\n\n# Getting Started\n\nFollow these few steps to get ready with `@loadable/component`.\n\n## Installation\n\nInstalling `@loadable/component` only takes a single command and you're ready to roll:\n\n```bash\nnpm install @loadable/component\n# or use yarn\nyarn add @loadable/component\n```\n\n> `@loadable/babel-plugin` is required for [Server Side Rendering](/docs/server-side-rendering/) and automatic chunk names generation. `@loadable/server` and `@loadable/webpack-plugin` are only required for [Server Side Rendering](/docs/server-side-rendering/).\n\n## Split your first component\n\nLoadable lets you render a dynamic import as a regular component.\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <OtherComponent />\n    </div>\n  )\n}\n```\n\nThat's it, `OtherComponent` will now be loaded in a separated bundle!\n"
  },
  {
    "path": "website/src/pages/docs/library-splitting.mdx",
    "content": "---\nmenu: Guides\ntitle: Loading library\norder: 10\n---\n\n# Library Splitting\n\n`loadable.lib` lets you defer the loading of a library. It takes a render props called when the library is loaded.\n\n```js\nimport loadable from '@loadable/component'\n\nconst Moment = loadable.lib(() => import('moment'))\n\nfunction FromNow({ date }) {\n  return (\n    <div>\n      <Moment fallback={date.toLocaleDateString()}>\n        {({ default: moment }) => moment(date).fromNow()}\n      </Moment>\n    </div>\n  )\n}\n```\n\nYou can also use a `ref`, populated when the library is loaded.\n\n```js\nimport loadable from '@loadable/component'\n\nconst Moment = loadable.lib(() => import('moment'))\n\nclass MyComponent {\n  moment = React.createRef()\n\n  handleClick = () => {\n    if (this.moment.current) {\n      return alert(this.moment.current.default.format('HH:mm'))\n    }\n  }\n\n  render() {\n    return (\n      <div>\n        <button onClick={this.handleClick}>What time is it?</button>\n        <Moment ref={this.moment} />\n      </div>\n    )\n  }\n}\n```\n\n> You can also pass a function to `ref`, called when the library is loaded.\n"
  },
  {
    "path": "website/src/pages/docs/loadable-vs-react-lazy.mdx",
    "content": "---\nmenu: Introduction\ntitle: Comparison with React.lazy\norder: 20\n---\n\n# Comparison with React.lazy\n\nWhat are the differences between `React.lazy` and `@loadable/components`?\n\n[`React.lazy`](https://reactjs.org/docs/code-splitting.html#reactlazy) is the recommended solution for Code Splitting. It uses Suspense and it is maintained by React.\n\nIf you are already using `React.lazy` and if you are good with it, you don't need `@loadable/component`.\n\nIf you feel limited or if you need SSR, then `@loadable/component` is the solution.\n\n## Comparison table\n\n| Library               | Suspense | SSR | Library splitting | `` import(`./${value}`) `` |\n| --------------------- | -------- | --- | ----------------- | -------------------------- |\n| `React.lazy`          | ✅       | ❌  | ❌                | ❌                         |\n| `@loadable/component` | ✅       | ✅  | ✅                | ✅                         |\n\n## Suspense\n\nSuspense is supported by `React.lazy` and by `@loadable/component`. `@loadable/component` can also be used without Suspense.\n\n## Server Side Rendering\n\nSuspense is not available server-side and `React.lazy` can only work with Suspense. That's why today, `React.lazy` is not an option if you need Server Side Rendering.\n\n`@loadable/component` provides a complete solution to make [Server Side Rendering](/docs/server-side-rendering/) possible.\n\n## Library splitting\n\n`@loadable/component` supports library splitting using render props. This is not possible with `React.lazy`.\n\n## Full dynamic import\n\nFull dynamic import also called agressive code splitting is a feature supported by Webpack. It consists of passing a dynamic value to the dynamic `import()` function.\n\n```js\n// All files that could match this pattern will be automatically code splitted.\nconst loadFile = file => import(`./${file}`)\n```\n\nIn React, it permits to create reusable components:\n\n```js\nimport loadable from '@loadable/component'\n\nconst AsyncPage = loadable(props => import(`./${props.page}`))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <AsyncPage page=\"Home\" />\n      <AsyncPage page=\"Contact\" />\n    </div>\n  )\n}\n```\n\nThis feature is not supported by `React.lazy`.\n\n## Note about `react-loadable`\n\n[react-loadable](https://github.com/jamiebuilds/react-loadable) was the recommended way for React code splitting for a long time. However, today it is not maintained any more and it is not compatible with Webpack v4+ and Babel v7+.\n\nIf you use it, it is recommended to migrate to `React.lazy` or `@loadable/component`.\n"
  },
  {
    "path": "website/src/pages/docs/migrate-from-react-loadable.mdx",
    "content": "---\nmenu: Guides\ntitle: Migrate from react-loadable\norder: 90\n---\n\n# Migrate from react-loadable\n\nCodemods are tools that can help us make changes in our code automatically. Think of it like 'find and replace', but more flexible.\n\n## Usage\n\n```sh\nnpx loadable-codemod react-loadable-to-loadable-component ./client/src\n```\n\n## Caveats\n\nSince `react-loadable` and `@loadable/component` do have differences, it is not possible to make a 100% fully automated codemod to handle all of the change needed.\nYou still need to set up server-side rendering yourself.\n\n- Updating your server side rendering code to use `ChunkExtractor`\n- Updating your webpack configuration to use `@loadable`\n- Using `loadableReady` to hydrate your app on the client side.\n\nPlease also note that `react-loadable` comes with stuffs like `Loadable.Map`, `pastDelay`, `timedOut`, `delay`, etc that do not exist in `@loadable/components`.\nIf your code were using those features, you will still need to migrate them manually.\n\nFor `loading` placeholder, this codemod already tries to render the loader as usual, but with a mocked up props as follows:\n\n```javascript\n{\n  pastDelay: true,\n  error: false,\n  timedOut: false,\n}\n```\n\nYour app should still works, but this means some of your app logic will be lost because `@loadable/component` simply does not support these features out of the box yet.\n"
  },
  {
    "path": "website/src/pages/docs/prefetching.mdx",
    "content": "---\nmenu: Guides\ntitle: Prefetching\norder: 60\n---\n\n# Prefetching\n\nLoadable Components is fully compatible with [webpack hints `webpackPrefetch` and `webpackPreload`](https://webpack.js.org/guides/code-splitting/#prefetching-preloading-modules).\n\nMost of the time, you want to \"prefetch\" a component, it means it will be loaded when the browser is idle. You can do it by adding `/* webpackPrefetch: true */` inside your import statement.\n\n```js\nimport loadable from '@loadable/component'\n\nconst OtherComponent = loadable(() =>\n  import(/* webpackPrefetch: true */ './OtherComponent'),\n)\n```\n\n> You can extract prefetched resources server-side to add `<link rel=\"prefetch\">` in your head.\n\n## Manually preload a component\n\nIt is possible to _force_ the preload of a component. It has the same effect as if the component is rendered for the first time.\n\nIt can be useful to trigger a `preload` on mouse over:\n\n```js\nimport loadable from '@loadable/component'\n\nconst Infos = loadable(() => import('./Infos'))\n\nfunction App() {\n  const [show, setShow] = useState(false)\n  return (\n    <div>\n      <a onMouseOver={() => Infos.preload()} onClick={() => setShow(true)}>\n        Show Infos\n      </a>\n      {show && <Infos />}\n    </div>\n  )\n}\n```\n\n> `preload` is not available server-side, you should only call it client-side. If you want to use prefetching server-side, use webpack hints instead.\n\n> `preload` is aggressive and doesn't take care of network condition and data saving preference of the user. You should call it carefully.\n"
  },
  {
    "path": "website/src/pages/docs/server-side-rendering.mdx",
    "content": "---\nmenu: Guides\ntitle: Server Side Rendering\norder: 65\n---\n\n# Server Side Rendering\n\n## Install\n\n```bash\nnpm install @loadable/server && npm install --save-dev @loadable/babel-plugin @loadable/webpack-plugin\n# or using yarn\nyarn add @loadable/server && yarn add --dev @loadable/babel-plugin @loadable/webpack-plugin\n```\n\n## Guide\n\n### 1. Install `@loadable/babel-plugin`\n\n**.babelrc**\n\n```json\n{\n  \"plugins\": [\"@loadable/babel-plugin\"]\n}\n```\n\n### 2. Install `@loadable/webpack-plugin`\n\n**webpack.config.js**\n\n```js\nconst LoadablePlugin = require('@loadable/webpack-plugin')\n\nmodule.exports = {\n  // ...\n  plugins: [new LoadablePlugin()],\n}\n```\n\n### 3. Setup `ChunkExtractor` server-side\n\n```js\nimport { ChunkExtractor } from '@loadable/server'\n\n// This is the stats file generated by webpack loadable plugin\nconst statsFile = path.resolve('../dist/loadable-stats.json')\n\n// We create an extractor from the statsFile\nconst extractor = new ChunkExtractor({ statsFile })\n\n// Wrap your application using \"collectChunks\"\nconst jsx = extractor.collectChunks(<YourApp />)\n\n// Render your application\nconst html = renderToString(jsx)\n\n/* `renderToString` must be called before `getScriptTags`, `getLinkTags`\n * and `getStyleTags`.\n */\n\n// You can now collect your script tags\nconst scriptTags = extractor.getScriptTags() // or extractor.getScriptElements();\n\n// You can also collect your \"preload/prefetch\" links\nconst linkTags = extractor.getLinkTags() // or extractor.getLinkElements();\n\n// And you can even collect your style tags (if you use \"mini-css-extract-plugin\")\nconst styleTags = extractor.getStyleTags() // or extractor.getStyleElements();\n```\n\n### 4. Add `loadableReady` client-side\n\nLoadable components loads all your scripts asynchronously to ensure optimal performances. All scripts are loaded in parallel, so you have to wait for them to be ready using `loadableReady`.\n\n```js\nimport { loadableReady } from '@loadable/component'\n\nloadableReady(() => {\n  const root = document.getElementById('main')\n  hydrate(<App />, root)\n})\n```\n\n**🚀 [Checkout the complete example in this repository](https://github.com/gregberge/loadable-components/tree/master/examples/server-side-rendering)**\n\n## Collecting chunks\n\nThe basic API goes as follows:\n\n```js\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\nconst extractor = new ChunkExtractor({ statsFile })\nconst html = renderToString(extractor.collectChunks(<YourApp />))\nconst scriptTags = extractor.getScriptTags() // or extractor.getScriptElements();\n```\n\nThe `collectChunks` method wraps your element in a provider. Optionally you can use the `ChunkExtractorManager` provider directly, instead of this method. Just make sure not to use it on the client-side.\n\n```js\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor, ChunkExtractorManager } from '@loadable/server'\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\nconst extractor = new ChunkExtractor({ statsFile })\nconst html = renderToString(\n  <ChunkExtractorManager extractor={extractor}>\n    <YourApp />\n  </ChunkExtractorManager>,\n)\n\nconst scriptTags = extractor.getScriptTags() // or extractor.getScriptElements();\n```\n\nThe `extractor.getScriptTags()` returns a string of multiple `<script>` tags marked as \"async\". You have to wait for them to be ready using `loadableReady`.\n\nAlternatively the `ChunkExtractor` also has a `getScriptElements()` method that returns an array of React elements.\n\n## Streaming rendering\n\nLoadable is compatible with streaming rendering, if you use it you have to include script when the stream is complete.\n\n```js\nimport { renderToNodeStream } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\n// if you're using express.js, you'd have access to the response object \"res\"\n\n// typically you'd want to write some preliminary HTML, since React doesn't handle this\nres.write('<html><head><title>Test</title></head><body>')\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\nconst chunkExtractor = new ChunkExtractor({ statsFile })\nconst jsx = chunkExtractor.collectChunks(<YourApp />)\nconst stream = renderToNodeStream(jsx)\n\n// you'd then pipe the stream into the response object until it's done\nstream.pipe(res, { end: false })\n\n// and finalize the response with closing HTML\nstream.on('end', () =>\n  res.end(`${chunkExtractor.getScriptTags()}</body></html>`),\n)\n```\n\n> Streaming rendering is not compatible with prefetch `<link>` tags.\n\n## Prefetching\n\n[Webpack prefetching](https://webpack.js.org/guides/code-splitting/#prefetching-preloading-modules) is supported out of the box by Loadable. [`<link rel=\"preload\">` and `<link rel=\"prefetch\">`](https://css-tricks.com/prefetching-preloading-prebrowsing/) can be added directly server-side to improve performances.\n\n```js\nimport path from 'path'\nimport { ChunkExtractor, ChunkExtractorManager } from '@loadable/server'\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\nconst extractor = new ChunkExtractor({ statsFile })\n\nconst jsx = extractor.collectChunks(<YourApp />)\n\nconst html = renderToString(jsx)\n\nconst linkTags = extractor.getLinkTags() // or chunkExtractor.getLinkElements();\n\nconst html = `<html>\n  <head>${linkTags}</head>\n  <body>\n    <div id=\"root\">${html}</div>\n  </body>\n</html>`\n```\n\n> It only works with `renderToString` API. Since `<link>` must be added in the `<head>`, you can't do it using `renderToNodeStream`.\n\n## CSS\n\nExtracted CSS using plugins like [\"mini-css-extract-plugin\"](https://github.com/webpack-contrib/mini-css-extract-plugin) are automatically collected, you can get them using `getStyleTags` or `getStyleElements`.\n\n```js\nimport { renderToString } from 'react-dom/server'\nimport { ChunkExtractor } from '@loadable/server'\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\nconst extractor = new ChunkExtractor({ statsFile })\nconst html = renderToString(extractor.collectChunks(<YourApp />))\nconst styleTags = extractor.getStyleTags() // or extractor.getStyleElements();\n```\n\n## Disable SSR on a specific loadable\n\nDisable SSR on a specific loadable component with `ssr: false`:\n\n```js\nimport loadable from '@loadable/component'\n\n// This dynamic import will not be processed server-side\nconst Other = loadable(() => import('./Other'), { ssr: false })\n```\n\n## Override `stats.publicPath` at runtime\n\nTo override `stats.publicPath` at runtime, pass in a custom `publicPath` to the `ChunkExtractor` constructor:\n\n```js\nimport { ChunkExtractor } from '@loadable/server'\n\nconst statsFile = path.resolve('../dist/loadable-stats.json')\n\nconst extractor = new ChunkExtractor({\n  statsFile,\n  publicPath: 'https://cdn.example.org/v1.1.0/',\n})\n```\n\n## `ChunkExtractor` entrypoints\n\nWhen running your build, notice `@loadable/webpack-plugin` generates a file called `loadable-stats.json`, which contains information\nabout all your entries and chunks from webpack.\n\nOnce that's in place, `ChunkExtractor` will be responsible of finding your entries into this file.\n\nThe default behaviour of webpack, is to create an asset called `main.js` if no named entry is specified, like so.\n\n**webpack.config.js**\n\n```js\nmodule.exports = {\n  entry: './src/index.js',\n  // ...\n}\n```\n\n[Checkout webpack's entry naming configuration](https://webpack.js.org/configuration/entry-context/#naming).\n\n> `ChunkExtractor` will try to find your `main.js`, and will look into `loadable-stats.json` to confirm it's there.\n\nIf for instance, your wish is to get a different named entry, you will need to pass an `entrypoints` option.\n\n```js\nconst extractor = new ChunkExtractor({\n  statsFile,\n  entrypoints: ['client'], // array of webpack entries (default: ['main'])\n})\n```\n\n## Using your own stats file\n\nBy default, the webpack plugin adds an asset to the webpack build called `loadable-stats.json`. This contains the result of running webpack's [`stats.toJson()`](https://webpack.js.org/api/node/#statstojsonoptions) with the following options:\n\n```js\n{\n  hash: true,\n  publicPath: true,\n  assets: true,\n  chunks: false,\n  modules: false,\n  source: false,\n  errorDetails: false,\n  timings: false,\n}\n```\n\n`stats.toJson()` is an expensive operation, and it can significantly slow down webpack watching recompiles.\nIf you already have a webpack stats file in your build that includes the necessary options, you may choose to use your existing stats object instead of creating a new one. You can do this as follows:\n - pass your existing stats object into [`ChunkExtractor`](/docs/api-loadable-server/#chunkextractor) via the `stats` option\n - disable both the `outputAsset` and `writeToDisk` options in the [webpack plugin](/docs/api-loadable-webpack-plugin/#loadableplugin) to prevent it from calling `stats.toJson()`\n"
  },
  {
    "path": "website/src/pages/docs/support.mdx",
    "content": "---\nmenu: About\ntitle: Support\norder: 20\n---\n\n# Support\n\n## Supporting Loadable components\n\nLoadable Components is an MIT-licensed open source project. It is created an maintained by a single person: Greg Bergé. If you want to help me, then:\n\n- [Sponsor me on GitHub ❤️](https://github.com/sponsors/gregberge).\n"
  },
  {
    "path": "website/src/pages/docs/suspense.mdx",
    "content": "---\nmenu: Guides\ntitle: Suspense\norder: 30\n---\n\n# Suspense\n\n`@loadable/component` exposes a `lazy` method that acts similarly as `React.lazy` one.\n\n```js\nimport React, { Suspense } from 'react'\nimport { lazy } from '@loadable/component'\n\nconst OtherComponent = lazy(() => import('./OtherComponent'))\n\nfunction MyComponent() {\n  return (\n    <div>\n      <Suspense fallback={<div>Loading...</div>}>\n        <OtherComponent />\n      </Suspense>\n    </div>\n  )\n}\n```\n\n> Use `lazy.lib` for libraries.\n\n> ⚠️ Suspense is not yet available for server-side rendering.\n"
  },
  {
    "path": "website/src/pages/docs/timeout.mdx",
    "content": "---\nmenu: Guides\ntitle: Timeout\norder: 55\n---\n\n# Timeout\n\nInfinite loading is not good for user experience, to avoid it implementing a timeout is a good workaround. You can do it using a third party module like [`promise-timeout`](https://github.com/building5/promise-timeout):\n\n```js\nimport loadable from '@loadable/component'\nimport { timeout } from 'promise-timeout'\n\n// Wait a maximum of 2s before sending an error.\nexport const OtherComponent = loadable(() =>\n  timeout(import('./OtherComponent'), 2000)\n)\n```\n"
  },
  {
    "path": "website/src/pages/index.js",
    "content": "/* eslint-disable react/jsx-one-expression-per-line */\n/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from 'react'\nimport { Box } from '@xstyled/styled-components'\nimport Helmet from 'react-helmet'\nimport { HomeHero, ShowCase, BaseLayout } from 'smooth-doc/components'\n\nexport default function Index() {\n  return (\n    <BaseLayout>\n      <Helmet>\n        <title>Loadable Components - React code splitting</title>\n      </Helmet>\n\n      <HomeHero title=\"React code splitting made easy.\" />\n\n      <ShowCase>\n        <Box maxWidth={660} px={20}>\n          <Box row>\n            <Box col={{ xs: 1, md: true }}>\n              <h2>What is it?</h2>\n              <ul>\n                <li>A React code splitting library</li>\n                <li>Not an alternative to React.lazy</li>\n                <li>\n                  A solution{' '}\n                  <a\n                    href=\"https://reactjs.org/docs/code-splitting.html#reactlazy\"\n                    target=\"_blank\"\n                    rel=\"noopener noreferrer\"\n                  >\n                    recommended by React Team\n                  </a>\n                </li>\n              </ul>\n            </Box>\n            <Box col={{ xs: 1, md: 'auto' }}>\n              <h2>Features</h2>\n              <ul>\n                <li>📚 Library splitting</li>\n                <li>⚡️ Prefetching</li>\n                <li>💫 Server Side Rendering</li>\n                <li>🎛 Full dynamic import</li>\n              </ul>\n            </Box>\n          </Box>\n        </Box>\n      </ShowCase>\n    </BaseLayout>\n  )\n}\n"
  }
]