From a4f9b0ff18d718e1eec07ef443549b823b6f4f10 Mon Sep 17 00:00:00 2001 From: facebook-github-bot Date: Thu, 21 Dec 2023 14:17:26 +0000 Subject: [PATCH] Deploy website - based on a941ba443881785b7f815c6df1c03bf669204967 --- 404.html | 8 ++++---- _src/Configuration.md | 2 +- .../{163e71e1.0adf7e63.js => 163e71e1.c8a001e2.js} | 2 +- .../{37a9b1a2.19077660.js => 37a9b1a2.3e0e586b.js} | 2 +- .../{51001101.f13d564f.js => 51001101.e553b5bb.js} | 2 +- .../{6373d68f.913b28f6.js => 6373d68f.c5fea588.js} | 2 +- .../{6681bed1.544d4ac6.js => 6681bed1.29b5b3da.js} | 2 +- .../{812be9b9.e9cfac08.js => 812be9b9.6105f00a.js} | 2 +- .../{8b9b5fbc.5e2544a2.js => 8b9b5fbc.3c950ae5.js} | 2 +- .../{ae2a35ac.03e1616a.js => ae2a35ac.49d67f32.js} | 2 +- .../{ba2a2799.c2a471fe.js => ba2a2799.7305bfb1.js} | 2 +- .../{ba92a0db.ff27c9ab.js => ba92a0db.e5a6082d.js} | 2 +- .../{c026fe4c.0ed392da.js => c026fe4c.4739fe9a.js} | 2 +- .../{e08abecb.aaca3b71.js => e08abecb.248aeed4.js} | 2 +- .../{fc1f0afe.581a6525.js => fc1f0afe.562ca30a.js} | 2 +- assets/js/{main.569eb80f.js => main.935b1cc8.js} | 4 ++-- ...f.js.LICENSE.txt => main.935b1cc8.js.LICENSE.txt} | 0 ...ime~main.6cbd035d.js => runtime~main.8dcf05e7.js} | 2 +- docs/api/index.html | 10 +++++----- docs/bundling/index.html | 10 +++++----- docs/caching/index.html | 10 +++++----- docs/cli/index.html | 10 +++++----- docs/concepts/index.html | 10 +++++----- docs/configuration/index.html | 12 ++++++------ docs/getting-started/index.html | 10 +++++----- docs/local-development/index.html | 10 +++++----- docs/module-api/index.html | 10 +++++----- docs/package-exports/index.html | 10 +++++----- docs/resolution/index.html | 10 +++++----- docs/source-map-format/index.html | 10 +++++----- docs/troubleshooting/index.html | 10 +++++----- help/index.html | 8 ++++---- index.html | 8 ++++---- search/index.html | 8 ++++---- 34 files changed, 99 insertions(+), 99 deletions(-) rename assets/js/{163e71e1.0adf7e63.js => 163e71e1.c8a001e2.js} (99%) rename assets/js/{37a9b1a2.19077660.js => 37a9b1a2.3e0e586b.js} (99%) rename assets/js/{51001101.f13d564f.js => 51001101.e553b5bb.js} (98%) rename assets/js/{6373d68f.913b28f6.js => 6373d68f.c5fea588.js} (99%) rename assets/js/{6681bed1.544d4ac6.js => 6681bed1.29b5b3da.js} (99%) rename assets/js/{812be9b9.e9cfac08.js => 812be9b9.6105f00a.js} (99%) rename assets/js/{8b9b5fbc.5e2544a2.js => 8b9b5fbc.3c950ae5.js} (98%) rename assets/js/{ae2a35ac.03e1616a.js => ae2a35ac.49d67f32.js} (99%) rename assets/js/{ba2a2799.c2a471fe.js => ba2a2799.7305bfb1.js} (76%) rename assets/js/{ba92a0db.ff27c9ab.js => ba92a0db.e5a6082d.js} (98%) rename assets/js/{c026fe4c.0ed392da.js => c026fe4c.4739fe9a.js} (97%) rename assets/js/{e08abecb.aaca3b71.js => e08abecb.248aeed4.js} (99%) rename assets/js/{fc1f0afe.581a6525.js => fc1f0afe.562ca30a.js} (98%) rename assets/js/{main.569eb80f.js => main.935b1cc8.js} (99%) rename assets/js/{main.569eb80f.js.LICENSE.txt => main.935b1cc8.js.LICENSE.txt} (100%) rename assets/js/{runtime~main.6cbd035d.js => runtime~main.8dcf05e7.js} (50%) diff --git a/404.html b/404.html index 35c1f990f8..4b3508f6ce 100644 --- a/404.html +++ b/404.html @@ -13,15 +13,15 @@ - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/_src/Configuration.md b/_src/Configuration.md index 4293a3dd3d..e3a1a5754a 100644 --- a/_src/Configuration.md +++ b/_src/Configuration.md @@ -535,7 +535,7 @@ Type: `string` The name of a module that compiles code with Babel, returning an AST and optional metadata. Defaults to `metro-babel-transformer`. -Refer to the source code of [`metro-babel-transformer`](https://github.com/facebook/metro/blob/main/packages/metro-babel-transformer/src/index.js) and [`metro-react-native-babel-transformer`](https://github.com/facebook/metro/blob/main/packages/metro-react-native-babel-transformer/src/index.js) for details on implementing a custom Babel transformer. +Refer to the source code of [`metro-babel-transformer`](https://github.com/facebook/metro/blob/main/packages/metro-babel-transformer/src/index.js) and [`@react-native/metro-babel-transformer`](https://github.com/facebook/react-native/blob/main/packages/react-native-babel-transformer/src/index.js) for details on implementing a custom Babel transformer. :::note This option only has an effect under the default [`transformerPath`](#transformerpath). Custom transformers may ignore it. diff --git a/assets/js/163e71e1.0adf7e63.js b/assets/js/163e71e1.c8a001e2.js similarity index 99% rename from assets/js/163e71e1.0adf7e63.js rename to assets/js/163e71e1.c8a001e2.js index 304f93a549..5b7fb8ccd7 100644 --- a/assets/js/163e71e1.0adf7e63.js +++ b/assets/js/163e71e1.c8a001e2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[662],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>s,MDXProvider:()=>u,mdx:()=>x,useMDXComponents:()=>p,withMDXComponents:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=r.createContext({}),m=function(e){return function(n){var t=p(n.components);return r.createElement(e,a({},n,{components:t}))}},p=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u=function(e){var n=p(e.components);return r.createElement(s.Provider,{value:n},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,s=d(e,["components","mdxType","originalType","parentName"]),m=p(t),u=o,c=m["".concat(i,".").concat(u)]||m[u]||h[u]||a;return t?r.createElement(c,l(l({ref:n},s),{},{components:t})):r.createElement(c,l({ref:n},s))}));function x(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=f;var l={};for(var d in n)hasOwnProperty.call(n,d)&&(l[d]=n[d]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>m,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var r=t(83117),o=t(80102),a=(t(67294),t(3905)),i=["components"],l={id:"getting-started",title:"Getting Started"},d=void 0,s={unversionedId:"getting-started",id:"getting-started",title:"Getting Started",description:"Install Metro using npm:",source:"@site/../docs/GettingStarted.md",sourceDirName:".",slug:"/getting-started",permalink:"/docs/getting-started",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/GettingStarted.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"getting-started",title:"Getting Started"},sidebar:"docs",next:{title:"Concepts",permalink:"/docs/concepts"}},m={},p=[{value:"Running metro",id:"running-metro",level:2},{value:"Running Programmatically",id:"running-programmatically",level:3},{value:"Method runMetro(config)",id:"method-runmetroconfig",level:3},{value:"Method runServer(config, options)",id:"method-runserverconfig-options",level:3},{value:"Options",id:"options",level:4},{value:"Method runBuild(config, options)",id:"method-runbuildconfig-options",level:3},{value:"Options",id:"options-1",level:4},{value:"Method createConnectMiddleware(config)",id:"method-createconnectmiddlewareconfig",level:3},{value:"Options",id:"options-2",level:4},{value:"Available options",id:"available-options",level:2},{value:"Configuration",id:"configuration",level:3},{value:"URL and bundle request",id:"url-and-bundle-request",level:2},{value:"Assets",id:"assets",level:3},{value:"Bundle",id:"bundle",level:3},{value:"Source maps",id:"source-maps",level:3},{value:"JavaScript transformer",id:"javascript-transformer",level:2},{value:"Method transform(module)",id:"method-transformmodule",level:3},{value:"Method getCacheKey()",id:"method-getcachekey",level:3}],u={toc:p},c="wrapper";function h(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.mdx)(c,(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Install Metro using ",(0,a.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/"},(0,a.mdx)("inlineCode",{parentName:"a"},"npm")),":"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-bash"},"npm install --save-dev metro metro-core\n")),(0,a.mdx)("p",null,"Or via ",(0,a.mdx)("a",{parentName:"p",href:"https://yarnpkg.com/"},(0,a.mdx)("inlineCode",{parentName:"a"},"yarn")),":"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-bash"},"yarn add --dev metro metro-core\n")),(0,a.mdx)("h2",{id:"running-metro"},"Running ",(0,a.mdx)("inlineCode",{parentName:"h2"},"metro")),(0,a.mdx)("p",null,"You can run Metro by either running the ",(0,a.mdx)("a",{parentName:"p",href:"/docs/cli"},"CLI")," or by calling it programmatically."),(0,a.mdx)("h3",{id:"running-programmatically"},"Running Programmatically"),(0,a.mdx)("p",null,"First, require the module by doing:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\n")),(0,a.mdx)("p",null,"Within the object returned, several main methods are given:"),(0,a.mdx)("h3",{id:"method-runmetroconfig"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runMetro(config)")),(0,a.mdx)("p",null,"Given the config, a ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro-server")," will be returned. You can then hook this into a proper HTTP(S) server by using its ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," method:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"'use strict';\n\nconst http = require('http');\nconst Metro = require('metro');\n\n// We first load the config from the file system\nMetro.loadConfig().then(async (config) => {\n const metroBundlerServer = await Metro.runMetro(config);\n\n const httpServer = http.createServer(\n metroBundlerServer.processRequest.bind(metroBundlerServer),\n );\n\n httpServer.listen(8081);\n});\n")),(0,a.mdx)("p",null,"In order to be also compatible with Express apps, ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," will also call its third parameter when the request could not be handled by Metro. This allows you to integrate the server with your existing server, or to extend a new one:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const httpServer = http.createServer((req, res) => {\n metroBundlerServer.processRequest(req, res, () => {\n // Metro does not know how to handle the request.\n });\n});\n")),(0,a.mdx)("p",null,"If you are using ",(0,a.mdx)("a",{parentName:"p",href:"http://expressjs.com/"},"Express"),", you can just pass ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," as a middleware:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const express = require('express');\nconst app = express();\n\napp.use(\n metroBundlerServer.processRequest.bind(metroBundlerServer),\n);\n\napp.listen(8081);\n")),(0,a.mdx)("h3",{id:"method-runserverconfig-options"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runServer(config, options)")),(0,a.mdx)("p",null,"Starts a development server based on the given configuration and options. Returns the server.\nWe recommend using ",(0,a.mdx)("inlineCode",{parentName:"p"},"runMetro")," instead of ",(0,a.mdx)("inlineCode",{parentName:"p"},"runServer"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"runMetro")," calls this function."),(0,a.mdx)("h4",{id:"options"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"host (string)"),": Where to host the server on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onReady (Function)"),": Called when the server is ready to serve requests."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secure (boolean)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," Whether the server should run on ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," instead of ",(0,a.mdx)("inlineCode",{parentName:"li"},"http"),"."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureKey (string)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," The key to use for ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," when ",(0,a.mdx)("inlineCode",{parentName:"li"},"secure")," is on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureCert (string)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," The cert to use for ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," when ",(0,a.mdx)("inlineCode",{parentName:"li"},"secure")," is on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureServerOptions (Object)"),": The options object to pass to Metro's HTTPS server. The presence of this object will make Metro's server run on ",(0,a.mdx)("inlineCode",{parentName:"li"},"https"),". Refer to the ",(0,a.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener"},"Node docs")," for valid options."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"waitForBundler (boolean)"),": Whether to wait for the bundler to finish initializing before returning the server instance.")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runServer(config);\n")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const fs = require('fs');\n\nconst config = await Metro.loadConfig();\n\nawait Metro.runServer(config, {\n secureServerOptions: {\n ca: fs.readFileSync('path/to/ca'),\n cert: fs.readFileSync('path/to/cert'),\n key: fs.readFileSync('path/to/key'),\n }\n});\n")),(0,a.mdx)("h3",{id:"method-runbuildconfig-options"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runBuild(config, options)")),(0,a.mdx)("p",null,"Given a configuration and a set of options that you would typically pass to a server, plus a set of options specific to the bundle itself, a bundle will be built. The return value is a Promise that resolves to an object with two properties, ",(0,a.mdx)("inlineCode",{parentName:"p"},"code")," and ",(0,a.mdx)("inlineCode",{parentName:"p"},"map"),". This is useful at build time."),(0,a.mdx)("h4",{id:"options-1"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"dev (boolean)"),": Create a development version of the build (",(0,a.mdx)("inlineCode",{parentName:"li"},"process.env.NODE_ENV = 'development'"),")."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"entry (string)"),": Pointing to the entry file to bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onBegin (Function)"),": Called when the bundling starts."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onComplete (Function)"),": Called when the bundling finishes."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onProgress (Function)"),": Called during the bundle, every time there's new information available about the module count/progress."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"minify (boolean)"),": Whether Metro should minify the bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"out (string)"),": Path to the output bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"platform ('web' | 'android' | 'ios')"),": Which platform to bundle for if a list of platforms is provided."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"sourceMap (boolean)"),": Whether Metro should generate source maps."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"sourceMapUrl (string)"),": URL where the source map can be found. It defaults to the same same URL as the bundle, but changing the extension from ",(0,a.mdx)("inlineCode",{parentName:"li"},".bundle")," to ",(0,a.mdx)("inlineCode",{parentName:"li"},".map"),". When ",(0,a.mdx)("inlineCode",{parentName:"li"},"inlineSourceMap")," is ",(0,a.mdx)("inlineCode",{parentName:"li"},"true"),", this property has no effect.")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runBuild(config, {\n entry: 'index.js',\n platform: 'ios',\n minify: true,\n out: '/Users/Metro/metro-ios.js'\n});\n")),(0,a.mdx)("h3",{id:"method-createconnectmiddlewareconfig"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"createConnectMiddleware(config)")),(0,a.mdx)("p",null,"Instead of creating the full server, creates a Connect middleware that answers to bundle requests. This middleware can then be plugged into your own servers. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"port")," parameter is optional and only used for logging purposes."),(0,a.mdx)("h4",{id:"options-2"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"port (number)"),": Port for the Connect middleware (only for logging purposes).")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\nconst express = require('express');\nconst app = express();\nconst server = require('http').Server(app);\n\nMetro.loadConfig().then(async config => {\n const connectMiddleware = await Metro.createConnectMiddleware(config);\n const {server: {port}} = config;\n\n app.use(connectMiddleware.middleware);\n server.listen(port);\n connectMiddleware.attachHmrServer(server);\n});\n")),(0,a.mdx)("h2",{id:"available-options"},"Available options"),(0,a.mdx)("h3",{id:"configuration"},"Configuration"),(0,a.mdx)("p",null,"Check ",(0,a.mdx)("a",{parentName:"p",href:"/docs/configuration"},"Configuring Metro")," for details on configuration options."),(0,a.mdx)("h2",{id:"url-and-bundle-request"},"URL and bundle request"),(0,a.mdx)("p",null,"The server has the ability to serve assets, bundles and source maps for those bundles."),(0,a.mdx)("h3",{id:"assets"},"Assets"),(0,a.mdx)("p",null,"In order to request an asset, you can freely use the ",(0,a.mdx)("inlineCode",{parentName:"p"},"require")," method as if it was another JS file. The server will treat this specific ",(0,a.mdx)("inlineCode",{parentName:"p"},"require")," calls and make them return the path to that file. When an asset is requested (an asset is recognized by its extension, which has to be on the ",(0,a.mdx)("inlineCode",{parentName:"p"},"assetExts")," array) it is generally served as-is."),(0,a.mdx)("p",null,"However, the server is also able to serve specific assets depending on the platform and on the requested size (in the case of images). The way you specify the platform is via the dotted suffix (e.g. ",(0,a.mdx)("inlineCode",{parentName:"p"},".ios"),") and the resolution via the at suffix (e.g. ",(0,a.mdx)("inlineCode",{parentName:"p"},"@2x"),"). This is transparently handled for you when using ",(0,a.mdx)("inlineCode",{parentName:"p"},"require"),"."),(0,a.mdx)("h3",{id:"bundle"},"Bundle"),(0,a.mdx)("p",null,"Any JS file can be used as the root for a bundle request. The file will be looked in the ",(0,a.mdx)("inlineCode",{parentName:"p"},"projectRoot"),". All files that are required by the root will be recursively included. In order to request a bundle, just change the extension from ",(0,a.mdx)("inlineCode",{parentName:"p"},".js")," to ",(0,a.mdx)("inlineCode",{parentName:"p"},".bundle"),". Options for building the bundle are passed as query parameters (all optional)."),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"dev"),": build the bundle in development mode or not. Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"dev")," setting of the bundles. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"platform"),": platform requesting the bundle. Can be ",(0,a.mdx)("inlineCode",{parentName:"li"},"ios")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"android"),". Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"platform")," setting of the bundles."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"minify"),": whether code should be minified or not. Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"minify")," setting of the bundles. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"excludeSource"),": whether sources should be included in the source map or not. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL.")),(0,a.mdx)("p",null,"For instance, requesting ",(0,a.mdx)("inlineCode",{parentName:"p"},"http://localhost:8081/foo/bar/baz.bundle?dev=true&platform=ios")," will create a bundle out of ",(0,a.mdx)("inlineCode",{parentName:"p"},"foo/bar/baz.js")," for iOS in development mode."),(0,a.mdx)("h3",{id:"source-maps"},"Source maps"),(0,a.mdx)("p",null,"Source maps are built for each bundle by using the same URL as the bundle (thus, the same as the JS file acting as a root). This will only work when ",(0,a.mdx)("inlineCode",{parentName:"p"},"inlineSourceMap")," is set to ",(0,a.mdx)("inlineCode",{parentName:"p"},"false"),". All options you passed to the bundle will be added to the source map URL; otherwise, they wouldn't match."),(0,a.mdx)("h2",{id:"javascript-transformer"},"JavaScript transformer"),(0,a.mdx)("p",null,"The JavaScript transformer (",(0,a.mdx)("a",{parentName:"p",href:"/docs/configuration#babeltransformerpath"},(0,a.mdx)("inlineCode",{parentName:"a"},"babelTransformerPath")),") is the place where JS code will be manipulated; useful for calling Babel. The transformer can export two methods:"),(0,a.mdx)("h3",{id:"method-transformmodule"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"transform(module)")),(0,a.mdx)("p",null,"Mandatory method that will transform code. The object received has information about the module being transformed (e.g its path, code...) and the returned object has to contain an ",(0,a.mdx)("inlineCode",{parentName:"p"},"ast")," key that is the AST representation of the transformed code. The default shipped transformer does the bare minimum amount of work by just parsing the code to AST:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const babylon = require('@babel/parser');\n\nmodule.exports.transform = (file: {filename: string, src: string}) => {\n const ast = babylon.parse(file.src, {sourceType: 'module'});\n\n return {ast};\n};\n")),(0,a.mdx)("p",null,"If you would like to plug-in Babel, you can simply do that by passing the code to it:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const {transformSync} = require('@babel/core');\n\nmodule.exports.transform = file => {\n return transformSync(file.src, {\n // Babel options...\n });\n};\n")),(0,a.mdx)("h3",{id:"method-getcachekey"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"getCacheKey()")),(0,a.mdx)("p",null,"Optional method that returns the cache key of the transformer. When using different transformers, this allows to correctly tie a transformed file to the transformer that converted it. The result of the method has to be a ",(0,a.mdx)("inlineCode",{parentName:"p"},"string"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[662],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>s,MDXProvider:()=>u,mdx:()=>x,useMDXComponents:()=>p,withMDXComponents:()=>m});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=r.createContext({}),m=function(e){return function(n){var t=p(n.components);return r.createElement(e,a({},n,{components:t}))}},p=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u=function(e){var n=p(e.components);return r.createElement(s.Provider,{value:n},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},f=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,s=d(e,["components","mdxType","originalType","parentName"]),m=p(t),u=o,c=m["".concat(i,".").concat(u)]||m[u]||h[u]||a;return t?r.createElement(c,l(l({ref:n},s),{},{components:t})):r.createElement(c,l({ref:n},s))}));function x(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=f;var l={};for(var d in n)hasOwnProperty.call(n,d)&&(l[d]=n[d]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>m,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var r=t(83117),o=t(80102),a=(t(67294),t(3905)),i=["components"],l={id:"getting-started",title:"Getting Started"},d=void 0,s={unversionedId:"getting-started",id:"getting-started",title:"Getting Started",description:"Install Metro using npm:",source:"@site/../docs/GettingStarted.md",sourceDirName:".",slug:"/getting-started",permalink:"/docs/getting-started",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/GettingStarted.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"getting-started",title:"Getting Started"},sidebar:"docs",next:{title:"Concepts",permalink:"/docs/concepts"}},m={},p=[{value:"Running metro",id:"running-metro",level:2},{value:"Running Programmatically",id:"running-programmatically",level:3},{value:"Method runMetro(config)",id:"method-runmetroconfig",level:3},{value:"Method runServer(config, options)",id:"method-runserverconfig-options",level:3},{value:"Options",id:"options",level:4},{value:"Method runBuild(config, options)",id:"method-runbuildconfig-options",level:3},{value:"Options",id:"options-1",level:4},{value:"Method createConnectMiddleware(config)",id:"method-createconnectmiddlewareconfig",level:3},{value:"Options",id:"options-2",level:4},{value:"Available options",id:"available-options",level:2},{value:"Configuration",id:"configuration",level:3},{value:"URL and bundle request",id:"url-and-bundle-request",level:2},{value:"Assets",id:"assets",level:3},{value:"Bundle",id:"bundle",level:3},{value:"Source maps",id:"source-maps",level:3},{value:"JavaScript transformer",id:"javascript-transformer",level:2},{value:"Method transform(module)",id:"method-transformmodule",level:3},{value:"Method getCacheKey()",id:"method-getcachekey",level:3}],u={toc:p},c="wrapper";function h(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.mdx)(c,(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Install Metro using ",(0,a.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/"},(0,a.mdx)("inlineCode",{parentName:"a"},"npm")),":"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-bash"},"npm install --save-dev metro metro-core\n")),(0,a.mdx)("p",null,"Or via ",(0,a.mdx)("a",{parentName:"p",href:"https://yarnpkg.com/"},(0,a.mdx)("inlineCode",{parentName:"a"},"yarn")),":"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-bash"},"yarn add --dev metro metro-core\n")),(0,a.mdx)("h2",{id:"running-metro"},"Running ",(0,a.mdx)("inlineCode",{parentName:"h2"},"metro")),(0,a.mdx)("p",null,"You can run Metro by either running the ",(0,a.mdx)("a",{parentName:"p",href:"/docs/cli"},"CLI")," or by calling it programmatically."),(0,a.mdx)("h3",{id:"running-programmatically"},"Running Programmatically"),(0,a.mdx)("p",null,"First, require the module by doing:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\n")),(0,a.mdx)("p",null,"Within the object returned, several main methods are given:"),(0,a.mdx)("h3",{id:"method-runmetroconfig"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runMetro(config)")),(0,a.mdx)("p",null,"Given the config, a ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro-server")," will be returned. You can then hook this into a proper HTTP(S) server by using its ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," method:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"'use strict';\n\nconst http = require('http');\nconst Metro = require('metro');\n\n// We first load the config from the file system\nMetro.loadConfig().then(async (config) => {\n const metroBundlerServer = await Metro.runMetro(config);\n\n const httpServer = http.createServer(\n metroBundlerServer.processRequest.bind(metroBundlerServer),\n );\n\n httpServer.listen(8081);\n});\n")),(0,a.mdx)("p",null,"In order to be also compatible with Express apps, ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," will also call its third parameter when the request could not be handled by Metro. This allows you to integrate the server with your existing server, or to extend a new one:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const httpServer = http.createServer((req, res) => {\n metroBundlerServer.processRequest(req, res, () => {\n // Metro does not know how to handle the request.\n });\n});\n")),(0,a.mdx)("p",null,"If you are using ",(0,a.mdx)("a",{parentName:"p",href:"http://expressjs.com/"},"Express"),", you can just pass ",(0,a.mdx)("inlineCode",{parentName:"p"},"processRequest")," as a middleware:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const express = require('express');\nconst app = express();\n\napp.use(\n metroBundlerServer.processRequest.bind(metroBundlerServer),\n);\n\napp.listen(8081);\n")),(0,a.mdx)("h3",{id:"method-runserverconfig-options"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runServer(config, options)")),(0,a.mdx)("p",null,"Starts a development server based on the given configuration and options. Returns the server.\nWe recommend using ",(0,a.mdx)("inlineCode",{parentName:"p"},"runMetro")," instead of ",(0,a.mdx)("inlineCode",{parentName:"p"},"runServer"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"runMetro")," calls this function."),(0,a.mdx)("h4",{id:"options"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"host (string)"),": Where to host the server on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onReady (Function)"),": Called when the server is ready to serve requests."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secure (boolean)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," Whether the server should run on ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," instead of ",(0,a.mdx)("inlineCode",{parentName:"li"},"http"),"."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureKey (string)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," The key to use for ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," when ",(0,a.mdx)("inlineCode",{parentName:"li"},"secure")," is on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureCert (string)"),": ",(0,a.mdx)("strong",{parentName:"li"},"DEPRECATED")," The cert to use for ",(0,a.mdx)("inlineCode",{parentName:"li"},"https")," when ",(0,a.mdx)("inlineCode",{parentName:"li"},"secure")," is on."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"secureServerOptions (Object)"),": The options object to pass to Metro's HTTPS server. The presence of this object will make Metro's server run on ",(0,a.mdx)("inlineCode",{parentName:"li"},"https"),". Refer to the ",(0,a.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener"},"Node docs")," for valid options."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"waitForBundler (boolean)"),": Whether to wait for the bundler to finish initializing before returning the server instance.")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runServer(config);\n")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const fs = require('fs');\n\nconst config = await Metro.loadConfig();\n\nawait Metro.runServer(config, {\n secureServerOptions: {\n ca: fs.readFileSync('path/to/ca'),\n cert: fs.readFileSync('path/to/cert'),\n key: fs.readFileSync('path/to/key'),\n }\n});\n")),(0,a.mdx)("h3",{id:"method-runbuildconfig-options"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"runBuild(config, options)")),(0,a.mdx)("p",null,"Given a configuration and a set of options that you would typically pass to a server, plus a set of options specific to the bundle itself, a bundle will be built. The return value is a Promise that resolves to an object with two properties, ",(0,a.mdx)("inlineCode",{parentName:"p"},"code")," and ",(0,a.mdx)("inlineCode",{parentName:"p"},"map"),". This is useful at build time."),(0,a.mdx)("h4",{id:"options-1"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"dev (boolean)"),": Create a development version of the build (",(0,a.mdx)("inlineCode",{parentName:"li"},"process.env.NODE_ENV = 'development'"),")."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"entry (string)"),": Pointing to the entry file to bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onBegin (Function)"),": Called when the bundling starts."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onComplete (Function)"),": Called when the bundling finishes."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"onProgress (Function)"),": Called during the bundle, every time there's new information available about the module count/progress."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"minify (boolean)"),": Whether Metro should minify the bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"out (string)"),": Path to the output bundle."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"platform ('web' | 'android' | 'ios')"),": Which platform to bundle for if a list of platforms is provided."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"sourceMap (boolean)"),": Whether Metro should generate source maps."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"sourceMapUrl (string)"),": URL where the source map can be found. It defaults to the same same URL as the bundle, but changing the extension from ",(0,a.mdx)("inlineCode",{parentName:"li"},".bundle")," to ",(0,a.mdx)("inlineCode",{parentName:"li"},".map"),". When ",(0,a.mdx)("inlineCode",{parentName:"li"},"inlineSourceMap")," is ",(0,a.mdx)("inlineCode",{parentName:"li"},"true"),", this property has no effect.")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runBuild(config, {\n entry: 'index.js',\n platform: 'ios',\n minify: true,\n out: '/Users/Metro/metro-ios.js'\n});\n")),(0,a.mdx)("h3",{id:"method-createconnectmiddlewareconfig"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"createConnectMiddleware(config)")),(0,a.mdx)("p",null,"Instead of creating the full server, creates a Connect middleware that answers to bundle requests. This middleware can then be plugged into your own servers. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"port")," parameter is optional and only used for logging purposes."),(0,a.mdx)("h4",{id:"options-2"},"Options"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"port (number)"),": Port for the Connect middleware (only for logging purposes).")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\nconst express = require('express');\nconst app = express();\nconst server = require('http').Server(app);\n\nMetro.loadConfig().then(async config => {\n const connectMiddleware = await Metro.createConnectMiddleware(config);\n const {server: {port}} = config;\n\n app.use(connectMiddleware.middleware);\n server.listen(port);\n connectMiddleware.attachHmrServer(server);\n});\n")),(0,a.mdx)("h2",{id:"available-options"},"Available options"),(0,a.mdx)("h3",{id:"configuration"},"Configuration"),(0,a.mdx)("p",null,"Check ",(0,a.mdx)("a",{parentName:"p",href:"/docs/configuration"},"Configuring Metro")," for details on configuration options."),(0,a.mdx)("h2",{id:"url-and-bundle-request"},"URL and bundle request"),(0,a.mdx)("p",null,"The server has the ability to serve assets, bundles and source maps for those bundles."),(0,a.mdx)("h3",{id:"assets"},"Assets"),(0,a.mdx)("p",null,"In order to request an asset, you can freely use the ",(0,a.mdx)("inlineCode",{parentName:"p"},"require")," method as if it was another JS file. The server will treat this specific ",(0,a.mdx)("inlineCode",{parentName:"p"},"require")," calls and make them return the path to that file. When an asset is requested (an asset is recognized by its extension, which has to be on the ",(0,a.mdx)("inlineCode",{parentName:"p"},"assetExts")," array) it is generally served as-is."),(0,a.mdx)("p",null,"However, the server is also able to serve specific assets depending on the platform and on the requested size (in the case of images). The way you specify the platform is via the dotted suffix (e.g. ",(0,a.mdx)("inlineCode",{parentName:"p"},".ios"),") and the resolution via the at suffix (e.g. ",(0,a.mdx)("inlineCode",{parentName:"p"},"@2x"),"). This is transparently handled for you when using ",(0,a.mdx)("inlineCode",{parentName:"p"},"require"),"."),(0,a.mdx)("h3",{id:"bundle"},"Bundle"),(0,a.mdx)("p",null,"Any JS file can be used as the root for a bundle request. The file will be looked in the ",(0,a.mdx)("inlineCode",{parentName:"p"},"projectRoot"),". All files that are required by the root will be recursively included. In order to request a bundle, just change the extension from ",(0,a.mdx)("inlineCode",{parentName:"p"},".js")," to ",(0,a.mdx)("inlineCode",{parentName:"p"},".bundle"),". Options for building the bundle are passed as query parameters (all optional)."),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"dev"),": build the bundle in development mode or not. Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"dev")," setting of the bundles. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"platform"),": platform requesting the bundle. Can be ",(0,a.mdx)("inlineCode",{parentName:"li"},"ios")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"android"),". Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"platform")," setting of the bundles."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"minify"),": whether code should be minified or not. Maps 1:1 to the ",(0,a.mdx)("inlineCode",{parentName:"li"},"minify")," setting of the bundles. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL."),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("inlineCode",{parentName:"li"},"excludeSource"),": whether sources should be included in the source map or not. Pass ",(0,a.mdx)("inlineCode",{parentName:"li"},"true")," or ",(0,a.mdx)("inlineCode",{parentName:"li"},"false")," as strings into the URL.")),(0,a.mdx)("p",null,"For instance, requesting ",(0,a.mdx)("inlineCode",{parentName:"p"},"http://localhost:8081/foo/bar/baz.bundle?dev=true&platform=ios")," will create a bundle out of ",(0,a.mdx)("inlineCode",{parentName:"p"},"foo/bar/baz.js")," for iOS in development mode."),(0,a.mdx)("h3",{id:"source-maps"},"Source maps"),(0,a.mdx)("p",null,"Source maps are built for each bundle by using the same URL as the bundle (thus, the same as the JS file acting as a root). This will only work when ",(0,a.mdx)("inlineCode",{parentName:"p"},"inlineSourceMap")," is set to ",(0,a.mdx)("inlineCode",{parentName:"p"},"false"),". All options you passed to the bundle will be added to the source map URL; otherwise, they wouldn't match."),(0,a.mdx)("h2",{id:"javascript-transformer"},"JavaScript transformer"),(0,a.mdx)("p",null,"The JavaScript transformer (",(0,a.mdx)("a",{parentName:"p",href:"/docs/configuration#babeltransformerpath"},(0,a.mdx)("inlineCode",{parentName:"a"},"babelTransformerPath")),") is the place where JS code will be manipulated; useful for calling Babel. The transformer can export two methods:"),(0,a.mdx)("h3",{id:"method-transformmodule"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"transform(module)")),(0,a.mdx)("p",null,"Mandatory method that will transform code. The object received has information about the module being transformed (e.g its path, code...) and the returned object has to contain an ",(0,a.mdx)("inlineCode",{parentName:"p"},"ast")," key that is the AST representation of the transformed code. The default shipped transformer does the bare minimum amount of work by just parsing the code to AST:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const babylon = require('@babel/parser');\n\nmodule.exports.transform = (file: {filename: string, src: string}) => {\n const ast = babylon.parse(file.src, {sourceType: 'module'});\n\n return {ast};\n};\n")),(0,a.mdx)("p",null,"If you would like to plug-in Babel, you can simply do that by passing the code to it:"),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const {transformSync} = require('@babel/core');\n\nmodule.exports.transform = file => {\n return transformSync(file.src, {\n // Babel options...\n });\n};\n")),(0,a.mdx)("h3",{id:"method-getcachekey"},"Method ",(0,a.mdx)("inlineCode",{parentName:"h3"},"getCacheKey()")),(0,a.mdx)("p",null,"Optional method that returns the cache key of the transformer. When using different transformers, this allows to correctly tie a transformed file to the transformer that converted it. The result of the method has to be a ",(0,a.mdx)("inlineCode",{parentName:"p"},"string"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/37a9b1a2.19077660.js b/assets/js/37a9b1a2.3e0e586b.js similarity index 99% rename from assets/js/37a9b1a2.19077660.js rename to assets/js/37a9b1a2.3e0e586b.js index f8852bc430..067a56ddd3 100644 --- a/assets/js/37a9b1a2.19077660.js +++ b/assets/js/37a9b1a2.3e0e586b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[536],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>u,MDXProvider:()=>c,mdx:()=>b,useMDXComponents:()=>m,withMDXComponents:()=>s});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var u=r.createContext({}),s=function(e){return function(n){var t=m(n.components);return r.createElement(e,a({},n,{components:t}))}},m=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=m(e.components);return r.createElement(u.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,u=d(e,["components","mdxType","originalType","parentName"]),s=m(t),c=i,p=s["".concat(l,".").concat(c)]||s[c]||f[c]||a;return t?r.createElement(p,o(o({ref:n},u),{},{components:t})):r.createElement(p,o({ref:n},u))}));function b(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,l=new Array(a);l[0]=h;var o={};for(var d in n)hasOwnProperty.call(n,d)&&(o[d]=n[d]);o.originalType=e,o[p]="string"==typeof e?e:i,l[1]=o;for(var u=2;u{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>d,default:()=>f,frontMatter:()=>o,metadata:()=>u,toc:()=>m});var r=t(83117),i=t(80102),a=(t(67294),t(3905)),l=["components"],o={id:"bundling",title:"Bundle Formats"},d=void 0,u={unversionedId:"bundling",id:"bundling",title:"Bundle Formats",description:"When bundling, each of the modules gets assigned a numeric id, meaning no dynamic requires are supported. Requires are changed by its numeric version, and modules are stored in different possible formats. Three different formats of bundling are supported:",source:"@site/../docs/Bundling.md",sourceDirName:".",slug:"/bundling",permalink:"/docs/bundling",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Bundling.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"bundling",title:"Bundle Formats"},sidebar:"docs",previous:{title:"Local Development Setup",permalink:"/docs/local-development"},next:{title:"Caching",permalink:"/docs/caching"}},s={},m=[{value:"Plain bundle",id:"plain-bundle",level:2},{value:"Indexed RAM bundle",id:"indexed-ram-bundle",level:2},{value:"File RAM bundle",id:"file-ram-bundle",level:2}],c={toc:m},p="wrapper";function f(e){var n=e.components,t=(0,i.Z)(e,l);return(0,a.mdx)(p,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"When bundling, each of the modules gets assigned a numeric id, meaning no dynamic requires are supported. Requires are changed by its numeric version, and modules are stored in different possible formats. Three different formats of bundling are supported:"),(0,a.mdx)("h2",{id:"plain-bundle"},"Plain bundle"),(0,a.mdx)("p",null,"This is the standard bundling format. In this format, all files are wrapped with a function call, then added to the global file. This is useful for environments that expect a JS only bundle (e.g. a browser). Just requiring the entry point with the ",(0,a.mdx)("inlineCode",{parentName:"p"},".bundle")," extension should trigger a build of it."),(0,a.mdx)("h2",{id:"indexed-ram-bundle"},"Indexed RAM bundle"),(0,a.mdx)("p",null,"This format composes the bundle as a binary file, which format has the following parts (all numbers are expressed in Little Endian):"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},"A magic number: a ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32")," must be located at the beginning of the file, with the value ",(0,a.mdx)("inlineCode",{parentName:"li"},"0xFB0BD1E5"),". This is used to verify the file."),(0,a.mdx)("li",{parentName:"ul"},"An offset table: the table is a sequence of ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32")," pairs, with a header",(0,a.mdx)("ul",{parentName:"li"},(0,a.mdx)("li",{parentName:"ul"},"For the header, two ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32"),"s can be found: the length of the table, and the length of the startup code."),(0,a.mdx)("li",{parentName:"ul"},"For the pairs, they represent the offset in the file and the length of code module, in bytes."))),(0,a.mdx)("li",{parentName:"ul"},"Each of the modules, finished by a null byte (",(0,a.mdx)("inlineCode",{parentName:"li"},"\\0"),").")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre"},"` 0 1 2 3 4 5 6\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Magic number | Header size |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Startup code size | Module 0 offset |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module 0 length | |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +\n| |\n+ ... +\n| |\n+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| | Module n offset |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module n length | Module 0 code | Module 0 code | ... | \\0 |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module 1 code | Module 1 code | ... | \\0 | |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +\n| |\n+ ... +\n| |\n+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| | Module n code | Module n code | ... | \\0 |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`\n")),(0,a.mdx)("p",null,"This structure is optimal for an environment that is able to load all code in memory at once:"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},"By using the offset table, one can load any module in constant time, where the code for module ",(0,a.mdx)("inlineCode",{parentName:"li"},"x")," is located at ",(0,a.mdx)("inlineCode",{parentName:"li"},"file[(x + 3) * sizeof(uint32)]"),". Since there is a null character (",(0,a.mdx)("inlineCode",{parentName:"li"},"\\0"),") separating all modules, usually length does not even need to be used, and the module can be loaded directly as an ASCIIZ string."),(0,a.mdx)("li",{parentName:"ul"},"Startup code is always found at ",(0,a.mdx)("inlineCode",{parentName:"li"},"file[sizeof(uint32)]"),".")),(0,a.mdx)("p",null,"This bundling is usually used by iOS."),(0,a.mdx)("h2",{id:"file-ram-bundle"},"File RAM bundle"),(0,a.mdx)("p",null,"Each module is stored as a file, with the name ",(0,a.mdx)("inlineCode",{parentName:"p"},"js-modules/${id}.js"),", plus an extra file called ",(0,a.mdx)("inlineCode",{parentName:"p"},"UNBUNDLE")," is created, which its only content is the magic number, ",(0,a.mdx)("inlineCode",{parentName:"p"},"0xFB0BD1E5"),". Note that the ",(0,a.mdx)("inlineCode",{parentName:"p"},"UNBUNDLE")," file is created at the root.\nThis bundling is usually used by Android, since package contents are zipped, and access to a zipped file is much faster. If the indexed format was used instead, all the bundled should be unzipped at once to get the code for the corresponding module."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[536],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>u,MDXProvider:()=>c,mdx:()=>b,useMDXComponents:()=>m,withMDXComponents:()=>s});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var u=r.createContext({}),s=function(e){return function(n){var t=m(n.components);return r.createElement(e,a({},n,{components:t}))}},m=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},c=function(e){var n=m(e.components);return r.createElement(u.Provider,{value:n},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,u=d(e,["components","mdxType","originalType","parentName"]),s=m(t),c=i,p=s["".concat(l,".").concat(c)]||s[c]||f[c]||a;return t?r.createElement(p,o(o({ref:n},u),{},{components:t})):r.createElement(p,o({ref:n},u))}));function b(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,l=new Array(a);l[0]=h;var o={};for(var d in n)hasOwnProperty.call(n,d)&&(o[d]=n[d]);o.originalType=e,o[p]="string"==typeof e?e:i,l[1]=o;for(var u=2;u{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>d,default:()=>f,frontMatter:()=>o,metadata:()=>u,toc:()=>m});var r=t(83117),i=t(80102),a=(t(67294),t(3905)),l=["components"],o={id:"bundling",title:"Bundle Formats"},d=void 0,u={unversionedId:"bundling",id:"bundling",title:"Bundle Formats",description:"When bundling, each of the modules gets assigned a numeric id, meaning no dynamic requires are supported. Requires are changed by its numeric version, and modules are stored in different possible formats. Three different formats of bundling are supported:",source:"@site/../docs/Bundling.md",sourceDirName:".",slug:"/bundling",permalink:"/docs/bundling",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Bundling.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"bundling",title:"Bundle Formats"},sidebar:"docs",previous:{title:"Local Development Setup",permalink:"/docs/local-development"},next:{title:"Caching",permalink:"/docs/caching"}},s={},m=[{value:"Plain bundle",id:"plain-bundle",level:2},{value:"Indexed RAM bundle",id:"indexed-ram-bundle",level:2},{value:"File RAM bundle",id:"file-ram-bundle",level:2}],c={toc:m},p="wrapper";function f(e){var n=e.components,t=(0,i.Z)(e,l);return(0,a.mdx)(p,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"When bundling, each of the modules gets assigned a numeric id, meaning no dynamic requires are supported. Requires are changed by its numeric version, and modules are stored in different possible formats. Three different formats of bundling are supported:"),(0,a.mdx)("h2",{id:"plain-bundle"},"Plain bundle"),(0,a.mdx)("p",null,"This is the standard bundling format. In this format, all files are wrapped with a function call, then added to the global file. This is useful for environments that expect a JS only bundle (e.g. a browser). Just requiring the entry point with the ",(0,a.mdx)("inlineCode",{parentName:"p"},".bundle")," extension should trigger a build of it."),(0,a.mdx)("h2",{id:"indexed-ram-bundle"},"Indexed RAM bundle"),(0,a.mdx)("p",null,"This format composes the bundle as a binary file, which format has the following parts (all numbers are expressed in Little Endian):"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},"A magic number: a ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32")," must be located at the beginning of the file, with the value ",(0,a.mdx)("inlineCode",{parentName:"li"},"0xFB0BD1E5"),". This is used to verify the file."),(0,a.mdx)("li",{parentName:"ul"},"An offset table: the table is a sequence of ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32")," pairs, with a header",(0,a.mdx)("ul",{parentName:"li"},(0,a.mdx)("li",{parentName:"ul"},"For the header, two ",(0,a.mdx)("inlineCode",{parentName:"li"},"uint32"),"s can be found: the length of the table, and the length of the startup code."),(0,a.mdx)("li",{parentName:"ul"},"For the pairs, they represent the offset in the file and the length of code module, in bytes."))),(0,a.mdx)("li",{parentName:"ul"},"Each of the modules, finished by a null byte (",(0,a.mdx)("inlineCode",{parentName:"li"},"\\0"),").")),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre"},"` 0 1 2 3 4 5 6\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Magic number | Header size |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Startup code size | Module 0 offset |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module 0 length | |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +\n| |\n+ ... +\n| |\n+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| | Module n offset |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module n length | Module 0 code | Module 0 code | ... | \\0 |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| Module 1 code | Module 1 code | ... | \\0 | |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +\n| |\n+ ... +\n| |\n+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n| | Module n code | Module n code | ... | \\0 |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+`\n")),(0,a.mdx)("p",null,"This structure is optimal for an environment that is able to load all code in memory at once:"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},"By using the offset table, one can load any module in constant time, where the code for module ",(0,a.mdx)("inlineCode",{parentName:"li"},"x")," is located at ",(0,a.mdx)("inlineCode",{parentName:"li"},"file[(x + 3) * sizeof(uint32)]"),". Since there is a null character (",(0,a.mdx)("inlineCode",{parentName:"li"},"\\0"),") separating all modules, usually length does not even need to be used, and the module can be loaded directly as an ASCIIZ string."),(0,a.mdx)("li",{parentName:"ul"},"Startup code is always found at ",(0,a.mdx)("inlineCode",{parentName:"li"},"file[sizeof(uint32)]"),".")),(0,a.mdx)("p",null,"This bundling is usually used by iOS."),(0,a.mdx)("h2",{id:"file-ram-bundle"},"File RAM bundle"),(0,a.mdx)("p",null,"Each module is stored as a file, with the name ",(0,a.mdx)("inlineCode",{parentName:"p"},"js-modules/${id}.js"),", plus an extra file called ",(0,a.mdx)("inlineCode",{parentName:"p"},"UNBUNDLE")," is created, which its only content is the magic number, ",(0,a.mdx)("inlineCode",{parentName:"p"},"0xFB0BD1E5"),". Note that the ",(0,a.mdx)("inlineCode",{parentName:"p"},"UNBUNDLE")," file is created at the root.\nThis bundling is usually used by Android, since package contents are zipped, and access to a zipped file is much faster. If the indexed format was used instead, all the bundled should be unzipped at once to get the code for the corresponding module."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/51001101.f13d564f.js b/assets/js/51001101.e553b5bb.js similarity index 98% rename from assets/js/51001101.f13d564f.js rename to assets/js/51001101.e553b5bb.js index fd742657c6..0fa47878cb 100644 --- a/assets/js/51001101.f13d564f.js +++ b/assets/js/51001101.e553b5bb.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[645],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>p,mdx:()=>g,useMDXComponents:()=>d,withMDXComponents:()=>c});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var m=r.createContext({}),c=function(e){return function(t){var n=d(t.components);return r.createElement(e,o({},t,{components:n}))}},d=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(m.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),c=d(n),p=a,u=c["".concat(i,".").concat(p)]||c[p]||h[p]||o;return n?r.createElement(u,s(s({ref:t},m),{},{components:n})):r.createElement(u,s({ref:t},m))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>m,toc:()=>d});var r=n(83117),a=n(80102),o=(n(67294),n(3905)),i=["components"],s={id:"caching",title:"Caching"},l=void 0,m={unversionedId:"caching",id:"caching",title:"Caching",description:"Out of the box, Metro speeds up builds using a local cache of transformed modules. Thanks to this cache, Metro doesn't need to retransform modules unless the source code (or current configuration) has changed since the last time they were transformed.",source:"@site/../docs/Caching.md",sourceDirName:".",slug:"/caching",permalink:"/docs/caching",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Caching.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"caching",title:"Caching"},sidebar:"docs",previous:{title:"Bundle Formats",permalink:"/docs/bundling"},next:{title:"Module Resolution",permalink:"/docs/resolution"}},c={},d=[{value:"Built-in cache stores",id:"built-in-cache-stores",level:2},{value:"Custom cache stores",id:"custom-cache-stores",level:2}],p={toc:d},u="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,i);return(0,o.mdx)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Out of the box, Metro speeds up builds using a ",(0,o.mdx)("strong",{parentName:"p"},"local cache")," of ",(0,o.mdx)("a",{parentName:"p",href:"/docs/concepts#transformation"},"transformed")," modules. Thanks to this cache, Metro doesn't need to retransform modules unless the source code (or current configuration) has changed since the last time they were transformed."),(0,o.mdx)("p",null,"Metro also has the ability to use a ",(0,o.mdx)("strong",{parentName:"p"},"remote cache"),". This can dramatically speed up builds for larger teams and/or larger codebases by reducing the amount of time spent locally building remote changes even further. For example, this is how we use Metro to build React Native apps at Meta (a codebase with many thousands of files and hundreds of daily active engineers)."),(0,o.mdx)("p",null,"A typical setup for a remote cache involves:"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"A storage backend specific to your team (e.g."," ",(0,o.mdx)("a",{parentName:"li",href:"https://internalfb.com/sevmanager/view/3"},"S3")," ","bucket)."),(0,o.mdx)("li",{parentName:"ol"},"Running ",(0,o.mdx)("a",{parentName:"li",href:"/docs/cli#build-entry"},(0,o.mdx)("inlineCode",{parentName:"a"},"metro build"))," periodically (e.g. in a CI job) to populate the cache, using ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore")," (or a custom read/write cache store) in your Metro config."),(0,o.mdx)("li",{parentName:"ol"},"Configuring Metro on your development machines to read from the cache, using ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpGetStore")," (or a custom read-only cache store) in your Metro config.")),(0,o.mdx)("p",null,"The main option for configuring the Metro cache is ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores")),". Typically, the local cache (e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"FileStore"),") should be listed first, followed by the remote cache (e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"HttpCache"),")."),(0,o.mdx)("h2",{id:"built-in-cache-stores"},"Built-in cache stores"),(0,o.mdx)("p",null,"Metro provides a number of built-in cache store implementations for use with the ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores"))," config option:"),(0,o.mdx)("ul",null,(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"FileStore({root: string})"))," will store cache entries as files under the directory specified by ",(0,o.mdx)("inlineCode",{parentName:"li"},"root"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"AutoCleanFileStore()"))," is a ",(0,o.mdx)("inlineCode",{parentName:"li"},"FileStore")," that periodically cleans up old entries. It accepts the same options as ",(0,o.mdx)("inlineCode",{parentName:"li"},"FileStore")," plus the following:",(0,o.mdx)("ul",{parentName:"li"},(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.intervalMs: number"))," is the time in milliseconds between cleanup attempts. Defaults to 10 minutes."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.cleanupThresholdMs: number"))," is the minimum time in milliseconds since the last modification of an entry before it can be deleted. Defaults to 3 days."))),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"HttpStore(options)"))," is a bare-bones remote cache client that reads (",(0,o.mdx)("inlineCode",{parentName:"li"},"GET"),") and writes (",(0,o.mdx)("inlineCode",{parentName:"li"},"PUT"),") compressed cache artifacts over HTTP or HTTPS.",(0,o.mdx)("ul",{parentName:"li"},(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.endpoint: string"))," is the base URL for the cache server. For example, an ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore")," with ",(0,o.mdx)("inlineCode",{parentName:"li"},"'http://www.example.com/endpoint'")," as the endpoint would issue requests to URLs such as ",(0,o.mdx)("inlineCode",{parentName:"li"},"http://www.example.com/endpoint/c083bff944879d9f528cf185eba0f496bc10a47d"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.timeout: number"))," is the timeout for requests to the cache server, in milliseconds. Defaults to 5000."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.family: 4 | 6"))," is the same as the ",(0,o.mdx)("inlineCode",{parentName:"li"},"family")," parameter to Node's ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#httprequesturl-options-callback"},(0,o.mdx)("inlineCode",{parentName:"a"},"http.request")),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.cert"),", ",(0,o.mdx)("inlineCode",{parentName:"strong"},"options.ca"),", ",(0,o.mdx)("inlineCode",{parentName:"strong"},"options.key")),": HTTPS options passed directly to ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/https.html"},"Node's built-in HTTPS client"),"."))),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"HttpGetStore(options)"))," is a read-only version of ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore"),".")),(0,o.mdx)("p",null,"You can import these classes from the ",(0,o.mdx)("inlineCode",{parentName:"p"},"metro-cache")," package or get them through the function form of ",(0,o.mdx)("inlineCode",{parentName:"p"},"cacheStores"),":"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// metro.config.js\nconst os = require('node:os');\nconst path = require('node:path');\n\nmodule.exports = {\n cacheStores: ({ FileStore }) => [\n new FileStore({\n root: path.join(os.tmpdir(), 'metro-cache'),\n }),\n ],\n};\n\n")),(0,o.mdx)("h2",{id:"custom-cache-stores"},"Custom cache stores"),(0,o.mdx)("p",null,"To implement a custom cache store, pass an instance of a class with the following interface into ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores")),":"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"interface CacheStore {\n // Read an entry from the cache. Returns `null` if not found.\n get(key: Buffer): ?T | Promise;\n\n // Write an entry to the cache (if writable) or do nothing (if read-only)\n set(key: Buffer, value: T): void | Promise;\n\n // Clear the cache (if possible) or do nothing\n clear(): void | Promise;\n}\n\ntype JsonSerializable = /* Any JSON-serializable value */;\n")),(0,o.mdx)("p",null,"The value of a cache entry is either an instance of ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/buffer.html#buffer"},(0,o.mdx)("inlineCode",{parentName:"a"},"Buffer"))," or a JSON-serializable value (with unspecified internal structure in both cases). For a given cache key, ",(0,o.mdx)("inlineCode",{parentName:"p"},"get()")," ",(0,o.mdx)("em",{parentName:"p"},"must")," return the same type of value that was originally provided to ",(0,o.mdx)("inlineCode",{parentName:"p"},"set()"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[645],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>p,mdx:()=>g,useMDXComponents:()=>d,withMDXComponents:()=>c});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var m=r.createContext({}),c=function(e){return function(t){var n=d(t.components);return r.createElement(e,o({},t,{components:n}))}},d=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},p=function(e){var t=d(e.components);return r.createElement(m.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),c=d(n),p=a,u=c["".concat(i,".").concat(p)]||c[p]||h[p]||o;return n?r.createElement(u,s(s({ref:t},m),{},{components:n})):r.createElement(u,s({ref:t},m))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var m=2;m{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>m,toc:()=>d});var r=n(83117),a=n(80102),o=(n(67294),n(3905)),i=["components"],s={id:"caching",title:"Caching"},l=void 0,m={unversionedId:"caching",id:"caching",title:"Caching",description:"Out of the box, Metro speeds up builds using a local cache of transformed modules. Thanks to this cache, Metro doesn't need to retransform modules unless the source code (or current configuration) has changed since the last time they were transformed.",source:"@site/../docs/Caching.md",sourceDirName:".",slug:"/caching",permalink:"/docs/caching",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Caching.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"caching",title:"Caching"},sidebar:"docs",previous:{title:"Bundle Formats",permalink:"/docs/bundling"},next:{title:"Module Resolution",permalink:"/docs/resolution"}},c={},d=[{value:"Built-in cache stores",id:"built-in-cache-stores",level:2},{value:"Custom cache stores",id:"custom-cache-stores",level:2}],p={toc:d},u="wrapper";function h(e){var t=e.components,n=(0,a.Z)(e,i);return(0,o.mdx)(u,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Out of the box, Metro speeds up builds using a ",(0,o.mdx)("strong",{parentName:"p"},"local cache")," of ",(0,o.mdx)("a",{parentName:"p",href:"/docs/concepts#transformation"},"transformed")," modules. Thanks to this cache, Metro doesn't need to retransform modules unless the source code (or current configuration) has changed since the last time they were transformed."),(0,o.mdx)("p",null,"Metro also has the ability to use a ",(0,o.mdx)("strong",{parentName:"p"},"remote cache"),". This can dramatically speed up builds for larger teams and/or larger codebases by reducing the amount of time spent locally building remote changes even further. For example, this is how we use Metro to build React Native apps at Meta (a codebase with many thousands of files and hundreds of daily active engineers)."),(0,o.mdx)("p",null,"A typical setup for a remote cache involves:"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"A storage backend specific to your team (e.g."," ",(0,o.mdx)("a",{parentName:"li",href:"https://internalfb.com/sevmanager/view/3"},"S3")," ","bucket)."),(0,o.mdx)("li",{parentName:"ol"},"Running ",(0,o.mdx)("a",{parentName:"li",href:"/docs/cli#build-entry"},(0,o.mdx)("inlineCode",{parentName:"a"},"metro build"))," periodically (e.g. in a CI job) to populate the cache, using ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore")," (or a custom read/write cache store) in your Metro config."),(0,o.mdx)("li",{parentName:"ol"},"Configuring Metro on your development machines to read from the cache, using ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpGetStore")," (or a custom read-only cache store) in your Metro config.")),(0,o.mdx)("p",null,"The main option for configuring the Metro cache is ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores")),". Typically, the local cache (e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"FileStore"),") should be listed first, followed by the remote cache (e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"HttpCache"),")."),(0,o.mdx)("h2",{id:"built-in-cache-stores"},"Built-in cache stores"),(0,o.mdx)("p",null,"Metro provides a number of built-in cache store implementations for use with the ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores"))," config option:"),(0,o.mdx)("ul",null,(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"FileStore({root: string})"))," will store cache entries as files under the directory specified by ",(0,o.mdx)("inlineCode",{parentName:"li"},"root"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"AutoCleanFileStore()"))," is a ",(0,o.mdx)("inlineCode",{parentName:"li"},"FileStore")," that periodically cleans up old entries. It accepts the same options as ",(0,o.mdx)("inlineCode",{parentName:"li"},"FileStore")," plus the following:",(0,o.mdx)("ul",{parentName:"li"},(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.intervalMs: number"))," is the time in milliseconds between cleanup attempts. Defaults to 10 minutes."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.cleanupThresholdMs: number"))," is the minimum time in milliseconds since the last modification of an entry before it can be deleted. Defaults to 3 days."))),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"HttpStore(options)"))," is a bare-bones remote cache client that reads (",(0,o.mdx)("inlineCode",{parentName:"li"},"GET"),") and writes (",(0,o.mdx)("inlineCode",{parentName:"li"},"PUT"),") compressed cache artifacts over HTTP or HTTPS.",(0,o.mdx)("ul",{parentName:"li"},(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.endpoint: string"))," is the base URL for the cache server. For example, an ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore")," with ",(0,o.mdx)("inlineCode",{parentName:"li"},"'http://www.example.com/endpoint'")," as the endpoint would issue requests to URLs such as ",(0,o.mdx)("inlineCode",{parentName:"li"},"http://www.example.com/endpoint/c083bff944879d9f528cf185eba0f496bc10a47d"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.timeout: number"))," is the timeout for requests to the cache server, in milliseconds. Defaults to 5000."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.family: 4 | 6"))," is the same as the ",(0,o.mdx)("inlineCode",{parentName:"li"},"family")," parameter to Node's ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/http.html#httprequesturl-options-callback"},(0,o.mdx)("inlineCode",{parentName:"a"},"http.request")),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"options.cert"),", ",(0,o.mdx)("inlineCode",{parentName:"strong"},"options.ca"),", ",(0,o.mdx)("inlineCode",{parentName:"strong"},"options.key")),": HTTPS options passed directly to ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/api/https.html"},"Node's built-in HTTPS client"),"."))),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},(0,o.mdx)("inlineCode",{parentName:"strong"},"HttpGetStore(options)"))," is a read-only version of ",(0,o.mdx)("inlineCode",{parentName:"li"},"HttpStore"),".")),(0,o.mdx)("p",null,"You can import these classes from the ",(0,o.mdx)("inlineCode",{parentName:"p"},"metro-cache")," package or get them through the function form of ",(0,o.mdx)("inlineCode",{parentName:"p"},"cacheStores"),":"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// metro.config.js\nconst os = require('node:os');\nconst path = require('node:path');\n\nmodule.exports = {\n cacheStores: ({ FileStore }) => [\n new FileStore({\n root: path.join(os.tmpdir(), 'metro-cache'),\n }),\n ],\n};\n\n")),(0,o.mdx)("h2",{id:"custom-cache-stores"},"Custom cache stores"),(0,o.mdx)("p",null,"To implement a custom cache store, pass an instance of a class with the following interface into ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#cachestores"},(0,o.mdx)("inlineCode",{parentName:"a"},"cacheStores")),":"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"interface CacheStore {\n // Read an entry from the cache. Returns `null` if not found.\n get(key: Buffer): ?T | Promise;\n\n // Write an entry to the cache (if writable) or do nothing (if read-only)\n set(key: Buffer, value: T): void | Promise;\n\n // Clear the cache (if possible) or do nothing\n clear(): void | Promise;\n}\n\ntype JsonSerializable = /* Any JSON-serializable value */;\n")),(0,o.mdx)("p",null,"The value of a cache entry is either an instance of ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/buffer.html#buffer"},(0,o.mdx)("inlineCode",{parentName:"a"},"Buffer"))," or a JSON-serializable value (with unspecified internal structure in both cases). For a given cache key, ",(0,o.mdx)("inlineCode",{parentName:"p"},"get()")," ",(0,o.mdx)("em",{parentName:"p"},"must")," return the same type of value that was originally provided to ",(0,o.mdx)("inlineCode",{parentName:"p"},"set()"),"."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6373d68f.913b28f6.js b/assets/js/6373d68f.c5fea588.js similarity index 99% rename from assets/js/6373d68f.913b28f6.js rename to assets/js/6373d68f.c5fea588.js index 8c51ad7ea5..c82f35781e 100644 --- a/assets/js/6373d68f.913b28f6.js +++ b/assets/js/6373d68f.c5fea588.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[874],{3905:(e,n,a)=>{a.r(n),a.d(n,{MDXContext:()=>d,MDXProvider:()=>c,mdx:()=>h,useMDXComponents:()=>s,withMDXComponents:()=>p});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(){return i=Object.assign||function(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var d=t.createContext({}),p=function(e){return function(n){var a=s(n.components);return t.createElement(e,i({},n,{components:a}))}},s=function(e){var n=t.useContext(d),a=n;return e&&(a="function"==typeof e?e(n):m(m({},n),e)),a},c=function(e){var n=s(e.components);return t.createElement(d.Provider,{value:n},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},x=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,r=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(a),c=o,u=p["".concat(r,".").concat(c)]||p[c]||f[c]||i;return a?t.createElement(u,m(m({ref:n},d),{},{components:a})):t.createElement(u,m({ref:n},d))}));function h(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=x;var m={};for(var l in n)hasOwnProperty.call(n,l)&&(m[l]=n[l]);m.originalType=e,m[u]="string"==typeof e?e:o,r[1]=m;for(var d=2;d{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>m,metadata:()=>d,toc:()=>s});var t=a(83117),o=a(80102),i=(a(67294),a(3905)),r=["components"],m={id:"source-map-format",title:"Source Map Format"},l=void 0,d={unversionedId:"source-map-format",id:"source-map-format",title:"Source Map Format",description:"Metro produces standard source maps along with its JavaScript bundle output. In addition to the standard information, Metro encodes extra information in vendor-specific fields within the source map. This page serves as a specification for this encoding.",source:"@site/../docs/SourceMapFormat.md",sourceDirName:".",slug:"/source-map-format",permalink:"/docs/source-map-format",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/SourceMapFormat.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"source-map-format",title:"Source Map Format"},sidebar:"docs",previous:{title:"Module Resolution",permalink:"/docs/resolution"}},p={},s=[{value:"x_facebook_sources",id:"x_facebook_sources",level:2},{value:"Metadata tuple",id:"metadata-tuple",level:3},{value:"Function map",id:"function-map",level:4},{value:"Function map mappings field encoding",id:"function-map-mappings-field-encoding",level:5},{value:"Example",id:"example",level:3},{value:"x_google_ignoreList",id:"x_google_ignorelist",level:2}],c={toc:s},u="wrapper";function f(e){var n=e.components,a=(0,o.Z)(e,r);return(0,i.mdx)(u,(0,t.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.mdx)("p",null,"Metro produces standard ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html"},"source maps")," along with its JavaScript bundle output. In addition to the standard information, Metro encodes extra information in ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm"},"vendor-specific fields")," within the source map. This page serves as a specification for this encoding."),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"The content on this page assumes familiarity with the ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html"},"source map specification"),". Check out ",(0,i.mdx)("a",{parentName:"p",href:"https://www.bugsnag.com/blog/source-maps"},"Anatomy of source maps")," for a general introduction to source maps and how they work.")),(0,i.mdx)("h2",{id:"x_facebook_sources"},(0,i.mdx)("inlineCode",{parentName:"h2"},"x_facebook_sources")),(0,i.mdx)("p",null,"The ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field encodes metadata about source files in a source map. Each piece of metadata represents some attribute intrinsic to the source code of that particular file - for example, the result of running some analysis over the AST. This allows tools such as debuggers and JS engines to access such analyses efficiently, without needing to parse or even have access to the source code."),(0,i.mdx)("p",null,"In the same way that the standard ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm:~:text=sourceRoot%22%3A%20%22%22%2C-,%22sources%22%3A,-%5B%22foo.js%22%2C%20%22bar"},(0,i.mdx)("inlineCode",{parentName:"a"},"sources"))," field is a list of source URLs and ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm:~:text=js%22%2C%20%22bar.js%22%5D%2C-,%22sourcesContent%22%3A,-%5Bnull%2C%20null%5D%2C"},(0,i.mdx)("inlineCode",{parentName:"a"},"sourcesContent"))," is a list of (optional) source code strings, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," is a list of optional ",(0,i.mdx)("strong",{parentName:"p"},"metadata tuples"),". The ",(0,i.mdx)("em",{parentName:"p"},"i"),"-th metadata tuple (",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources[i]"),") corresponds to the source file whose URL is ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources[i]"),"."),(0,i.mdx)("p",null,"In nested (indexed) source maps, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," may appear as part of any nested source map in ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.535es3xeprgt"},(0,i.mdx)("inlineCode",{parentName:"a"},"sections"))," that itself has a ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," field."),(0,i.mdx)("p",null,"If present, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," may be a different length than ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," (but usually shouldn't be). In particular, if it's shorter than ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),", ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," interpreted as if it were padded with ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," values to match the length of ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),"."),(0,i.mdx)("admonition",{type:"info"},(0,i.mdx)("p",{parentName:"admonition"},"If you are writing a tool that processes source maps generated by Metro, and want to generate a new source map containing a valid ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field, you'll mainly need to ensure that ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources[i]")," still corresponds to ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources[i]")," in the output - even if your tool reorders, adds or deletes elements in ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),". Notably, this can be done ",(0,i.mdx)("em",{parentName:"p"},"without")," parsing/decoding the metadata tuples: unless your tool actively needs to access the information within them, you can treat them as opaque blobs of JSON."),(0,i.mdx)("p",{parentName:"admonition"},"If a tool cannot guarantee that the ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," arrays will stay in sync, it should delete the ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field from its output.")),(0,i.mdx)("h3",{id:"metadata-tuple"},"Metadata tuple"),(0,i.mdx)("p",null,"Each metadata tuple is encoded as an array of zero or more entries. Each entry may be ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," to signify that it's missing. A run of trailing ",(0,i.mdx)("inlineCode",{parentName:"p"},"null"),"s may be truncated from the end of the tuple with no change in meaning. The metadata tuple itself may also be ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," to signify that the source file has no associated metadata."),(0,i.mdx)("p",null,"The indices in each metadata tuple are assigned as follows:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Index 0: ",(0,i.mdx)("a",{parentName:"li",href:"#function-map"},"Function map")," or ",(0,i.mdx)("inlineCode",{parentName:"li"},"null"),".",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"In Metro, this is the result of calling ",(0,i.mdx)("a",{parentName:"li",href:"https://github.com/facebook/metro/blob/main/packages/metro-source-map/src/generateFunctionMap.js"},(0,i.mdx)("inlineCode",{parentName:"a"},"generateFunctionMap"))," on the source AST."))),(0,i.mdx)("li",{parentName:"ul"},"Index 1-\u221e: Reserved for future use.")),(0,i.mdx)("h4",{id:"function-map"},"Function map"),(0,i.mdx)("p",null,"A function map is encoded as an object with the following two fields:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"names"),": An array of strings."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"mappings"),": A string following the ",(0,i.mdx)("a",{parentName:"li",href:"#function-map-mappings-field-encoding"},"encoding")," described below.")),(0,i.mdx)("p",null,"When decoded, ",(0,i.mdx)("inlineCode",{parentName:"p"},"mappings")," represents a list of 3-tuples of integers: ",(0,i.mdx)("inlineCode",{parentName:"p"},"(column, nameIndex, line), (column, nameIndex, line), ..."),". The list is ordered by ",(0,i.mdx)("inlineCode",{parentName:"p"},"line")," and then ",(0,i.mdx)("inlineCode",{parentName:"p"},"column"),"."),(0,i.mdx)("p",null,"The presence of a 3-tuple ",(0,i.mdx)("inlineCode",{parentName:"p"},"(column, nameIndex, line)")," means that the ",(0,i.mdx)("em",{parentName:"p"},"local function name")," in the code region beginning at ",(0,i.mdx)("inlineCode",{parentName:"p"},"line")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"column")," (in the source file described by the current metadata tuple) is ",(0,i.mdx)("inlineCode",{parentName:"p"},"names[nameIndex]"),"."),(0,i.mdx)("h5",{id:"function-map-mappings-field-encoding"},"Function map ",(0,i.mdx)("inlineCode",{parentName:"h5"},"mappings")," field encoding"),(0,i.mdx)("p",null,"The value of the ",(0,i.mdx)("inlineCode",{parentName:"p"},"mappings")," field is described by the ",(0,i.mdx)("em",{parentName:"p"},"Mappings")," production of the grammar detailed below."),(0,i.mdx)("ol",null,(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},'Mappings = [ ";" ] LineMappings { ";" { ";" } LineMappings }')),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},'LineMappings = FirstColumnMapping "," ColumnMapping')),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"FirstColumnMapping = VLQ VLQ VLQ")),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"ColumnMapping = VLQ VLQ [ VLQ ]")),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"VLQ =")," ",(0,i.mdx)("em",{parentName:"li"},"A single Base64-encoded variable-length quantity, as defined in the ",(0,i.mdx)("a",{parentName:"em",href:"https://sourcemaps.info/spec.html#h.crcf4lqeivt8"},"source map specification")),".")),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"The above grammar uses the following BNF-like notation:"),(0,i.mdx)("table",{parentName:"admonition"},(0,i.mdx)("thead",{parentName:"table"},(0,i.mdx)("tr",{parentName:"thead"},(0,i.mdx)("th",{parentName:"tr",align:null},"Notation"),(0,i.mdx)("th",{parentName:"tr",align:null},"Meaning"))),(0,i.mdx)("tbody",{parentName:"table"},(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},"[ X ]")),(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("em",{parentName:"td"},"X")," appears zero or 1 times.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},"{ X }")),(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("em",{parentName:"td"},"X")," appears 0 or more times.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},'"foo"')),(0,i.mdx)("td",{parentName:"tr",align:null},"The literal characters ",(0,i.mdx)("inlineCode",{parentName:"td"},"foo"),"."))))),(0,i.mdx)("p",null,"The three VLQs in ",(0,i.mdx)("em",{parentName:"p"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"p"},"ColumnMapping")," represent, in this order:"),(0,i.mdx)("ol",null,(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Column delta"),":",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"In ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping"),": The column offset from the beginning of the line. (0 = first column)"),(0,i.mdx)("li",{parentName:"ul"},"In ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),": The column offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),"."))),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Name delta"),": The name index offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),". This is ",(0,i.mdx)("em",{parentName:"li"},"not")," reset between lines."),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Line delta"),": The line offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),". This is ",(0,i.mdx)("em",{parentName:"li"},"not")," reset between lines.",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"This MUST be 0 (Base64 VLQ: ",(0,i.mdx)("inlineCode",{parentName:"li"},"A"),") if it is part of a ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),"."),(0,i.mdx)("li",{parentName:"ul"},"Implementations SHOULD omit this field from the encoded form of ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),".")))),(0,i.mdx)("h3",{id:"example"},"Example"),(0,i.mdx)("p",null,"Given a single source file called ",(0,i.mdx)("inlineCode",{parentName:"p"},"file.js"),", a complete source map might look like this:"),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"Comments are for illustrative purposes - the source map format does not allow comments.")),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "version": 3,\n "sources": ["file.js"],\n "sourcesContent": ["function a(){} function b(){}"],\n "mappings": "AAAA", // NOTE: Simplified\n "x_facebook_sources": [\n // Metadata tuple for source #0 (file.js)\n [\n // Metadata item #0.0 = function map for source #0 (file.js)\n {\n // a from 1:0\n // from 1:14\n // b from 1:15\n // (See detailed decoding procedure below.)\n "mappings": "AAA,cC,CC",\n "names": [\n "a",\n "",\n "b",\n ]\n }\n ]\n ]\n}\n')),(0,i.mdx)("p",null,"The decoding procedure for the function map in the above example is illustrated by the following code:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"const decoded = [];\nconst names = ['a', '', 'b']; // From the function map\n\nlet column = 0, nameIndex = 0, line = 1;\ncolumn += 0 /* A */; nameIndex += 0 /* A */; line += 0 /* A */;\ndecoded.push({column, name: names[nameIndex] /* 'a' */, line});\n\ncolumn += 14 /* c */; nameIndex += 1 /* C */; // no line delta\ndecoded.push({column, name: names[nameIndex] /* '' */, line});\n\ncolumn += 1 /* C */; nameIndex += 1 /* C */; // no line delta\ndecoded.push({column, name: names[nameIndex] /* 'b' */, line});\n\n/*\n decoded = [\n {column: 0, name: 'a', line: 1},\n {column: 14, name: '', line: 1},\n {column: 15, name: 'b', line: 1},\n ]\n*/\n")),(0,i.mdx)("h2",{id:"x_google_ignorelist"},(0,i.mdx)("inlineCode",{parentName:"h2"},"x_google_ignoreList")),(0,i.mdx)("p",null,"Metro's source maps include the ",(0,i.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/articles/x-google-ignore-list/"},(0,i.mdx)("inlineCode",{parentName:"a"},"x_google_ignoreList"))," field by default. The ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration#isthirdpartymodule"},(0,i.mdx)("inlineCode",{parentName:"a"},"serializer.isThirdPartyModule"))," option can be used to control which modules are ignore-listed."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[874],{3905:(e,n,a)=>{a.r(n),a.d(n,{MDXContext:()=>d,MDXProvider:()=>c,mdx:()=>h,useMDXComponents:()=>s,withMDXComponents:()=>p});var t=a(67294);function o(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(){return i=Object.assign||function(e){for(var n=1;n=0||(o[a]=e[a]);return o}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(o[a]=e[a])}return o}var d=t.createContext({}),p=function(e){return function(n){var a=s(n.components);return t.createElement(e,i({},n,{components:a}))}},s=function(e){var n=t.useContext(d),a=n;return e&&(a="function"==typeof e?e(n):m(m({},n),e)),a},c=function(e){var n=s(e.components);return t.createElement(d.Provider,{value:n},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},x=t.forwardRef((function(e,n){var a=e.components,o=e.mdxType,i=e.originalType,r=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=s(a),c=o,u=p["".concat(r,".").concat(c)]||p[c]||f[c]||i;return a?t.createElement(u,m(m({ref:n},d),{},{components:a})):t.createElement(u,m({ref:n},d))}));function h(e,n){var a=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var i=a.length,r=new Array(i);r[0]=x;var m={};for(var l in n)hasOwnProperty.call(n,l)&&(m[l]=n[l]);m.originalType=e,m[u]="string"==typeof e?e:o,r[1]=m;for(var d=2;d{a.r(n),a.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>m,metadata:()=>d,toc:()=>s});var t=a(83117),o=a(80102),i=(a(67294),a(3905)),r=["components"],m={id:"source-map-format",title:"Source Map Format"},l=void 0,d={unversionedId:"source-map-format",id:"source-map-format",title:"Source Map Format",description:"Metro produces standard source maps along with its JavaScript bundle output. In addition to the standard information, Metro encodes extra information in vendor-specific fields within the source map. This page serves as a specification for this encoding.",source:"@site/../docs/SourceMapFormat.md",sourceDirName:".",slug:"/source-map-format",permalink:"/docs/source-map-format",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/SourceMapFormat.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"source-map-format",title:"Source Map Format"},sidebar:"docs",previous:{title:"Module Resolution",permalink:"/docs/resolution"}},p={},s=[{value:"x_facebook_sources",id:"x_facebook_sources",level:2},{value:"Metadata tuple",id:"metadata-tuple",level:3},{value:"Function map",id:"function-map",level:4},{value:"Function map mappings field encoding",id:"function-map-mappings-field-encoding",level:5},{value:"Example",id:"example",level:3},{value:"x_google_ignoreList",id:"x_google_ignorelist",level:2}],c={toc:s},u="wrapper";function f(e){var n=e.components,a=(0,o.Z)(e,r);return(0,i.mdx)(u,(0,t.Z)({},c,a,{components:n,mdxType:"MDXLayout"}),(0,i.mdx)("p",null,"Metro produces standard ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html"},"source maps")," along with its JavaScript bundle output. In addition to the standard information, Metro encodes extra information in ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm"},"vendor-specific fields")," within the source map. This page serves as a specification for this encoding."),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"The content on this page assumes familiarity with the ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html"},"source map specification"),". Check out ",(0,i.mdx)("a",{parentName:"p",href:"https://www.bugsnag.com/blog/source-maps"},"Anatomy of source maps")," for a general introduction to source maps and how they work.")),(0,i.mdx)("h2",{id:"x_facebook_sources"},(0,i.mdx)("inlineCode",{parentName:"h2"},"x_facebook_sources")),(0,i.mdx)("p",null,"The ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field encodes metadata about source files in a source map. Each piece of metadata represents some attribute intrinsic to the source code of that particular file - for example, the result of running some analysis over the AST. This allows tools such as debuggers and JS engines to access such analyses efficiently, without needing to parse or even have access to the source code."),(0,i.mdx)("p",null,"In the same way that the standard ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm:~:text=sourceRoot%22%3A%20%22%22%2C-,%22sources%22%3A,-%5B%22foo.js%22%2C%20%22bar"},(0,i.mdx)("inlineCode",{parentName:"a"},"sources"))," field is a list of source URLs and ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.ghqpj1ytqjbm:~:text=js%22%2C%20%22bar.js%22%5D%2C-,%22sourcesContent%22%3A,-%5Bnull%2C%20null%5D%2C"},(0,i.mdx)("inlineCode",{parentName:"a"},"sourcesContent"))," is a list of (optional) source code strings, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," is a list of optional ",(0,i.mdx)("strong",{parentName:"p"},"metadata tuples"),". The ",(0,i.mdx)("em",{parentName:"p"},"i"),"-th metadata tuple (",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources[i]"),") corresponds to the source file whose URL is ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources[i]"),"."),(0,i.mdx)("p",null,"In nested (indexed) source maps, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," may appear as part of any nested source map in ",(0,i.mdx)("a",{parentName:"p",href:"https://sourcemaps.info/spec.html#h.535es3xeprgt"},(0,i.mdx)("inlineCode",{parentName:"a"},"sections"))," that itself has a ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," field."),(0,i.mdx)("p",null,"If present, ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," may be a different length than ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," (but usually shouldn't be). In particular, if it's shorter than ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),", ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," interpreted as if it were padded with ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," values to match the length of ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),"."),(0,i.mdx)("admonition",{type:"info"},(0,i.mdx)("p",{parentName:"admonition"},"If you are writing a tool that processes source maps generated by Metro, and want to generate a new source map containing a valid ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field, you'll mainly need to ensure that ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources[i]")," still corresponds to ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources[i]")," in the output - even if your tool reorders, adds or deletes elements in ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources"),". Notably, this can be done ",(0,i.mdx)("em",{parentName:"p"},"without")," parsing/decoding the metadata tuples: unless your tool actively needs to access the information within them, you can treat them as opaque blobs of JSON."),(0,i.mdx)("p",{parentName:"admonition"},"If a tool cannot guarantee that the ",(0,i.mdx)("inlineCode",{parentName:"p"},"sources")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," arrays will stay in sync, it should delete the ",(0,i.mdx)("inlineCode",{parentName:"p"},"x_facebook_sources")," field from its output.")),(0,i.mdx)("h3",{id:"metadata-tuple"},"Metadata tuple"),(0,i.mdx)("p",null,"Each metadata tuple is encoded as an array of zero or more entries. Each entry may be ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," to signify that it's missing. A run of trailing ",(0,i.mdx)("inlineCode",{parentName:"p"},"null"),"s may be truncated from the end of the tuple with no change in meaning. The metadata tuple itself may also be ",(0,i.mdx)("inlineCode",{parentName:"p"},"null")," to signify that the source file has no associated metadata."),(0,i.mdx)("p",null,"The indices in each metadata tuple are assigned as follows:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Index 0: ",(0,i.mdx)("a",{parentName:"li",href:"#function-map"},"Function map")," or ",(0,i.mdx)("inlineCode",{parentName:"li"},"null"),".",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"In Metro, this is the result of calling ",(0,i.mdx)("a",{parentName:"li",href:"https://github.com/facebook/metro/blob/main/packages/metro-source-map/src/generateFunctionMap.js"},(0,i.mdx)("inlineCode",{parentName:"a"},"generateFunctionMap"))," on the source AST."))),(0,i.mdx)("li",{parentName:"ul"},"Index 1-\u221e: Reserved for future use.")),(0,i.mdx)("h4",{id:"function-map"},"Function map"),(0,i.mdx)("p",null,"A function map is encoded as an object with the following two fields:"),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"names"),": An array of strings."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"mappings"),": A string following the ",(0,i.mdx)("a",{parentName:"li",href:"#function-map-mappings-field-encoding"},"encoding")," described below.")),(0,i.mdx)("p",null,"When decoded, ",(0,i.mdx)("inlineCode",{parentName:"p"},"mappings")," represents a list of 3-tuples of integers: ",(0,i.mdx)("inlineCode",{parentName:"p"},"(column, nameIndex, line), (column, nameIndex, line), ..."),". The list is ordered by ",(0,i.mdx)("inlineCode",{parentName:"p"},"line")," and then ",(0,i.mdx)("inlineCode",{parentName:"p"},"column"),"."),(0,i.mdx)("p",null,"The presence of a 3-tuple ",(0,i.mdx)("inlineCode",{parentName:"p"},"(column, nameIndex, line)")," means that the ",(0,i.mdx)("em",{parentName:"p"},"local function name")," in the code region beginning at ",(0,i.mdx)("inlineCode",{parentName:"p"},"line")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"column")," (in the source file described by the current metadata tuple) is ",(0,i.mdx)("inlineCode",{parentName:"p"},"names[nameIndex]"),"."),(0,i.mdx)("h5",{id:"function-map-mappings-field-encoding"},"Function map ",(0,i.mdx)("inlineCode",{parentName:"h5"},"mappings")," field encoding"),(0,i.mdx)("p",null,"The value of the ",(0,i.mdx)("inlineCode",{parentName:"p"},"mappings")," field is described by the ",(0,i.mdx)("em",{parentName:"p"},"Mappings")," production of the grammar detailed below."),(0,i.mdx)("ol",null,(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},'Mappings = [ ";" ] LineMappings { ";" { ";" } LineMappings }')),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},'LineMappings = FirstColumnMapping "," ColumnMapping')),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"FirstColumnMapping = VLQ VLQ VLQ")),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"ColumnMapping = VLQ VLQ [ VLQ ]")),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("inlineCode",{parentName:"li"},"VLQ =")," ",(0,i.mdx)("em",{parentName:"li"},"A single Base64-encoded variable-length quantity, as defined in the ",(0,i.mdx)("a",{parentName:"em",href:"https://sourcemaps.info/spec.html#h.crcf4lqeivt8"},"source map specification")),".")),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"The above grammar uses the following BNF-like notation:"),(0,i.mdx)("table",{parentName:"admonition"},(0,i.mdx)("thead",{parentName:"table"},(0,i.mdx)("tr",{parentName:"thead"},(0,i.mdx)("th",{parentName:"tr",align:null},"Notation"),(0,i.mdx)("th",{parentName:"tr",align:null},"Meaning"))),(0,i.mdx)("tbody",{parentName:"table"},(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},"[ X ]")),(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("em",{parentName:"td"},"X")," appears zero or 1 times.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},"{ X }")),(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("em",{parentName:"td"},"X")," appears 0 or more times.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("inlineCode",{parentName:"td"},'"foo"')),(0,i.mdx)("td",{parentName:"tr",align:null},"The literal characters ",(0,i.mdx)("inlineCode",{parentName:"td"},"foo"),"."))))),(0,i.mdx)("p",null,"The three VLQs in ",(0,i.mdx)("em",{parentName:"p"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"p"},"ColumnMapping")," represent, in this order:"),(0,i.mdx)("ol",null,(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Column delta"),":",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"In ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping"),": The column offset from the beginning of the line. (0 = first column)"),(0,i.mdx)("li",{parentName:"ul"},"In ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),": The column offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),"."))),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Name delta"),": The name index offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),". This is ",(0,i.mdx)("em",{parentName:"li"},"not")," reset between lines."),(0,i.mdx)("li",{parentName:"ol"},(0,i.mdx)("strong",{parentName:"li"},"Line delta"),": The line offset from the last-encountered ",(0,i.mdx)("em",{parentName:"li"},"FirstColumnMapping")," or ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),". This is ",(0,i.mdx)("em",{parentName:"li"},"not")," reset between lines.",(0,i.mdx)("ul",{parentName:"li"},(0,i.mdx)("li",{parentName:"ul"},"This MUST be 0 (Base64 VLQ: ",(0,i.mdx)("inlineCode",{parentName:"li"},"A"),") if it is part of a ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),"."),(0,i.mdx)("li",{parentName:"ul"},"Implementations SHOULD omit this field from the encoded form of ",(0,i.mdx)("em",{parentName:"li"},"ColumnMapping"),".")))),(0,i.mdx)("h3",{id:"example"},"Example"),(0,i.mdx)("p",null,"Given a single source file called ",(0,i.mdx)("inlineCode",{parentName:"p"},"file.js"),", a complete source map might look like this:"),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"Comments are for illustrative purposes - the source map format does not allow comments.")),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "version": 3,\n "sources": ["file.js"],\n "sourcesContent": ["function a(){} function b(){}"],\n "mappings": "AAAA", // NOTE: Simplified\n "x_facebook_sources": [\n // Metadata tuple for source #0 (file.js)\n [\n // Metadata item #0.0 = function map for source #0 (file.js)\n {\n // a from 1:0\n // from 1:14\n // b from 1:15\n // (See detailed decoding procedure below.)\n "mappings": "AAA,cC,CC",\n "names": [\n "a",\n "",\n "b",\n ]\n }\n ]\n ]\n}\n')),(0,i.mdx)("p",null,"The decoding procedure for the function map in the above example is illustrated by the following code:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"const decoded = [];\nconst names = ['a', '', 'b']; // From the function map\n\nlet column = 0, nameIndex = 0, line = 1;\ncolumn += 0 /* A */; nameIndex += 0 /* A */; line += 0 /* A */;\ndecoded.push({column, name: names[nameIndex] /* 'a' */, line});\n\ncolumn += 14 /* c */; nameIndex += 1 /* C */; // no line delta\ndecoded.push({column, name: names[nameIndex] /* '' */, line});\n\ncolumn += 1 /* C */; nameIndex += 1 /* C */; // no line delta\ndecoded.push({column, name: names[nameIndex] /* 'b' */, line});\n\n/*\n decoded = [\n {column: 0, name: 'a', line: 1},\n {column: 14, name: '', line: 1},\n {column: 15, name: 'b', line: 1},\n ]\n*/\n")),(0,i.mdx)("h2",{id:"x_google_ignorelist"},(0,i.mdx)("inlineCode",{parentName:"h2"},"x_google_ignoreList")),(0,i.mdx)("p",null,"Metro's source maps include the ",(0,i.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/articles/x-google-ignore-list/"},(0,i.mdx)("inlineCode",{parentName:"a"},"x_google_ignoreList"))," field by default. The ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration#isthirdpartymodule"},(0,i.mdx)("inlineCode",{parentName:"a"},"serializer.isThirdPartyModule"))," option can be used to control which modules are ignore-listed."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6681bed1.544d4ac6.js b/assets/js/6681bed1.29b5b3da.js similarity index 99% rename from assets/js/6681bed1.544d4ac6.js rename to assets/js/6681bed1.29b5b3da.js index 4c802e2135..73820f6de6 100644 --- a/assets/js/6681bed1.544d4ac6.js +++ b/assets/js/6681bed1.29b5b3da.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[76],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>i,MDXProvider:()=>s,mdx:()=>g,useMDXComponents:()=>u,withMDXComponents:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(){return l=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){return function(t){var n=u(t.components);return r.createElement(e,l({},t,{components:n}))}},u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):m(m({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},x="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},N=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),p=u(n),s=a,x=p["".concat(d,".").concat(s)]||p[s]||c[s]||l;return n?r.createElement(x,m(m({ref:t},i),{},{components:n})):r.createElement(x,m({ref:t},i))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,d=new Array(l);d[0]=N;var m={};for(var o in t)hasOwnProperty.call(t,o)&&(m[o]=t[o]);m.originalType=e,m[x]="string"==typeof e?e:a,d[1]=m;for(var i=2;i{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>m,metadata:()=>i,toc:()=>u});var r=n(83117),a=n(80102),l=(n(67294),n(3905)),d=["components"],m={id:"cli",title:"Metro CLI Options"},o=void 0,i={unversionedId:"cli",id:"cli",title:"Metro CLI Options",description:"The metro command line runner has a number of useful options. You can run `metro",source:"@site/../docs/CLI.md",sourceDirName:".",slug:"/cli",permalink:"/docs/cli",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/CLI.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"cli",title:"Metro CLI Options"},sidebar:"docs",previous:{title:"Configuring Metro",permalink:"/docs/configuration"},next:{title:"Package Exports Support (Experimental)",permalink:"/docs/package-exports"}},p={},u=[{value:"build <entry>",id:"build-entry",level:2},{value:"Options",id:"options",level:3},{value:"serve",id:"serve",level:2},{value:"get-dependencies <entryFile>",id:"get-dependencies-entryfile",level:2},{value:"Options",id:"options-1",level:3}],s={toc:u},x="wrapper";function c(e){var t=e.components,n=(0,a.Z)(e,d);return(0,l.mdx)(x,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,l.mdx)("p",null,"The ",(0,l.mdx)("inlineCode",{parentName:"p"},"metro")," command line runner has a number of useful options. You can run ",(0,l.mdx)("inlineCode",{parentName:"p"},"metro\n--help")," to view all available options. Here is a brief overview:"),(0,l.mdx)("h2",{id:"build-entry"},(0,l.mdx)("inlineCode",{parentName:"h2"},"build ")),(0,l.mdx)("p",null,"Generates a JavaScript bundle containing the specified entrypoint and its descendants."),(0,l.mdx)("h3",{id:"options"},"Options"),(0,l.mdx)("table",null,(0,l.mdx)("thead",{parentName:"table"},(0,l.mdx)("tr",{parentName:"thead"},(0,l.mdx)("th",{parentName:"tr",align:null},"Option"),(0,l.mdx)("th",{parentName:"tr",align:null},"Alias"),(0,l.mdx)("th",{parentName:"tr",align:null},"Description"),(0,l.mdx)("th",{parentName:"tr",align:null},"Value"))),(0,l.mdx)("tbody",{parentName:"table"},(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"out")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"O")),(0,l.mdx)("td",{parentName:"tr",align:null},"File name where to store the output"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"platform")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"p")),(0,l.mdx)("td",{parentName:"tr",align:null},"Which platform to bundle for"),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"web"),", ",(0,l.mdx)("inlineCode",{parentName:"td"},"android"),", ",(0,l.mdx)("inlineCode",{parentName:"td"},"ios"))),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"minify")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"z")),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should minify the bundle"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"dev")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"g")),(0,l.mdx)("td",{parentName:"tr",align:null},"Create a development version of the build (",(0,l.mdx)("inlineCode",{parentName:"td"},"process.env.NODE_ENV = 'development'"),")"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"config")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"c")),(0,l.mdx)("td",{parentName:"tr",align:null},"Location of the ",(0,l.mdx)("inlineCode",{parentName:"td"},"metro.config.js")," to use"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"max-workers")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"j")),(0,l.mdx)("td",{parentName:"tr",align:null},"The number of workers Metro should parallelize the transformer on"),(0,l.mdx)("td",{parentName:"tr",align:null},"Number")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"project-roots")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"P")),(0,l.mdx)("td",{parentName:"tr",align:null},"The root folder of your project"),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"source-map")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should generate source maps"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"source-map-url")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"URL where the source map can be found"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"legacy-bundler")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should use the legacy bundler"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"resolver-option")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("a",{parentName:"td",href:"/docs/resolution#customresolveroptions-string-mixed"},"Custom resolver options")," of the form ",(0,l.mdx)("inlineCode",{parentName:"td"},"key=value")),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"transform-option")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Custom transform options of the form ",(0,l.mdx)("inlineCode",{parentName:"td"},"key=value")),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")))),(0,l.mdx)("h2",{id:"serve"},(0,l.mdx)("inlineCode",{parentName:"h2"},"serve")),(0,l.mdx)("p",null,"Starts Metro on the given port, building bundles on the fly."),(0,l.mdx)("h2",{id:"get-dependencies-entryfile"},(0,l.mdx)("inlineCode",{parentName:"h2"},"get-dependencies ")),(0,l.mdx)("p",null,"List all dependencies that will be bundled for a given entry point."),(0,l.mdx)("h3",{id:"options-1"},"Options"),(0,l.mdx)("table",null,(0,l.mdx)("thead",{parentName:"table"},(0,l.mdx)("tr",{parentName:"thead"},(0,l.mdx)("th",{parentName:"tr",align:null},"Option"),(0,l.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,l.mdx)("tbody",{parentName:"table"},(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"entry-file")),(0,l.mdx)("td",{parentName:"tr",align:null},"Absolute path to the root JS file. This can also be given as the first positional arg.")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"output")),(0,l.mdx)("td",{parentName:"tr",align:null},"File name where to store the output, ex. /tmp/dependencies.txt")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"platform")),(0,l.mdx)("td",{parentName:"tr",align:null},"The platform extension used for selecting modules")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"transformer")),(0,l.mdx)("td",{parentName:"tr",align:null},"Specify a custom transformer to be used")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"max-workers")),(0,l.mdx)("td",{parentName:"tr",align:null},"Specifies the maximum number of workers the worker-pool will spawn for transforming files. This defaults to the number of the cores available on your machine.")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"dev")),(0,l.mdx)("td",{parentName:"tr",align:null},"If false, skip all dev-only code path")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"verbose")),(0,l.mdx)("td",{parentName:"tr",align:null},"Enables logging")))))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[76],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>i,MDXProvider:()=>s,mdx:()=>g,useMDXComponents:()=>u,withMDXComponents:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(){return l=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),p=function(e){return function(t){var n=u(t.components);return r.createElement(e,l({},t,{components:n}))}},u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):m(m({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},x="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},N=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,d=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),p=u(n),s=a,x=p["".concat(d,".").concat(s)]||p[s]||c[s]||l;return n?r.createElement(x,m(m({ref:t},i),{},{components:n})):r.createElement(x,m({ref:t},i))}));function g(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,d=new Array(l);d[0]=N;var m={};for(var o in t)hasOwnProperty.call(t,o)&&(m[o]=t[o]);m.originalType=e,m[x]="string"==typeof e?e:a,d[1]=m;for(var i=2;i{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>c,frontMatter:()=>m,metadata:()=>i,toc:()=>u});var r=n(83117),a=n(80102),l=(n(67294),n(3905)),d=["components"],m={id:"cli",title:"Metro CLI Options"},o=void 0,i={unversionedId:"cli",id:"cli",title:"Metro CLI Options",description:"The metro command line runner has a number of useful options. You can run `metro",source:"@site/../docs/CLI.md",sourceDirName:".",slug:"/cli",permalink:"/docs/cli",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/CLI.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"cli",title:"Metro CLI Options"},sidebar:"docs",previous:{title:"Configuring Metro",permalink:"/docs/configuration"},next:{title:"Package Exports Support (Experimental)",permalink:"/docs/package-exports"}},p={},u=[{value:"build <entry>",id:"build-entry",level:2},{value:"Options",id:"options",level:3},{value:"serve",id:"serve",level:2},{value:"get-dependencies <entryFile>",id:"get-dependencies-entryfile",level:2},{value:"Options",id:"options-1",level:3}],s={toc:u},x="wrapper";function c(e){var t=e.components,n=(0,a.Z)(e,d);return(0,l.mdx)(x,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,l.mdx)("p",null,"The ",(0,l.mdx)("inlineCode",{parentName:"p"},"metro")," command line runner has a number of useful options. You can run ",(0,l.mdx)("inlineCode",{parentName:"p"},"metro\n--help")," to view all available options. Here is a brief overview:"),(0,l.mdx)("h2",{id:"build-entry"},(0,l.mdx)("inlineCode",{parentName:"h2"},"build ")),(0,l.mdx)("p",null,"Generates a JavaScript bundle containing the specified entrypoint and its descendants."),(0,l.mdx)("h3",{id:"options"},"Options"),(0,l.mdx)("table",null,(0,l.mdx)("thead",{parentName:"table"},(0,l.mdx)("tr",{parentName:"thead"},(0,l.mdx)("th",{parentName:"tr",align:null},"Option"),(0,l.mdx)("th",{parentName:"tr",align:null},"Alias"),(0,l.mdx)("th",{parentName:"tr",align:null},"Description"),(0,l.mdx)("th",{parentName:"tr",align:null},"Value"))),(0,l.mdx)("tbody",{parentName:"table"},(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"out")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"O")),(0,l.mdx)("td",{parentName:"tr",align:null},"File name where to store the output"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"platform")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"p")),(0,l.mdx)("td",{parentName:"tr",align:null},"Which platform to bundle for"),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"web"),", ",(0,l.mdx)("inlineCode",{parentName:"td"},"android"),", ",(0,l.mdx)("inlineCode",{parentName:"td"},"ios"))),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"minify")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"z")),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should minify the bundle"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"dev")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"g")),(0,l.mdx)("td",{parentName:"tr",align:null},"Create a development version of the build (",(0,l.mdx)("inlineCode",{parentName:"td"},"process.env.NODE_ENV = 'development'"),")"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"config")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"c")),(0,l.mdx)("td",{parentName:"tr",align:null},"Location of the ",(0,l.mdx)("inlineCode",{parentName:"td"},"metro.config.js")," to use"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"max-workers")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"j")),(0,l.mdx)("td",{parentName:"tr",align:null},"The number of workers Metro should parallelize the transformer on"),(0,l.mdx)("td",{parentName:"tr",align:null},"Number")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"project-roots")),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"P")),(0,l.mdx)("td",{parentName:"tr",align:null},"The root folder of your project"),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"source-map")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should generate source maps"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"source-map-url")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"URL where the source map can be found"),(0,l.mdx)("td",{parentName:"tr",align:null},"String")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"legacy-bundler")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Whether Metro should use the legacy bundler"),(0,l.mdx)("td",{parentName:"tr",align:null},"Boolean")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"resolver-option")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("a",{parentName:"td",href:"/docs/resolution#customresolveroptions-string-mixed"},"Custom resolver options")," of the form ",(0,l.mdx)("inlineCode",{parentName:"td"},"key=value")),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"transform-option")),(0,l.mdx)("td",{parentName:"tr",align:null}),(0,l.mdx)("td",{parentName:"tr",align:null},"Custom transform options of the form ",(0,l.mdx)("inlineCode",{parentName:"td"},"key=value")),(0,l.mdx)("td",{parentName:"tr",align:null},"Array")))),(0,l.mdx)("h2",{id:"serve"},(0,l.mdx)("inlineCode",{parentName:"h2"},"serve")),(0,l.mdx)("p",null,"Starts Metro on the given port, building bundles on the fly."),(0,l.mdx)("h2",{id:"get-dependencies-entryfile"},(0,l.mdx)("inlineCode",{parentName:"h2"},"get-dependencies ")),(0,l.mdx)("p",null,"List all dependencies that will be bundled for a given entry point."),(0,l.mdx)("h3",{id:"options-1"},"Options"),(0,l.mdx)("table",null,(0,l.mdx)("thead",{parentName:"table"},(0,l.mdx)("tr",{parentName:"thead"},(0,l.mdx)("th",{parentName:"tr",align:null},"Option"),(0,l.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,l.mdx)("tbody",{parentName:"table"},(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"entry-file")),(0,l.mdx)("td",{parentName:"tr",align:null},"Absolute path to the root JS file. This can also be given as the first positional arg.")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"output")),(0,l.mdx)("td",{parentName:"tr",align:null},"File name where to store the output, ex. /tmp/dependencies.txt")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"platform")),(0,l.mdx)("td",{parentName:"tr",align:null},"The platform extension used for selecting modules")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"transformer")),(0,l.mdx)("td",{parentName:"tr",align:null},"Specify a custom transformer to be used")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"max-workers")),(0,l.mdx)("td",{parentName:"tr",align:null},"Specifies the maximum number of workers the worker-pool will spawn for transforming files. This defaults to the number of the cores available on your machine.")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"dev")),(0,l.mdx)("td",{parentName:"tr",align:null},"If false, skip all dev-only code path")),(0,l.mdx)("tr",{parentName:"tbody"},(0,l.mdx)("td",{parentName:"tr",align:null},(0,l.mdx)("inlineCode",{parentName:"td"},"verbose")),(0,l.mdx)("td",{parentName:"tr",align:null},"Enables logging")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/812be9b9.e9cfac08.js b/assets/js/812be9b9.6105f00a.js similarity index 99% rename from assets/js/812be9b9.e9cfac08.js rename to assets/js/812be9b9.6105f00a.js index 6bb8bd7465..c5cc10445b 100644 --- a/assets/js/812be9b9.e9cfac08.js +++ b/assets/js/812be9b9.6105f00a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[599],{3905:(e,a,t)=>{t.r(a),t.d(a,{MDXContext:()=>d,MDXProvider:()=>x,mdx:()=>f,useMDXComponents:()=>p,withMDXComponents:()=>s});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(){return o=Object.assign||function(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var d=n.createContext({}),s=function(e){return function(a){var t=p(a.components);return n.createElement(e,o({},a,{components:t}))}},p=function(e){var a=n.useContext(d),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},x=function(e){var a=p(e.components);return n.createElement(d.Provider,{value:a},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},h=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=m(e,["components","mdxType","originalType","parentName"]),s=p(t),x=r,u=s["".concat(l,".").concat(x)]||s[x]||c[x]||o;return t?n.createElement(u,i(i({ref:a},d),{},{components:t})):n.createElement(u,i({ref:a},d))}));function f(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,l=new Array(o);l[0]=h;var i={};for(var m in a)hasOwnProperty.call(a,m)&&(i[m]=a[m]);i.originalType=e,i[u]="string"==typeof e?e:r,l[1]=i;for(var d=2;d{t.r(a),t.d(a,{assets:()=>s,contentTitle:()=>m,default:()=>c,frontMatter:()=>i,metadata:()=>d,toc:()=>p});var n=t(83117),r=t(80102),o=(t(67294),t(3905)),l=["components"],i={id:"resolution",title:"Module Resolution"},m=void 0,d={unversionedId:"resolution",id:"resolution",title:"Module Resolution",description:"Module resolution is the process of translating module names to module paths at build time. For example, if your project contains the code:",source:"@site/../docs/Resolution.md",sourceDirName:".",slug:"/resolution",permalink:"/docs/resolution",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Resolution.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"resolution",title:"Module Resolution"},sidebar:"docs",previous:{title:"Caching",permalink:"/docs/caching"},next:{title:"Source Map Format",permalink:"/docs/source-map-format"}},s={},p=[{value:"Resolution algorithm",id:"resolution-algorithm",level:2},{value:"Resolution types",id:"resolution-types",level:3},{value:"Source file",id:"source-file",level:4},{value:"Asset files",id:"asset-files",level:4},{value:"Empty module",id:"empty-module",level:4},{value:"Algorithm",id:"algorithm",level:3},{value:"RESOLVE",id:"resolve",level:4},{value:"RESOLVE_MODULE",id:"resolve_module",level:4},{value:"RESOLVE_PACKAGE",id:"resolve_package",level:4},{value:"RESOLVE_PACKAGE_EXPORTS",id:"resolve_package_exports",level:4},{value:"RESOLVE_FILE",id:"resolve_file",level:4},{value:"RESOLVE_ASSET",id:"resolve_asset",level:4},{value:"RESOLVE_HASTE",id:"resolve_haste",level:4},{value:"Resolution context",id:"resolution-context",level:3},{value:"assetExts: $ReadOnlySet<string>",id:"assetexts-readonlysetstring",level:4},{value:"doesFileExist: string => boolean",id:"doesfileexist-string--boolean",level:4},{value:"nodeModulesPaths: $ReadOnlyArray<string>",id:"nodemodulespaths-readonlyarraystring",level:4},{value:"preferNativePlatform: boolean",id:"prefernativeplatform-boolean",level:4},{value:"redirectModulePath: string => string | false",id:"redirectmodulepath-string--string--false",level:4},{value:"resolveAsset: (dirPath: string, assetName: string, extension: string) => ?$ReadOnlyArray<string>",id:"resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring",level:4},{value:"sourceExts: $ReadOnlyArray<string>",id:"sourceexts-readonlyarraystring",level:4},{value:"mainFields: $ReadOnlyArray<string>",id:"mainfields-readonlyarraystring",level:4},{value:"getPackage: string => PackageJson",id:"getpackage-string--packagejson",level:4},{value:'getPackageForModule: (modulePath: string) => ?PackageInfo
Deprecated
',id:"getpackageformodule-modulepath-string--packageinfo-deprecated",level:4},{value:"resolveHasteModule: string => ?string",id:"resolvehastemodule-string--string",level:4},{value:"resolveHastePackage: string => ?string",id:"resolvehastepackage-string--string",level:4},{value:"allowHaste: boolean",id:"allowhaste-boolean",level:4},{value:"disableHierarchicalLookup: boolean",id:"disablehierarchicallookup-boolean",level:4},{value:"extraNodeModules: ?{[string]: string}",id:"extranodemodules-string-string",level:4},{value:"originModulePath: string",id:"originmodulepath-string",level:4},{value:"customResolverOptions: {[string]: mixed}",id:"customresolveroptions-string-mixed",level:4},{value:"resolveRequest: CustomResolver",id:"resolverequest-customresolver",level:4},{value:"dependency: ?Dependency",id:"dependency-dependency",level:4},{value:"Caching",id:"caching",level:2}],x={toc:p},u="wrapper";function c(e){var a=e.components,t=(0,r.Z)(e,l);return(0,o.mdx)(u,(0,n.Z)({},x,t,{components:a,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Module resolution is the process of translating module names to module paths at build time. For example, if your project contains the code:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// src/App.js\nimport {View} from 'react-native';\n// ...\n")),(0,o.mdx)("p",null,"Metro needs to know where in your project to load the ",(0,o.mdx)("inlineCode",{parentName:"p"},"react-native")," module from. This will typically resolve to something like ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules/react-native/index.js"),"."),(0,o.mdx)("p",null,"Likewise, if your project contains the (similar) code:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// src/App.js\nimport Comp from './Component';\n// ...\n")),(0,o.mdx)("p",null,"Metro needs to understand that you are referring to, say, ",(0,o.mdx)("inlineCode",{parentName:"p"},"src/Component.js"),", and not another file named ",(0,o.mdx)("inlineCode",{parentName:"p"},"Component")," that may also exist elsewhere."),(0,o.mdx)("p",null,"Metro implements a version of ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#loading-from-node_modules-folders"},"Node's module resolution algorithm"),", augmented with additional Metro-specific features."),(0,o.mdx)("p",null,"These Metro-specific features include:"),(0,o.mdx)("ul",null,(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Haste"),": An opt-in mechanism for importing modules by their globally-unique name anywhere in the project, e.g. ",(0,o.mdx)("inlineCode",{parentName:"li"},"import Foo from 'Foo'"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Platform extensions"),": Used by ",(0,o.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions"},"React Native")," to allow developers to write platform-specific versions of their JavaScript modules."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Asset extensions and image resolutions"),": Used by ",(0,o.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/images#static-image-resources"},"React Native")," to automatically select the best version of an image asset based on the device's screen density at runtime."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Custom resolvers"),": Metro integrators can provide their own resolver implementations to override almost everything about how modules are resolved.")),(0,o.mdx)("h2",{id:"resolution-algorithm"},"Resolution algorithm"),(0,o.mdx)("p",null,"Given a ",(0,o.mdx)("a",{parentName:"p",href:"#resolution-context"},"resolution context")," ",(0,o.mdx)("em",{parentName:"p"},"context"),", a module name ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", and an optional platform identifier ",(0,o.mdx)("em",{parentName:"p"},"platform"),", Metro's resolver performs ",(0,o.mdx)("a",{parentName:"p",href:"#resolve"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE")),"(",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),"), which either returns one of the ",(0,o.mdx)("a",{parentName:"p",href:"#resolution-types"},"resolution types"),", or throws an error."),(0,o.mdx)("h3",{id:"resolution-types"},"Resolution types"),(0,o.mdx)("h4",{id:"source-file"},"Source file"),(0,o.mdx)("p",null,"The request is resolved to some absolute path representing a physical file on disk."),(0,o.mdx)("h4",{id:"asset-files"},"Asset files"),(0,o.mdx)("p",null,"The request is resolved to one or more absolute paths representing physical files on disk."),(0,o.mdx)("h4",{id:"empty-module"},"Empty module"),(0,o.mdx)("p",null,"The request is resolved to a built-in empty module, namely the one specified in ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#emptymodulepath"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.emptyModulePath")),"."),(0,o.mdx)("h3",{id:"algorithm"},"Algorithm"),(0,o.mdx)("admonition",{type:"note"},(0,o.mdx)("p",{parentName:"admonition"},"These are the rules that Metro's default resolver follows. Refer to ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-resolver/src/resolve.js"},(0,o.mdx)("inlineCode",{parentName:"a"},"metro-resolver"),"'s source code")," for more details.")),(0,o.mdx)("h4",{id:"resolve"},"RESOLVE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If a ",(0,o.mdx)("a",{parentName:"li",href:"#resolverequest-customresolver"},"custom resolver")," is defined, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of the custom resolver."))),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, attempt to resolve ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a path",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"absoluteModuleName")," be the result of prepending the current directory (i.e. parent of ",(0,o.mdx)("a",{parentName:"li",href:"#originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.originModulePath")),") with ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_module"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_MODULE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"absoluteModuleName"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."))),(0,o.mdx)("li",{parentName:"ol"},"Apply ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections")," to ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),". If this results in an ",(0,o.mdx)("a",{parentName:"li",href:"#empty-module"},"empty module"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the empty module."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#allowhaste-boolean"},"Haste resolutions are allowed"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Get the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_haste"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_HASTE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."),(0,o.mdx)("li",{parentName:"ol"},"If resolved as a Haste package path, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Perform the algorithm for resolving a path (step 2 above). Throw an error if this resolution fails.\nFor example, if the Haste package path for ",(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b'")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"foo/package.json"),", perform step 2 as if ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," was ",(0,o.mdx)("inlineCode",{parentName:"li"},"foo/c"),"."))))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#disableHierarchicalLookup-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.disableHierarchicalLookup"))," is not ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," under ",(0,o.mdx)("inlineCode",{parentName:"li"},"node_modules")," from the current directory (i.e. parent of ",(0,o.mdx)("a",{parentName:"li",href:"#originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.originModulePath")),") up to the root directory."),(0,o.mdx)("li",{parentName:"ol"},"Perform ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),") for each candidate path."))),(0,o.mdx)("li",{parentName:"ol"},"For each element ",(0,o.mdx)("em",{parentName:"li"},"nodeModulesPath")," of ",(0,o.mdx)("a",{parentName:"li",href:"#nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.nodeModulesPaths")),":",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," under ",(0,o.mdx)("em",{parentName:"li"},"nodeModulesPath")," as if the latter was another ",(0,o.mdx)("inlineCode",{parentName:"li"},"node_modules")," directory (similar to step 5 above)."),(0,o.mdx)("li",{parentName:"ol"},"Perform ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),") for each candidate path."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules"))," is set:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Split ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," into a package name (including an optional ",(0,o.mdx)("a",{parentName:"li",href:"https://docs.npmjs.com/cli/v8/using-npm/scope"},"scope"),") and relative path."),(0,o.mdx)("li",{parentName:"ol"},"Look up the package name in ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules")),". If found, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Construct a path ",(0,o.mdx)("em",{parentName:"li"},"modulePath")," by replacing the package name part of ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," with the value found in ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules"))),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))))),(0,o.mdx)("li",{parentName:"ol"},"If no valid resolution has been found, throw a resolution failure error.")),(0,o.mdx)("h4",{id:"resolve_module"},"RESOLVE_MODULE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"filePath")," be the result of applying ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections")," to ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),". This may locate a replacement subpath from a containing ",(0,o.mdx)("inlineCode",{parentName:"li"},"package.json")," file based on the ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, let ",(0,o.mdx)("em",{parentName:"li"},"dirPath")," be the directory path of ",(0,o.mdx)("em",{parentName:"li"},"filePath"),"."),(0,o.mdx)("li",{parentName:"ol"},"If a file ",(0,o.mdx)("em",{parentName:"li"},"dirPath")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'package.json'")," exists, resolve based on the ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),":",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath")," be the result of reading the package's entry path using ",(0,o.mdx)("a",{parentName:"li",href:"#mainfields-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.mainFields")),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'/index'"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."),(0,o.mdx)("li",{parentName:"ol"},"Throw an error if no resolution could be found.")))),(0,o.mdx)("h4",{id:"resolve_package"},"RESOLVE_PACKAGE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.enablePackageExports")," is enabled, and a containing ",(0,o.mdx)("inlineCode",{parentName:"li"},"package.json")," file contains the field ",(0,o.mdx)("inlineCode",{parentName:"li"},'"exports"'),", get result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package-exports"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE_EXPORTS")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"packagePath"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),").",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"If resolved path exists, return result."),(0,o.mdx)("li",{parentName:"ol"},"Else, log either a package configuration or package encapsulation warning."))),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_module"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_MODULE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),").")),(0,o.mdx)("h4",{id:"resolve_package_exports"},"RESOLVE_PACKAGE_EXPORTS"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"packagePath"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"exportsField"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("blockquote",null,(0,o.mdx)("p",{parentName:"blockquote"},"Resolves a package subpath based on the ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"Package Entry Points spec")," (the ",(0,o.mdx)("inlineCode",{parentName:"p"},'"exports"')," field), when ",(0,o.mdx)("a",{parentName:"p",href:"./configuration#unstable_enablepackageexports-experimental"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports"))," is enabled.")),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"subpath")," be the relative path from ",(0,o.mdx)("em",{parentName:"li"},"packagePath")," to ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", or ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.'"),"."),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"exportsField")," contains an invalid configuration or values, raise an ",(0,o.mdx)("inlineCode",{parentName:"li"},"InvalidPackageConfigurationError"),"."),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"subpath")," is not defined by ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),", raise a ",(0,o.mdx)("inlineCode",{parentName:"li"},"PackagePathNotExportedError"),"."),(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"target")," be the result of matching ",(0,o.mdx)("em",{parentName:"li"},"subpath")," in ",(0,o.mdx)("em",{parentName:"li"},"exportsField")," after applying any ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#conditional-exports"},"conditional exports")," and/or substituting a ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath pattern match"),".",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Condition names will be asserted from the union of ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.unstable_conditionNames")," and ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.unstable_conditionNamesByPlatform")," for ",(0,o.mdx)("em",{parentName:"li"},"platform"),", in the order defined by ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),"."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"target")," refers to an ",(0,o.mdx)("a",{parentName:"li",href:"#assetexts-readonlysetstring"},"asset"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_asset"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_ASSET")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"target"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))),(0,o.mdx)("li",{parentName:"ol"},"Return ",(0,o.mdx)("em",{parentName:"li"},"target")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," ",(0,o.mdx)("strong",{parentName:"li"},"without")," applying redirections or trying any platform or extension variants.")),(0,o.mdx)("h4",{id:"resolve_file"},"RESOLVE_FILE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If the path refers to an ",(0,o.mdx)("a",{parentName:"li",href:"#assetexts-readonlysetstring"},"asset"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_asset"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_ASSET")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, if the path ",(0,o.mdx)("a",{parentName:"li",href:"#doesfileexist-string--boolean"},"exists"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try all platform and extension variants in sequence. Return a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," for the first one that ",(0,o.mdx)("a",{parentName:"li",href:"#doesfileexist-string--boolean"},"exists")," after applying ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections"),". For example, if ",(0,o.mdx)("em",{parentName:"li"},"platform")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"android")," and ",(0,o.mdx)("a",{parentName:"li",href:"#sourceexts-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.sourceExts"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"['js', 'jsx']"),", try this sequence of potential file names:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.android.js'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.native.js'")," (if ",(0,o.mdx)("a",{parentName:"li",href:"#prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.preferNativePlatform"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),")"),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.js'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.android.jsx'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.native.jsx'")," (if ",(0,o.mdx)("a",{parentName:"li",href:"#prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.preferNativePlatform"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),")"),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.jsx'"))))))),(0,o.mdx)("h4",{id:"resolve_asset"},"RESOLVE_ASSET"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Use ",(0,o.mdx)("a",{parentName:"li",href:"#resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.resolveAsset"))," to collect all asset variants."),(0,o.mdx)("li",{parentName:"ol"},"Return an ",(0,o.mdx)("a",{parentName:"li",href:"#asset-files"},"asset resolution")," containing the collected asset paths.")),(0,o.mdx)("h4",{id:"resolve_haste"},"RESOLVE_HASTE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#resolvehastemodule-string--string"},"Haste module"),".\nIf found, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return result as a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," ",(0,o.mdx)("strong",{parentName:"li"},"without")," applying redirections or trying any platform or extension variants."))),(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#resolvehastepackage-string--string"},"Haste (global) package"),", or a path ",(0,o.mdx)("em",{parentName:"li"},"relative")," to a Haste package.\nFor example, if ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b/c'"),", try the following potential Haste package names:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b/c'"),", relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"''")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b'"),", relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"'./c'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a'"),", with relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"'./b/c'"))))),(0,o.mdx)("h3",{id:"resolution-context"},"Resolution context"),(0,o.mdx)("h4",{id:"assetexts-readonlysetstring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"assetExts: $ReadOnlySet")),(0,o.mdx)("p",null,"The set of file extensions used to identify asset files. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#assetexts"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.assetExts")),"."),(0,o.mdx)("h4",{id:"doesfileexist-string--boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"doesFileExist: string => boolean")),(0,o.mdx)("p",null,"Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"true")," if the file with the given path exists, or ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," otherwise."),(0,o.mdx)("p",null,"By default, Metro implements this by consulting an in-memory map of the filesystem that has been prepared in advance. This approach avoids disk I/O during module resolution."),(0,o.mdx)("h4",{id:"nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"nodeModulesPaths: $ReadOnlyArray")),(0,o.mdx)("p",null,"A list of paths to check for modules after looking through all ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories."),(0,o.mdx)("p",null,"By default this is set to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#nodemodulespaths"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.nodeModulesPaths"))),(0,o.mdx)("h4",{id:"prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"preferNativePlatform: boolean")),(0,o.mdx)("p",null,"If ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),", try ",(0,o.mdx)("inlineCode",{parentName:"p"},".native.${ext}")," before ",(0,o.mdx)("inlineCode",{parentName:"p"},".${ext}")," and after ",(0,o.mdx)("inlineCode",{parentName:"p"},".${platform}.${ext}")," during resolution. Metro sets this to ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,o.mdx)("h4",{id:"redirectmodulepath-string--string--false"},(0,o.mdx)("inlineCode",{parentName:"h4"},"redirectModulePath: string => string | false")),(0,o.mdx)("p",null,"Rewrites a module path, or returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," to redirect to the special ",(0,o.mdx)("a",{parentName:"p",href:"#empty-module"},"empty module"),". In the default resolver, the resolution algorithm terminates with an ",(0,o.mdx)("a",{parentName:"p",href:"#empty-module"},"empty module result")," if ",(0,o.mdx)("inlineCode",{parentName:"p"},"redirectModulePath")," returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,o.mdx)("p",null,"Metro uses this to implement the ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),", particularly the ability to ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#replace-specific-files---advanced"},"replace")," and ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module"},"ignore")," specific files."),(0,o.mdx)("p",null,"The default implementation of this function respects ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvermainfields"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolverMainFields")),"."),(0,o.mdx)("h4",{id:"resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveAsset: (dirPath: string, assetName: string, extension: string) => ?$ReadOnlyArray")),(0,o.mdx)("p",null,"Given a directory path, the base asset name and an extension, returns a list of all the asset file names that match the given base name in that directory, or ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such files are found. The default implementation considers each of ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#assetresolutions"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.assetResolutions"))," and uses the ",(0,o.mdx)("inlineCode",{parentName:"p"},"${assetName}@${resolution}${extension}")," format for asset variant file names."),(0,o.mdx)("p",null,"See also ",(0,o.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/images#static-image-resources"},"Static Image Resources")," in the React Native docs."),(0,o.mdx)("h4",{id:"sourceexts-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"sourceExts: $ReadOnlyArray")),(0,o.mdx)("p",null,"The list of file extensions to try, in order, when resolving a module path that does not exist on disk. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#sourceexts"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.sourceExts")),"."),(0,o.mdx)("h4",{id:"mainfields-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"mainFields: $ReadOnlyArray")),(0,o.mdx)("p",null,"The ordered list of fields in ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," that should be read to resolve a package's main entry point (and any subpath file replacements) per the ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},'"browser" field spec'),". Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvermainfields"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolverMainFields")),"."),(0,o.mdx)("h4",{id:"getpackage-string--packagejson"},(0,o.mdx)("inlineCode",{parentName:"h4"},"getPackage: string => PackageJson")),(0,o.mdx)("p",null,"Given the path to a ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," file, returns the parsed file contents."),(0,o.mdx)("h4",{id:"getpackageformodule-modulepath-string--packageinfo-deprecated"},(0,o.mdx)("inlineCode",{parentName:"h4"},"getPackageForModule: (modulePath: string) => ?PackageInfo")," ",(0,o.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,o.mdx)("p",null,"Given a module path that may exist under an npm package, locates and returns the package root path and parsed ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," contents."),(0,o.mdx)("h4",{id:"resolvehastemodule-string--string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveHasteModule: string => ?string")),(0,o.mdx)("p",null,"Resolves a Haste module name to an absolute path. Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such module exists."),(0,o.mdx)("p",null,"The default implementation of this function uses ",(0,o.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/metro-file-map"},"metro-file-map"),"'s ",(0,o.mdx)("inlineCode",{parentName:"p"},"getModule")," method."),(0,o.mdx)("h4",{id:"resolvehastepackage-string--string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveHastePackage: string => ?string")),(0,o.mdx)("p",null,"Resolves a Haste (global) package name to an absolute ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," path. Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such package exists."),(0,o.mdx)("p",null,"The default implementation of this function uses ",(0,o.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/metro-file-map"},"metro-file-map"),"'s ",(0,o.mdx)("inlineCode",{parentName:"p"},"getPackage")," method and can be turned on or off using ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#enableglobalpackages"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.enableGlobalPackages")),"."),(0,o.mdx)("h4",{id:"allowhaste-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"allowHaste: boolean")),(0,o.mdx)("p",null,(0,o.mdx)("inlineCode",{parentName:"p"},"true")," if Haste resolutions are allowed in the current context, ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," otherwise."),(0,o.mdx)("h4",{id:"disablehierarchicallookup-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"disableHierarchicalLookup: boolean")),(0,o.mdx)("p",null,"If ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),", the resolver should not perform lookup in ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories per the Node resolution algorithm. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#disablehierarchicallookup"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.disableHierarchicalLookup")),"."),(0,o.mdx)("h4",{id:"extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"extraNodeModules: ?{[string]: string}")),(0,o.mdx)("p",null,"A mapping of package names to directories that is consulted after the standard lookup through ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," as well as any ",(0,o.mdx)("a",{parentName:"p",href:"#nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"nodeModulesPaths")),"."),(0,o.mdx)("h4",{id:"originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"originModulePath: string")),(0,o.mdx)("p",null,"The path to the current module, e.g. the one containing the ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," we are currently resolving."),(0,o.mdx)("h4",{id:"customresolveroptions-string-mixed"},(0,o.mdx)("inlineCode",{parentName:"h4"},"customResolverOptions: {[string]: mixed}")),(0,o.mdx)("p",null,"Any custom options passed to the resolver. By default, Metro populates this based on URL parameters in the bundle request, e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"http://localhost:8081/index.bundle?resolver.key=value")," becomes ",(0,o.mdx)("inlineCode",{parentName:"p"},"{key: 'value'}"),"."),(0,o.mdx)("h4",{id:"resolverequest-customresolver"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveRequest: CustomResolver")),(0,o.mdx)("p",null,"A alternative resolver function to which the current request may be delegated. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvereqeuest"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolveRequest")),"."),(0,o.mdx)("p",null,"Metro expects ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," to have the following signature:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"function resolveRequest(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null,\n): Resolution {\n // ...\n}\n\ntype Resolution =\n | {type: 'empty'}\n | {type: 'sourceFile', filePath: string}\n | {type: 'assetFiles', filePaths: $ReadOnlyArray};\n")),(0,o.mdx)("p",null,"When calling the default resolver with a non-null ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," function, it represents a custom resolver and will always be called, fully replacing the default resolution logic."),(0,o.mdx)("p",null,"Inside a custom resolver, ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," is set to the default resolver function, for easy chaining and customization."),(0,o.mdx)("h4",{id:"dependency-dependency"},(0,o.mdx)("inlineCode",{parentName:"h4"},"dependency: ?Dependency")),(0,o.mdx)("p",null,"A dependency descriptor corresponding to the current resolution request. This is provided for diagnostic purposes ",(0,o.mdx)("em",{parentName:"p"},"only")," and may not be used for semantic purposes. See the ",(0,o.mdx)("a",{parentName:"p",href:"#caching"},"Caching")," section for more information."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"type Dependency = {\n // The literal name provided to a require or import call. For example 'foo' in\n // case of `require('foo')`.\n name: string,\n\n data: {\n // A locally unique key for this dependency within the origin module.\n key: string,\n\n // Source locations from the Babel AST, relative to the origin module, where\n // this dependency was encountered. This may be an empty array.\n locs: $ReadOnlyArray,\n\n asyncType: 'async' | 'prefetch' | 'weak' | null,\n\n // Other properties are considered internal and may change in the future.\n ...\n },\n};\n")),(0,o.mdx)("h2",{id:"caching"},"Caching"),(0,o.mdx)("p",null,"Resolver results may be cached under the following conditions:"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"For given origin module paths ",(0,o.mdx)("em",{parentName:"li"},"A")," and ",(0,o.mdx)("em",{parentName:"li"},"B")," and target module name ",(0,o.mdx)("em",{parentName:"li"},"M"),", the resolution for ",(0,o.mdx)("em",{parentName:"li"},"M")," may be reused if ",(0,o.mdx)("strong",{parentName:"li"},"all")," of the following conditions hold:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"A")," and ",(0,o.mdx)("em",{parentName:"li"},"B")," are in the same directory."),(0,o.mdx)("li",{parentName:"ol"},"The contents of ",(0,o.mdx)("a",{parentName:"li",href:"#customresolveroptions-string-mixed"},(0,o.mdx)("inlineCode",{parentName:"a"},"customResolverOptions"))," are equivalent ( = serialize to JSON the same) in both calls to the resolver."))),(0,o.mdx)("li",{parentName:"ol"},"Any cache of resolutions must be invalidated if any file in the project has changed.")),(0,o.mdx)("p",null,"Custom resolvers must adhere to these assumptions, e.g. they may not return different resolutions for origin modules in the same directory under the same ",(0,o.mdx)("inlineCode",{parentName:"p"},"customResolverOptions"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[599],{3905:(e,a,t)=>{t.r(a),t.d(a,{MDXContext:()=>d,MDXProvider:()=>x,mdx:()=>f,useMDXComponents:()=>p,withMDXComponents:()=>s});var n=t(67294);function r(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function o(){return o=Object.assign||function(e){for(var a=1;a=0||(r[t]=e[t]);return r}(e,a);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var d=n.createContext({}),s=function(e){return function(a){var t=p(a.components);return n.createElement(e,o({},a,{components:t}))}},p=function(e){var a=n.useContext(d),t=a;return e&&(t="function"==typeof e?e(a):i(i({},a),e)),t},x=function(e){var a=p(e.components);return n.createElement(d.Provider,{value:a},e.children)},u="mdxType",c={inlineCode:"code",wrapper:function(e){var a=e.children;return n.createElement(n.Fragment,{},a)}},h=n.forwardRef((function(e,a){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,d=m(e,["components","mdxType","originalType","parentName"]),s=p(t),x=r,u=s["".concat(l,".").concat(x)]||s[x]||c[x]||o;return t?n.createElement(u,i(i({ref:a},d),{},{components:t})):n.createElement(u,i({ref:a},d))}));function f(e,a){var t=arguments,r=a&&a.mdxType;if("string"==typeof e||r){var o=t.length,l=new Array(o);l[0]=h;var i={};for(var m in a)hasOwnProperty.call(a,m)&&(i[m]=a[m]);i.originalType=e,i[u]="string"==typeof e?e:r,l[1]=i;for(var d=2;d{t.r(a),t.d(a,{assets:()=>s,contentTitle:()=>m,default:()=>c,frontMatter:()=>i,metadata:()=>d,toc:()=>p});var n=t(83117),r=t(80102),o=(t(67294),t(3905)),l=["components"],i={id:"resolution",title:"Module Resolution"},m=void 0,d={unversionedId:"resolution",id:"resolution",title:"Module Resolution",description:"Module resolution is the process of translating module names to module paths at build time. For example, if your project contains the code:",source:"@site/../docs/Resolution.md",sourceDirName:".",slug:"/resolution",permalink:"/docs/resolution",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Resolution.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"resolution",title:"Module Resolution"},sidebar:"docs",previous:{title:"Caching",permalink:"/docs/caching"},next:{title:"Source Map Format",permalink:"/docs/source-map-format"}},s={},p=[{value:"Resolution algorithm",id:"resolution-algorithm",level:2},{value:"Resolution types",id:"resolution-types",level:3},{value:"Source file",id:"source-file",level:4},{value:"Asset files",id:"asset-files",level:4},{value:"Empty module",id:"empty-module",level:4},{value:"Algorithm",id:"algorithm",level:3},{value:"RESOLVE",id:"resolve",level:4},{value:"RESOLVE_MODULE",id:"resolve_module",level:4},{value:"RESOLVE_PACKAGE",id:"resolve_package",level:4},{value:"RESOLVE_PACKAGE_EXPORTS",id:"resolve_package_exports",level:4},{value:"RESOLVE_FILE",id:"resolve_file",level:4},{value:"RESOLVE_ASSET",id:"resolve_asset",level:4},{value:"RESOLVE_HASTE",id:"resolve_haste",level:4},{value:"Resolution context",id:"resolution-context",level:3},{value:"assetExts: $ReadOnlySet<string>",id:"assetexts-readonlysetstring",level:4},{value:"doesFileExist: string => boolean",id:"doesfileexist-string--boolean",level:4},{value:"nodeModulesPaths: $ReadOnlyArray<string>",id:"nodemodulespaths-readonlyarraystring",level:4},{value:"preferNativePlatform: boolean",id:"prefernativeplatform-boolean",level:4},{value:"redirectModulePath: string => string | false",id:"redirectmodulepath-string--string--false",level:4},{value:"resolveAsset: (dirPath: string, assetName: string, extension: string) => ?$ReadOnlyArray<string>",id:"resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring",level:4},{value:"sourceExts: $ReadOnlyArray<string>",id:"sourceexts-readonlyarraystring",level:4},{value:"mainFields: $ReadOnlyArray<string>",id:"mainfields-readonlyarraystring",level:4},{value:"getPackage: string => PackageJson",id:"getpackage-string--packagejson",level:4},{value:'getPackageForModule: (modulePath: string) => ?PackageInfo
Deprecated
',id:"getpackageformodule-modulepath-string--packageinfo-deprecated",level:4},{value:"resolveHasteModule: string => ?string",id:"resolvehastemodule-string--string",level:4},{value:"resolveHastePackage: string => ?string",id:"resolvehastepackage-string--string",level:4},{value:"allowHaste: boolean",id:"allowhaste-boolean",level:4},{value:"disableHierarchicalLookup: boolean",id:"disablehierarchicallookup-boolean",level:4},{value:"extraNodeModules: ?{[string]: string}",id:"extranodemodules-string-string",level:4},{value:"originModulePath: string",id:"originmodulepath-string",level:4},{value:"customResolverOptions: {[string]: mixed}",id:"customresolveroptions-string-mixed",level:4},{value:"resolveRequest: CustomResolver",id:"resolverequest-customresolver",level:4},{value:"dependency: ?Dependency",id:"dependency-dependency",level:4},{value:"Caching",id:"caching",level:2}],x={toc:p},u="wrapper";function c(e){var a=e.components,t=(0,r.Z)(e,l);return(0,o.mdx)(u,(0,n.Z)({},x,t,{components:a,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Module resolution is the process of translating module names to module paths at build time. For example, if your project contains the code:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// src/App.js\nimport {View} from 'react-native';\n// ...\n")),(0,o.mdx)("p",null,"Metro needs to know where in your project to load the ",(0,o.mdx)("inlineCode",{parentName:"p"},"react-native")," module from. This will typically resolve to something like ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules/react-native/index.js"),"."),(0,o.mdx)("p",null,"Likewise, if your project contains the (similar) code:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"// src/App.js\nimport Comp from './Component';\n// ...\n")),(0,o.mdx)("p",null,"Metro needs to understand that you are referring to, say, ",(0,o.mdx)("inlineCode",{parentName:"p"},"src/Component.js"),", and not another file named ",(0,o.mdx)("inlineCode",{parentName:"p"},"Component")," that may also exist elsewhere."),(0,o.mdx)("p",null,"Metro implements a version of ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#loading-from-node_modules-folders"},"Node's module resolution algorithm"),", augmented with additional Metro-specific features."),(0,o.mdx)("p",null,"These Metro-specific features include:"),(0,o.mdx)("ul",null,(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Haste"),": An opt-in mechanism for importing modules by their globally-unique name anywhere in the project, e.g. ",(0,o.mdx)("inlineCode",{parentName:"li"},"import Foo from 'Foo'"),"."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Platform extensions"),": Used by ",(0,o.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions"},"React Native")," to allow developers to write platform-specific versions of their JavaScript modules."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Asset extensions and image resolutions"),": Used by ",(0,o.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/images#static-image-resources"},"React Native")," to automatically select the best version of an image asset based on the device's screen density at runtime."),(0,o.mdx)("li",{parentName:"ul"},(0,o.mdx)("strong",{parentName:"li"},"Custom resolvers"),": Metro integrators can provide their own resolver implementations to override almost everything about how modules are resolved.")),(0,o.mdx)("h2",{id:"resolution-algorithm"},"Resolution algorithm"),(0,o.mdx)("p",null,"Given a ",(0,o.mdx)("a",{parentName:"p",href:"#resolution-context"},"resolution context")," ",(0,o.mdx)("em",{parentName:"p"},"context"),", a module name ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", and an optional platform identifier ",(0,o.mdx)("em",{parentName:"p"},"platform"),", Metro's resolver performs ",(0,o.mdx)("a",{parentName:"p",href:"#resolve"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE")),"(",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),"), which either returns one of the ",(0,o.mdx)("a",{parentName:"p",href:"#resolution-types"},"resolution types"),", or throws an error."),(0,o.mdx)("h3",{id:"resolution-types"},"Resolution types"),(0,o.mdx)("h4",{id:"source-file"},"Source file"),(0,o.mdx)("p",null,"The request is resolved to some absolute path representing a physical file on disk."),(0,o.mdx)("h4",{id:"asset-files"},"Asset files"),(0,o.mdx)("p",null,"The request is resolved to one or more absolute paths representing physical files on disk."),(0,o.mdx)("h4",{id:"empty-module"},"Empty module"),(0,o.mdx)("p",null,"The request is resolved to a built-in empty module, namely the one specified in ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#emptymodulepath"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.emptyModulePath")),"."),(0,o.mdx)("h3",{id:"algorithm"},"Algorithm"),(0,o.mdx)("admonition",{type:"note"},(0,o.mdx)("p",{parentName:"admonition"},"These are the rules that Metro's default resolver follows. Refer to ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-resolver/src/resolve.js"},(0,o.mdx)("inlineCode",{parentName:"a"},"metro-resolver"),"'s source code")," for more details.")),(0,o.mdx)("h4",{id:"resolve"},"RESOLVE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If a ",(0,o.mdx)("a",{parentName:"li",href:"#resolverequest-customresolver"},"custom resolver")," is defined, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of the custom resolver."))),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, attempt to resolve ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a path",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"absoluteModuleName")," be the result of prepending the current directory (i.e. parent of ",(0,o.mdx)("a",{parentName:"li",href:"#originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.originModulePath")),") with ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_module"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_MODULE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"absoluteModuleName"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."))),(0,o.mdx)("li",{parentName:"ol"},"Apply ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections")," to ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),". If this results in an ",(0,o.mdx)("a",{parentName:"li",href:"#empty-module"},"empty module"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the empty module."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#allowhaste-boolean"},"Haste resolutions are allowed"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Get the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_haste"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_HASTE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."),(0,o.mdx)("li",{parentName:"ol"},"If resolved as a Haste package path, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Perform the algorithm for resolving a path (step 2 above). Throw an error if this resolution fails.\nFor example, if the Haste package path for ",(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b'")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"foo/package.json"),", perform step 2 as if ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," was ",(0,o.mdx)("inlineCode",{parentName:"li"},"foo/c"),"."))))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#disableHierarchicalLookup-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.disableHierarchicalLookup"))," is not ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," under ",(0,o.mdx)("inlineCode",{parentName:"li"},"node_modules")," from the current directory (i.e. parent of ",(0,o.mdx)("a",{parentName:"li",href:"#originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.originModulePath")),") up to the root directory."),(0,o.mdx)("li",{parentName:"ol"},"Perform ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),") for each candidate path."))),(0,o.mdx)("li",{parentName:"ol"},"For each element ",(0,o.mdx)("em",{parentName:"li"},"nodeModulesPath")," of ",(0,o.mdx)("a",{parentName:"li",href:"#nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.nodeModulesPaths")),":",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," under ",(0,o.mdx)("em",{parentName:"li"},"nodeModulesPath")," as if the latter was another ",(0,o.mdx)("inlineCode",{parentName:"li"},"node_modules")," directory (similar to step 5 above)."),(0,o.mdx)("li",{parentName:"ol"},"Perform ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),") for each candidate path."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules"))," is set:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Split ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," into a package name (including an optional ",(0,o.mdx)("a",{parentName:"li",href:"https://docs.npmjs.com/cli/v8/using-npm/scope"},"scope"),") and relative path."),(0,o.mdx)("li",{parentName:"ol"},"Look up the package name in ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules")),". If found, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Construct a path ",(0,o.mdx)("em",{parentName:"li"},"modulePath")," by replacing the package name part of ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," with the value found in ",(0,o.mdx)("a",{parentName:"li",href:"#extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.extraNodeModules"))),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"modulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))))),(0,o.mdx)("li",{parentName:"ol"},"If no valid resolution has been found, throw a resolution failure error.")),(0,o.mdx)("h4",{id:"resolve_module"},"RESOLVE_MODULE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"filePath")," be the result of applying ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections")," to ",(0,o.mdx)("em",{parentName:"li"},"moduleName"),". This may locate a replacement subpath from a containing ",(0,o.mdx)("inlineCode",{parentName:"li"},"package.json")," file based on the ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, let ",(0,o.mdx)("em",{parentName:"li"},"dirPath")," be the directory path of ",(0,o.mdx)("em",{parentName:"li"},"filePath"),"."),(0,o.mdx)("li",{parentName:"ol"},"If a file ",(0,o.mdx)("em",{parentName:"li"},"dirPath")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'package.json'")," exists, resolve based on the ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),":",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath")," be the result of reading the package's entry path using ",(0,o.mdx)("a",{parentName:"li",href:"#mainfields-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.mainFields")),"."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),"), or continue."),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_file"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_FILE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"mainModulePath")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'/index'"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."),(0,o.mdx)("li",{parentName:"ol"},"Throw an error if no resolution could be found.")))),(0,o.mdx)("h4",{id:"resolve_package"},"RESOLVE_PACKAGE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.enablePackageExports")," is enabled, and a containing ",(0,o.mdx)("inlineCode",{parentName:"li"},"package.json")," file contains the field ",(0,o.mdx)("inlineCode",{parentName:"li"},'"exports"'),", get result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_package-exports"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_PACKAGE_EXPORTS")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"packagePath"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),").",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"If resolved path exists, return result."),(0,o.mdx)("li",{parentName:"ol"},"Else, log either a package configuration or package encapsulation warning."))),(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_module"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_MODULE")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),").")),(0,o.mdx)("h4",{id:"resolve_package_exports"},"RESOLVE_PACKAGE_EXPORTS"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"packagePath"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"exportsField"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("blockquote",null,(0,o.mdx)("p",{parentName:"blockquote"},"Resolves a package subpath based on the ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"Package Entry Points spec")," (the ",(0,o.mdx)("inlineCode",{parentName:"p"},'"exports"')," field), when ",(0,o.mdx)("a",{parentName:"p",href:"./configuration#unstable_enablepackageexports-experimental"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports"))," is enabled.")),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"subpath")," be the relative path from ",(0,o.mdx)("em",{parentName:"li"},"packagePath")," to ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", or ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.'"),"."),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"exportsField")," contains an invalid configuration or values, raise an ",(0,o.mdx)("inlineCode",{parentName:"li"},"InvalidPackageConfigurationError"),"."),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"subpath")," is not defined by ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),", raise a ",(0,o.mdx)("inlineCode",{parentName:"li"},"PackagePathNotExportedError"),"."),(0,o.mdx)("li",{parentName:"ol"},"Let ",(0,o.mdx)("em",{parentName:"li"},"target")," be the result of matching ",(0,o.mdx)("em",{parentName:"li"},"subpath")," in ",(0,o.mdx)("em",{parentName:"li"},"exportsField")," after applying any ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#conditional-exports"},"conditional exports")," and/or substituting a ",(0,o.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath pattern match"),".",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Condition names will be asserted from the union of ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.unstable_conditionNames")," and ",(0,o.mdx)("inlineCode",{parentName:"li"},"context.unstable_conditionNamesByPlatform")," for ",(0,o.mdx)("em",{parentName:"li"},"platform"),", in the order defined by ",(0,o.mdx)("em",{parentName:"li"},"exportsField"),"."))),(0,o.mdx)("li",{parentName:"ol"},"If ",(0,o.mdx)("em",{parentName:"li"},"target")," refers to an ",(0,o.mdx)("a",{parentName:"li",href:"#assetexts-readonlysetstring"},"asset"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_asset"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_ASSET")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"target"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))),(0,o.mdx)("li",{parentName:"ol"},"Return ",(0,o.mdx)("em",{parentName:"li"},"target")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," ",(0,o.mdx)("strong",{parentName:"li"},"without")," applying redirections or trying any platform or extension variants.")),(0,o.mdx)("h4",{id:"resolve_file"},"RESOLVE_FILE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"If the path refers to an ",(0,o.mdx)("a",{parentName:"li",href:"#assetexts-readonlysetstring"},"asset"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return the result of ",(0,o.mdx)("a",{parentName:"li",href:"#resolve_asset"},(0,o.mdx)("strong",{parentName:"a"},"RESOLVE_ASSET")),"(",(0,o.mdx)("em",{parentName:"li"},"context"),", ",(0,o.mdx)("em",{parentName:"li"},"filePath"),", ",(0,o.mdx)("em",{parentName:"li"},"platform"),")."))),(0,o.mdx)("li",{parentName:"ol"},"Otherwise, if the path ",(0,o.mdx)("a",{parentName:"li",href:"#doesfileexist-string--boolean"},"exists"),", then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Try all platform and extension variants in sequence. Return a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," for the first one that ",(0,o.mdx)("a",{parentName:"li",href:"#doesfileexist-string--boolean"},"exists")," after applying ",(0,o.mdx)("a",{parentName:"li",href:"#redirectmodulepath-string--string--false"},"redirections"),". For example, if ",(0,o.mdx)("em",{parentName:"li"},"platform")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"android")," and ",(0,o.mdx)("a",{parentName:"li",href:"#sourceexts-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.sourceExts"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"['js', 'jsx']"),", try this sequence of potential file names:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.android.js'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.native.js'")," (if ",(0,o.mdx)("a",{parentName:"li",href:"#prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.preferNativePlatform"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),")"),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.js'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.android.jsx'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.native.jsx'")," (if ",(0,o.mdx)("a",{parentName:"li",href:"#prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.preferNativePlatform"))," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"true"),")"),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"moduleName")," + ",(0,o.mdx)("inlineCode",{parentName:"li"},"'.jsx'"))))))),(0,o.mdx)("h4",{id:"resolve_asset"},"RESOLVE_ASSET"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"filePath"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Use ",(0,o.mdx)("a",{parentName:"li",href:"#resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"context.resolveAsset"))," to collect all asset variants."),(0,o.mdx)("li",{parentName:"ol"},"Return an ",(0,o.mdx)("a",{parentName:"li",href:"#asset-files"},"asset resolution")," containing the collected asset paths.")),(0,o.mdx)("h4",{id:"resolve_haste"},"RESOLVE_HASTE"),(0,o.mdx)("p",null,"Parameters: (",(0,o.mdx)("em",{parentName:"p"},"context"),", ",(0,o.mdx)("em",{parentName:"p"},"moduleName"),", ",(0,o.mdx)("em",{parentName:"p"},"platform"),")"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#resolvehastemodule-string--string"},"Haste module"),".\nIf found, then",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},"Return result as a ",(0,o.mdx)("a",{parentName:"li",href:"#source-file"},"source file resolution")," ",(0,o.mdx)("strong",{parentName:"li"},"without")," applying redirections or trying any platform or extension variants."))),(0,o.mdx)("li",{parentName:"ol"},"Try resolving ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," as a ",(0,o.mdx)("a",{parentName:"li",href:"#resolvehastepackage-string--string"},"Haste (global) package"),", or a path ",(0,o.mdx)("em",{parentName:"li"},"relative")," to a Haste package.\nFor example, if ",(0,o.mdx)("em",{parentName:"li"},"moduleName")," is ",(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b/c'"),", try the following potential Haste package names:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b/c'"),", relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"''")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a/b'"),", relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"'./c'")),(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("inlineCode",{parentName:"li"},"'a'"),", with relative path ",(0,o.mdx)("inlineCode",{parentName:"li"},"'./b/c'"))))),(0,o.mdx)("h3",{id:"resolution-context"},"Resolution context"),(0,o.mdx)("h4",{id:"assetexts-readonlysetstring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"assetExts: $ReadOnlySet")),(0,o.mdx)("p",null,"The set of file extensions used to identify asset files. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#assetexts"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.assetExts")),"."),(0,o.mdx)("h4",{id:"doesfileexist-string--boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"doesFileExist: string => boolean")),(0,o.mdx)("p",null,"Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"true")," if the file with the given path exists, or ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," otherwise."),(0,o.mdx)("p",null,"By default, Metro implements this by consulting an in-memory map of the filesystem that has been prepared in advance. This approach avoids disk I/O during module resolution."),(0,o.mdx)("h4",{id:"nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"nodeModulesPaths: $ReadOnlyArray")),(0,o.mdx)("p",null,"A list of paths to check for modules after looking through all ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories."),(0,o.mdx)("p",null,"By default this is set to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#nodemodulespaths"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.nodeModulesPaths"))),(0,o.mdx)("h4",{id:"prefernativeplatform-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"preferNativePlatform: boolean")),(0,o.mdx)("p",null,"If ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),", try ",(0,o.mdx)("inlineCode",{parentName:"p"},".native.${ext}")," before ",(0,o.mdx)("inlineCode",{parentName:"p"},".${ext}")," and after ",(0,o.mdx)("inlineCode",{parentName:"p"},".${platform}.${ext}")," during resolution. Metro sets this to ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,o.mdx)("h4",{id:"redirectmodulepath-string--string--false"},(0,o.mdx)("inlineCode",{parentName:"h4"},"redirectModulePath: string => string | false")),(0,o.mdx)("p",null,"Rewrites a module path, or returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," to redirect to the special ",(0,o.mdx)("a",{parentName:"p",href:"#empty-module"},"empty module"),". In the default resolver, the resolution algorithm terminates with an ",(0,o.mdx)("a",{parentName:"p",href:"#empty-module"},"empty module result")," if ",(0,o.mdx)("inlineCode",{parentName:"p"},"redirectModulePath")," returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,o.mdx)("p",null,"Metro uses this to implement the ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,o.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),", particularly the ability to ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#replace-specific-files---advanced"},"replace")," and ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module"},"ignore")," specific files."),(0,o.mdx)("p",null,"The default implementation of this function respects ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvermainfields"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolverMainFields")),"."),(0,o.mdx)("h4",{id:"resolveasset-dirpath-string-assetname-string-extension-string--readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveAsset: (dirPath: string, assetName: string, extension: string) => ?$ReadOnlyArray")),(0,o.mdx)("p",null,"Given a directory path, the base asset name and an extension, returns a list of all the asset file names that match the given base name in that directory, or ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such files are found. The default implementation considers each of ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#assetresolutions"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.assetResolutions"))," and uses the ",(0,o.mdx)("inlineCode",{parentName:"p"},"${assetName}@${resolution}${extension}")," format for asset variant file names."),(0,o.mdx)("p",null,"See also ",(0,o.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/images#static-image-resources"},"Static Image Resources")," in the React Native docs."),(0,o.mdx)("h4",{id:"sourceexts-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"sourceExts: $ReadOnlyArray")),(0,o.mdx)("p",null,"The list of file extensions to try, in order, when resolving a module path that does not exist on disk. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#sourceexts"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.sourceExts")),"."),(0,o.mdx)("h4",{id:"mainfields-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"h4"},"mainFields: $ReadOnlyArray")),(0,o.mdx)("p",null,"The ordered list of fields in ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," that should be read to resolve a package's main entry point (and any subpath file replacements) per the ",(0,o.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},'"browser" field spec'),". Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvermainfields"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolverMainFields")),"."),(0,o.mdx)("h4",{id:"getpackage-string--packagejson"},(0,o.mdx)("inlineCode",{parentName:"h4"},"getPackage: string => PackageJson")),(0,o.mdx)("p",null,"Given the path to a ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," file, returns the parsed file contents."),(0,o.mdx)("h4",{id:"getpackageformodule-modulepath-string--packageinfo-deprecated"},(0,o.mdx)("inlineCode",{parentName:"h4"},"getPackageForModule: (modulePath: string) => ?PackageInfo")," ",(0,o.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,o.mdx)("p",null,"Given a module path that may exist under an npm package, locates and returns the package root path and parsed ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," contents."),(0,o.mdx)("h4",{id:"resolvehastemodule-string--string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveHasteModule: string => ?string")),(0,o.mdx)("p",null,"Resolves a Haste module name to an absolute path. Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such module exists."),(0,o.mdx)("p",null,"The default implementation of this function uses ",(0,o.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/metro-file-map"},"metro-file-map"),"'s ",(0,o.mdx)("inlineCode",{parentName:"p"},"getModule")," method."),(0,o.mdx)("h4",{id:"resolvehastepackage-string--string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveHastePackage: string => ?string")),(0,o.mdx)("p",null,"Resolves a Haste (global) package name to an absolute ",(0,o.mdx)("inlineCode",{parentName:"p"},"package.json")," path. Returns ",(0,o.mdx)("inlineCode",{parentName:"p"},"null")," if no such package exists."),(0,o.mdx)("p",null,"The default implementation of this function uses ",(0,o.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/metro-file-map"},"metro-file-map"),"'s ",(0,o.mdx)("inlineCode",{parentName:"p"},"getPackage")," method and can be turned on or off using ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#enableglobalpackages"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.enableGlobalPackages")),"."),(0,o.mdx)("h4",{id:"allowhaste-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"allowHaste: boolean")),(0,o.mdx)("p",null,(0,o.mdx)("inlineCode",{parentName:"p"},"true")," if Haste resolutions are allowed in the current context, ",(0,o.mdx)("inlineCode",{parentName:"p"},"false")," otherwise."),(0,o.mdx)("h4",{id:"disablehierarchicallookup-boolean"},(0,o.mdx)("inlineCode",{parentName:"h4"},"disableHierarchicalLookup: boolean")),(0,o.mdx)("p",null,"If ",(0,o.mdx)("inlineCode",{parentName:"p"},"true"),", the resolver should not perform lookup in ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories per the Node resolution algorithm. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#disablehierarchicallookup"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.disableHierarchicalLookup")),"."),(0,o.mdx)("h4",{id:"extranodemodules-string-string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"extraNodeModules: ?{[string]: string}")),(0,o.mdx)("p",null,"A mapping of package names to directories that is consulted after the standard lookup through ",(0,o.mdx)("inlineCode",{parentName:"p"},"node_modules")," as well as any ",(0,o.mdx)("a",{parentName:"p",href:"#nodemodulespaths-readonlyarraystring"},(0,o.mdx)("inlineCode",{parentName:"a"},"nodeModulesPaths")),"."),(0,o.mdx)("h4",{id:"originmodulepath-string"},(0,o.mdx)("inlineCode",{parentName:"h4"},"originModulePath: string")),(0,o.mdx)("p",null,"The path to the current module, e.g. the one containing the ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," we are currently resolving."),(0,o.mdx)("h4",{id:"customresolveroptions-string-mixed"},(0,o.mdx)("inlineCode",{parentName:"h4"},"customResolverOptions: {[string]: mixed}")),(0,o.mdx)("p",null,"Any custom options passed to the resolver. By default, Metro populates this based on URL parameters in the bundle request, e.g. ",(0,o.mdx)("inlineCode",{parentName:"p"},"http://localhost:8081/index.bundle?resolver.key=value")," becomes ",(0,o.mdx)("inlineCode",{parentName:"p"},"{key: 'value'}"),"."),(0,o.mdx)("h4",{id:"resolverequest-customresolver"},(0,o.mdx)("inlineCode",{parentName:"h4"},"resolveRequest: CustomResolver")),(0,o.mdx)("p",null,"A alternative resolver function to which the current request may be delegated. Defaults to ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#resolvereqeuest"},(0,o.mdx)("inlineCode",{parentName:"a"},"resolver.resolveRequest")),"."),(0,o.mdx)("p",null,"Metro expects ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," to have the following signature:"),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"function resolveRequest(\n context: ResolutionContext,\n moduleName: string,\n platform: string | null,\n): Resolution {\n // ...\n}\n\ntype Resolution =\n | {type: 'empty'}\n | {type: 'sourceFile', filePath: string}\n | {type: 'assetFiles', filePaths: $ReadOnlyArray};\n")),(0,o.mdx)("p",null,"When calling the default resolver with a non-null ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," function, it represents a custom resolver and will always be called, fully replacing the default resolution logic."),(0,o.mdx)("p",null,"Inside a custom resolver, ",(0,o.mdx)("inlineCode",{parentName:"p"},"resolveRequest")," is set to the default resolver function, for easy chaining and customization."),(0,o.mdx)("h4",{id:"dependency-dependency"},(0,o.mdx)("inlineCode",{parentName:"h4"},"dependency: ?Dependency")),(0,o.mdx)("p",null,"A dependency descriptor corresponding to the current resolution request. This is provided for diagnostic purposes ",(0,o.mdx)("em",{parentName:"p"},"only")," and may not be used for semantic purposes. See the ",(0,o.mdx)("a",{parentName:"p",href:"#caching"},"Caching")," section for more information."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-flow"},"type Dependency = {\n // The literal name provided to a require or import call. For example 'foo' in\n // case of `require('foo')`.\n name: string,\n\n data: {\n // A locally unique key for this dependency within the origin module.\n key: string,\n\n // Source locations from the Babel AST, relative to the origin module, where\n // this dependency was encountered. This may be an empty array.\n locs: $ReadOnlyArray,\n\n asyncType: 'async' | 'prefetch' | 'weak' | null,\n\n // Other properties are considered internal and may change in the future.\n ...\n },\n};\n")),(0,o.mdx)("h2",{id:"caching"},"Caching"),(0,o.mdx)("p",null,"Resolver results may be cached under the following conditions:"),(0,o.mdx)("ol",null,(0,o.mdx)("li",{parentName:"ol"},"For given origin module paths ",(0,o.mdx)("em",{parentName:"li"},"A")," and ",(0,o.mdx)("em",{parentName:"li"},"B")," and target module name ",(0,o.mdx)("em",{parentName:"li"},"M"),", the resolution for ",(0,o.mdx)("em",{parentName:"li"},"M")," may be reused if ",(0,o.mdx)("strong",{parentName:"li"},"all")," of the following conditions hold:",(0,o.mdx)("ol",{parentName:"li"},(0,o.mdx)("li",{parentName:"ol"},(0,o.mdx)("em",{parentName:"li"},"A")," and ",(0,o.mdx)("em",{parentName:"li"},"B")," are in the same directory."),(0,o.mdx)("li",{parentName:"ol"},"The contents of ",(0,o.mdx)("a",{parentName:"li",href:"#customresolveroptions-string-mixed"},(0,o.mdx)("inlineCode",{parentName:"a"},"customResolverOptions"))," are equivalent ( = serialize to JSON the same) in both calls to the resolver."))),(0,o.mdx)("li",{parentName:"ol"},"Any cache of resolutions must be invalidated if any file in the project has changed.")),(0,o.mdx)("p",null,"Custom resolvers must adhere to these assumptions, e.g. they may not return different resolutions for origin modules in the same directory under the same ",(0,o.mdx)("inlineCode",{parentName:"p"},"customResolverOptions"),"."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b9b5fbc.5e2544a2.js b/assets/js/8b9b5fbc.3c950ae5.js similarity index 98% rename from assets/js/8b9b5fbc.5e2544a2.js rename to assets/js/8b9b5fbc.3c950ae5.js index cc247ea087..74b185f664 100644 --- a/assets/js/8b9b5fbc.5e2544a2.js +++ b/assets/js/8b9b5fbc.3c950ae5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[424],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>c,mdx:()=>f,useMDXComponents:()=>s,withMDXComponents:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var m=r.createContext({}),d=function(e){return function(t){var n=s(t.components);return r.createElement(e,a({},t,{components:n}))}},s=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(m.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,m=p(e,["components","mdxType","originalType","parentName"]),d=s(n),c=o,u=d["".concat(i,".").concat(c)]||d[c]||g[c]||a;return n?r.createElement(u,l(l({ref:t},m),{},{components:n})):r.createElement(u,l({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var m=2;m{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>g,frontMatter:()=>l,metadata:()=>m,toc:()=>s});var r=n(83117),o=n(80102),a=(n(67294),n(3905)),i=["components"],l={id:"local-development",title:"Local Development Setup"},p=void 0,m={unversionedId:"local-development",id:"local-development",title:"Local Development Setup",description:"This page includes tips for developers working on Metro itself, including how to test your changes within other local projects.",source:"@site/../docs/LocalDevelopment.md",sourceDirName:".",slug:"/local-development",permalink:"/docs/local-development",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/LocalDevelopment.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"local-development",title:"Local Development Setup"},sidebar:"docs",previous:{title:"Troubleshooting",permalink:"/docs/troubleshooting"},next:{title:"Bundle Formats",permalink:"/docs/bundling"}},d={},s=[{value:"Testing Metro Changes inside a React Native Project",id:"testing-metro-changes-inside-a-react-native-project",level:3},{value:"Debug Logging",id:"debug-logging",level:3}],c={toc:s},u="wrapper";function g(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.mdx)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"This page includes tips for developers working on Metro itself, including how to test your changes within other local projects."),(0,a.mdx)("h3",{id:"testing-metro-changes-inside-a-react-native-project"},"Testing Metro Changes inside a React Native Project"),(0,a.mdx)("p",null,"When developing Metro, running your iterations against a local target project can be a great way to test the impact of your changes end-to-end."),(0,a.mdx)("p",null,"Our recommended workflow is to use ",(0,a.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/en/docs/cli/link"},(0,a.mdx)("inlineCode",{parentName:"a"},"yarn link"))," to register local ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages within your development clone and then hot-switch to these versions in the consuming project. These instructions cover linking a local Metro clone with a bare workflow React Native app (i.e. having run ",(0,a.mdx)("inlineCode",{parentName:"p"},"npx react-native init MetroTestApp"),")."),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-sh"},".\n\u2514\u2500\u2500 Development\n \u251c\u2500\u2500 metro # metro clone\n \u2514\u2500\u2500 MetroTestApp # target project\n")),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Use ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn link")," in your ",(0,a.mdx)("inlineCode",{parentName:"strong"},"metro")," clone to register local packages")),(0,a.mdx)("p",{parentName:"li"},"From inside our ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," clone, ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link")," is responsible for registering local package folders to be linked to elsewhere."),(0,a.mdx)("p",{parentName:"li"},"We recommend using ",(0,a.mdx)("inlineCode",{parentName:"p"},"npm exec --workspaces")," to register all packages in the ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," repo \u2014 these can be individually linked into the target project later."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre"},"npm exec --workspaces -- yarn link\n"))),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Use ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn link")," to replace Metro packages in your target project")),(0,a.mdx)("p",{parentName:"li"},"From inside our target project folder, ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link ")," can be used to apply our registered ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages for that project only."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-sh"},"# Links 3 packages\nyarn link metro metro-config metro-runtime\n")),(0,a.mdx)("p",{parentName:"li"},"Note: At mininum, the ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," and ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro-runtime")," packages need to be linked.")),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Configure Metro ",(0,a.mdx)("inlineCode",{parentName:"strong"},"watchFolders")," to work with our linked packages")),(0,a.mdx)("p",{parentName:"li"},"Because ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link")," has included files outside of the immediate React Native project folder, we need to inform Metro that this set of files exists (as it will not automatically follow the symlinks). Add the following to your ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js"),":"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-diff"},"+ const path = require('path');\n\n module.exports = {\n+ watchFolders: [\n+ path.resolve(__dirname, './node_modules'),\n+ // Include necessary file paths for `yarn link`ed modules\n+ path.resolve(__dirname, '../metro/packages'),\n+ path.resolve(__dirname, '../metro/node_modules'),\n+ ],\n ...\n };\n")),(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Run Metro")),(0,a.mdx)("p",{parentName:"li"},"Now we should be able to run Metro within our target project. Remember to restart this command after any code changes you make to ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," or to the target project's ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js")," file."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre"},"yarn react-native start\n"))),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"(Optional) Clean up with ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn unlink"))),(0,a.mdx)("p",{parentName:"li"},"If you want to restore the remote (i.e. production npm) versions of ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages in your target project, step 2 (and 1) can be repeated with ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn unlink"),"."))),(0,a.mdx)("h3",{id:"debug-logging"},"Debug Logging"),(0,a.mdx)("p",null,"Metro uses the ",(0,a.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/debug"},"debug")," package to write logs under named debug scopes (for example: ",(0,a.mdx)("inlineCode",{parentName:"p"},"Metro:WatchmanWatcher"),"). Set the ",(0,a.mdx)("inlineCode",{parentName:"p"},"DEBUG")," environment variable before starting Metro to enable logs matching the supplied pattern."),(0,a.mdx)("p",null,"The snippet below provides a pattern matching all Metro-defined messages."),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre"},"DEBUG='Metro:*' yarn metro serve\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[424],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>c,mdx:()=>f,useMDXComponents:()=>s,withMDXComponents:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var m=r.createContext({}),d=function(e){return function(t){var n=s(t.components);return r.createElement(e,a({},t,{components:n}))}},s=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=s(e.components);return r.createElement(m.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,m=p(e,["components","mdxType","originalType","parentName"]),d=s(n),c=o,u=d["".concat(i,".").concat(c)]||d[c]||g[c]||a;return n?r.createElement(u,l(l({ref:t},m),{},{components:n})):r.createElement(u,l({ref:t},m))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var m=2;m{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>g,frontMatter:()=>l,metadata:()=>m,toc:()=>s});var r=n(83117),o=n(80102),a=(n(67294),n(3905)),i=["components"],l={id:"local-development",title:"Local Development Setup"},p=void 0,m={unversionedId:"local-development",id:"local-development",title:"Local Development Setup",description:"This page includes tips for developers working on Metro itself, including how to test your changes within other local projects.",source:"@site/../docs/LocalDevelopment.md",sourceDirName:".",slug:"/local-development",permalink:"/docs/local-development",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/LocalDevelopment.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"local-development",title:"Local Development Setup"},sidebar:"docs",previous:{title:"Troubleshooting",permalink:"/docs/troubleshooting"},next:{title:"Bundle Formats",permalink:"/docs/bundling"}},d={},s=[{value:"Testing Metro Changes inside a React Native Project",id:"testing-metro-changes-inside-a-react-native-project",level:3},{value:"Debug Logging",id:"debug-logging",level:3}],c={toc:s},u="wrapper";function g(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.mdx)(u,(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"This page includes tips for developers working on Metro itself, including how to test your changes within other local projects."),(0,a.mdx)("h3",{id:"testing-metro-changes-inside-a-react-native-project"},"Testing Metro Changes inside a React Native Project"),(0,a.mdx)("p",null,"When developing Metro, running your iterations against a local target project can be a great way to test the impact of your changes end-to-end."),(0,a.mdx)("p",null,"Our recommended workflow is to use ",(0,a.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/en/docs/cli/link"},(0,a.mdx)("inlineCode",{parentName:"a"},"yarn link"))," to register local ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages within your development clone and then hot-switch to these versions in the consuming project. These instructions cover linking a local Metro clone with a bare workflow React Native app (i.e. having run ",(0,a.mdx)("inlineCode",{parentName:"p"},"npx react-native init MetroTestApp"),")."),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre",className:"language-sh"},".\n\u2514\u2500\u2500 Development\n \u251c\u2500\u2500 metro # metro clone\n \u2514\u2500\u2500 MetroTestApp # target project\n")),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Use ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn link")," in your ",(0,a.mdx)("inlineCode",{parentName:"strong"},"metro")," clone to register local packages")),(0,a.mdx)("p",{parentName:"li"},"From inside our ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," clone, ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link")," is responsible for registering local package folders to be linked to elsewhere."),(0,a.mdx)("p",{parentName:"li"},"We recommend using ",(0,a.mdx)("inlineCode",{parentName:"p"},"npm exec --workspaces")," to register all packages in the ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," repo \u2014 these can be individually linked into the target project later."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre"},"npm exec --workspaces -- yarn link\n"))),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Use ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn link")," to replace Metro packages in your target project")),(0,a.mdx)("p",{parentName:"li"},"From inside our target project folder, ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link ")," can be used to apply our registered ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages for that project only."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-sh"},"# Links 3 packages\nyarn link metro metro-config metro-runtime\n")),(0,a.mdx)("p",{parentName:"li"},"Note: At mininum, the ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," and ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro-runtime")," packages need to be linked.")),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Configure Metro ",(0,a.mdx)("inlineCode",{parentName:"strong"},"watchFolders")," to work with our linked packages")),(0,a.mdx)("p",{parentName:"li"},"Because ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn link")," has included files outside of the immediate React Native project folder, we need to inform Metro that this set of files exists (as it will not automatically follow the symlinks). Add the following to your ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js"),":"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-diff"},"+ const path = require('path');\n\n module.exports = {\n+ watchFolders: [\n+ path.resolve(__dirname, './node_modules'),\n+ // Include necessary file paths for `yarn link`ed modules\n+ path.resolve(__dirname, '../metro/packages'),\n+ path.resolve(__dirname, '../metro/node_modules'),\n+ ],\n ...\n };\n")),(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"Run Metro")),(0,a.mdx)("p",{parentName:"li"},"Now we should be able to run Metro within our target project. Remember to restart this command after any code changes you make to ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," or to the target project's ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js")," file."),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre"},"yarn react-native start\n"))),(0,a.mdx)("li",{parentName:"ol"},(0,a.mdx)("p",{parentName:"li"},(0,a.mdx)("strong",{parentName:"p"},"(Optional) Clean up with ",(0,a.mdx)("inlineCode",{parentName:"strong"},"yarn unlink"))),(0,a.mdx)("p",{parentName:"li"},"If you want to restore the remote (i.e. production npm) versions of ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro")," packages in your target project, step 2 (and 1) can be repeated with ",(0,a.mdx)("inlineCode",{parentName:"p"},"yarn unlink"),"."))),(0,a.mdx)("h3",{id:"debug-logging"},"Debug Logging"),(0,a.mdx)("p",null,"Metro uses the ",(0,a.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/debug"},"debug")," package to write logs under named debug scopes (for example: ",(0,a.mdx)("inlineCode",{parentName:"p"},"Metro:WatchmanWatcher"),"). Set the ",(0,a.mdx)("inlineCode",{parentName:"p"},"DEBUG")," environment variable before starting Metro to enable logs matching the supplied pattern."),(0,a.mdx)("p",null,"The snippet below provides a pattern matching all Metro-defined messages."),(0,a.mdx)("pre",null,(0,a.mdx)("code",{parentName:"pre"},"DEBUG='Metro:*' yarn metro serve\n")))}g.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ae2a35ac.03e1616a.js b/assets/js/ae2a35ac.49d67f32.js similarity index 99% rename from assets/js/ae2a35ac.03e1616a.js rename to assets/js/ae2a35ac.49d67f32.js index 1f369543ac..e17fc012ed 100644 --- a/assets/js/ae2a35ac.03e1616a.js +++ b/assets/js/ae2a35ac.49d67f32.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[708],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>l,MDXProvider:()=>c,mdx:()=>h,useMDXComponents:()=>m,withMDXComponents:()=>d});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){return function(t){var n=m(t.components);return a.createElement(e,i({},t,{components:n}))}},m=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=m(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",x={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,r=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),d=m(n),c=o,u=d["".concat(r,".").concat(c)]||d[c]||x[c]||i;return n?a.createElement(u,s(s({ref:t},l),{},{components:n})):a.createElement(u,s({ref:t},l))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=g;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>x,frontMatter:()=>s,metadata:()=>l,toc:()=>m});var a=n(83117),o=n(80102),i=(n(67294),n(3905)),r=["components"],s={id:"package-exports",title:"Package Exports Support (Experimental)"},p=void 0,l={unversionedId:"package-exports",id:"package-exports",title:"Package Exports Support (Experimental)",description:"Background",source:"@site/../docs/PackageExports.md",sourceDirName:".",slug:"/package-exports",permalink:"/docs/package-exports",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/PackageExports.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"package-exports",title:"Package Exports Support (Experimental)"},sidebar:"docs",previous:{title:"Metro CLI Options",permalink:"/docs/cli"},next:{title:"Troubleshooting",permalink:"/docs/troubleshooting"}},d={},m=[{value:"Background",id:"background",level:2},{value:"Configuration options",id:"configuration-options",level:2},{value:"Summary of breaking changes",id:"summary-of-breaking-changes",level:2},{value:"Breaking: Match "exports" first, then fall back to legacy resolution",id:"breaking-match-exports-first-then-fall-back-to-legacy-resolution",level:3},{value:"Example",id:"example",level:4},{value:"Breaking: Import specifiers are matched exactly",id:"breaking-import-specifiers-are-matched-exactly",level:3},{value:"Example",id:"example-1",level:4},{value:"Package encapsulation is lenient",id:"package-encapsulation-is-lenient",level:3},{value:"Migration guide for package maintainers",id:"migration-guide-for-package-maintainers",level:2},{value:"Recommended: Introducing "exports" is a breaking change",id:"recommended-introducing-exports-is-a-breaking-change",level:3},{value:"Package subpaths",id:"package-subpaths",level:3},{value:"File extensions are important!",id:"file-extensions-are-important",level:4},{value:"Subpath patterns do not permit expansion",id:"subpath-patterns-do-not-permit-expansion",level:4},{value:"Replacing "browser" and "react-native" fields",id:"replacing-browser-and-react-native-fields",level:3},{value:"Example: Use conditional exports to target web and React Native",id:"example-use-conditional-exports-to-target-web-and-react-native",level:4},{value:"Replacing platform-specific extensions",id:"replacing-platform-specific-extensions",level:3},{value:"Use Platform.select() (React Native)",id:"use-platformselect-react-native",level:4},{value:"Asset files",id:"asset-files",level:3}],c={toc:m},u="wrapper";function x(e){var t=e.components,n=(0,o.Z)(e,r);return(0,i.mdx)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.mdx)("h2",{id:"background"},"Background"),(0,i.mdx)("p",null,"Introduced in Node.js 12.7.0, Package Exports is a modern approach for npm packages to specify ",(0,i.mdx)("strong",{parentName:"p"},"entry points")," \u2014 the mapping of package subpaths which can be externally imported and which file(s) they should resolve to."),(0,i.mdx)("p",null,"When Package Exports support is enabled via ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration/#unstable_enablepackageexports-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports")),", Metro's ",(0,i.mdx)("a",{parentName:"p",href:"/docs/resolution#algorithm"},"module resolution algorithm")," will consider the ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field in ",(0,i.mdx)("inlineCode",{parentName:"p"},"package.json")," files."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"Node.js spec")),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md"},"RFC for Package Exports in Metro")),(0,i.mdx)("li",{parentName:"ul"},"React Native announcement post (coming soon!)")),(0,i.mdx)("h2",{id:"configuration-options"},"Configuration options"),(0,i.mdx)("table",null,(0,i.mdx)("thead",{parentName:"table"},(0,i.mdx)("tr",{parentName:"thead"},(0,i.mdx)("th",{parentName:"tr",align:null},"Option"),(0,i.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,i.mdx)("tbody",{parentName:"table"},(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_enablepackageexports-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports"))),(0,i.mdx)("td",{parentName:"tr",align:null},"Enable Package Exports support.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_conditionnames-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_conditionNames"))),(0,i.mdx)("td",{parentName:"tr",align:null},"The set of condition names to assert when resolving conditional exports.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_conditionsbyplatform-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_conditionsByPlatform"))),(0,i.mdx)("td",{parentName:"tr",align:null},"The additional condition names to assert when resolving for a given platform target.")))),(0,i.mdx)("h2",{id:"summary-of-breaking-changes"},"Summary of breaking changes"),(0,i.mdx)("admonition",{type:"info"},(0,i.mdx)("p",{parentName:"admonition"},(0,i.mdx)("strong",{parentName:"p"},"Package Exports resolution is available since Metro 0.76.1 and is disabled by default"),". We will provide the option to disable it for a long time yet, and have no plans to remove existing non-",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," resolution behaviour.")),(0,i.mdx)("p",null,"Since Package Exports features overlap with existing React Native concepts (such as ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions"),"), and since ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," had been live in the npm ecosystem for some time, we reached out to the React Native community to make sure our implementation would meet developers' needs (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/pull/534"},"PR"),", ",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md"},"final RFC"),")."),(0,i.mdx)("p",null,"This led us to create an implementation of Package Exports in Metro that is spec-compliant (necessitating some breaking changes), but backwards compatible otherwise (helping apps with existing imports to migrate gradually)."),(0,i.mdx)("h3",{id:"breaking-match-exports-first-then-fall-back-to-legacy-resolution"},"Breaking: Match ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"exports"')," first, then fall back to legacy resolution"),(0,i.mdx)("p",null,"If present in a ",(0,i.mdx)("inlineCode",{parentName:"p"},"package.json")," file, ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," will be the first field consulted when resolving a package."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},'"exports"')," will be used instead of any existing ",(0,i.mdx)("inlineCode",{parentName:"li"},'"react-native"'),", ",(0,i.mdx)("inlineCode",{parentName:"li"},'"browser"'),", or ",(0,i.mdx)("inlineCode",{parentName:"li"},'"main"')," field \u2014\xa0or a file on disk at the same subpath (edge case)."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("strong",{parentName:"li"},"Fallback"),": If the requested subpath is not matched in ",(0,i.mdx)("inlineCode",{parentName:"li"},'"exports"'),", Metro will try to resolve it again, considering the above fields.")),(0,i.mdx)("p",null,"Subpaths matched in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," (including via ",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath patterns"),") will use the exact target file path specified by a package."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Metro will not expand ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration/#sourceexts"},(0,i.mdx)("inlineCode",{parentName:"a"},"sourceExts"))," against the import specifier."),(0,i.mdx)("li",{parentName:"ul"},"Metro will not resolve ",(0,i.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions")," against the target file."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("strong",{parentName:"li"},"Unchanged"),": Metro will expand ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration#assetresolutions"},"asset densities")," (e.g. ",(0,i.mdx)("inlineCode",{parentName:"li"},"icon.png")," \u2192 ",(0,i.mdx)("inlineCode",{parentName:"li"},"icon@2x.png"),") if the target file ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration/#assetexts"},"is an asset"),".")),(0,i.mdx)("h4",{id:"example"},"Example"),(0,i.mdx)("p",null,"For a package without an ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field, Metro tries multiple potential file locations based on the import specifier:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"import FooComponent from 'some-pkg/FooComponent';\n// Tries .[platform].js, .native.js, .js (+ TypeScript variants)\n")),(0,i.mdx)("p",null,"However, if ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./FooComponent"')," is listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", Metro matches the import specifier to this subpath, and uses the target file specified by the package with no further rules:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"import FooComponent from 'some-pkg/FooComponent';\n// Resolves exact target from \"exports\" only\n")),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We have no plans to drop platform-specific extensions for packages not using ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", or in app code.")),(0,i.mdx)("h3",{id:"breaking-import-specifiers-are-matched-exactly"},"Breaking: Import specifiers are matched exactly"),(0,i.mdx)("p",null,"Previously, import specifiers (the string given to ",(0,i.mdx)("inlineCode",{parentName:"p"},"import")," or ",(0,i.mdx)("inlineCode",{parentName:"p"},"require()"),") could be defined using both extensioned or extensionless paths. This is no longer the case for subpath keys in the ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field."),(0,i.mdx)("h4",{id:"example-1"},"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "name": "some-pkg",\n "exports": {\n "./FooComponent": "./src/FooComponent.js"\n }\n}\n')),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},'import FooComponent from \'some-pkg/FooComponent.js\';\n// Inaccessible unless the package had also listed "./FooComponent.js"\n// as an "exports" key\n')),(0,i.mdx)("p",null,"Note that this behaviour also applies for subpath patterns: ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./*": "./src/*.js"')," is distinct from ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./*.js": "./src/*.js"'),"."),(0,i.mdx)("h3",{id:"package-encapsulation-is-lenient"},"Package encapsulation is lenient"),(0,i.mdx)("p",null,"In Node.js, it is an error to import package subpaths that aren't explicitly listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),". In Metro, we've decided to handle these errors leniently and resolve modules following the old behavior as necessary. This is intended to reduce user friction for previously allowed imports in existing Metro projects."),(0,i.mdx)("p",null,"Instead of throwing an error, Metro will log a warning and fall back to file-based resolution."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-sh"},'warn: You have imported the module "foo/private/fn.js" which is not listed in\nthe "exports" of "foo". Consider updating your call site or asking the package\nmaintainer(s) to expose this API.\n')),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We plan to implement a strict mode for package encapsulation in future, to align with Node's default behavior. ",(0,i.mdx)("strong",{parentName:"p"},"We recommend that all developers fix encapsulation warnings in their code"),".")),(0,i.mdx)("h2",{id:"migration-guide-for-package-maintainers"},"Migration guide for package maintainers"),(0,i.mdx)("p",null,(0,i.mdx)("strong",{parentName:"p"},"Adding an ",(0,i.mdx)("inlineCode",{parentName:"strong"},'"exports"')," field to your package is entirely optional"),". Existing package resolution features will behave identically for packages which don't use ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," \u2014 and we have no plans to remove this behaviour."),(0,i.mdx)("h3",{id:"recommended-introducing-exports-is-a-breaking-change"},"Recommended: Introducing ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"exports"')," is a breaking change"),(0,i.mdx)("p",null,"The Node.js spec gives guidance on migrating to ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," in a non-breaking manner, however this is challenging in practice. For instance, if your React Native package uses ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions")," on its public exports, this is a breaking change by default."),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},"To make the introduction of ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," non-breaking, ensure that every previously supported entry point is exported. It is best to explicitly specify entry points so that the package's public API is well-defined."),(0,i.mdx)("p",{parentName:"blockquote"},"\u2014\xa0",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"))),(0,i.mdx)("h3",{id:"package-subpaths"},"Package subpaths"),(0,i.mdx)("admonition",{type:"caution"},(0,i.mdx)("p",{parentName:"admonition"},(0,i.mdx)("strong",{parentName:"p"},"Please do not rely on ",(0,i.mdx)("a",{parentName:"strong",href:"#package-encapsulation-is-lenient"},"lenient package encapsulation")," under Metro.")," While Metro does this for backwards compatibility, packages should follow how ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," is documented in the spec and strictly implemented by other tools.")),(0,i.mdx)("h4",{id:"file-extensions-are-important"},"File extensions are important!"),(0,i.mdx)("p",null,"Each subpath is an exact specifier (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md#exact-path-specifiers"},"see section in RFC"),")."),(0,i.mdx)("p",null,"We recommend continuing to use ",(0,i.mdx)("strong",{parentName:"p"},"extensionless specifiers")," for subpaths in packages targeting React Native \u2014\xa0or ",(0,i.mdx)("strong",{parentName:"p"},"defining both extensioned and extensionless specifiers"),". This will match matching existing user expectations."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n ".": "./src/index.js",\n "./FooComponent": "./src/FooComponent.js",\n "./FooComponent.js": "./src/FooComponent.js"\n }\n')),(0,i.mdx)("h4",{id:"subpath-patterns-do-not-permit-expansion"},"Subpath patterns do not permit expansion"),(0,i.mdx)("p",null,"Subpath patterns are a shorthand for mapping multiple subpaths \u2014\xa0they do not permit path expansion (strictly a substring replacement), however will match nested directories (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md#subpath-patterns"},"see section in RFC"),")."),(0,i.mdx)("p",null,"Only one ",(0,i.mdx)("inlineCode",{parentName:"p"},"*")," is permitted per side of a subpath pattern."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n ".": "./index.js",\n "./utils/*": "./utils/*.js"\n }\n')),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo'")," matches ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo.js'"),"."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo/bar'")," matches ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo/bar.js'"),"."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo'")," ",(0,i.mdx)("strong",{parentName:"li"},"does not match")," ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo.bar.js'"),".")),(0,i.mdx)("h3",{id:"replacing-browser-and-react-native-fields"},"Replacing ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"browser"')," and ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"react-native"')," fields"),(0,i.mdx)("p",null,"We've introduced ",(0,i.mdx)("inlineCode",{parentName:"p"},'"react-native"')," as a community condition (for use with conditional exports). This represents React Native, the framework, sitting alongside other recognised runtimes such as ",(0,i.mdx)("inlineCode",{parentName:"p"},'"node"')," and ",(0,i.mdx)("inlineCode",{parentName:"p"},'"deno"')," (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/nodejs/node/pull/45367"},"RFC"),")."),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#community-conditions-definitions"},"Community Conditions Definitions \u2014\xa0",(0,i.mdx)("strong",{parentName:"a"},(0,i.mdx)("inlineCode",{parentName:"strong"},'"react-native"')))),(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("em",{parentName:"p"},'Will be matched by the React Native framework (all platforms). To target React Native for Web, "browser" should be specified before this condition.'))),(0,i.mdx)("p",null,"This replaces the previous ",(0,i.mdx)("inlineCode",{parentName:"p"},'"react-native"')," root field. The priority order for how this was previously resolved was determined by projects, ",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/expo/router/issues/37#issuecomment-1275925758"},"which created ambiguity when using React Native for Web"),". Under ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", ",(0,i.mdx)("em",{parentName:"p"},"packages concretely define the resolution order for conditional entry points")," \u2014\xa0removing this ambiguity."),(0,i.mdx)("h4",{id:"example-use-conditional-exports-to-target-web-and-react-native"},"Example: Use conditional exports to target web and React Native"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n "browser": "./dist/index-browser.js",\n "react-native": "./dist/index-react-native.js",\n "default": "./dist/index.js"\n }\n')),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We chose not to introduce ",(0,i.mdx)("inlineCode",{parentName:"p"},'"android"')," and ",(0,i.mdx)("inlineCode",{parentName:"p"},'"ios"')," conditions, due to the prevalence of other existing platform selection methods, and the complexity of how this behavior might work across frameworks. We recommend the ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform#select"},(0,i.mdx)("inlineCode",{parentName:"a"},"Platform.select()"))," API instead.")),(0,i.mdx)("h3",{id:"replacing-platform-specific-extensions"},"Replacing platform-specific extensions"),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("strong",{parentName:"p"},"Breaking change"),": Subpaths matched in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," (including via ",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath patterns"),") will use the exact file path specified by a package, and will not attempt to expand ",(0,i.mdx)("inlineCode",{parentName:"p"},"sourceExts")," or platform-specific extensions.")),(0,i.mdx)("h4",{id:"use-platformselect-react-native"},"Use ",(0,i.mdx)("a",{parentName:"h4",href:"https://reactnative.dev/docs/platform#select"},(0,i.mdx)("inlineCode",{parentName:"a"},"Platform.select()"))," (React Native)"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n "./FooComponent": "./src/FooComponent.js"\n }\n')),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"// src/FooComponent.js\n\nconst FooComponent = Platform.select({\n android: require('./FooComponentAndroid.js'),\n ios: require('FooComponentIOS.js'),\n});\n\nexport default FooComponent;\n")),(0,i.mdx)("h3",{id:"asset-files"},"Asset files"),(0,i.mdx)("p",null,"As with source files, assets must be listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," to be imported without warnings. Asset files with ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration#assetresolutions"},"multiple densities"),", e.g. ",(0,i.mdx)("inlineCode",{parentName:"p"},"icon.png")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"icon@2x.png"),", will continue to work without being listed individually."),(0,i.mdx)("p",null,"Using subpath patterns can be a convenient method to export many assets. We recommend specifying asset subpaths ",(0,i.mdx)("strong",{parentName:"p"},"with their file extension"),"."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "exports": {\n "./assets/*.png": "./dist/assets/*.png"\n }\n}\n')))}x.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[708],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>l,MDXProvider:()=>c,mdx:()=>h,useMDXComponents:()=>m,withMDXComponents:()=>d});var a=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){return function(t){var n=m(t.components);return a.createElement(e,i({},t,{components:n}))}},m=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},c=function(e){var t=m(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",x={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,r=e.parentName,l=p(e,["components","mdxType","originalType","parentName"]),d=m(n),c=o,u=d["".concat(r,".").concat(c)]||d[c]||x[c]||i;return n?a.createElement(u,s(s({ref:t},l),{},{components:n})):a.createElement(u,s({ref:t},l))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=n.length,r=new Array(i);r[0]=g;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:o,r[1]=s;for(var l=2;l{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>x,frontMatter:()=>s,metadata:()=>l,toc:()=>m});var a=n(83117),o=n(80102),i=(n(67294),n(3905)),r=["components"],s={id:"package-exports",title:"Package Exports Support (Experimental)"},p=void 0,l={unversionedId:"package-exports",id:"package-exports",title:"Package Exports Support (Experimental)",description:"Background",source:"@site/../docs/PackageExports.md",sourceDirName:".",slug:"/package-exports",permalink:"/docs/package-exports",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/PackageExports.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"package-exports",title:"Package Exports Support (Experimental)"},sidebar:"docs",previous:{title:"Metro CLI Options",permalink:"/docs/cli"},next:{title:"Troubleshooting",permalink:"/docs/troubleshooting"}},d={},m=[{value:"Background",id:"background",level:2},{value:"Configuration options",id:"configuration-options",level:2},{value:"Summary of breaking changes",id:"summary-of-breaking-changes",level:2},{value:"Breaking: Match "exports" first, then fall back to legacy resolution",id:"breaking-match-exports-first-then-fall-back-to-legacy-resolution",level:3},{value:"Example",id:"example",level:4},{value:"Breaking: Import specifiers are matched exactly",id:"breaking-import-specifiers-are-matched-exactly",level:3},{value:"Example",id:"example-1",level:4},{value:"Package encapsulation is lenient",id:"package-encapsulation-is-lenient",level:3},{value:"Migration guide for package maintainers",id:"migration-guide-for-package-maintainers",level:2},{value:"Recommended: Introducing "exports" is a breaking change",id:"recommended-introducing-exports-is-a-breaking-change",level:3},{value:"Package subpaths",id:"package-subpaths",level:3},{value:"File extensions are important!",id:"file-extensions-are-important",level:4},{value:"Subpath patterns do not permit expansion",id:"subpath-patterns-do-not-permit-expansion",level:4},{value:"Replacing "browser" and "react-native" fields",id:"replacing-browser-and-react-native-fields",level:3},{value:"Example: Use conditional exports to target web and React Native",id:"example-use-conditional-exports-to-target-web-and-react-native",level:4},{value:"Replacing platform-specific extensions",id:"replacing-platform-specific-extensions",level:3},{value:"Use Platform.select() (React Native)",id:"use-platformselect-react-native",level:4},{value:"Asset files",id:"asset-files",level:3}],c={toc:m},u="wrapper";function x(e){var t=e.components,n=(0,o.Z)(e,r);return(0,i.mdx)(u,(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,i.mdx)("h2",{id:"background"},"Background"),(0,i.mdx)("p",null,"Introduced in Node.js 12.7.0, Package Exports is a modern approach for npm packages to specify ",(0,i.mdx)("strong",{parentName:"p"},"entry points")," \u2014 the mapping of package subpaths which can be externally imported and which file(s) they should resolve to."),(0,i.mdx)("p",null,"When Package Exports support is enabled via ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration/#unstable_enablepackageexports-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports")),", Metro's ",(0,i.mdx)("a",{parentName:"p",href:"/docs/resolution#algorithm"},"module resolution algorithm")," will consider the ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field in ",(0,i.mdx)("inlineCode",{parentName:"p"},"package.json")," files."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"Node.js spec")),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md"},"RFC for Package Exports in Metro")),(0,i.mdx)("li",{parentName:"ul"},"React Native announcement post (coming soon!)")),(0,i.mdx)("h2",{id:"configuration-options"},"Configuration options"),(0,i.mdx)("table",null,(0,i.mdx)("thead",{parentName:"table"},(0,i.mdx)("tr",{parentName:"thead"},(0,i.mdx)("th",{parentName:"tr",align:null},"Option"),(0,i.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,i.mdx)("tbody",{parentName:"table"},(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_enablepackageexports-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_enablePackageExports"))),(0,i.mdx)("td",{parentName:"tr",align:null},"Enable Package Exports support.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_conditionnames-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_conditionNames"))),(0,i.mdx)("td",{parentName:"tr",align:null},"The set of condition names to assert when resolving conditional exports.")),(0,i.mdx)("tr",{parentName:"tbody"},(0,i.mdx)("td",{parentName:"tr",align:null},(0,i.mdx)("a",{parentName:"td",href:"/docs/configuration/#unstable_conditionsbyplatform-experimental"},(0,i.mdx)("inlineCode",{parentName:"a"},"resolver.unstable_conditionsByPlatform"))),(0,i.mdx)("td",{parentName:"tr",align:null},"The additional condition names to assert when resolving for a given platform target.")))),(0,i.mdx)("h2",{id:"summary-of-breaking-changes"},"Summary of breaking changes"),(0,i.mdx)("admonition",{type:"info"},(0,i.mdx)("p",{parentName:"admonition"},(0,i.mdx)("strong",{parentName:"p"},"Package Exports resolution is available since Metro 0.76.1 and is disabled by default"),". We will provide the option to disable it for a long time yet, and have no plans to remove existing non-",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," resolution behaviour.")),(0,i.mdx)("p",null,"Since Package Exports features overlap with existing React Native concepts (such as ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions"),"), and since ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," had been live in the npm ecosystem for some time, we reached out to the React Native community to make sure our implementation would meet developers' needs (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/pull/534"},"PR"),", ",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md"},"final RFC"),")."),(0,i.mdx)("p",null,"This led us to create an implementation of Package Exports in Metro that is spec-compliant (necessitating some breaking changes), but backwards compatible otherwise (helping apps with existing imports to migrate gradually)."),(0,i.mdx)("h3",{id:"breaking-match-exports-first-then-fall-back-to-legacy-resolution"},"Breaking: Match ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"exports"')," first, then fall back to legacy resolution"),(0,i.mdx)("p",null,"If present in a ",(0,i.mdx)("inlineCode",{parentName:"p"},"package.json")," file, ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," will be the first field consulted when resolving a package."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},'"exports"')," will be used instead of any existing ",(0,i.mdx)("inlineCode",{parentName:"li"},'"react-native"'),", ",(0,i.mdx)("inlineCode",{parentName:"li"},'"browser"'),", or ",(0,i.mdx)("inlineCode",{parentName:"li"},'"main"')," field \u2014\xa0or a file on disk at the same subpath (edge case)."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("strong",{parentName:"li"},"Fallback"),": If the requested subpath is not matched in ",(0,i.mdx)("inlineCode",{parentName:"li"},'"exports"'),", Metro will try to resolve it again, considering the above fields.")),(0,i.mdx)("p",null,"Subpaths matched in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," (including via ",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath patterns"),") will use the exact target file path specified by a package."),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},"Metro will not expand ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration/#sourceexts"},(0,i.mdx)("inlineCode",{parentName:"a"},"sourceExts"))," against the import specifier."),(0,i.mdx)("li",{parentName:"ul"},"Metro will not resolve ",(0,i.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions")," against the target file."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("strong",{parentName:"li"},"Unchanged"),": Metro will expand ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration#assetresolutions"},"asset densities")," (e.g. ",(0,i.mdx)("inlineCode",{parentName:"li"},"icon.png")," \u2192 ",(0,i.mdx)("inlineCode",{parentName:"li"},"icon@2x.png"),") if the target file ",(0,i.mdx)("a",{parentName:"li",href:"/docs/configuration/#assetexts"},"is an asset"),".")),(0,i.mdx)("h4",{id:"example"},"Example"),(0,i.mdx)("p",null,"For a package without an ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field, Metro tries multiple potential file locations based on the import specifier:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"import FooComponent from 'some-pkg/FooComponent';\n// Tries .[platform].js, .native.js, .js (+ TypeScript variants)\n")),(0,i.mdx)("p",null,"However, if ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./FooComponent"')," is listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", Metro matches the import specifier to this subpath, and uses the target file specified by the package with no further rules:"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"import FooComponent from 'some-pkg/FooComponent';\n// Resolves exact target from \"exports\" only\n")),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We have no plans to drop platform-specific extensions for packages not using ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", or in app code.")),(0,i.mdx)("h3",{id:"breaking-import-specifiers-are-matched-exactly"},"Breaking: Import specifiers are matched exactly"),(0,i.mdx)("p",null,"Previously, import specifiers (the string given to ",(0,i.mdx)("inlineCode",{parentName:"p"},"import")," or ",(0,i.mdx)("inlineCode",{parentName:"p"},"require()"),") could be defined using both extensioned or extensionless paths. This is no longer the case for subpath keys in the ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," field."),(0,i.mdx)("h4",{id:"example-1"},"Example"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "name": "some-pkg",\n "exports": {\n "./FooComponent": "./src/FooComponent.js"\n }\n}\n')),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},'import FooComponent from \'some-pkg/FooComponent.js\';\n// Inaccessible unless the package had also listed "./FooComponent.js"\n// as an "exports" key\n')),(0,i.mdx)("p",null,"Note that this behaviour also applies for subpath patterns: ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./*": "./src/*.js"')," is distinct from ",(0,i.mdx)("inlineCode",{parentName:"p"},'"./*.js": "./src/*.js"'),"."),(0,i.mdx)("h3",{id:"package-encapsulation-is-lenient"},"Package encapsulation is lenient"),(0,i.mdx)("p",null,"In Node.js, it is an error to import package subpaths that aren't explicitly listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),". In Metro, we've decided to handle these errors leniently and resolve modules following the old behavior as necessary. This is intended to reduce user friction for previously allowed imports in existing Metro projects."),(0,i.mdx)("p",null,"Instead of throwing an error, Metro will log a warning and fall back to file-based resolution."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-sh"},'warn: You have imported the module "foo/private/fn.js" which is not listed in\nthe "exports" of "foo". Consider updating your call site or asking the package\nmaintainer(s) to expose this API.\n')),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We plan to implement a strict mode for package encapsulation in future, to align with Node's default behavior. ",(0,i.mdx)("strong",{parentName:"p"},"We recommend that all developers fix encapsulation warnings in their code"),".")),(0,i.mdx)("h2",{id:"migration-guide-for-package-maintainers"},"Migration guide for package maintainers"),(0,i.mdx)("p",null,(0,i.mdx)("strong",{parentName:"p"},"Adding an ",(0,i.mdx)("inlineCode",{parentName:"strong"},'"exports"')," field to your package is entirely optional"),". Existing package resolution features will behave identically for packages which don't use ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," \u2014 and we have no plans to remove this behaviour."),(0,i.mdx)("h3",{id:"recommended-introducing-exports-is-a-breaking-change"},"Recommended: Introducing ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"exports"')," is a breaking change"),(0,i.mdx)("p",null,"The Node.js spec gives guidance on migrating to ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," in a non-breaking manner, however this is challenging in practice. For instance, if your React Native package uses ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code"},"platform-specific extensions")," on its public exports, this is a breaking change by default."),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},"To make the introduction of ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," non-breaking, ensure that every previously supported entry point is exported. It is best to explicitly specify entry points so that the package's public API is well-defined."),(0,i.mdx)("p",{parentName:"blockquote"},"\u2014\xa0",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"},"https://nodejs.org/docs/latest-v19.x/api/packages.html#package-entry-points"))),(0,i.mdx)("h3",{id:"package-subpaths"},"Package subpaths"),(0,i.mdx)("admonition",{type:"caution"},(0,i.mdx)("p",{parentName:"admonition"},(0,i.mdx)("strong",{parentName:"p"},"Please do not rely on ",(0,i.mdx)("a",{parentName:"strong",href:"#package-encapsulation-is-lenient"},"lenient package encapsulation")," under Metro.")," While Metro does this for backwards compatibility, packages should follow how ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," is documented in the spec and strictly implemented by other tools.")),(0,i.mdx)("h4",{id:"file-extensions-are-important"},"File extensions are important!"),(0,i.mdx)("p",null,"Each subpath is an exact specifier (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md#exact-path-specifiers"},"see section in RFC"),")."),(0,i.mdx)("p",null,"We recommend continuing to use ",(0,i.mdx)("strong",{parentName:"p"},"extensionless specifiers")," for subpaths in packages targeting React Native \u2014\xa0or ",(0,i.mdx)("strong",{parentName:"p"},"defining both extensioned and extensionless specifiers"),". This will match matching existing user expectations."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n ".": "./src/index.js",\n "./FooComponent": "./src/FooComponent.js",\n "./FooComponent.js": "./src/FooComponent.js"\n }\n')),(0,i.mdx)("h4",{id:"subpath-patterns-do-not-permit-expansion"},"Subpath patterns do not permit expansion"),(0,i.mdx)("p",null,"Subpath patterns are a shorthand for mapping multiple subpaths \u2014\xa0they do not permit path expansion (strictly a substring replacement), however will match nested directories (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0534-metro-package-exports-support.md#subpath-patterns"},"see section in RFC"),")."),(0,i.mdx)("p",null,"Only one ",(0,i.mdx)("inlineCode",{parentName:"p"},"*")," is permitted per side of a subpath pattern."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n ".": "./index.js",\n "./utils/*": "./utils/*.js"\n }\n')),(0,i.mdx)("ul",null,(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo'")," matches ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo.js'"),"."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo/bar'")," matches ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo/bar.js'"),"."),(0,i.mdx)("li",{parentName:"ul"},(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo'")," ",(0,i.mdx)("strong",{parentName:"li"},"does not match")," ",(0,i.mdx)("inlineCode",{parentName:"li"},"'pkg/utils/foo.bar.js'"),".")),(0,i.mdx)("h3",{id:"replacing-browser-and-react-native-fields"},"Replacing ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"browser"')," and ",(0,i.mdx)("inlineCode",{parentName:"h3"},'"react-native"')," fields"),(0,i.mdx)("p",null,"We've introduced ",(0,i.mdx)("inlineCode",{parentName:"p"},'"react-native"')," as a community condition (for use with conditional exports). This represents React Native, the framework, sitting alongside other recognised runtimes such as ",(0,i.mdx)("inlineCode",{parentName:"p"},'"node"')," and ",(0,i.mdx)("inlineCode",{parentName:"p"},'"deno"')," (",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/nodejs/node/pull/45367"},"RFC"),")."),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#community-conditions-definitions"},"Community Conditions Definitions \u2014\xa0",(0,i.mdx)("strong",{parentName:"a"},(0,i.mdx)("inlineCode",{parentName:"strong"},'"react-native"')))),(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("em",{parentName:"p"},'Will be matched by the React Native framework (all platforms). To target React Native for Web, "browser" should be specified before this condition.'))),(0,i.mdx)("p",null,"This replaces the previous ",(0,i.mdx)("inlineCode",{parentName:"p"},'"react-native"')," root field. The priority order for how this was previously resolved was determined by projects, ",(0,i.mdx)("a",{parentName:"p",href:"https://github.com/expo/router/issues/37#issuecomment-1275925758"},"which created ambiguity when using React Native for Web"),". Under ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"'),", ",(0,i.mdx)("em",{parentName:"p"},"packages concretely define the resolution order for conditional entry points")," \u2014\xa0removing this ambiguity."),(0,i.mdx)("h4",{id:"example-use-conditional-exports-to-target-web-and-react-native"},"Example: Use conditional exports to target web and React Native"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n "browser": "./dist/index-browser.js",\n "react-native": "./dist/index-react-native.js",\n "default": "./dist/index.js"\n }\n')),(0,i.mdx)("admonition",{type:"note"},(0,i.mdx)("p",{parentName:"admonition"},"We chose not to introduce ",(0,i.mdx)("inlineCode",{parentName:"p"},'"android"')," and ",(0,i.mdx)("inlineCode",{parentName:"p"},'"ios"')," conditions, due to the prevalence of other existing platform selection methods, and the complexity of how this behavior might work across frameworks. We recommend the ",(0,i.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform#select"},(0,i.mdx)("inlineCode",{parentName:"a"},"Platform.select()"))," API instead.")),(0,i.mdx)("h3",{id:"replacing-platform-specific-extensions"},"Replacing platform-specific extensions"),(0,i.mdx)("blockquote",null,(0,i.mdx)("p",{parentName:"blockquote"},(0,i.mdx)("strong",{parentName:"p"},"Breaking change"),": Subpaths matched in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," (including via ",(0,i.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v19.x/api/packages.html#subpath-patterns"},"subpath patterns"),") will use the exact file path specified by a package, and will not attempt to expand ",(0,i.mdx)("inlineCode",{parentName:"p"},"sourceExts")," or platform-specific extensions.")),(0,i.mdx)("h4",{id:"use-platformselect-react-native"},"Use ",(0,i.mdx)("a",{parentName:"h4",href:"https://reactnative.dev/docs/platform#select"},(0,i.mdx)("inlineCode",{parentName:"a"},"Platform.select()"))," (React Native)"),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},' "exports": {\n "./FooComponent": "./src/FooComponent.js"\n }\n')),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-js"},"// src/FooComponent.js\n\nconst FooComponent = Platform.select({\n android: require('./FooComponentAndroid.js'),\n ios: require('FooComponentIOS.js'),\n});\n\nexport default FooComponent;\n")),(0,i.mdx)("h3",{id:"asset-files"},"Asset files"),(0,i.mdx)("p",null,"As with source files, assets must be listed in ",(0,i.mdx)("inlineCode",{parentName:"p"},'"exports"')," to be imported without warnings. Asset files with ",(0,i.mdx)("a",{parentName:"p",href:"/docs/configuration#assetresolutions"},"multiple densities"),", e.g. ",(0,i.mdx)("inlineCode",{parentName:"p"},"icon.png")," and ",(0,i.mdx)("inlineCode",{parentName:"p"},"icon@2x.png"),", will continue to work without being listed individually."),(0,i.mdx)("p",null,"Using subpath patterns can be a convenient method to export many assets. We recommend specifying asset subpaths ",(0,i.mdx)("strong",{parentName:"p"},"with their file extension"),"."),(0,i.mdx)("pre",null,(0,i.mdx)("code",{parentName:"pre",className:"language-json"},'{\n "exports": {\n "./assets/*.png": "./dist/assets/*.png"\n }\n}\n')))}x.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ba2a2799.c2a471fe.js b/assets/js/ba2a2799.7305bfb1.js similarity index 76% rename from assets/js/ba2a2799.c2a471fe.js rename to assets/js/ba2a2799.7305bfb1.js index 07e76ee26c..6c4eb93922 100644 --- a/assets/js/ba2a2799.c2a471fe.js +++ b/assets/js/ba2a2799.7305bfb1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[122],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>m,MDXProvider:()=>c,mdx:()=>f,useMDXComponents:()=>p,withMDXComponents:()=>s});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(){return r=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var m=a.createContext({}),s=function(e){return function(n){var t=p(n.components);return a.createElement(e,r({},n,{components:t}))}},p=function(e){var n=a.useContext(m),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(m.Provider,{value:n},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},x=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,m=d(e,["components","mdxType","originalType","parentName"]),s=p(t),c=o,u=s["".concat(i,".").concat(c)]||s[c]||h[c]||r;return t?a.createElement(u,l(l({ref:n},m),{},{components:t})):a.createElement(u,l({ref:n},m))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=x;var l={};for(var d in n)hasOwnProperty.call(n,d)&&(l[d]=n[d]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var m=2;m{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>m,toc:()=>p});var a=t(83117),o=t(80102),r=(t(67294),t(3905)),i=["components"],l={id:"configuration",title:"Configuring Metro"},d=void 0,m={unversionedId:"configuration",id:"configuration",title:"Configuring Metro",description:"A Metro config can be created in these three ways (ordered by priority):",source:"@site/../docs/Configuration.md",sourceDirName:".",slug:"/configuration",permalink:"/docs/configuration",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Configuration.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"configuration",title:"Configuring Metro"},sidebar:"docs",previous:{title:"Module API",permalink:"/docs/module-api"},next:{title:"Metro CLI Options",permalink:"/docs/cli"}},s={},p=[{value:"Configuration Structure",id:"configuration-structure",level:2},{value:"General Options",id:"general-options",level:3},{value:"cacheStores",id:"cachestores",level:4},{value:"cacheVersion",id:"cacheversion",level:4},{value:"projectRoot",id:"projectroot",level:4},{value:"watchFolders",id:"watchfolders",level:4},{value:"transformerPath",id:"transformerpath",level:4},{value:"reporter",id:"reporter",level:4},{value:"resetCache",id:"resetcache",level:4},{value:"stickyWorkers",id:"stickyworkers",level:4},{value:"maxWorkers",id:"maxworkers",level:4},{value:"fileMapCacheDirectory",id:"filemapcachedirectory",level:4},{value:'hasteMapCacheDirectory
Deprecated
',id:"hastemapcachedirectory-deprecated",level:4},{value:"unstable_perfLoggerFactory",id:"unstable_perfloggerfactory",level:4},{value:"Resolver Options",id:"resolver-options",level:3},{value:"assetExts",id:"assetexts",level:4},{value:"sourceExts",id:"sourceexts",level:4},{value:"resolverMainFields",id:"resolvermainfields",level:4},{value:"disableHierarchicalLookup",id:"disablehierarchicallookup",level:4},{value:"emptyModulePath",id:"emptymodulepath",level:4},{value:"enableGlobalPackages",id:"enableglobalpackages",level:4},{value:"extraNodeModules",id:"extranodemodules",level:4},{value:"nodeModulesPaths",id:"nodemodulespaths",level:4},{value:"resolveRequest",id:"resolverequest",level:4},{value:"useWatchman",id:"usewatchman",level:4},{value:"blockList",id:"blocklist",level:4},{value:"hasteImplModulePath",id:"hasteimplmodulepath",level:4},{value:"platforms",id:"platforms",level:4},{value:"requireCycleIgnorePatterns",id:"requirecycleignorepatterns",level:4},{value:'unstable_conditionNames
Experimental
',id:"unstable_conditionnames-experimental",level:4},{value:'unstable_conditionsByPlatform
Experimental
',id:"unstable_conditionsbyplatform-experimental",level:4},{value:'unstable_enablePackageExports
Experimental
',id:"unstable_enablepackageexports-experimental",level:4},{value:'unstable_enableSymlinks
Experimental
',id:"unstable_enablesymlinks-experimental",level:4},{value:"Transformer Options",id:"transformer-options",level:3},{value:'asyncRequireModulePath
Deprecated
',id:"asyncrequiremodulepath-deprecated",level:4},{value:"dynamicDepsInPackages",id:"dynamicdepsinpackages",level:4},{value:"getTransformOptions",id:"gettransformoptions",level:4},{value:"minifierPath",id:"minifierpath",level:4},{value:"minifierConfig",id:"minifierconfig",level:4},{value:"optimizationSizeLimit",id:"optimizationsizelimit",level:4},{value:"React Native Only",id:"react-native-only",level:4},{value:"assetPlugins",id:"assetplugins",level:4},{value:"assetRegistryPath",id:"assetregistrypath",level:4},{value:"Babel-specific transformer options",id:"babel-specific-transformer-options",level:3},{value:"babelTransformerPath",id:"babeltransformerpath",level:4},{value:"enableBabelRCLookup",id:"enablebabelrclookup",level:4},{value:"enableBabelRuntime",id:"enablebabelruntime",level:4},{value:"hermesParser",id:"hermesparser",level:4},{value:"Serializer Options",id:"serializer-options",level:3},{value:"getRunModuleStatement",id:"getrunmodulestatement",level:4},{value:"createModuleIdFactory",id:"createmoduleidfactory",level:4},{value:"getPolyfills",id:"getpolyfills",level:4},{value:"getModulesRunBeforeMainModule",id:"getmodulesrunbeforemainmodule",level:4},{value:"processModuleFilter",id:"processmodulefilter",level:4},{value:"isThirdPartyModule",id:"isthirdpartymodule",level:4},{value:"Server Options",id:"server-options",level:3},{value:"port",id:"port",level:4},{value:"useGlobalHotkey",id:"useglobalhotkey",level:4},{value:'enhanceMiddleware
Deprecated
',id:"enhancemiddleware-deprecated",level:4},{value:"rewriteRequestUrl",id:"rewriterequesturl",level:4},{value:"Watcher Options",id:"watcher-options",level:3},{value:"additionalExts",id:"additionalexts",level:4},{value:"healthCheck.enabled",id:"healthcheckenabled",level:4},{value:"healthCheck.filePrefix",id:"healthcheckfileprefix",level:4},{value:"healthCheck.interval",id:"healthcheckinterval",level:4},{value:"healthCheck.timeout",id:"healthchecktimeout",level:4},{value:"watchman.deferStates",id:"watchmandeferstates",level:4},{value:"Merging Configurations",id:"merging-configurations",level:2},{value:"Merging Example",id:"merging-example",level:4}],c={toc:p},u="wrapper";function h(e){var n=e.components,t=(0,o.Z)(e,i);return(0,r.mdx)(u,(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.mdx)("p",null,"A Metro config can be created in these three ways (ordered by priority):"),(0,r.mdx)("ol",null,(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("inlineCode",{parentName:"li"},"metro.config.js")),(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("inlineCode",{parentName:"li"},"metro.config.json")),(0,r.mdx)("li",{parentName:"ol"},"The ",(0,r.mdx)("inlineCode",{parentName:"li"},"metro")," field in ",(0,r.mdx)("inlineCode",{parentName:"li"},"package.json"))),(0,r.mdx)("p",null,"You can also give a custom file to the configuration by specifying ",(0,r.mdx)("inlineCode",{parentName:"p"},"--config ")," when calling the CLI."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When Metro is started via the React Native CLI, some defaults are different from those mentioned below.\nSee the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/react-native/blob/main/packages/community-cli-plugin/src/utils/loadMetroConfig.js"},"React Native repository")," for details.")),(0,r.mdx)("h2",{id:"configuration-structure"},"Configuration Structure"),(0,r.mdx)("p",null,"The configuration is based on ",(0,r.mdx)("a",{parentName:"p",href:"/docs/concepts"},"our concepts"),", which means that for every module we have a separate config option. A common configuration structure in Metro looks like this:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-js"},"module.exports = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n },\n watcher: {\n /* watcher options */\n watchman: {\n /* Watchman-specific options */\n }\n }\n};\n")),(0,r.mdx)("h3",{id:"general-options"},"General Options"),(0,r.mdx)("h4",{id:"cachestores"},(0,r.mdx)("inlineCode",{parentName:"h4"},"cacheStores")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"CacheStores")," (see details below)"),(0,r.mdx)("p",null,"A list of storage adapters for Metro's ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching"},"transformer cache"),". This can be any combination of ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching#built-in-cache-stores"},"built-in cache stores")," and ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching#custom-cache-stores"},"custom cache stores"),". Defaults to using a temporary directory on disk as the only cache store."),(0,r.mdx)("p",null,"When Metro needs to transform a module, it first computes a machine-independent cache key for that file, and uses it to try to read from each of the stores in order. Once Metro has obtained the output of the transformer (whether already cached or not), it writes the transform result to ",(0,r.mdx)("em",{parentName:"p"},"all")," of the stores that returned ",(0,r.mdx)("inlineCode",{parentName:"p"},"null")," (a cache miss) for that key."),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"type CacheStores =\n | Array>\n | ((MetroCache) => Array<\n CacheStore\n >);\n\n// The exports of 'metro-cache'\ntype MetroCache = {\n FileStore,\n AutoCleanFileStore,\n HttpStore,\n HttpGetStore,\n ...\n};\n\ntype JsonSerializable = /* Any JSON-serializable value */;\n")),(0,r.mdx)("h4",{id:"cacheversion"},(0,r.mdx)("inlineCode",{parentName:"h4"},"cacheVersion")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"An arbitrary string appended to all cache keys in the project before they are hashed. There is generally no need to set this explicitly, as Metro will automatically derive the correct cache keys from your project config and the contents of source files."),(0,r.mdx)("h4",{id:"projectroot"},(0,r.mdx)("inlineCode",{parentName:"h4"},"projectRoot")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The root folder of your project. If your project depends on any files outside this root, their containing directories must be listed in ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"If your Metro project is developed in a monorepo and includes files from multiple logical packages, you'll generally want to set ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot")," to the root of your repository, or at least high enough in the hierarchy that all relevant files are reachable without separately configuring ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders"),".")),(0,r.mdx)("h4",{id:"watchfolders"},(0,r.mdx)("inlineCode",{parentName:"h4"},"watchFolders")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A list of directories outside of ",(0,r.mdx)("a",{parentName:"p",href:"#projectroot"},(0,r.mdx)("inlineCode",{parentName:"a"},"projectRoot"))," that can contain source files for the project."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Despite the naming of this option, it isn't related solely to file watching. Even in an offline build (for example, in CI), all files must be visible to Metro through the combination of ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders")," and ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot"),".")),(0,r.mdx)("h4",{id:"transformerpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"transformerPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The absolute path of a module (or a package name resolvable from the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro")," package) that implements a transformer."),(0,r.mdx)("p",null,"See the implementation of Metro's default transformer (",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-transform-worker/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-transform-worker")),") for more information about the transformer interface."),(0,r.mdx)("h4",{id:"reporter"},(0,r.mdx)("inlineCode",{parentName:"h4"},"reporter")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{update: (event: ReportableEvent) => void}")),(0,r.mdx)("p",null,"Used to report the status of the bundler during the bundling process. The default implementation prints most events to the terminal."),(0,r.mdx)("p",null,"See also the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro/src/lib/reporting.js"},"definition of ",(0,r.mdx)("inlineCode",{parentName:"a"},"ReportableEvent"))," in Metro's source code."),(0,r.mdx)("h4",{id:"resetcache"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resetCache")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),", Metro will reset the transformer cache (see ",(0,r.mdx)("a",{parentName:"p",href:"#cachestores"},(0,r.mdx)("inlineCode",{parentName:"a"},"cacheStores")),") and the file map cache (see ",(0,r.mdx)("a",{parentName:"p",href:"#filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"a"},"fileMapCacheDirectory")),") on startup."),(0,r.mdx)("h4",{id:"stickyworkers"},(0,r.mdx)("inlineCode",{parentName:"h4"},"stickyWorkers")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),", Metro will use a stable mapping from files to transformer workers, so the same file is always transformed by the same worker. This can improve initial build performance if the transformer is expensive to initialize, but can slow down concurrent builds with different configurations (e.g. multiple React Native apps connected to one Metro server). Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("h4",{id:"maxworkers"},(0,r.mdx)("inlineCode",{parentName:"h4"},"maxWorkers")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"The number of workers to use for parallel processing in Metro. Defaults to approximately half of the number of cores available on the machine, as reported by ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/os.html#oscpus"},(0,r.mdx)("inlineCode",{parentName:"a"},"os.cpus()")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("ol",{parentName:"admonition"},(0,r.mdx)("li",{parentName:"ol"},"Values exceeding the number of available cores have no effect."),(0,r.mdx)("li",{parentName:"ol"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"maxWorkers")," is set to 1 or lower, worker code will run in the main Metro process instead of concurrently."),(0,r.mdx)("li",{parentName:"ol"},"Metro has two separate worker pools - one for transformation and one for building the file map. Each pool has its worker count set to ",(0,r.mdx)("inlineCode",{parentName:"li"},"maxWorkers")," independently."))),(0,r.mdx)("h4",{id:"filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"fileMapCacheDirectory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The path to the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-file-map")," cache directory, defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"os.tmpdir()"),"."),(0,r.mdx)("h4",{id:"hastemapcachedirectory-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hasteMapCacheDirectory")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"Alias of ",(0,r.mdx)("a",{parentName:"p",href:"#filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"a"},"fileMapCacheDirectory"))),(0,r.mdx)("h4",{id:"unstable_perfloggerfactory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_perfLoggerFactory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"PerfLoggerFactory")),(0,r.mdx)("p",null,"A logger factory function that can be used to get insights about Metro performance timings and metadata for events including startup, bundling and HMR. Metro expects ",(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_perfLoggerFactory")," to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"function unstable_perfLoggerFactory(\n type: string,\n opts: $ReadOnly<{\n key?: string\n }>,\n): RootPerfLogger {\n // ...\n};\n")),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"type"))," Type of event being logged, e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"'STARTUP'"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"'BUNDLING_REQUEST'"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"'HMR'"),". See type definition of ",(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/configTypes.flow.js"},"PerfLoggerFactory")," for a full list of event types."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"opts")),(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"key")),": An opaque identifier to distinguish between instances of an event type (e.g. multiple, possibly concurrent, HMR requests).")))),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_perfLoggerFactory")," should return an object implementing the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/configTypes.flow.js"},"RootPerfLogger")," interface. For example, a factory function returning a no-op RootPerfLogger could be implemented as follows:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-javascript"},"const unstable_perfLoggerFactory = (type, factoryOpts) => {\n const getLogger = subSpanLabel => {\n const logger = {\n start(opts) {},\n end(status, opts) {},\n subSpan(label) {\n return getLogger(`${subSpanLabel ?? ''}/${label}`);\n },\n point(name, opts) {},\n annotate(annotations) {},\n };\n return logger;\n };\n\n return getLogger();\n};\n")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"resolver-options"},"Resolver Options"),(0,r.mdx)("h4",{id:"assetexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of asset file extensions to include in the bundle. For example, including ",(0,r.mdx)("inlineCode",{parentName:"p"},"'ttf'")," allows Metro bundles to reference ",(0,r.mdx)("inlineCode",{parentName:"p"},".ttf")," files. This is used primarily to enable React Native's ",(0,r.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/images"},"image asset support"),". The default list includes many common image, video and audio file extensions. See ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/defaults/defaults.js#L16"},"Metro's source code")," for the full list."),(0,r.mdx)("h4",{id:"sourceexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"sourceExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of source file extensions to include in the bundle. For example, including ",(0,r.mdx)("inlineCode",{parentName:"p"},"'ts'")," allows Metro to include ",(0,r.mdx)("inlineCode",{parentName:"p"},".ts")," files in the bundle."),(0,r.mdx)("p",null,"The order of these extensions defines the order to match files on disk. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['js', 'jsx', 'json', 'ts', 'tsx']"),"."),(0,r.mdx)("h4",{id:"resolvermainfields"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resolverMainFields")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of fields in ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," that Metro will treat as describing a package's entry points. The default is ",(0,r.mdx)("inlineCode",{parentName:"p"},"['browser', 'main']"),", so the resolver will use the ",(0,r.mdx)("inlineCode",{parentName:"p"},"browser")," field if it exists and ",(0,r.mdx)("inlineCode",{parentName:"p"},"main")," otherwise."),(0,r.mdx)("p",null,"Metro's default resolver processes each of these fields according to the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,r.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),", including the ability to ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#replace-specific-files---advanced"},"replace")," and ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module"},"ignore")," specific files. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When using React Native, ",(0,r.mdx)("inlineCode",{parentName:"p"},"resolverMainFields")," defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['react-native', 'browser', 'main']"),".")),(0,r.mdx)("h4",{id:"disablehierarchicallookup"},(0,r.mdx)("inlineCode",{parentName:"h4"},"disableHierarchicalLookup")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to disable ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders"},"looking up modules in ",(0,r.mdx)("inlineCode",{parentName:"a"},"node_modules")," folders"),". This only affects the default search through the directory tree, not other Metro options like ",(0,r.mdx)("inlineCode",{parentName:"p"},"extraNodeModules")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"nodeModulesPaths"),". Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"emptymodulepath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"emptyModulePath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,'What module to use as the canonical "empty" module when one is needed. Defaults to using the one included in ',(0,r.mdx)("inlineCode",{parentName:"p"},"metro-runtime"),". You only need to change this if Metro is installed outside of your project."),(0,r.mdx)("h4",{id:"enableglobalpackages"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableGlobalPackages")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean"),"."),(0,r.mdx)("p",null,"Whether to automatically resolve references to first-party packages (e.g. workspaces) in your project. Any ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," file with a valid ",(0,r.mdx)("inlineCode",{parentName:"p"},"name")," property within ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders")," (but outside of ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),") counts as a package for this purpose. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"extranodemodules"},(0,r.mdx)("inlineCode",{parentName:"h4"},"extraNodeModules")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[string]: string}")),(0,r.mdx)("p",null,"A mapping of package names to directories that is consulted after the standard lookup through ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules")," as well as any ",(0,r.mdx)("a",{parentName:"p",href:"#nodemodulespaths"},(0,r.mdx)("inlineCode",{parentName:"a"},"nodeModulesPaths")),". For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"nodemodulespaths"},(0,r.mdx)("inlineCode",{parentName:"h4"},"nodeModulesPaths")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A list of paths to check for modules after looking through all ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories. This is useful if third-party dependencies are installed in a different location outside of the direct path of source files. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"resolverequest"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resolveRequest")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution#resolverequest-customresolver"},(0,r.mdx)("inlineCode",{parentName:"a"},"?CustomResolver"))),(0,r.mdx)("p",null,"An optional function used to override the default resolution algorithm. This is particularly useful for cases where aliases or custom protocols are used. For example:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-javascript"},"resolveRequest: (context, moduleName, platform) => {\n if (moduleName.startsWith('my-custom-resolver:')) {\n // Logic to resolve the module name to a file path...\n // NOTE: Throw an error if there is no resolution.\n return {\n filePath: 'path/to/file',\n type: 'sourceFile',\n };\n }\n // Optionally, chain to the standard Metro resolver.\n return context.resolveRequest(context, moduleName, platform);\n}\n")),(0,r.mdx)("p",null,"For more information on customizing the resolver, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"usewatchman"},(0,r.mdx)("inlineCode",{parentName:"h4"},"useWatchman")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If set to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),", prevents Metro from using Watchman (even if it's installed)."),(0,r.mdx)("h4",{id:"blocklist"},(0,r.mdx)("inlineCode",{parentName:"h4"},"blockList")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"RegExp")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A regular expression (or list of regular expressions) defining which paths to exclude from Metro's file map. Files whose absolute paths match these patterns are effectively hidden from Metro and cannot be resolved or imported in the current project."),(0,r.mdx)("h4",{id:"hasteimplmodulepath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hasteImplModulePath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"?string")),(0,r.mdx)("p",null,"The path to the Haste implementation for the current project. Haste is an opt-in mechanism for importing modules by their globally-unique name anywhere in the project, e.g. ",(0,r.mdx)("inlineCode",{parentName:"p"},"import Foo from 'Foo'"),"."),(0,r.mdx)("p",null,"Metro expects this module to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"module.exports = {\n getHasteName(filePath: string): ?string {\n // ...\n },\n};\n")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getHasteName")," should return a short, globally unique name for the module whose path is ",(0,r.mdx)("inlineCode",{parentName:"p"},"filePath"),", or ",(0,r.mdx)("inlineCode",{parentName:"p"},"null")," if the module should not be accessible via Haste."),(0,r.mdx)("h4",{id:"platforms"},(0,r.mdx)("inlineCode",{parentName:"h4"},"platforms")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"Additional platforms to resolve. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['ios', 'android', 'windows', 'web']"),"."),(0,r.mdx)("p",null,"For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"Module Resolution")," and ",(0,r.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions"},"React Native's documentation for platform-specific extensions"),"."),(0,r.mdx)("h4",{id:"requirecycleignorepatterns"},(0,r.mdx)("inlineCode",{parentName:"h4"},"requireCycleIgnorePatterns")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"In development mode, suppress require cycle warnings for any cycle involving a module that matches any of these expressions. This is useful for third-party code and first-party expected cycles."),(0,r.mdx)("p",null,"Note that if you specify your own value for this config option it will replace (not concatenate with) Metro's default."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"[/(^|\\/|\\\\)node_modules($|\\/|\\\\)/]"),"."),(0,r.mdx)("h4",{id:"unstable_conditionnames-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_conditionNames")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This setting will take effect when ",(0,r.mdx)("a",{parentName:"p",href:"#unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_enablePackageExports"))," is ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),". It may not behave as described while this feature is experimental.")),(0,r.mdx)("p",null,"The set of ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#conditional-exports"},"condition names")," to assert globally when interpreting the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in package.json."),(0,r.mdx)("p",null,"Conditions may be any string value and are resolved in the order specified by each package. Node.js documents a number of ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#community-conditions-definitions"},"community conditions")," which are commonly used by package authors. The ",(0,r.mdx)("inlineCode",{parentName:"p"},"default")," condition is always matched."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['require']"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When using React Native, ",(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_conditionNames")," defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['require', 'react-native']"),".")),(0,r.mdx)("h4",{id:"unstable_conditionsbyplatform-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_conditionsByPlatform")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[platform: string]: Array}")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This setting will take effect when ",(0,r.mdx)("a",{parentName:"p",href:"#unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_enablePackageExports"))," is ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),". It may not behave as described while this feature is experimental.")),(0,r.mdx)("p",null,"The set of additional ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#conditional-exports"},"condition names")," to dynamically assert by platform (see ",(0,r.mdx)("a",{parentName:"p",href:"#platforms"},(0,r.mdx)("inlineCode",{parentName:"a"},"platforms")),") when interpreting the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in package.json."),(0,r.mdx)("p",null,"Matched conditions are merged with ",(0,r.mdx)("a",{parentName:"p",href:"#unstable-conditionnames"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_conditionNames"))," before resolution. With the defaults for both options, the conditions ",(0,r.mdx)("inlineCode",{parentName:"p"},"new Set(['require', 'browser'])")," will be asserted when requesting a ",(0,r.mdx)("inlineCode",{parentName:"p"},"web")," bundle, and ",(0,r.mdx)("inlineCode",{parentName:"p"},"new Set(['require'])")," otherwise. Again, these are resolved in the order specified by each package."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"\u200c{ web: ['browser'] }"),"."),(0,r.mdx)("h4",{id:"unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_enablePackageExports")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Enable experimental ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#package-entry-points"},"Package Exports")," support. Under this mode, Metro will read the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," files when present and use it to resolve package entry points."),(0,r.mdx)("p",null,"When no match is found in ",(0,r.mdx)("inlineCode",{parentName:"p"},'"exports"'),", Metro will log a warning and fall back to resolving modules without considering ",(0,r.mdx)("inlineCode",{parentName:"p"},'"exports"'),". This makes this mode largely backwards-compatible, with the following exceptions:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},"If a module is matched in ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"'),", ",(0,r.mdx)("a",{parentName:"li",href:"#sourceexts"},(0,r.mdx)("inlineCode",{parentName:"a"},"sourceExts"))," and ",(0,r.mdx)("a",{parentName:"li",href:"#platforms"},(0,r.mdx)("inlineCode",{parentName:"a"},"platforms"))," will not be considered (i.e. platform-specific extensions will not be used). This is done for compatibility with Node."),(0,r.mdx)("li",{parentName:"ul"},"If a module exists at a file path that is also listed in ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"'),", and the ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"')," entry maps to a different file, the ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"')," entry will be preferred.")),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In a future release of Metro, this option will become ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," by default.")),(0,r.mdx)("hr",null),(0,r.mdx)("h4",{id:"unstable_enablesymlinks-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_enableSymlinks")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Enable experimental support for projects containing symbolic links (symlinks)."),(0,r.mdx)("p",null,"When enabled, Metro traverses symlinks during module and asset ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolution"),", instead of ignoring symlinks. Note that, as with any other file Metro needs to resolve, the symlink target ",(0,r.mdx)("em",{parentName:"p"},"must be within configured ",(0,r.mdx)("a",{parentName:"em",href:"#watchfolders"},"watched folders"))," and not otherwise excluded."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," since Metro v0.79.0."),(0,r.mdx)("admonition",{type:"info"},(0,r.mdx)("p",{parentName:"admonition"},"For example, if you have a Metro project within a ",(0,r.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/workspaces/"},"Yarn workspace")," (a subdirectory of a Yarn workspace root), it's likely you'll want to include your workspace ",(0,r.mdx)("em",{parentName:"p"},"root")," path in your configured ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders"))," so that Metro can resolve other workspaces or hoisted ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),". Similarly, to use ",(0,r.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/cli/link/"},"linked packages"),", you'll need to list those package source locations (or a containing directory) in ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders")),".")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In a future release of Metro, this option will be removed (symlink support will be always-on).")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"transformer-options"},"Transformer Options"),(0,r.mdx)("a",{name:"asyncrequiremodulepath"}),(0,r.mdx)("h4",{id:"asyncrequiremodulepath-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"asyncRequireModulePath")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The name of a module that provides the ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequire")," function, which is used to implement ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"dynamic ",(0,r.mdx)("inlineCode",{parentName:"a"},"import()"))," at runtime. Defaults to ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-runtime/src/modules/asyncRequire.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-runtime/src/modules/asyncRequire")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"The module named by ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," is ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolved")," relative to the module containing the original ",(0,r.mdx)("inlineCode",{parentName:"p"},"import()")," call. In particular, assuming the default value of ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," is in use, the project must have a compatible version of ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-runtime")," installed in ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),".")),(0,r.mdx)("admonition",{type:"info"},(0,r.mdx)("p",{parentName:"admonition"},"In older versions of Metro, a custom ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," could be used as part of a bundle splitting solution. This usage is now deprecated in favor of the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md#__loadbundleasync-in-metro"},(0,r.mdx)("inlineCode",{parentName:"a"},"__loadBundleAsync"))," API.")),(0,r.mdx)("h4",{id:"dynamicdepsinpackages"},(0,r.mdx)("inlineCode",{parentName:"h4"},"dynamicDepsInPackages")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"'throwAtRuntime' | 'reject'")),(0,r.mdx)("p",null,"Controls how Metro handles dependencies that cannot be statically analyzed at build time. For example, ",(0,r.mdx)("inlineCode",{parentName:"p"},"require('./' + someFunction() + '.js')")," cannot be resolved without knowing what ",(0,r.mdx)("inlineCode",{parentName:"p"},"someFunction()")," will return."),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"'throwAtRuntime'"))," (the default): Metro does not stop bundling, but the ",(0,r.mdx)("inlineCode",{parentName:"li"},"require")," call will throw at runtime."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"'reject'")),": Metro will stop bundling and report an error to the user.")),(0,r.mdx)("h4",{id:"gettransformoptions"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getTransformOptions")),(0,r.mdx)("p",null,"Type: Function (see details below)"),(0,r.mdx)("p",null,"A function called by Metro to calculate additional options for the transformer and serializer based on the specific bundle being built."),(0,r.mdx)("p",null,"Metro expects ",(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"function getTransformOptions(\n entryPoints: $ReadOnlyArray,\n options: {\n dev: boolean,\n hot: boolean,\n platform: ?string,\n },\n getDependenciesOf: (path: string) => Promise>,\n): Promise {\n // ...\n}\n")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," receives these parameters:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"entryPoints")),": Absolute paths to the bundle's entry points (typically just one)."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"options")),":",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"dev")),": Whether the bundle is being built in development mode."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"hot")),": ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")," Always true."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"platform")),": The target platform (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"ios"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"android"),")."))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"getDependenciesOf")),": A function which, given an absolute path to a module, returns a promise that resolves to the absolute paths of the module's transitive dependencies.")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," should return a promise that resolves to an object with the following properties:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"type ExtraTransformOptions = {\n preloadedModules?: {[path: string]: true} | false,\n ramGroups?: Array,\n transform?: {\n inlineRequires?: {blockList: {[string]: true}} | boolean,\n nonInlinedRequires?: $ReadOnlyArray,\n },\n};\n")),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"preloadedModules")),": A plain object whose keys represent a set of absolute paths. When serializing an ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#enable-the-ram-format"},"indexed RAM bundle"),", the modules in this set will be marked for eager evaluation at runtime."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"ramGroups")),": An array of absolute paths. When serializing an ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#enable-the-ram-format"},"indexed RAM bundle"),", each of the listed modules will be serialized along with its transitive dependencies. At runtime, the modules will all be parsed together as soon as any one of them is evaluated."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"transform")),": Advanced options for the transformer.",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"inlineRequires")),":",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires")," is a boolean, it controls whether ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#inline-requires"},"inline requires")," are enabled in this bundle."),(0,r.mdx)("li",{parentName:"ul"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires")," is an object, inline requires are enabled in all modules, except ones whose absolute paths appear as keys of ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires.blockList"),"."))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"nonInlinedRequires")),": An array of unresolved module specifiers (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"react"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"react-native"),") to never inline, even when inline requires are enabled.")))),(0,r.mdx)("h4",{id:"minifierpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"minifierPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")," (default: ",(0,r.mdx)("inlineCode",{parentName:"p"},"'metro-minify-terser'"),")"),(0,r.mdx)("p",null,"Path, or package name resolvable from ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-transform-worker"),", to the minifier that minifies the code after transformation."),(0,r.mdx)("h4",{id:"minifierconfig"},(0,r.mdx)("inlineCode",{parentName:"h4"},"minifierConfig")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[key: string]: mixed}")),(0,r.mdx)("p",null,"Configuration object that will be passed to the minifier (it should be serializable)."),(0,r.mdx)("h4",{id:"optimizationsizelimit"},(0,r.mdx)("inlineCode",{parentName:"h4"},"optimizationSizeLimit")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"Define a threshold (in bytes) to disable some expensive optimizations for big files."),(0,r.mdx)("h4",{id:"react-native-only"},"React Native Only"),(0,r.mdx)("h4",{id:"assetplugins"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetPlugins")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"List of modules to call to modify Asset data"),(0,r.mdx)("h4",{id:"assetregistrypath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetRegistryPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"Where to fetch the assets from."),(0,r.mdx)("h3",{id:"babel-specific-transformer-options"},"Babel-specific transformer options"),(0,r.mdx)("h4",{id:"babeltransformerpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"babelTransformerPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The name of a module that compiles code with Babel, returning an AST and optional metadata. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-babel-transformer"),"."),(0,r.mdx)("p",null,"Refer to the source code of ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-babel-transformer/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-babel-transformer"))," and ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-react-native-babel-transformer/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-react-native-babel-transformer"))," for details on implementing a custom Babel transformer."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),". Custom transformers may ignore it.")),(0,r.mdx)("h4",{id:"enablebabelrclookup"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableBabelRCLookup")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to enable searching for Babel configuration files. This is passed to Babel as the ",(0,r.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/en/options#babelrc"},(0,r.mdx)("inlineCode",{parentName:"a"},"babelrc"))," config option. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),". Custom transformers may ignore it. Custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," should respect this option.")),(0,r.mdx)("h4",{id:"enablebabelruntime"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableBabelRuntime")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean | string")),(0,r.mdx)("p",null,"Whether the transformer should use the ",(0,r.mdx)("inlineCode",{parentName:"p"},"@babel/transform/runtime")," plugin. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("p",null,"If the value is a string, it is treated as a runtime version number and passed as ",(0,r.mdx)("inlineCode",{parentName:"p"},"version")," to the ",(0,r.mdx)("inlineCode",{parentName:"p"},"@babel/plugin-transform-runtime")," configuration. This allows you to optimize the generated Babel runtime calls based on the version installed in your project."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only works under the default settings for React Native. It may have no effect in a project that uses custom ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),", a custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"babelTransformerPath"))," or a custom ",(0,r.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/en/config-files"},"Babel config file"),".")),(0,r.mdx)("h4",{id:"hermesparser"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hermesParser")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to use the ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/hermes-parser"},(0,r.mdx)("inlineCode",{parentName:"a"},"hermes-parser"))," package to parse JavaScript source files, instead of Babel. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath"))," and the ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," built into Metro. Custom transformers and custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," may ignore it.")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"serializer-options"},"Serializer Options"),(0,r.mdx)("h4",{id:"getrunmodulestatement"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getRunModuleStatement")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(number | string) => string")),(0,r.mdx)("p",null,"Specify the format of the initial require statements that are appended at the end of the bundle. By default is ",(0,r.mdx)("inlineCode",{parentName:"p"},"__r(${moduleId});"),"."),(0,r.mdx)("h4",{id:"createmoduleidfactory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"createModuleIdFactory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"() => (path: string) => number")),(0,r.mdx)("p",null,"Used to generate the module id for ",(0,r.mdx)("inlineCode",{parentName:"p"},"require")," statements."),(0,r.mdx)("h4",{id:"getpolyfills"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getPolyfills")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"({platform: ?string}) => $ReadOnlyArray")),(0,r.mdx)("p",null,"An optional list of polyfills to include in the bundle. The list defaults to a set of common polyfills for Number, String, Array, Object..."),(0,r.mdx)("h4",{id:"getmodulesrunbeforemainmodule"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getModulesRunBeforeMainModule")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(entryFilePath: string) => Array")),(0,r.mdx)("p",null,"An array of modules to be required before the entry point. It should contain the absolute path of each module. Note that this will add the additional require statements only if the passed modules are already included as part of the bundle."),(0,r.mdx)("h4",{id:"processmodulefilter"},(0,r.mdx)("inlineCode",{parentName:"h4"},"processModuleFilter")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(module: Array) => boolean")),(0,r.mdx)("p",null,"A filter function to discard specific modules from the output."),(0,r.mdx)("h4",{id:"isthirdpartymodule"},(0,r.mdx)("inlineCode",{parentName:"h4"},"isThirdPartyModule")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(module: {path: string, ...}) => boolean")),(0,r.mdx)("p",null,"A function that determines which modules are added to the ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/articles/x-google-ignore-list/"},(0,r.mdx)("inlineCode",{parentName:"a"},"x_google_ignoreList"))," field of the source map. This supports ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/blog/devtools-modern-web-debugging/#just-my-code"},'"Just My Code"')," debugging in Chrome DevTools and other compatible debuggers."),(0,r.mdx)("p",null,"Defaults to returning ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," for modules with a path component named ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In addition to modules marked as ignored by ",(0,r.mdx)("inlineCode",{parentName:"p"},"isThirdPartyModule"),", Metro will also automatically add modules generated by the bundler itself to the ignore list.")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"server-options"},"Server Options"),(0,r.mdx)("p",null,"These options are used when Metro serves the content."),(0,r.mdx)("h4",{id:"port"},(0,r.mdx)("inlineCode",{parentName:"h4"},"port")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"Which port to listen on."),(0,r.mdx)("h4",{id:"useglobalhotkey"},(0,r.mdx)("inlineCode",{parentName:"h4"},"useGlobalHotkey")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether we should enable CMD+R hotkey for refreshing the bundle."),(0,r.mdx)("h4",{id:"enhancemiddleware-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enhanceMiddleware")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(Middleware, MetroServer) => Middleware")),(0,r.mdx)("p",null,"A function that allows attaching custom ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/connect"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect"))," middleware to Metro. For example:"),(0,r.mdx)("admonition",{type:"tip"},(0,r.mdx)("p",{parentName:"admonition"},"You can use ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/connect#mount-middleware"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect()"))," as a utility to extend the base ",(0,r.mdx)("inlineCode",{parentName:"p"},"metroMiddleware")," and to mount additional middleware handlers.")),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-ts"},"enhanceMiddleware: (metroMiddleware: Middleware, metroServer: MetroServer) => {\n return connect()\n .use(metroMiddleware)\n .use('/custom-endpoint', customEndpointMiddleware());\n},\n")),(0,r.mdx)("p",null,"The ",(0,r.mdx)("inlineCode",{parentName:"p"},"Middleware")," type is an alias for ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/DefinitelyTyped/DefinitelyTyped/blob/876b9ec96ba02d0c84b1e49af5890c8f5aa2dfe3/types/connect/index.d.ts#L29"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect.HandleFunction")),"."),(0,r.mdx)("h4",{id:"rewriterequesturl"},(0,r.mdx)("inlineCode",{parentName:"h4"},"rewriteRequestUrl")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string => string")),(0,r.mdx)("p",null,"A function that will be called every time Metro processes a URL, after normalization of non-standard query-string delimiters using ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/jsc-safe-url"},(0,r.mdx)("inlineCode",{parentName:"a"},"jsc-safe-url")),". Metro will use the return value of this function as if it were the original URL provided by the client. This applies to all incoming HTTP requests (after any custom middleware), as well as bundle URLs in ",(0,r.mdx)("inlineCode",{parentName:"p"},"/symbolicate")," request payloads and within the hot reloading protocol."),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"watcher-options"},"Watcher Options"),(0,r.mdx)("p",null,"Options for the filesystem watcher."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Dot notation in this section indicates a nested configuration object, e.g. ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchman.deferStates")," \u2192 ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchman: { deferStates: ... }"),".")),(0,r.mdx)("h4",{id:"additionalexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"additionalExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The extensions which Metro should watch in addition to ",(0,r.mdx)("inlineCode",{parentName:"p"},"sourceExts"),", but which will not be automatically tried by the resolver."),(0,r.mdx)("p",null,"Therefore, the two behavior differences from ",(0,r.mdx)("inlineCode",{parentName:"p"},"resolver.sourceExts")," when importing a module are:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},"Modules can only be required when fully specified (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"import moduleA from 'moduleA.mjs'"),")."),(0,r.mdx)("li",{parentName:"ul"},"No platform-specific resolution is performed.")),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['cjs', 'mjs']"),"."),(0,r.mdx)("h4",{id:"healthcheckenabled"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.enabled")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to periodically check the health of the filesystem watcher by writing a temporary file to the project and waiting for it to be observed."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"healthcheckfileprefix"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.filePrefix")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls the name of the temporary file that will be written into the project filesystem."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"'.metro-health-check'"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"There's no need to commit health check files to source control. If you choose to enable health checks in your project, make sure you add ",(0,r.mdx)("inlineCode",{parentName:"p"},".metro-health-check*")," to your ",(0,r.mdx)("inlineCode",{parentName:"p"},".gitignore")," file to avoid generating unnecessary changes.")),(0,r.mdx)("h4",{id:"healthcheckinterval"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.interval")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls how often they occur (in milliseconds)."),(0,r.mdx)("p",null,"The default value is 30000."),(0,r.mdx)("h4",{id:"healthchecktimeout"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.timeout")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls the time (in milliseconds) Metro will wait for a file change to be observed before considering the check to have failed."),(0,r.mdx)("p",null,"The default value is 5000."),(0,r.mdx)("h4",{id:"watchmandeferstates"},(0,r.mdx)("inlineCode",{parentName:"h4"},"watchman.deferStates")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"Applies when using Watchman. Metro will ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/watchman/docs/cmd/subscribe.html#defer"},"defer processing filesystem updates")," while these ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/watchman/docs/cmd/state-enter.html"},"states")," are asserted in the watch. This is useful for debouncing builds while the filesystem hasn't settled, e.g. during large source control operations."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"['hg.update']"),"."),(0,r.mdx)("h2",{id:"merging-configurations"},"Merging Configurations"),(0,r.mdx)("p",null,"Using the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-config")," package it is possible to merge multiple configurations together."),(0,r.mdx)("table",null,(0,r.mdx)("thead",{parentName:"table"},(0,r.mdx)("tr",{parentName:"thead"},(0,r.mdx)("th",{parentName:"tr",align:null},"Method"),(0,r.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,r.mdx)("tbody",{parentName:"table"},(0,r.mdx)("tr",{parentName:"tbody"},(0,r.mdx)("td",{parentName:"tr",align:null},(0,r.mdx)("inlineCode",{parentName:"td"},"mergeConfig(...configs): MergedConfig")),(0,r.mdx)("td",{parentName:"tr",align:null},"Returns the merged configuration of two or more configuration objects.")))),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Arrays and function based config parameters do not deeply merge and will instead override any pre-existing config parameters.\nThis allows overriding and removing default config parameters such as ",(0,r.mdx)("inlineCode",{parentName:"p"},"platforms")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"getModulesRunBeforeMainModule")," that may not be required in your environment.")),(0,r.mdx)("h4",{id:"merging-example"},"Merging Example"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-js"},"// metro.config.js\nconst { mergeConfig } = require('metro-config');\n\nconst configA = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n }\n};\n\nconst configB = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n }\n};\n\nmodule.exports = mergeConfig(configA, configB);\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[122],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>m,MDXProvider:()=>c,mdx:()=>f,useMDXComponents:()=>p,withMDXComponents:()=>s});var a=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(){return r=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var m=a.createContext({}),s=function(e){return function(n){var t=p(n.components);return a.createElement(e,r({},n,{components:t}))}},p=function(e){var n=a.useContext(m),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(m.Provider,{value:n},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},x=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,r=e.originalType,i=e.parentName,m=d(e,["components","mdxType","originalType","parentName"]),s=p(t),c=o,u=s["".concat(i,".").concat(c)]||s[c]||h[c]||r;return t?a.createElement(u,l(l({ref:n},m),{},{components:t})):a.createElement(u,l({ref:n},m))}));function f(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var r=t.length,i=new Array(r);i[0]=x;var l={};for(var d in n)hasOwnProperty.call(n,d)&&(l[d]=n[d]);l.originalType=e,l[u]="string"==typeof e?e:o,i[1]=l;for(var m=2;m{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>m,toc:()=>p});var a=t(83117),o=t(80102),r=(t(67294),t(3905)),i=["components"],l={id:"configuration",title:"Configuring Metro"},d=void 0,m={unversionedId:"configuration",id:"configuration",title:"Configuring Metro",description:"A Metro config can be created in these three ways (ordered by priority):",source:"@site/../docs/Configuration.md",sourceDirName:".",slug:"/configuration",permalink:"/docs/configuration",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Configuration.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"configuration",title:"Configuring Metro"},sidebar:"docs",previous:{title:"Module API",permalink:"/docs/module-api"},next:{title:"Metro CLI Options",permalink:"/docs/cli"}},s={},p=[{value:"Configuration Structure",id:"configuration-structure",level:2},{value:"General Options",id:"general-options",level:3},{value:"cacheStores",id:"cachestores",level:4},{value:"cacheVersion",id:"cacheversion",level:4},{value:"projectRoot",id:"projectroot",level:4},{value:"watchFolders",id:"watchfolders",level:4},{value:"transformerPath",id:"transformerpath",level:4},{value:"reporter",id:"reporter",level:4},{value:"resetCache",id:"resetcache",level:4},{value:"stickyWorkers",id:"stickyworkers",level:4},{value:"maxWorkers",id:"maxworkers",level:4},{value:"fileMapCacheDirectory",id:"filemapcachedirectory",level:4},{value:'hasteMapCacheDirectory
Deprecated
',id:"hastemapcachedirectory-deprecated",level:4},{value:"unstable_perfLoggerFactory",id:"unstable_perfloggerfactory",level:4},{value:"Resolver Options",id:"resolver-options",level:3},{value:"assetExts",id:"assetexts",level:4},{value:"sourceExts",id:"sourceexts",level:4},{value:"resolverMainFields",id:"resolvermainfields",level:4},{value:"disableHierarchicalLookup",id:"disablehierarchicallookup",level:4},{value:"emptyModulePath",id:"emptymodulepath",level:4},{value:"enableGlobalPackages",id:"enableglobalpackages",level:4},{value:"extraNodeModules",id:"extranodemodules",level:4},{value:"nodeModulesPaths",id:"nodemodulespaths",level:4},{value:"resolveRequest",id:"resolverequest",level:4},{value:"useWatchman",id:"usewatchman",level:4},{value:"blockList",id:"blocklist",level:4},{value:"hasteImplModulePath",id:"hasteimplmodulepath",level:4},{value:"platforms",id:"platforms",level:4},{value:"requireCycleIgnorePatterns",id:"requirecycleignorepatterns",level:4},{value:'unstable_conditionNames
Experimental
',id:"unstable_conditionnames-experimental",level:4},{value:'unstable_conditionsByPlatform
Experimental
',id:"unstable_conditionsbyplatform-experimental",level:4},{value:'unstable_enablePackageExports
Experimental
',id:"unstable_enablepackageexports-experimental",level:4},{value:'unstable_enableSymlinks
Experimental
',id:"unstable_enablesymlinks-experimental",level:4},{value:"Transformer Options",id:"transformer-options",level:3},{value:'asyncRequireModulePath
Deprecated
',id:"asyncrequiremodulepath-deprecated",level:4},{value:"dynamicDepsInPackages",id:"dynamicdepsinpackages",level:4},{value:"getTransformOptions",id:"gettransformoptions",level:4},{value:"minifierPath",id:"minifierpath",level:4},{value:"minifierConfig",id:"minifierconfig",level:4},{value:"optimizationSizeLimit",id:"optimizationsizelimit",level:4},{value:"React Native Only",id:"react-native-only",level:4},{value:"assetPlugins",id:"assetplugins",level:4},{value:"assetRegistryPath",id:"assetregistrypath",level:4},{value:"Babel-specific transformer options",id:"babel-specific-transformer-options",level:3},{value:"babelTransformerPath",id:"babeltransformerpath",level:4},{value:"enableBabelRCLookup",id:"enablebabelrclookup",level:4},{value:"enableBabelRuntime",id:"enablebabelruntime",level:4},{value:"hermesParser",id:"hermesparser",level:4},{value:"Serializer Options",id:"serializer-options",level:3},{value:"getRunModuleStatement",id:"getrunmodulestatement",level:4},{value:"createModuleIdFactory",id:"createmoduleidfactory",level:4},{value:"getPolyfills",id:"getpolyfills",level:4},{value:"getModulesRunBeforeMainModule",id:"getmodulesrunbeforemainmodule",level:4},{value:"processModuleFilter",id:"processmodulefilter",level:4},{value:"isThirdPartyModule",id:"isthirdpartymodule",level:4},{value:"Server Options",id:"server-options",level:3},{value:"port",id:"port",level:4},{value:"useGlobalHotkey",id:"useglobalhotkey",level:4},{value:'enhanceMiddleware
Deprecated
',id:"enhancemiddleware-deprecated",level:4},{value:"rewriteRequestUrl",id:"rewriterequesturl",level:4},{value:"Watcher Options",id:"watcher-options",level:3},{value:"additionalExts",id:"additionalexts",level:4},{value:"healthCheck.enabled",id:"healthcheckenabled",level:4},{value:"healthCheck.filePrefix",id:"healthcheckfileprefix",level:4},{value:"healthCheck.interval",id:"healthcheckinterval",level:4},{value:"healthCheck.timeout",id:"healthchecktimeout",level:4},{value:"watchman.deferStates",id:"watchmandeferstates",level:4},{value:"Merging Configurations",id:"merging-configurations",level:2},{value:"Merging Example",id:"merging-example",level:4}],c={toc:p},u="wrapper";function h(e){var n=e.components,t=(0,o.Z)(e,i);return(0,r.mdx)(u,(0,a.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,r.mdx)("p",null,"A Metro config can be created in these three ways (ordered by priority):"),(0,r.mdx)("ol",null,(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("inlineCode",{parentName:"li"},"metro.config.js")),(0,r.mdx)("li",{parentName:"ol"},(0,r.mdx)("inlineCode",{parentName:"li"},"metro.config.json")),(0,r.mdx)("li",{parentName:"ol"},"The ",(0,r.mdx)("inlineCode",{parentName:"li"},"metro")," field in ",(0,r.mdx)("inlineCode",{parentName:"li"},"package.json"))),(0,r.mdx)("p",null,"You can also give a custom file to the configuration by specifying ",(0,r.mdx)("inlineCode",{parentName:"p"},"--config ")," when calling the CLI."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When Metro is started via the React Native CLI, some defaults are different from those mentioned below.\nSee the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/react-native/blob/main/packages/community-cli-plugin/src/utils/loadMetroConfig.js"},"React Native repository")," for details.")),(0,r.mdx)("h2",{id:"configuration-structure"},"Configuration Structure"),(0,r.mdx)("p",null,"The configuration is based on ",(0,r.mdx)("a",{parentName:"p",href:"/docs/concepts"},"our concepts"),", which means that for every module we have a separate config option. A common configuration structure in Metro looks like this:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-js"},"module.exports = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n },\n watcher: {\n /* watcher options */\n watchman: {\n /* Watchman-specific options */\n }\n }\n};\n")),(0,r.mdx)("h3",{id:"general-options"},"General Options"),(0,r.mdx)("h4",{id:"cachestores"},(0,r.mdx)("inlineCode",{parentName:"h4"},"cacheStores")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"CacheStores")," (see details below)"),(0,r.mdx)("p",null,"A list of storage adapters for Metro's ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching"},"transformer cache"),". This can be any combination of ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching#built-in-cache-stores"},"built-in cache stores")," and ",(0,r.mdx)("a",{parentName:"p",href:"/docs/caching#custom-cache-stores"},"custom cache stores"),". Defaults to using a temporary directory on disk as the only cache store."),(0,r.mdx)("p",null,"When Metro needs to transform a module, it first computes a machine-independent cache key for that file, and uses it to try to read from each of the stores in order. Once Metro has obtained the output of the transformer (whether already cached or not), it writes the transform result to ",(0,r.mdx)("em",{parentName:"p"},"all")," of the stores that returned ",(0,r.mdx)("inlineCode",{parentName:"p"},"null")," (a cache miss) for that key."),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"type CacheStores =\n | Array>\n | ((MetroCache) => Array<\n CacheStore\n >);\n\n// The exports of 'metro-cache'\ntype MetroCache = {\n FileStore,\n AutoCleanFileStore,\n HttpStore,\n HttpGetStore,\n ...\n};\n\ntype JsonSerializable = /* Any JSON-serializable value */;\n")),(0,r.mdx)("h4",{id:"cacheversion"},(0,r.mdx)("inlineCode",{parentName:"h4"},"cacheVersion")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"An arbitrary string appended to all cache keys in the project before they are hashed. There is generally no need to set this explicitly, as Metro will automatically derive the correct cache keys from your project config and the contents of source files."),(0,r.mdx)("h4",{id:"projectroot"},(0,r.mdx)("inlineCode",{parentName:"h4"},"projectRoot")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The root folder of your project. If your project depends on any files outside this root, their containing directories must be listed in ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"If your Metro project is developed in a monorepo and includes files from multiple logical packages, you'll generally want to set ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot")," to the root of your repository, or at least high enough in the hierarchy that all relevant files are reachable without separately configuring ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders"),".")),(0,r.mdx)("h4",{id:"watchfolders"},(0,r.mdx)("inlineCode",{parentName:"h4"},"watchFolders")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A list of directories outside of ",(0,r.mdx)("a",{parentName:"p",href:"#projectroot"},(0,r.mdx)("inlineCode",{parentName:"a"},"projectRoot"))," that can contain source files for the project."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Despite the naming of this option, it isn't related solely to file watching. Even in an offline build (for example, in CI), all files must be visible to Metro through the combination of ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders")," and ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot"),".")),(0,r.mdx)("h4",{id:"transformerpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"transformerPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The absolute path of a module (or a package name resolvable from the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro")," package) that implements a transformer."),(0,r.mdx)("p",null,"See the implementation of Metro's default transformer (",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-transform-worker/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-transform-worker")),") for more information about the transformer interface."),(0,r.mdx)("h4",{id:"reporter"},(0,r.mdx)("inlineCode",{parentName:"h4"},"reporter")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{update: (event: ReportableEvent) => void}")),(0,r.mdx)("p",null,"Used to report the status of the bundler during the bundling process. The default implementation prints most events to the terminal."),(0,r.mdx)("p",null,"See also the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro/src/lib/reporting.js"},"definition of ",(0,r.mdx)("inlineCode",{parentName:"a"},"ReportableEvent"))," in Metro's source code."),(0,r.mdx)("h4",{id:"resetcache"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resetCache")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),", Metro will reset the transformer cache (see ",(0,r.mdx)("a",{parentName:"p",href:"#cachestores"},(0,r.mdx)("inlineCode",{parentName:"a"},"cacheStores")),") and the file map cache (see ",(0,r.mdx)("a",{parentName:"p",href:"#filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"a"},"fileMapCacheDirectory")),") on startup."),(0,r.mdx)("h4",{id:"stickyworkers"},(0,r.mdx)("inlineCode",{parentName:"h4"},"stickyWorkers")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),", Metro will use a stable mapping from files to transformer workers, so the same file is always transformed by the same worker. This can improve initial build performance if the transformer is expensive to initialize, but can slow down concurrent builds with different configurations (e.g. multiple React Native apps connected to one Metro server). Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("h4",{id:"maxworkers"},(0,r.mdx)("inlineCode",{parentName:"h4"},"maxWorkers")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"The number of workers to use for parallel processing in Metro. Defaults to approximately half of the number of cores available on the machine, as reported by ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/os.html#oscpus"},(0,r.mdx)("inlineCode",{parentName:"a"},"os.cpus()")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("ol",{parentName:"admonition"},(0,r.mdx)("li",{parentName:"ol"},"Values exceeding the number of available cores have no effect."),(0,r.mdx)("li",{parentName:"ol"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"maxWorkers")," is set to 1 or lower, worker code will run in the main Metro process instead of concurrently."),(0,r.mdx)("li",{parentName:"ol"},"Metro has two separate worker pools - one for transformation and one for building the file map. Each pool has its worker count set to ",(0,r.mdx)("inlineCode",{parentName:"li"},"maxWorkers")," independently."))),(0,r.mdx)("h4",{id:"filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"fileMapCacheDirectory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The path to the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-file-map")," cache directory, defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"os.tmpdir()"),"."),(0,r.mdx)("h4",{id:"hastemapcachedirectory-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hasteMapCacheDirectory")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"Alias of ",(0,r.mdx)("a",{parentName:"p",href:"#filemapcachedirectory"},(0,r.mdx)("inlineCode",{parentName:"a"},"fileMapCacheDirectory"))),(0,r.mdx)("h4",{id:"unstable_perfloggerfactory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_perfLoggerFactory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"PerfLoggerFactory")),(0,r.mdx)("p",null,"A logger factory function that can be used to get insights about Metro performance timings and metadata for events including startup, bundling and HMR. Metro expects ",(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_perfLoggerFactory")," to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"function unstable_perfLoggerFactory(\n type: string,\n opts: $ReadOnly<{\n key?: string\n }>,\n): RootPerfLogger {\n // ...\n};\n")),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"type"))," Type of event being logged, e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"'STARTUP'"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"'BUNDLING_REQUEST'"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"'HMR'"),". See type definition of ",(0,r.mdx)("a",{parentName:"li",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/configTypes.flow.js"},"PerfLoggerFactory")," for a full list of event types."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"opts")),(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"key")),": An opaque identifier to distinguish between instances of an event type (e.g. multiple, possibly concurrent, HMR requests).")))),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_perfLoggerFactory")," should return an object implementing the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/configTypes.flow.js"},"RootPerfLogger")," interface. For example, a factory function returning a no-op RootPerfLogger could be implemented as follows:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-javascript"},"const unstable_perfLoggerFactory = (type, factoryOpts) => {\n const getLogger = subSpanLabel => {\n const logger = {\n start(opts) {},\n end(status, opts) {},\n subSpan(label) {\n return getLogger(`${subSpanLabel ?? ''}/${label}`);\n },\n point(name, opts) {},\n annotate(annotations) {},\n };\n return logger;\n };\n\n return getLogger();\n};\n")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"resolver-options"},"Resolver Options"),(0,r.mdx)("h4",{id:"assetexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of asset file extensions to include in the bundle. For example, including ",(0,r.mdx)("inlineCode",{parentName:"p"},"'ttf'")," allows Metro bundles to reference ",(0,r.mdx)("inlineCode",{parentName:"p"},".ttf")," files. This is used primarily to enable React Native's ",(0,r.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/images"},"image asset support"),". The default list includes many common image, video and audio file extensions. See ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-config/src/defaults/defaults.js#L16"},"Metro's source code")," for the full list."),(0,r.mdx)("h4",{id:"sourceexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"sourceExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of source file extensions to include in the bundle. For example, including ",(0,r.mdx)("inlineCode",{parentName:"p"},"'ts'")," allows Metro to include ",(0,r.mdx)("inlineCode",{parentName:"p"},".ts")," files in the bundle."),(0,r.mdx)("p",null,"The order of these extensions defines the order to match files on disk. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['js', 'jsx', 'json', 'ts', 'tsx']"),"."),(0,r.mdx)("h4",{id:"resolvermainfields"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resolverMainFields")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The list of fields in ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," that Metro will treat as describing a package's entry points. The default is ",(0,r.mdx)("inlineCode",{parentName:"p"},"['browser', 'main']"),", so the resolver will use the ",(0,r.mdx)("inlineCode",{parentName:"p"},"browser")," field if it exists and ",(0,r.mdx)("inlineCode",{parentName:"p"},"main")," otherwise."),(0,r.mdx)("p",null,"Metro's default resolver processes each of these fields according to the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec"},(0,r.mdx)("inlineCode",{parentName:"a"},"browser")," field spec"),", including the ability to ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#replace-specific-files---advanced"},"replace")," and ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module"},"ignore")," specific files. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When using React Native, ",(0,r.mdx)("inlineCode",{parentName:"p"},"resolverMainFields")," defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['react-native', 'browser', 'main']"),".")),(0,r.mdx)("h4",{id:"disablehierarchicallookup"},(0,r.mdx)("inlineCode",{parentName:"h4"},"disableHierarchicalLookup")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to disable ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders"},"looking up modules in ",(0,r.mdx)("inlineCode",{parentName:"a"},"node_modules")," folders"),". This only affects the default search through the directory tree, not other Metro options like ",(0,r.mdx)("inlineCode",{parentName:"p"},"extraNodeModules")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"nodeModulesPaths"),". Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"emptymodulepath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"emptyModulePath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,'What module to use as the canonical "empty" module when one is needed. Defaults to using the one included in ',(0,r.mdx)("inlineCode",{parentName:"p"},"metro-runtime"),". You only need to change this if Metro is installed outside of your project."),(0,r.mdx)("h4",{id:"enableglobalpackages"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableGlobalPackages")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean"),"."),(0,r.mdx)("p",null,"Whether to automatically resolve references to first-party packages (e.g. workspaces) in your project. Any ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," file with a valid ",(0,r.mdx)("inlineCode",{parentName:"p"},"name")," property within ",(0,r.mdx)("inlineCode",{parentName:"p"},"projectRoot")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchFolders")," (but outside of ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),") counts as a package for this purpose. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"extranodemodules"},(0,r.mdx)("inlineCode",{parentName:"h4"},"extraNodeModules")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[string]: string}")),(0,r.mdx)("p",null,"A mapping of package names to directories that is consulted after the standard lookup through ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules")," as well as any ",(0,r.mdx)("a",{parentName:"p",href:"#nodemodulespaths"},(0,r.mdx)("inlineCode",{parentName:"a"},"nodeModulesPaths")),". For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"nodemodulespaths"},(0,r.mdx)("inlineCode",{parentName:"h4"},"nodeModulesPaths")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A list of paths to check for modules after looking through all ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules")," directories. This is useful if third-party dependencies are installed in a different location outside of the direct path of source files. For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"resolverequest"},(0,r.mdx)("inlineCode",{parentName:"h4"},"resolveRequest")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution#resolverequest-customresolver"},(0,r.mdx)("inlineCode",{parentName:"a"},"?CustomResolver"))),(0,r.mdx)("p",null,"An optional function used to override the default resolution algorithm. This is particularly useful for cases where aliases or custom protocols are used. For example:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-javascript"},"resolveRequest: (context, moduleName, platform) => {\n if (moduleName.startsWith('my-custom-resolver:')) {\n // Logic to resolve the module name to a file path...\n // NOTE: Throw an error if there is no resolution.\n return {\n filePath: 'path/to/file',\n type: 'sourceFile',\n };\n }\n // Optionally, chain to the standard Metro resolver.\n return context.resolveRequest(context, moduleName, platform);\n}\n")),(0,r.mdx)("p",null,"For more information on customizing the resolver, see ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/metro/docs/resolution"},"Module Resolution"),"."),(0,r.mdx)("h4",{id:"usewatchman"},(0,r.mdx)("inlineCode",{parentName:"h4"},"useWatchman")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"If set to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),", prevents Metro from using Watchman (even if it's installed)."),(0,r.mdx)("h4",{id:"blocklist"},(0,r.mdx)("inlineCode",{parentName:"h4"},"blockList")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"RegExp")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"A regular expression (or list of regular expressions) defining which paths to exclude from Metro's file map. Files whose absolute paths match these patterns are effectively hidden from Metro and cannot be resolved or imported in the current project."),(0,r.mdx)("h4",{id:"hasteimplmodulepath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hasteImplModulePath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"?string")),(0,r.mdx)("p",null,"The path to the Haste implementation for the current project. Haste is an opt-in mechanism for importing modules by their globally-unique name anywhere in the project, e.g. ",(0,r.mdx)("inlineCode",{parentName:"p"},"import Foo from 'Foo'"),"."),(0,r.mdx)("p",null,"Metro expects this module to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"module.exports = {\n getHasteName(filePath: string): ?string {\n // ...\n },\n};\n")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getHasteName")," should return a short, globally unique name for the module whose path is ",(0,r.mdx)("inlineCode",{parentName:"p"},"filePath"),", or ",(0,r.mdx)("inlineCode",{parentName:"p"},"null")," if the module should not be accessible via Haste."),(0,r.mdx)("h4",{id:"platforms"},(0,r.mdx)("inlineCode",{parentName:"h4"},"platforms")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"Additional platforms to resolve. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['ios', 'android', 'windows', 'web']"),"."),(0,r.mdx)("p",null,"For more information, see ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"Module Resolution")," and ",(0,r.mdx)("a",{parentName:"p",href:"https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions"},"React Native's documentation for platform-specific extensions"),"."),(0,r.mdx)("h4",{id:"requirecycleignorepatterns"},(0,r.mdx)("inlineCode",{parentName:"h4"},"requireCycleIgnorePatterns")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"In development mode, suppress require cycle warnings for any cycle involving a module that matches any of these expressions. This is useful for third-party code and first-party expected cycles."),(0,r.mdx)("p",null,"Note that if you specify your own value for this config option it will replace (not concatenate with) Metro's default."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"[/(^|\\/|\\\\)node_modules($|\\/|\\\\)/]"),"."),(0,r.mdx)("h4",{id:"unstable_conditionnames-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_conditionNames")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This setting will take effect when ",(0,r.mdx)("a",{parentName:"p",href:"#unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_enablePackageExports"))," is ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),". It may not behave as described while this feature is experimental.")),(0,r.mdx)("p",null,"The set of ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#conditional-exports"},"condition names")," to assert globally when interpreting the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in package.json."),(0,r.mdx)("p",null,"Conditions may be any string value and are resolved in the order specified by each package. Node.js documents a number of ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#community-conditions-definitions"},"community conditions")," which are commonly used by package authors. The ",(0,r.mdx)("inlineCode",{parentName:"p"},"default")," condition is always matched."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['require']"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"When using React Native, ",(0,r.mdx)("inlineCode",{parentName:"p"},"unstable_conditionNames")," defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['require', 'react-native']"),".")),(0,r.mdx)("h4",{id:"unstable_conditionsbyplatform-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_conditionsByPlatform")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[platform: string]: Array}")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This setting will take effect when ",(0,r.mdx)("a",{parentName:"p",href:"#unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_enablePackageExports"))," is ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),". It may not behave as described while this feature is experimental.")),(0,r.mdx)("p",null,"The set of additional ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#conditional-exports"},"condition names")," to dynamically assert by platform (see ",(0,r.mdx)("a",{parentName:"p",href:"#platforms"},(0,r.mdx)("inlineCode",{parentName:"a"},"platforms")),") when interpreting the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in package.json."),(0,r.mdx)("p",null,"Matched conditions are merged with ",(0,r.mdx)("a",{parentName:"p",href:"#unstable-conditionnames"},(0,r.mdx)("inlineCode",{parentName:"a"},"unstable_conditionNames"))," before resolution. With the defaults for both options, the conditions ",(0,r.mdx)("inlineCode",{parentName:"p"},"new Set(['require', 'browser'])")," will be asserted when requesting a ",(0,r.mdx)("inlineCode",{parentName:"p"},"web")," bundle, and ",(0,r.mdx)("inlineCode",{parentName:"p"},"new Set(['require'])")," otherwise. Again, these are resolved in the order specified by each package."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"\u200c{ web: ['browser'] }"),"."),(0,r.mdx)("h4",{id:"unstable_enablepackageexports-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_enablePackageExports")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Enable experimental ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#package-entry-points"},"Package Exports")," support. Under this mode, Metro will read the ",(0,r.mdx)("a",{parentName:"p",href:"https://nodejs.org/docs/latest-v18.x/api/packages.html#exports"},(0,r.mdx)("inlineCode",{parentName:"a"},'"exports"')," field")," in ",(0,r.mdx)("inlineCode",{parentName:"p"},"package.json")," files when present and use it to resolve package entry points."),(0,r.mdx)("p",null,"When no match is found in ",(0,r.mdx)("inlineCode",{parentName:"p"},'"exports"'),", Metro will log a warning and fall back to resolving modules without considering ",(0,r.mdx)("inlineCode",{parentName:"p"},'"exports"'),". This makes this mode largely backwards-compatible, with the following exceptions:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},"If a module is matched in ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"'),", ",(0,r.mdx)("a",{parentName:"li",href:"#sourceexts"},(0,r.mdx)("inlineCode",{parentName:"a"},"sourceExts"))," and ",(0,r.mdx)("a",{parentName:"li",href:"#platforms"},(0,r.mdx)("inlineCode",{parentName:"a"},"platforms"))," will not be considered (i.e. platform-specific extensions will not be used). This is done for compatibility with Node."),(0,r.mdx)("li",{parentName:"ul"},"If a module exists at a file path that is also listed in ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"'),", and the ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"')," entry maps to a different file, the ",(0,r.mdx)("inlineCode",{parentName:"li"},'"exports"')," entry will be preferred.")),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In a future release of Metro, this option will become ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," by default.")),(0,r.mdx)("hr",null),(0,r.mdx)("h4",{id:"unstable_enablesymlinks-experimental"},(0,r.mdx)("inlineCode",{parentName:"h4"},"unstable_enableSymlinks")," ",(0,r.mdx)("div",{class:"label experimental"},"Experimental")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Enable experimental support for projects containing symbolic links (symlinks)."),(0,r.mdx)("p",null,"When enabled, Metro traverses symlinks during module and asset ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolution"),", instead of ignoring symlinks. Note that, as with any other file Metro needs to resolve, the symlink target ",(0,r.mdx)("em",{parentName:"p"},"must be within configured ",(0,r.mdx)("a",{parentName:"em",href:"#watchfolders"},"watched folders"))," and not otherwise excluded."),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," since Metro v0.79.0."),(0,r.mdx)("admonition",{type:"info"},(0,r.mdx)("p",{parentName:"admonition"},"For example, if you have a Metro project within a ",(0,r.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/workspaces/"},"Yarn workspace")," (a subdirectory of a Yarn workspace root), it's likely you'll want to include your workspace ",(0,r.mdx)("em",{parentName:"p"},"root")," path in your configured ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders"))," so that Metro can resolve other workspaces or hoisted ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),". Similarly, to use ",(0,r.mdx)("a",{parentName:"p",href:"https://classic.yarnpkg.com/lang/en/docs/cli/link/"},"linked packages"),", you'll need to list those package source locations (or a containing directory) in ",(0,r.mdx)("a",{parentName:"p",href:"#watchfolders"},(0,r.mdx)("inlineCode",{parentName:"a"},"watchFolders")),".")),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In a future release of Metro, this option will be removed (symlink support will be always-on).")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"transformer-options"},"Transformer Options"),(0,r.mdx)("a",{name:"asyncrequiremodulepath"}),(0,r.mdx)("h4",{id:"asyncrequiremodulepath-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"asyncRequireModulePath")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The name of a module that provides the ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequire")," function, which is used to implement ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},"dynamic ",(0,r.mdx)("inlineCode",{parentName:"a"},"import()"))," at runtime. Defaults to ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-runtime/src/modules/asyncRequire.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-runtime/src/modules/asyncRequire")),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"The module named by ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," is ",(0,r.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolved")," relative to the module containing the original ",(0,r.mdx)("inlineCode",{parentName:"p"},"import()")," call. In particular, assuming the default value of ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," is in use, the project must have a compatible version of ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-runtime")," installed in ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),".")),(0,r.mdx)("admonition",{type:"info"},(0,r.mdx)("p",{parentName:"admonition"},"In older versions of Metro, a custom ",(0,r.mdx)("inlineCode",{parentName:"p"},"asyncRequireModulePath")," could be used as part of a bundle splitting solution. This usage is now deprecated in favor of the ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md#__loadbundleasync-in-metro"},(0,r.mdx)("inlineCode",{parentName:"a"},"__loadBundleAsync"))," API.")),(0,r.mdx)("h4",{id:"dynamicdepsinpackages"},(0,r.mdx)("inlineCode",{parentName:"h4"},"dynamicDepsInPackages")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"'throwAtRuntime' | 'reject'")),(0,r.mdx)("p",null,"Controls how Metro handles dependencies that cannot be statically analyzed at build time. For example, ",(0,r.mdx)("inlineCode",{parentName:"p"},"require('./' + someFunction() + '.js')")," cannot be resolved without knowing what ",(0,r.mdx)("inlineCode",{parentName:"p"},"someFunction()")," will return."),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"'throwAtRuntime'"))," (the default): Metro does not stop bundling, but the ",(0,r.mdx)("inlineCode",{parentName:"li"},"require")," call will throw at runtime."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"'reject'")),": Metro will stop bundling and report an error to the user.")),(0,r.mdx)("h4",{id:"gettransformoptions"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getTransformOptions")),(0,r.mdx)("p",null,"Type: Function (see details below)"),(0,r.mdx)("p",null,"A function called by Metro to calculate additional options for the transformer and serializer based on the specific bundle being built."),(0,r.mdx)("p",null,"Metro expects ",(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," to have the following signature:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"function getTransformOptions(\n entryPoints: $ReadOnlyArray,\n options: {\n dev: boolean,\n hot: boolean,\n platform: ?string,\n },\n getDependenciesOf: (path: string) => Promise>,\n): Promise {\n // ...\n}\n")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," receives these parameters:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"entryPoints")),": Absolute paths to the bundle's entry points (typically just one)."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"options")),":",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"dev")),": Whether the bundle is being built in development mode."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"hot")),": ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")," Always true."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"platform")),": The target platform (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"ios"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"android"),")."))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"getDependenciesOf")),": A function which, given an absolute path to a module, returns a promise that resolves to the absolute paths of the module's transitive dependencies.")),(0,r.mdx)("p",null,(0,r.mdx)("inlineCode",{parentName:"p"},"getTransformOptions")," should return a promise that resolves to an object with the following properties:"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-flow"},"type ExtraTransformOptions = {\n preloadedModules?: {[path: string]: true} | false,\n ramGroups?: Array,\n transform?: {\n inlineRequires?: {blockList: {[string]: true}} | boolean,\n nonInlinedRequires?: $ReadOnlyArray,\n },\n};\n")),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"preloadedModules")),": A plain object whose keys represent a set of absolute paths. When serializing an ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#enable-the-ram-format"},"indexed RAM bundle"),", the modules in this set will be marked for eager evaluation at runtime."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"ramGroups")),": An array of absolute paths. When serializing an ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#enable-the-ram-format"},"indexed RAM bundle"),", each of the listed modules will be serialized along with its transitive dependencies. At runtime, the modules will all be parsed together as soon as any one of them is evaluated."),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"transform")),": Advanced options for the transformer.",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"inlineRequires")),":",(0,r.mdx)("ul",{parentName:"li"},(0,r.mdx)("li",{parentName:"ul"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires")," is a boolean, it controls whether ",(0,r.mdx)("a",{parentName:"li",href:"https://reactnative.dev/docs/ram-bundles-inline-requires#inline-requires"},"inline requires")," are enabled in this bundle."),(0,r.mdx)("li",{parentName:"ul"},"If ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires")," is an object, inline requires are enabled in all modules, except ones whose absolute paths appear as keys of ",(0,r.mdx)("inlineCode",{parentName:"li"},"inlineRequires.blockList"),"."))),(0,r.mdx)("li",{parentName:"ul"},(0,r.mdx)("strong",{parentName:"li"},(0,r.mdx)("inlineCode",{parentName:"strong"},"nonInlinedRequires")),": An array of unresolved module specifiers (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"react"),", ",(0,r.mdx)("inlineCode",{parentName:"li"},"react-native"),") to never inline, even when inline requires are enabled.")))),(0,r.mdx)("h4",{id:"minifierpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"minifierPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")," (default: ",(0,r.mdx)("inlineCode",{parentName:"p"},"'metro-minify-terser'"),")"),(0,r.mdx)("p",null,"Path, or package name resolvable from ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-transform-worker"),", to the minifier that minifies the code after transformation."),(0,r.mdx)("h4",{id:"minifierconfig"},(0,r.mdx)("inlineCode",{parentName:"h4"},"minifierConfig")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"{[key: string]: mixed}")),(0,r.mdx)("p",null,"Configuration object that will be passed to the minifier (it should be serializable)."),(0,r.mdx)("h4",{id:"optimizationsizelimit"},(0,r.mdx)("inlineCode",{parentName:"h4"},"optimizationSizeLimit")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"Define a threshold (in bytes) to disable some expensive optimizations for big files."),(0,r.mdx)("h4",{id:"react-native-only"},"React Native Only"),(0,r.mdx)("h4",{id:"assetplugins"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetPlugins")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"List of modules to call to modify Asset data"),(0,r.mdx)("h4",{id:"assetregistrypath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"assetRegistryPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"Where to fetch the assets from."),(0,r.mdx)("h3",{id:"babel-specific-transformer-options"},"Babel-specific transformer options"),(0,r.mdx)("h4",{id:"babeltransformerpath"},(0,r.mdx)("inlineCode",{parentName:"h4"},"babelTransformerPath")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"The name of a module that compiles code with Babel, returning an AST and optional metadata. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-babel-transformer"),"."),(0,r.mdx)("p",null,"Refer to the source code of ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/metro/blob/main/packages/metro-babel-transformer/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"metro-babel-transformer"))," and ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/facebook/react-native/blob/main/packages/react-native-babel-transformer/src/index.js"},(0,r.mdx)("inlineCode",{parentName:"a"},"@react-native/metro-babel-transformer"))," for details on implementing a custom Babel transformer."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),". Custom transformers may ignore it.")),(0,r.mdx)("h4",{id:"enablebabelrclookup"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableBabelRCLookup")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to enable searching for Babel configuration files. This is passed to Babel as the ",(0,r.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/en/options#babelrc"},(0,r.mdx)("inlineCode",{parentName:"a"},"babelrc"))," config option. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),". Custom transformers may ignore it. Custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," should respect this option.")),(0,r.mdx)("h4",{id:"enablebabelruntime"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enableBabelRuntime")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean | string")),(0,r.mdx)("p",null,"Whether the transformer should use the ",(0,r.mdx)("inlineCode",{parentName:"p"},"@babel/transform/runtime")," plugin. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"true"),"."),(0,r.mdx)("p",null,"If the value is a string, it is treated as a runtime version number and passed as ",(0,r.mdx)("inlineCode",{parentName:"p"},"version")," to the ",(0,r.mdx)("inlineCode",{parentName:"p"},"@babel/plugin-transform-runtime")," configuration. This allows you to optimize the generated Babel runtime calls based on the version installed in your project."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only works under the default settings for React Native. It may have no effect in a project that uses custom ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath")),", a custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"babelTransformerPath"))," or a custom ",(0,r.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/en/config-files"},"Babel config file"),".")),(0,r.mdx)("h4",{id:"hermesparser"},(0,r.mdx)("inlineCode",{parentName:"h4"},"hermesParser")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to use the ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/hermes-parser"},(0,r.mdx)("inlineCode",{parentName:"a"},"hermes-parser"))," package to parse JavaScript source files, instead of Babel. Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"This option only has an effect under the default ",(0,r.mdx)("a",{parentName:"p",href:"#transformerpath"},(0,r.mdx)("inlineCode",{parentName:"a"},"transformerPath"))," and the ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," built into Metro. Custom transformers and custom ",(0,r.mdx)("a",{parentName:"p",href:"#babeltransformerpath"},"Babel transformers")," may ignore it.")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"serializer-options"},"Serializer Options"),(0,r.mdx)("h4",{id:"getrunmodulestatement"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getRunModuleStatement")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(number | string) => string")),(0,r.mdx)("p",null,"Specify the format of the initial require statements that are appended at the end of the bundle. By default is ",(0,r.mdx)("inlineCode",{parentName:"p"},"__r(${moduleId});"),"."),(0,r.mdx)("h4",{id:"createmoduleidfactory"},(0,r.mdx)("inlineCode",{parentName:"h4"},"createModuleIdFactory")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"() => (path: string) => number")),(0,r.mdx)("p",null,"Used to generate the module id for ",(0,r.mdx)("inlineCode",{parentName:"p"},"require")," statements."),(0,r.mdx)("h4",{id:"getpolyfills"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getPolyfills")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"({platform: ?string}) => $ReadOnlyArray")),(0,r.mdx)("p",null,"An optional list of polyfills to include in the bundle. The list defaults to a set of common polyfills for Number, String, Array, Object..."),(0,r.mdx)("h4",{id:"getmodulesrunbeforemainmodule"},(0,r.mdx)("inlineCode",{parentName:"h4"},"getModulesRunBeforeMainModule")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(entryFilePath: string) => Array")),(0,r.mdx)("p",null,"An array of modules to be required before the entry point. It should contain the absolute path of each module. Note that this will add the additional require statements only if the passed modules are already included as part of the bundle."),(0,r.mdx)("h4",{id:"processmodulefilter"},(0,r.mdx)("inlineCode",{parentName:"h4"},"processModuleFilter")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(module: Array) => boolean")),(0,r.mdx)("p",null,"A filter function to discard specific modules from the output."),(0,r.mdx)("h4",{id:"isthirdpartymodule"},(0,r.mdx)("inlineCode",{parentName:"h4"},"isThirdPartyModule")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(module: {path: string, ...}) => boolean")),(0,r.mdx)("p",null,"A function that determines which modules are added to the ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/articles/x-google-ignore-list/"},(0,r.mdx)("inlineCode",{parentName:"a"},"x_google_ignoreList"))," field of the source map. This supports ",(0,r.mdx)("a",{parentName:"p",href:"https://developer.chrome.com/blog/devtools-modern-web-debugging/#just-my-code"},'"Just My Code"')," debugging in Chrome DevTools and other compatible debuggers."),(0,r.mdx)("p",null,"Defaults to returning ",(0,r.mdx)("inlineCode",{parentName:"p"},"true")," for modules with a path component named ",(0,r.mdx)("inlineCode",{parentName:"p"},"node_modules"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"In addition to modules marked as ignored by ",(0,r.mdx)("inlineCode",{parentName:"p"},"isThirdPartyModule"),", Metro will also automatically add modules generated by the bundler itself to the ignore list.")),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"server-options"},"Server Options"),(0,r.mdx)("p",null,"These options are used when Metro serves the content."),(0,r.mdx)("h4",{id:"port"},(0,r.mdx)("inlineCode",{parentName:"h4"},"port")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"Which port to listen on."),(0,r.mdx)("h4",{id:"useglobalhotkey"},(0,r.mdx)("inlineCode",{parentName:"h4"},"useGlobalHotkey")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether we should enable CMD+R hotkey for refreshing the bundle."),(0,r.mdx)("h4",{id:"enhancemiddleware-deprecated"},(0,r.mdx)("inlineCode",{parentName:"h4"},"enhanceMiddleware")," ",(0,r.mdx)("div",{class:"label deprecated"},"Deprecated")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"(Middleware, MetroServer) => Middleware")),(0,r.mdx)("p",null,"A function that allows attaching custom ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/connect"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect"))," middleware to Metro. For example:"),(0,r.mdx)("admonition",{type:"tip"},(0,r.mdx)("p",{parentName:"admonition"},"You can use ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/connect#mount-middleware"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect()"))," as a utility to extend the base ",(0,r.mdx)("inlineCode",{parentName:"p"},"metroMiddleware")," and to mount additional middleware handlers.")),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-ts"},"enhanceMiddleware: (metroMiddleware: Middleware, metroServer: MetroServer) => {\n return connect()\n .use(metroMiddleware)\n .use('/custom-endpoint', customEndpointMiddleware());\n},\n")),(0,r.mdx)("p",null,"The ",(0,r.mdx)("inlineCode",{parentName:"p"},"Middleware")," type is an alias for ",(0,r.mdx)("a",{parentName:"p",href:"https://github.com/DefinitelyTyped/DefinitelyTyped/blob/876b9ec96ba02d0c84b1e49af5890c8f5aa2dfe3/types/connect/index.d.ts#L29"},(0,r.mdx)("inlineCode",{parentName:"a"},"connect.HandleFunction")),"."),(0,r.mdx)("h4",{id:"rewriterequesturl"},(0,r.mdx)("inlineCode",{parentName:"h4"},"rewriteRequestUrl")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string => string")),(0,r.mdx)("p",null,"A function that will be called every time Metro processes a URL, after normalization of non-standard query-string delimiters using ",(0,r.mdx)("a",{parentName:"p",href:"https://www.npmjs.com/package/jsc-safe-url"},(0,r.mdx)("inlineCode",{parentName:"a"},"jsc-safe-url")),". Metro will use the return value of this function as if it were the original URL provided by the client. This applies to all incoming HTTP requests (after any custom middleware), as well as bundle URLs in ",(0,r.mdx)("inlineCode",{parentName:"p"},"/symbolicate")," request payloads and within the hot reloading protocol."),(0,r.mdx)("hr",null),(0,r.mdx)("h3",{id:"watcher-options"},"Watcher Options"),(0,r.mdx)("p",null,"Options for the filesystem watcher."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Dot notation in this section indicates a nested configuration object, e.g. ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchman.deferStates")," \u2192 ",(0,r.mdx)("inlineCode",{parentName:"p"},"watchman: { deferStates: ... }"),".")),(0,r.mdx)("h4",{id:"additionalexts"},(0,r.mdx)("inlineCode",{parentName:"h4"},"additionalExts")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"The extensions which Metro should watch in addition to ",(0,r.mdx)("inlineCode",{parentName:"p"},"sourceExts"),", but which will not be automatically tried by the resolver."),(0,r.mdx)("p",null,"Therefore, the two behavior differences from ",(0,r.mdx)("inlineCode",{parentName:"p"},"resolver.sourceExts")," when importing a module are:"),(0,r.mdx)("ul",null,(0,r.mdx)("li",{parentName:"ul"},"Modules can only be required when fully specified (e.g. ",(0,r.mdx)("inlineCode",{parentName:"li"},"import moduleA from 'moduleA.mjs'"),")."),(0,r.mdx)("li",{parentName:"ul"},"No platform-specific resolution is performed.")),(0,r.mdx)("p",null,"Defaults to ",(0,r.mdx)("inlineCode",{parentName:"p"},"['cjs', 'mjs']"),"."),(0,r.mdx)("h4",{id:"healthcheckenabled"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.enabled")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"boolean")),(0,r.mdx)("p",null,"Whether to periodically check the health of the filesystem watcher by writing a temporary file to the project and waiting for it to be observed."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"false"),"."),(0,r.mdx)("h4",{id:"healthcheckfileprefix"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.filePrefix")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"string")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls the name of the temporary file that will be written into the project filesystem."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"'.metro-health-check'"),"."),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"There's no need to commit health check files to source control. If you choose to enable health checks in your project, make sure you add ",(0,r.mdx)("inlineCode",{parentName:"p"},".metro-health-check*")," to your ",(0,r.mdx)("inlineCode",{parentName:"p"},".gitignore")," file to avoid generating unnecessary changes.")),(0,r.mdx)("h4",{id:"healthcheckinterval"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.interval")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls how often they occur (in milliseconds)."),(0,r.mdx)("p",null,"The default value is 30000."),(0,r.mdx)("h4",{id:"healthchecktimeout"},(0,r.mdx)("inlineCode",{parentName:"h4"},"healthCheck.timeout")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"number")),(0,r.mdx)("p",null,"If watcher health checks are enabled, this property controls the time (in milliseconds) Metro will wait for a file change to be observed before considering the check to have failed."),(0,r.mdx)("p",null,"The default value is 5000."),(0,r.mdx)("h4",{id:"watchmandeferstates"},(0,r.mdx)("inlineCode",{parentName:"h4"},"watchman.deferStates")),(0,r.mdx)("p",null,"Type: ",(0,r.mdx)("inlineCode",{parentName:"p"},"Array")),(0,r.mdx)("p",null,"Applies when using Watchman. Metro will ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/watchman/docs/cmd/subscribe.html#defer"},"defer processing filesystem updates")," while these ",(0,r.mdx)("a",{parentName:"p",href:"https://facebook.github.io/watchman/docs/cmd/state-enter.html"},"states")," are asserted in the watch. This is useful for debouncing builds while the filesystem hasn't settled, e.g. during large source control operations."),(0,r.mdx)("p",null,"The default value is ",(0,r.mdx)("inlineCode",{parentName:"p"},"['hg.update']"),"."),(0,r.mdx)("h2",{id:"merging-configurations"},"Merging Configurations"),(0,r.mdx)("p",null,"Using the ",(0,r.mdx)("inlineCode",{parentName:"p"},"metro-config")," package it is possible to merge multiple configurations together."),(0,r.mdx)("table",null,(0,r.mdx)("thead",{parentName:"table"},(0,r.mdx)("tr",{parentName:"thead"},(0,r.mdx)("th",{parentName:"tr",align:null},"Method"),(0,r.mdx)("th",{parentName:"tr",align:null},"Description"))),(0,r.mdx)("tbody",{parentName:"table"},(0,r.mdx)("tr",{parentName:"tbody"},(0,r.mdx)("td",{parentName:"tr",align:null},(0,r.mdx)("inlineCode",{parentName:"td"},"mergeConfig(...configs): MergedConfig")),(0,r.mdx)("td",{parentName:"tr",align:null},"Returns the merged configuration of two or more configuration objects.")))),(0,r.mdx)("admonition",{type:"note"},(0,r.mdx)("p",{parentName:"admonition"},"Arrays and function based config parameters do not deeply merge and will instead override any pre-existing config parameters.\nThis allows overriding and removing default config parameters such as ",(0,r.mdx)("inlineCode",{parentName:"p"},"platforms")," or ",(0,r.mdx)("inlineCode",{parentName:"p"},"getModulesRunBeforeMainModule")," that may not be required in your environment.")),(0,r.mdx)("h4",{id:"merging-example"},"Merging Example"),(0,r.mdx)("pre",null,(0,r.mdx)("code",{parentName:"pre",className:"language-js"},"// metro.config.js\nconst { mergeConfig } = require('metro-config');\n\nconst configA = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n }\n};\n\nconst configB = {\n /* general options */\n\n resolver: {\n /* resolver options */\n },\n transformer: {\n /* transformer options */\n },\n serializer: {\n /* serializer options */\n },\n server: {\n /* server options */\n }\n};\n\nmodule.exports = mergeConfig(configA, configB);\n")))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ba92a0db.ff27c9ab.js b/assets/js/ba92a0db.e5a6082d.js similarity index 98% rename from assets/js/ba92a0db.ff27c9ab.js rename to assets/js/ba92a0db.e5a6082d.js index 059cb97bb3..3b043953c5 100644 --- a/assets/js/ba92a0db.ff27c9ab.js +++ b/assets/js/ba92a0db.e5a6082d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[177],{3905:(e,t,r)=>{r.r(t),r.d(t,{MDXContext:()=>c,MDXProvider:()=>u,mdx:()=>g,useMDXComponents:()=>m,withMDXComponents:()=>p});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){return function(t){var r=m(t.components);return n.createElement(e,a({},t,{components:r}))}},m=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=m(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=m(r),u=o,d=p["".concat(i,".").concat(u)]||p[u]||f[u]||a;return r?n.createElement(d,l(l({ref:t},c),{},{components:r})):n.createElement(d,l({ref:t},c))}));function g(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>m});var n=r(83117),o=r(80102),a=(r(67294),r(3905)),i=["components"],l={id:"troubleshooting",title:"Troubleshooting"},s=void 0,c={unversionedId:"troubleshooting",id:"troubleshooting",title:"Troubleshooting",description:"Uh oh, something went wrong? Use this guide to resolve issues with Metro.",source:"@site/../docs/Troubleshooting.md",sourceDirName:".",slug:"/troubleshooting",permalink:"/docs/troubleshooting",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Troubleshooting.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"troubleshooting",title:"Troubleshooting"},sidebar:"docs",previous:{title:"Package Exports Support (Experimental)",permalink:"/docs/package-exports"},next:{title:"Local Development Setup",permalink:"/docs/local-development"}},p={},m=[{value:"Still unresolved?",id:"still-unresolved",level:3}],u={toc:m},d="wrapper";function f(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.mdx)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Uh oh, something went wrong? Use this guide to resolve issues with Metro."),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},"Clear Watchman watches: ",(0,a.mdx)("inlineCode",{parentName:"li"},"watchman watch-del-all")),(0,a.mdx)("li",{parentName:"ol"},"Delete ",(0,a.mdx)("inlineCode",{parentName:"li"},"node_modules")," and run ",(0,a.mdx)("inlineCode",{parentName:"li"},"yarn install")),(0,a.mdx)("li",{parentName:"ol"},"Reset Metro's cache by passing the ",(0,a.mdx)("inlineCode",{parentName:"li"},"--reset-cache")," flag, or adding ",(0,a.mdx)("inlineCode",{parentName:"li"},"resetCache: true")," to your Metro configuration file."),(0,a.mdx)("li",{parentName:"ol"},"Remove the cache: ",(0,a.mdx)("inlineCode",{parentName:"li"},"rm -rf ${TMPDIR:-/tmp}/metro-*")),(0,a.mdx)("li",{parentName:"ol"},"Update Metro to the ",(0,a.mdx)("a",{parentName:"li",href:"https://www.npmjs.com/package/metro"},"latest version"))),(0,a.mdx)("h3",{id:"still-unresolved"},"Still unresolved?"),(0,a.mdx)("p",null,"See the ",(0,a.mdx)("a",{parentName:"p",href:"/help"},"Help")," pages."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[177],{3905:(e,t,r)=>{r.r(t),r.d(t,{MDXContext:()=>c,MDXProvider:()=>u,mdx:()=>g,useMDXComponents:()=>m,withMDXComponents:()=>p});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),p=function(e){return function(t){var r=m(t.components);return n.createElement(e,a({},t,{components:r}))}},m=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=m(e.components);return n.createElement(c.Provider,{value:t},e.children)},d="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=m(r),u=o,d=p["".concat(i,".").concat(u)]||p[u]||f[u]||a;return r?n.createElement(d,l(l({ref:t},c),{},{components:r})):n.createElement(d,l({ref:t},c))}));function g(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[d]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>m});var n=r(83117),o=r(80102),a=(r(67294),r(3905)),i=["components"],l={id:"troubleshooting",title:"Troubleshooting"},s=void 0,c={unversionedId:"troubleshooting",id:"troubleshooting",title:"Troubleshooting",description:"Uh oh, something went wrong? Use this guide to resolve issues with Metro.",source:"@site/../docs/Troubleshooting.md",sourceDirName:".",slug:"/troubleshooting",permalink:"/docs/troubleshooting",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Troubleshooting.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"troubleshooting",title:"Troubleshooting"},sidebar:"docs",previous:{title:"Package Exports Support (Experimental)",permalink:"/docs/package-exports"},next:{title:"Local Development Setup",permalink:"/docs/local-development"}},p={},m=[{value:"Still unresolved?",id:"still-unresolved",level:3}],u={toc:m},d="wrapper";function f(e){var t=e.components,r=(0,o.Z)(e,i);return(0,a.mdx)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Uh oh, something went wrong? Use this guide to resolve issues with Metro."),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},"Clear Watchman watches: ",(0,a.mdx)("inlineCode",{parentName:"li"},"watchman watch-del-all")),(0,a.mdx)("li",{parentName:"ol"},"Delete ",(0,a.mdx)("inlineCode",{parentName:"li"},"node_modules")," and run ",(0,a.mdx)("inlineCode",{parentName:"li"},"yarn install")),(0,a.mdx)("li",{parentName:"ol"},"Reset Metro's cache by passing the ",(0,a.mdx)("inlineCode",{parentName:"li"},"--reset-cache")," flag, or adding ",(0,a.mdx)("inlineCode",{parentName:"li"},"resetCache: true")," to your Metro configuration file."),(0,a.mdx)("li",{parentName:"ol"},"Remove the cache: ",(0,a.mdx)("inlineCode",{parentName:"li"},"rm -rf ${TMPDIR:-/tmp}/metro-*")),(0,a.mdx)("li",{parentName:"ol"},"Update Metro to the ",(0,a.mdx)("a",{parentName:"li",href:"https://www.npmjs.com/package/metro"},"latest version"))),(0,a.mdx)("h3",{id:"still-unresolved"},"Still unresolved?"),(0,a.mdx)("p",null,"See the ",(0,a.mdx)("a",{parentName:"p",href:"/help"},"Help")," pages."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c026fe4c.0ed392da.js b/assets/js/c026fe4c.4739fe9a.js similarity index 97% rename from assets/js/c026fe4c.0ed392da.js rename to assets/js/c026fe4c.4739fe9a.js index 45dccc2153..e71bb52254 100644 --- a/assets/js/c026fe4c.0ed392da.js +++ b/assets/js/c026fe4c.4739fe9a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[476],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>c,MDXProvider:()=>u,mdx:()=>v,useMDXComponents:()=>d,withMDXComponents:()=>p});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){return function(t){var n=d(t.components);return r.createElement(e,a({},t,{components:n}))}},d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=d(n),u=o,m=p["".concat(i,".").concat(u)]||p[u]||f[u]||a;return n?r.createElement(m,l(l({ref:t},c),{},{components:n})):r.createElement(m,l({ref:t},c))}));function v(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var r=n(83117),o=n(80102),a=(n(67294),n(3905)),i=["components"],l={id:"concepts",title:"Concepts"},s=void 0,c={unversionedId:"concepts",id:"concepts",title:"Concepts",description:"Metro is a JavaScript bundler. It takes in an entry file and various options, and gives you back a single JavaScript file that includes all your code and its dependencies.",source:"@site/../docs/Concepts.md",sourceDirName:".",slug:"/concepts",permalink:"/docs/concepts",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Concepts.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"concepts",title:"Concepts"},sidebar:"docs",previous:{title:"Getting Started",permalink:"/docs/getting-started"},next:{title:"Bundling API",permalink:"/docs/api"}},p={},d=[{value:"Resolution",id:"resolution",level:3},{value:"Transformation",id:"transformation",level:3},{value:"Serialization",id:"serialization",level:3},{value:"Modules",id:"modules",level:2}],u={toc:d},m="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.mdx)(m,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Metro is a JavaScript bundler. It takes in an entry file and various options, and gives you back a single JavaScript file that includes all your code and its dependencies."),(0,a.mdx)("p",null,"Metro has three separate stages in its bundling process:"),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},"Resolution"),(0,a.mdx)("li",{parentName:"ol"},"Transformation"),(0,a.mdx)("li",{parentName:"ol"},"Serialization")),(0,a.mdx)("h3",{id:"resolution"},"Resolution"),(0,a.mdx)("p",null,"Metro needs to build a graph of all the modules that are required from the entry point. To find which file is required from another file Metro uses a resolver. In reality this stage happens in parallel with the transformation stage."),(0,a.mdx)("h3",{id:"transformation"},"Transformation"),(0,a.mdx)("p",null,"All modules go through a transformer. A transformer is responsible for converting (transpiling) a module to a format that is understandable by the target platform (eg. React Native). Transformation of modules happens in parallel based on the amount of cores that you have."),(0,a.mdx)("h3",{id:"serialization"},"Serialization"),(0,a.mdx)("p",null,"As soon as all the modules have been transformed they will be serialized. A serializer combines the modules to generate one or multiple bundles. A bundle is literally a bundle of modules combined into a single JavaScript file."),(0,a.mdx)("h2",{id:"modules"},"Modules"),(0,a.mdx)("p",null,"Metro has been split out into multiple modules corresponding to every step in the flow, each with their own responsibility. This means that we have a resolver, transformer, and serializer. These modules can be swapped out depending on your needs."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[476],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>c,MDXProvider:()=>u,mdx:()=>v,useMDXComponents:()=>d,withMDXComponents:()=>p});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){return function(t){var n=d(t.components);return r.createElement(e,a({},t,{components:n}))}},d=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=d(e.components);return r.createElement(c.Provider,{value:t},e.children)},m="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=d(n),u=o,m=p["".concat(i,".").concat(u)]||p[u]||f[u]||a;return n?r.createElement(m,l(l({ref:t},c),{},{components:n})):r.createElement(m,l({ref:t},c))}));function v(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:o,i[1]=l;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var r=n(83117),o=n(80102),a=(n(67294),n(3905)),i=["components"],l={id:"concepts",title:"Concepts"},s=void 0,c={unversionedId:"concepts",id:"concepts",title:"Concepts",description:"Metro is a JavaScript bundler. It takes in an entry file and various options, and gives you back a single JavaScript file that includes all your code and its dependencies.",source:"@site/../docs/Concepts.md",sourceDirName:".",slug:"/concepts",permalink:"/docs/concepts",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/Concepts.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"concepts",title:"Concepts"},sidebar:"docs",previous:{title:"Getting Started",permalink:"/docs/getting-started"},next:{title:"Bundling API",permalink:"/docs/api"}},p={},d=[{value:"Resolution",id:"resolution",level:3},{value:"Transformation",id:"transformation",level:3},{value:"Serialization",id:"serialization",level:3},{value:"Modules",id:"modules",level:2}],u={toc:d},m="wrapper";function f(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.mdx)(m,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.mdx)("p",null,"Metro is a JavaScript bundler. It takes in an entry file and various options, and gives you back a single JavaScript file that includes all your code and its dependencies."),(0,a.mdx)("p",null,"Metro has three separate stages in its bundling process:"),(0,a.mdx)("ol",null,(0,a.mdx)("li",{parentName:"ol"},"Resolution"),(0,a.mdx)("li",{parentName:"ol"},"Transformation"),(0,a.mdx)("li",{parentName:"ol"},"Serialization")),(0,a.mdx)("h3",{id:"resolution"},"Resolution"),(0,a.mdx)("p",null,"Metro needs to build a graph of all the modules that are required from the entry point. To find which file is required from another file Metro uses a resolver. In reality this stage happens in parallel with the transformation stage."),(0,a.mdx)("h3",{id:"transformation"},"Transformation"),(0,a.mdx)("p",null,"All modules go through a transformer. A transformer is responsible for converting (transpiling) a module to a format that is understandable by the target platform (eg. React Native). Transformation of modules happens in parallel based on the amount of cores that you have."),(0,a.mdx)("h3",{id:"serialization"},"Serialization"),(0,a.mdx)("p",null,"As soon as all the modules have been transformed they will be serialized. A serializer combines the modules to generate one or multiple bundles. A bundle is literally a bundle of modules combined into a single JavaScript file."),(0,a.mdx)("h2",{id:"modules"},"Modules"),(0,a.mdx)("p",null,"Metro has been split out into multiple modules corresponding to every step in the flow, each with their own responsibility. This means that we have a resolver, transformer, and serializer. These modules can be swapped out depending on your needs."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e08abecb.aaca3b71.js b/assets/js/e08abecb.248aeed4.js similarity index 99% rename from assets/js/e08abecb.aaca3b71.js rename to assets/js/e08abecb.248aeed4.js index 6ed9367a80..323b241a1b 100644 --- a/assets/js/e08abecb.aaca3b71.js +++ b/assets/js/e08abecb.248aeed4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[350],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>s,mdx:()=>x,useMDXComponents:()=>u,withMDXComponents:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var m=r.createContext({}),p=function(e){return function(t){var n=u(t.components);return r.createElement(e,o({},t,{components:n}))}},u=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):d(d({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(m.Provider,{value:t},e.children)},c="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),p=u(n),s=a,c=p["".concat(i,".").concat(s)]||p[s]||f[s]||o;return n?r.createElement(c,d(d({ref:t},m),{},{components:n})):r.createElement(c,d({ref:t},m))}));function x(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var d={};for(var l in t)hasOwnProperty.call(t,l)&&(d[l]=t[l]);d.originalType=e,d[c]="string"==typeof e?e:a,i[1]=d;for(var m=2;m{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>d,metadata:()=>m,toc:()=>u});var r=n(83117),a=n(80102),o=(n(67294),n(3905)),i=["components"],d={id:"module-api",title:"Module API"},l=void 0,m={unversionedId:"module-api",id:"module-api",title:"Module API",description:"Metro is designed to allow code written for Node (or for bundlers targeting the Web) to run mostly unmodified. The main APIs available to application code are listed below.",source:"@site/../docs/ModuleAPI.md",sourceDirName:".",slug:"/module-api",permalink:"/docs/module-api",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/ModuleAPI.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"module-api",title:"Module API"},sidebar:"docs",previous:{title:"Bundling API",permalink:"/docs/api"},next:{title:"Configuring Metro",permalink:"/docs/configuration"}},p={},u=[{value:"require()",id:"require",level:2},{value:"Advanced usage: require at runtime",id:"advanced-usage-require-at-runtime",level:3},{value:"module.exports",id:"moduleexports",level:2},{value:"ES Modules syntax (import and export)",id:"es-modules-syntax-import-and-export",level:2},{value:"import() (dynamic import)",id:"import-dynamic-import",level:2},{value:"require.resolveWeak()",id:"requireresolveweak",level:2}],s={toc:u},c="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,i);return(0,o.mdx)(c,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Metro is designed to allow code written for Node (or for bundlers targeting the Web) to run mostly unmodified. The main APIs available to application code are listed below."),(0,o.mdx)("h2",{id:"require"},(0,o.mdx)("inlineCode",{parentName:"h2"},"require()")),(0,o.mdx)("p",null,"Similar to Node's ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#requireid"},(0,o.mdx)("inlineCode",{parentName:"a"},"require()"))," function. ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," takes a module name (or path) and returns the result of evaluating that module's code. Modules referenced by ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," will be added to the bundle."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"const localModule = require('./path/module');\nconst asset = require('./path/asset.png');\nconst jsonData = require('./path/data.json');\nconst {View} = require('react-native');\n")),(0,o.mdx)("p",null,"The argument to ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," must be a compile-time constant. The ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#dynamicdepsinpackages"},(0,o.mdx)("inlineCode",{parentName:"a"},"dynamicDepsInPackages"))," config option controls whether calling ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," with a non-constant argument will fail at build time or at runtime."),(0,o.mdx)("h3",{id:"advanced-usage-require-at-runtime"},"Advanced usage: ",(0,o.mdx)("inlineCode",{parentName:"h3"},"require")," at runtime"),(0,o.mdx)("p",null,"At build time, Metro ",(0,o.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolves")," module names to absolute paths and ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#createmoduleidfactory"},"assigns an opaque module ID")," to each one."),(0,o.mdx)("p",null,"At runtime, ",(0,o.mdx)("inlineCode",{parentName:"p"},"require")," refers to a function that takes an opaque module ID (",(0,o.mdx)("em",{parentName:"p"},"not")," a name or path) and returns a module. This can be useful if you already have a module ID returned by another module API, such as ",(0,o.mdx)("a",{parentName:"p",href:"#require-resolveweak"},(0,o.mdx)("inlineCode",{parentName:"a"},"require.resolveWeak")),"."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"const localModule = require('./path/module');\nconst id = require.resolveWeak('./path/module');\n// Bypass the restriction on non-constant require() arguments\nconst dynamicRequire = require;\ndynamicRequire(id) === localModule; // true\n")),(0,o.mdx)("h2",{id:"moduleexports"},(0,o.mdx)("inlineCode",{parentName:"h2"},"module.exports")),(0,o.mdx)("p",null,"Similar to ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#moduleexports"},(0,o.mdx)("inlineCode",{parentName:"a"},"module.exports"))," in Node. The ",(0,o.mdx)("inlineCode",{parentName:"p"},"module.exports")," property holds the value ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," will return for the current module after it finishes evaluating."),(0,o.mdx)("h2",{id:"es-modules-syntax-import-and-export"},"ES Modules syntax (",(0,o.mdx)("inlineCode",{parentName:"h2"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"h2"},"export"),")"),(0,o.mdx)("p",null,"We currently recommend the use of ",(0,o.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/babel-plugin-transform-modules-commonjs"},(0,o.mdx)("inlineCode",{parentName:"a"},"@babel/plugin-transform-modules-commonjs"))," in Metro projects to support ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"p"},"export"),"."),(0,o.mdx)("admonition",{type:"note"},(0,o.mdx)("p",{parentName:"admonition"},"In React Native projects that use ",(0,o.mdx)("inlineCode",{parentName:"p"},"@react-native/babel-preset"),", ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"p"},"export")," are supported out of the box.")),(0,o.mdx)("h2",{id:"import-dynamic-import"},(0,o.mdx)("inlineCode",{parentName:"h2"},"import()")," (dynamic import)"),(0,o.mdx)("p",null,(0,o.mdx)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},(0,o.mdx)("inlineCode",{parentName:"a"},"import()"))," calls are supported out of the box. In React Native, using ",(0,o.mdx)("inlineCode",{parentName:"p"},"import()")," automatically splits your application code so that it loads faster during development, without affecting release builds."),(0,o.mdx)("admonition",{type:"info"},(0,o.mdx)("p",{parentName:"admonition"},(0,o.mdx)("strong",{parentName:"p"},"For framework implementers"),":"),(0,o.mdx)("ol",{parentName:"admonition"},(0,o.mdx)("li",{parentName:"ol"},"Enable ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md"},"lazy bundling")," by adding ",(0,o.mdx)("inlineCode",{parentName:"li"},"&lazy=true")," to the initial HTTP bundle URL your framework requests from Metro."),(0,o.mdx)("li",{parentName:"ol"},"At runtime, ",(0,o.mdx)("inlineCode",{parentName:"li"},"import()")," calls a framework-defined function to ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md#__loadbundleasync-in-metro"},"fetch and evaluate")," the split bundle. Your framework ",(0,o.mdx)("strong",{parentName:"li"},"must")," implement this function if it uses the ",(0,o.mdx)("inlineCode",{parentName:"li"},"lazy=true")," parameter, or runtime errors will occur."))),(0,o.mdx)("h2",{id:"requireresolveweak"},(0,o.mdx)("inlineCode",{parentName:"h2"},"require.resolveWeak()")),(0,o.mdx)("p",null,"Takes a module name (or path) and returns that module's opaque ID, without including it in the bundle. This is a specialised API intended to be used by frameworks; application code will rarely need to use it directly. See the section about ",(0,o.mdx)("a",{parentName:"p",href:"#advanced-usage-require-at-runtime"},"using ",(0,o.mdx)("inlineCode",{parentName:"a"},"require")," at runtime"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[350],{3905:(e,t,n)=>{n.r(t),n.d(t,{MDXContext:()=>m,MDXProvider:()=>s,mdx:()=>x,useMDXComponents:()=>u,withMDXComponents:()=>p});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(){return o=Object.assign||function(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var m=r.createContext({}),p=function(e){return function(t){var n=u(t.components);return r.createElement(e,o({},t,{components:n}))}},u=function(e){var t=r.useContext(m),n=t;return e&&(n="function"==typeof e?e(t):d(d({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(m.Provider,{value:t},e.children)},c="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),p=u(n),s=a,c=p["".concat(i,".").concat(s)]||p[s]||f[s]||o;return n?r.createElement(c,d(d({ref:t},m),{},{components:n})):r.createElement(c,d({ref:t},m))}));function x(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,i=new Array(o);i[0]=h;var d={};for(var l in t)hasOwnProperty.call(t,l)&&(d[l]=t[l]);d.originalType=e,d[c]="string"==typeof e?e:a,i[1]=d;for(var m=2;m{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>f,frontMatter:()=>d,metadata:()=>m,toc:()=>u});var r=n(83117),a=n(80102),o=(n(67294),n(3905)),i=["components"],d={id:"module-api",title:"Module API"},l=void 0,m={unversionedId:"module-api",id:"module-api",title:"Module API",description:"Metro is designed to allow code written for Node (or for bundlers targeting the Web) to run mostly unmodified. The main APIs available to application code are listed below.",source:"@site/../docs/ModuleAPI.md",sourceDirName:".",slug:"/module-api",permalink:"/docs/module-api",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/ModuleAPI.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"module-api",title:"Module API"},sidebar:"docs",previous:{title:"Bundling API",permalink:"/docs/api"},next:{title:"Configuring Metro",permalink:"/docs/configuration"}},p={},u=[{value:"require()",id:"require",level:2},{value:"Advanced usage: require at runtime",id:"advanced-usage-require-at-runtime",level:3},{value:"module.exports",id:"moduleexports",level:2},{value:"ES Modules syntax (import and export)",id:"es-modules-syntax-import-and-export",level:2},{value:"import() (dynamic import)",id:"import-dynamic-import",level:2},{value:"require.resolveWeak()",id:"requireresolveweak",level:2}],s={toc:u},c="wrapper";function f(e){var t=e.components,n=(0,a.Z)(e,i);return(0,o.mdx)(c,(0,r.Z)({},s,n,{components:t,mdxType:"MDXLayout"}),(0,o.mdx)("p",null,"Metro is designed to allow code written for Node (or for bundlers targeting the Web) to run mostly unmodified. The main APIs available to application code are listed below."),(0,o.mdx)("h2",{id:"require"},(0,o.mdx)("inlineCode",{parentName:"h2"},"require()")),(0,o.mdx)("p",null,"Similar to Node's ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#requireid"},(0,o.mdx)("inlineCode",{parentName:"a"},"require()"))," function. ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," takes a module name (or path) and returns the result of evaluating that module's code. Modules referenced by ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," will be added to the bundle."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"const localModule = require('./path/module');\nconst asset = require('./path/asset.png');\nconst jsonData = require('./path/data.json');\nconst {View} = require('react-native');\n")),(0,o.mdx)("p",null,"The argument to ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," must be a compile-time constant. The ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#dynamicdepsinpackages"},(0,o.mdx)("inlineCode",{parentName:"a"},"dynamicDepsInPackages"))," config option controls whether calling ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," with a non-constant argument will fail at build time or at runtime."),(0,o.mdx)("h3",{id:"advanced-usage-require-at-runtime"},"Advanced usage: ",(0,o.mdx)("inlineCode",{parentName:"h3"},"require")," at runtime"),(0,o.mdx)("p",null,"At build time, Metro ",(0,o.mdx)("a",{parentName:"p",href:"/docs/resolution"},"resolves")," module names to absolute paths and ",(0,o.mdx)("a",{parentName:"p",href:"/docs/configuration#createmoduleidfactory"},"assigns an opaque module ID")," to each one."),(0,o.mdx)("p",null,"At runtime, ",(0,o.mdx)("inlineCode",{parentName:"p"},"require")," refers to a function that takes an opaque module ID (",(0,o.mdx)("em",{parentName:"p"},"not")," a name or path) and returns a module. This can be useful if you already have a module ID returned by another module API, such as ",(0,o.mdx)("a",{parentName:"p",href:"#require-resolveweak"},(0,o.mdx)("inlineCode",{parentName:"a"},"require.resolveWeak")),"."),(0,o.mdx)("pre",null,(0,o.mdx)("code",{parentName:"pre",className:"language-js"},"const localModule = require('./path/module');\nconst id = require.resolveWeak('./path/module');\n// Bypass the restriction on non-constant require() arguments\nconst dynamicRequire = require;\ndynamicRequire(id) === localModule; // true\n")),(0,o.mdx)("h2",{id:"moduleexports"},(0,o.mdx)("inlineCode",{parentName:"h2"},"module.exports")),(0,o.mdx)("p",null,"Similar to ",(0,o.mdx)("a",{parentName:"p",href:"https://nodejs.org/api/modules.html#moduleexports"},(0,o.mdx)("inlineCode",{parentName:"a"},"module.exports"))," in Node. The ",(0,o.mdx)("inlineCode",{parentName:"p"},"module.exports")," property holds the value ",(0,o.mdx)("inlineCode",{parentName:"p"},"require()")," will return for the current module after it finishes evaluating."),(0,o.mdx)("h2",{id:"es-modules-syntax-import-and-export"},"ES Modules syntax (",(0,o.mdx)("inlineCode",{parentName:"h2"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"h2"},"export"),")"),(0,o.mdx)("p",null,"We currently recommend the use of ",(0,o.mdx)("a",{parentName:"p",href:"https://babeljs.io/docs/babel-plugin-transform-modules-commonjs"},(0,o.mdx)("inlineCode",{parentName:"a"},"@babel/plugin-transform-modules-commonjs"))," in Metro projects to support ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"p"},"export"),"."),(0,o.mdx)("admonition",{type:"note"},(0,o.mdx)("p",{parentName:"admonition"},"In React Native projects that use ",(0,o.mdx)("inlineCode",{parentName:"p"},"@react-native/babel-preset"),", ",(0,o.mdx)("inlineCode",{parentName:"p"},"import")," and ",(0,o.mdx)("inlineCode",{parentName:"p"},"export")," are supported out of the box.")),(0,o.mdx)("h2",{id:"import-dynamic-import"},(0,o.mdx)("inlineCode",{parentName:"h2"},"import()")," (dynamic import)"),(0,o.mdx)("p",null,(0,o.mdx)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import"},(0,o.mdx)("inlineCode",{parentName:"a"},"import()"))," calls are supported out of the box. In React Native, using ",(0,o.mdx)("inlineCode",{parentName:"p"},"import()")," automatically splits your application code so that it loads faster during development, without affecting release builds."),(0,o.mdx)("admonition",{type:"info"},(0,o.mdx)("p",{parentName:"admonition"},(0,o.mdx)("strong",{parentName:"p"},"For framework implementers"),":"),(0,o.mdx)("ol",{parentName:"admonition"},(0,o.mdx)("li",{parentName:"ol"},"Enable ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md"},"lazy bundling")," by adding ",(0,o.mdx)("inlineCode",{parentName:"li"},"&lazy=true")," to the initial HTTP bundle URL your framework requests from Metro."),(0,o.mdx)("li",{parentName:"ol"},"At runtime, ",(0,o.mdx)("inlineCode",{parentName:"li"},"import()")," calls a framework-defined function to ",(0,o.mdx)("a",{parentName:"li",href:"https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0605-lazy-bundling.md#__loadbundleasync-in-metro"},"fetch and evaluate")," the split bundle. Your framework ",(0,o.mdx)("strong",{parentName:"li"},"must")," implement this function if it uses the ",(0,o.mdx)("inlineCode",{parentName:"li"},"lazy=true")," parameter, or runtime errors will occur."))),(0,o.mdx)("h2",{id:"requireresolveweak"},(0,o.mdx)("inlineCode",{parentName:"h2"},"require.resolveWeak()")),(0,o.mdx)("p",null,"Takes a module name (or path) and returns that module's opaque ID, without including it in the bundle. This is a specialised API intended to be used by frameworks; application code will rarely need to use it directly. See the section about ",(0,o.mdx)("a",{parentName:"p",href:"#advanced-usage-require-at-runtime"},"using ",(0,o.mdx)("inlineCode",{parentName:"a"},"require")," at runtime"),"."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fc1f0afe.581a6525.js b/assets/js/fc1f0afe.562ca30a.js similarity index 98% rename from assets/js/fc1f0afe.581a6525.js rename to assets/js/fc1f0afe.562ca30a.js index 4e9afdbbe6..db7ad70e6c 100644 --- a/assets/js/fc1f0afe.581a6525.js +++ b/assets/js/fc1f0afe.562ca30a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[371],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>p,MDXProvider:()=>m,mdx:()=>g,useMDXComponents:()=>c,withMDXComponents:()=>s});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=r.createContext({}),s=function(e){return function(n){var t=c(n.components);return r.createElement(e,a({},n,{components:t}))}},c=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):d(d({},n),e)),t},m=function(e){var n=c(e.components);return r.createElement(p.Provider,{value:n},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},x=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),s=c(t),m=o,u=s["".concat(i,".").concat(m)]||s[m]||f[m]||a;return t?r.createElement(u,d(d({ref:n},p),{},{components:t})):r.createElement(u,d({ref:n},p))}));function g(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=x;var d={};for(var l in n)hasOwnProperty.call(n,l)&&(d[l]=n[l]);d.originalType=e,d[u]="string"==typeof e?e:o,i[1]=d;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>l,default:()=>f,frontMatter:()=>d,metadata:()=>p,toc:()=>c});var r=t(83117),o=t(80102),a=(t(67294),t(3905)),i=["components"],d={id:"api",title:"Bundling API"},l=void 0,p={unversionedId:"api",id:"api",title:"Bundling API",description:"Quick Start",source:"@site/../docs/API.md",sourceDirName:".",slug:"/api",permalink:"/docs/api",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/API.md",tags:[],version:"current",lastUpdatedAt:1703091780,formattedLastUpdatedAt:"Dec 20, 2023",frontMatter:{id:"api",title:"Bundling API"},sidebar:"docs",previous:{title:"Concepts",permalink:"/docs/concepts"},next:{title:"Module API",permalink:"/docs/module-api"}},s={},c=[{value:"Quick Start",id:"quick-start",level:2},{value:"Reference",id:"reference",level:2},{value:"loadConfig(<options>)",id:"loadconfigoptions",level:3},{value:"async runMetro(config)",id:"async-runmetroconfig",level:3},{value:"async runBuild(config, <options>)",id:"async-runbuildconfig-options",level:3},{value:"async runServer(config, <options>)",id:"async-runserverconfig-options",level:3},{value:"createConnectMiddleware(config, <options>)",id:"createconnectmiddlewareconfig-options",level:3}],m={toc:c},u="wrapper";function f(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.mdx)(u,(0,r.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("h2",{id:"quick-start"},"Quick Start"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Compile a file"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runBuild(config, {\n entry: 'index.js',\n out: 'bundle.js',\n});\n"))),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Run a server and watch the filesystem for changes"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runServer(config);\n"))),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Create a Connect middleware and plug it into a server"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\nconst express = require('express');\nconst app = express();\nconst server = require('http').Server(app);\n\nMetro.loadConfig().then(async config => {\n const connectMiddleware = await Metro.createConnectMiddleware(config);\n const {server: {port}} = config;\n\n app.use(connectMiddleware.middleware);\n server.listen(port);\n connectMiddleware.attachHmrServer(server);\n});\n")))),(0,a.mdx)("h2",{id:"reference"},"Reference"),(0,a.mdx)("p",null,"All functions exposed below accept an additional ",(0,a.mdx)("inlineCode",{parentName:"p"},"config")," option. This object should be the ",(0,a.mdx)("a",{parentName:"p",href:"/docs/cli"},"Metro configuration")," exposed by your ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js")," file - you can obtain it using ",(0,a.mdx)("inlineCode",{parentName:"p"},"Metro.loadConfig"),"."),(0,a.mdx)("h3",{id:"loadconfigoptions"},(0,a.mdx)("inlineCode",{parentName:"h3"},"loadConfig()")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"config"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"cwd")),(0,a.mdx)("p",null,"Load the Metro configuration, either from ",(0,a.mdx)("inlineCode",{parentName:"p"},"config")," in options if specified, or by traversing the directory hierarchy from ",(0,a.mdx)("inlineCode",{parentName:"p"},"cwd")," to the root until it finds a file (by default ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js"),"). The returned configuration will have been normalized and merged with Metro's default values."),(0,a.mdx)("h3",{id:"async-runmetroconfig"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runMetro(config)")),(0,a.mdx)("p",null,"Creates a Metro server based on the config and returns it. You can use this as a middleware in your existing server."),(0,a.mdx)("h3",{id:"async-runbuildconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runBuild(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Required options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"entry"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"out")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"dev"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"minify"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"platform"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMap"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")),(0,a.mdx)("p",null,"Bundles ",(0,a.mdx)("inlineCode",{parentName:"p"},"entry")," for the given ",(0,a.mdx)("inlineCode",{parentName:"p"},"platform"),", and saves it to location ",(0,a.mdx)("inlineCode",{parentName:"p"},"out"),". If ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMap")," is set, also generates a source map. The source map will be inlined, unless ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")," is also defined. In the latter case, a new file will be generated with the basename of the ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")," parameter."),(0,a.mdx)("h3",{id:"async-runserverconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runServer(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"host"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"port"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secure (DEPRECATED)"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureKey (DEPRECATED)"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureCert (DEPRECATED)")),(0,a.mdx)("p",null,"Starts a full Metro HTTP server. It will listen on the specified ",(0,a.mdx)("inlineCode",{parentName:"p"},"host:port"),", and can then be queried to retrieve bundles for various entry points. If the ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions")," family of options are present, the server will be exposed over HTTPS."),(0,a.mdx)("p",null,(0,a.mdx)("inlineCode",{parentName:"p"},"secure"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureKey"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureCert")," are now deprecated and will be removed in a later release. The presence of ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions"),", along with its options will make Metro run over https."),(0,a.mdx)("h3",{id:"createconnectmiddlewareconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"createConnectMiddleware(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"port"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"onBundleBuilt")),(0,a.mdx)("p",null,"Instead of creating the full server, creates a Connect middleware that answers to bundle requests. This middleware can then be plugged into your own servers. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"port")," parameter is optional and only used for logging purposes. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"onBundleBuilt")," function is optional, is passed the bundle name, and is called when the server has finishing creating the bundle."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[371],{3905:(e,n,t)=>{t.r(n),t.d(n,{MDXContext:()=>p,MDXProvider:()=>m,mdx:()=>g,useMDXComponents:()=>c,withMDXComponents:()=>s});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(){return a=Object.assign||function(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var p=r.createContext({}),s=function(e){return function(n){var t=c(n.components);return r.createElement(e,a({},n,{components:t}))}},c=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):d(d({},n),e)),t},m=function(e){var n=c(e.components);return r.createElement(p.Provider,{value:n},e.children)},u="mdxType",f={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},x=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),s=c(t),m=o,u=s["".concat(i,".").concat(m)]||s[m]||f[m]||a;return t?r.createElement(u,d(d({ref:n},p),{},{components:t})):r.createElement(u,d({ref:n},p))}));function g(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=x;var d={};for(var l in n)hasOwnProperty.call(n,l)&&(d[l]=n[l]);d.originalType=e,d[u]="string"==typeof e?e:o,i[1]=d;for(var p=2;p{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>l,default:()=>f,frontMatter:()=>d,metadata:()=>p,toc:()=>c});var r=t(83117),o=t(80102),a=(t(67294),t(3905)),i=["components"],d={id:"api",title:"Bundling API"},l=void 0,p={unversionedId:"api",id:"api",title:"Bundling API",description:"Quick Start",source:"@site/../docs/API.md",sourceDirName:".",slug:"/api",permalink:"/docs/api",draft:!1,editUrl:"https://github.com/facebook/metro/edit/main/docs/../docs/API.md",tags:[],version:"current",lastUpdatedAt:1703167849,formattedLastUpdatedAt:"Dec 21, 2023",frontMatter:{id:"api",title:"Bundling API"},sidebar:"docs",previous:{title:"Concepts",permalink:"/docs/concepts"},next:{title:"Module API",permalink:"/docs/module-api"}},s={},c=[{value:"Quick Start",id:"quick-start",level:2},{value:"Reference",id:"reference",level:2},{value:"loadConfig(<options>)",id:"loadconfigoptions",level:3},{value:"async runMetro(config)",id:"async-runmetroconfig",level:3},{value:"async runBuild(config, <options>)",id:"async-runbuildconfig-options",level:3},{value:"async runServer(config, <options>)",id:"async-runserverconfig-options",level:3},{value:"createConnectMiddleware(config, <options>)",id:"createconnectmiddlewareconfig-options",level:3}],m={toc:c},u="wrapper";function f(e){var n=e.components,t=(0,o.Z)(e,i);return(0,a.mdx)(u,(0,r.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,a.mdx)("h2",{id:"quick-start"},"Quick Start"),(0,a.mdx)("ul",null,(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Compile a file"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runBuild(config, {\n entry: 'index.js',\n out: 'bundle.js',\n});\n"))),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Run a server and watch the filesystem for changes"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const config = await Metro.loadConfig();\n\nawait Metro.runServer(config);\n"))),(0,a.mdx)("li",{parentName:"ul"},(0,a.mdx)("p",{parentName:"li"},"Create a Connect middleware and plug it into a server"),(0,a.mdx)("pre",{parentName:"li"},(0,a.mdx)("code",{parentName:"pre",className:"language-js"},"const Metro = require('metro');\nconst express = require('express');\nconst app = express();\nconst server = require('http').Server(app);\n\nMetro.loadConfig().then(async config => {\n const connectMiddleware = await Metro.createConnectMiddleware(config);\n const {server: {port}} = config;\n\n app.use(connectMiddleware.middleware);\n server.listen(port);\n connectMiddleware.attachHmrServer(server);\n});\n")))),(0,a.mdx)("h2",{id:"reference"},"Reference"),(0,a.mdx)("p",null,"All functions exposed below accept an additional ",(0,a.mdx)("inlineCode",{parentName:"p"},"config")," option. This object should be the ",(0,a.mdx)("a",{parentName:"p",href:"/docs/cli"},"Metro configuration")," exposed by your ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js")," file - you can obtain it using ",(0,a.mdx)("inlineCode",{parentName:"p"},"Metro.loadConfig"),"."),(0,a.mdx)("h3",{id:"loadconfigoptions"},(0,a.mdx)("inlineCode",{parentName:"h3"},"loadConfig()")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"config"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"cwd")),(0,a.mdx)("p",null,"Load the Metro configuration, either from ",(0,a.mdx)("inlineCode",{parentName:"p"},"config")," in options if specified, or by traversing the directory hierarchy from ",(0,a.mdx)("inlineCode",{parentName:"p"},"cwd")," to the root until it finds a file (by default ",(0,a.mdx)("inlineCode",{parentName:"p"},"metro.config.js"),"). The returned configuration will have been normalized and merged with Metro's default values."),(0,a.mdx)("h3",{id:"async-runmetroconfig"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runMetro(config)")),(0,a.mdx)("p",null,"Creates a Metro server based on the config and returns it. You can use this as a middleware in your existing server."),(0,a.mdx)("h3",{id:"async-runbuildconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runBuild(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Required options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"entry"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"out")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"dev"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"minify"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"platform"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMap"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")),(0,a.mdx)("p",null,"Bundles ",(0,a.mdx)("inlineCode",{parentName:"p"},"entry")," for the given ",(0,a.mdx)("inlineCode",{parentName:"p"},"platform"),", and saves it to location ",(0,a.mdx)("inlineCode",{parentName:"p"},"out"),". If ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMap")," is set, also generates a source map. The source map will be inlined, unless ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")," is also defined. In the latter case, a new file will be generated with the basename of the ",(0,a.mdx)("inlineCode",{parentName:"p"},"sourceMapUrl")," parameter."),(0,a.mdx)("h3",{id:"async-runserverconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"async runServer(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"host"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"port"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secure (DEPRECATED)"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureKey (DEPRECATED)"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureCert (DEPRECATED)")),(0,a.mdx)("p",null,"Starts a full Metro HTTP server. It will listen on the specified ",(0,a.mdx)("inlineCode",{parentName:"p"},"host:port"),", and can then be queried to retrieve bundles for various entry points. If the ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions")," family of options are present, the server will be exposed over HTTPS."),(0,a.mdx)("p",null,(0,a.mdx)("inlineCode",{parentName:"p"},"secure"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureKey"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureCert")," are now deprecated and will be removed in a later release. The presence of ",(0,a.mdx)("inlineCode",{parentName:"p"},"secureServerOptions"),", along with its options will make Metro run over https."),(0,a.mdx)("h3",{id:"createconnectmiddlewareconfig-options"},(0,a.mdx)("inlineCode",{parentName:"h3"},"createConnectMiddleware(config, )")),(0,a.mdx)("p",null,(0,a.mdx)("strong",{parentName:"p"},"Basic options:")," ",(0,a.mdx)("inlineCode",{parentName:"p"},"port"),", ",(0,a.mdx)("inlineCode",{parentName:"p"},"onBundleBuilt")),(0,a.mdx)("p",null,"Instead of creating the full server, creates a Connect middleware that answers to bundle requests. This middleware can then be plugged into your own servers. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"port")," parameter is optional and only used for logging purposes. The ",(0,a.mdx)("inlineCode",{parentName:"p"},"onBundleBuilt")," function is optional, is passed the bundle name, and is called when the server has finishing creating the bundle."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.569eb80f.js b/assets/js/main.935b1cc8.js similarity index 99% rename from assets/js/main.569eb80f.js rename to assets/js/main.935b1cc8.js index 2ff999911e..27f4dc1d1a 100644 --- a/assets/js/main.569eb80f.js +++ b/assets/js/main.935b1cc8.js @@ -1,2 +1,2 @@ -/*! For license information please see main.569eb80f.js.LICENSE.txt */ -(self.webpackChunkmetro_website=self.webpackChunkmetro_website||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(67294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(67294),a=n(83117),o=n(68356),i=n.n(o),l=n(16887);const u={"163e71e1":[function(){return n.e(662).then(n.bind(n,33056))},"@site/../docs/GettingStarted.md",33056],17896441:[function(){return Promise.all([n.e(532),n.e(173),n.e(918)]).then(n.t.bind(n,62466,23))},"@theme/DocItem",62466],"1a4e3797":[function(){return Promise.all([n.e(532),n.e(920)]).then(n.bind(n,39172))},"@theme/SearchPage",39172],"1be78505":[function(){return Promise.all([n.e(532),n.e(514)]).then(n.bind(n,19963))},"@theme/DocPage",19963],"37a9b1a2":[function(){return n.e(536).then(n.bind(n,63873))},"@site/../docs/Bundling.md",63873],"48f2cf36":[function(){return n.e(576).then(n.t.bind(n,15745,19))},"/home/runner/work/metro/metro/website/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],51001101:[function(){return n.e(645).then(n.bind(n,68459))},"@site/../docs/Caching.md",68459],"5e9f5e1a":[function(){return Promise.resolve().then(n.bind(n,36809))},"@generated/docusaurus.config",36809],"6373d68f":[function(){return n.e(874).then(n.bind(n,54112))},"@site/../docs/SourceMapFormat.md",54112],"6681bed1":[function(){return n.e(76).then(n.bind(n,13591))},"@site/../docs/CLI.md",13591],"6c52fe38":[function(){return n.e(123).then(n.t.bind(n,83769,19))},"/home/runner/work/metro/metro/website/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",83769],"78e9b454":[function(){return n.e(93).then(n.bind(n,15839))},"@site/src/pages/help/index.js",15839],"812be9b9":[function(){return n.e(599).then(n.bind(n,65087))},"@site/../docs/Resolution.md",65087],"8b9b5fbc":[function(){return n.e(424).then(n.bind(n,18704))},"@site/../docs/LocalDevelopment.md",18704],"935f2afb":[function(){return n.e(53).then(n.t.bind(n,1109,19))},"~docs/default/version-current-metadata-prop-751.json",1109],ae2a35ac:[function(){return n.e(708).then(n.bind(n,72722))},"@site/../docs/PackageExports.md",72722],ba2a2799:[function(){return n.e(122).then(n.bind(n,15389))},"@site/../docs/Configuration.md",15389],ba92a0db:[function(){return n.e(177).then(n.bind(n,80622))},"@site/../docs/Troubleshooting.md",80622],c026fe4c:[function(){return n.e(476).then(n.bind(n,56646))},"@site/../docs/Concepts.md",56646],c4f5d8e4:[function(){return Promise.all([n.e(532),n.e(195)]).then(n.bind(n,45334))},"@site/src/pages/index.js",45334],e08abecb:[function(){return n.e(350).then(n.bind(n,81161))},"@site/../docs/ModuleAPI.md",81161],fc1f0afe:[function(){return n.e(371).then(n.bind(n,91041))},"@site/../docs/API.md",91041],feaddec7:[function(){return n.e(665).then(n.t.bind(n,7085,19))},"/home/runner/work/metro/metro/website/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085]};function s(e){var t=e.error,n=e.retry,a=e.pastDelay;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var c=n(99670),d=n(30226);function f(e,t){if("*"===e)return i()({loading:s,loader:function(){return n.e(972).then(n.bind(n,4972))},modules:["@theme/NotFound"],webpack:function(){return[4972]},render:function(e,t){var n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});var o=l[e+"-"+t],f={},p=[],m=[],h=(0,c.Z)(o);return Object.entries(h).forEach((function(e){var t=e[0],n=e[1],r=u[n];r&&(f[t]=r[0],p.push(r[1]),m.push(r[2]))})),i().Map({loading:s,loader:f,modules:p,webpack:function(){return m},render:function(t,n){var i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((function(t){var n=t[0],r=t[1],a=r.default;if(!a)throw new Error("The page component at "+e+" doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.");"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((function(e){return"default"!==e})).forEach((function(e){a[e]=r[e]}));var o=i,l=n.split(".");l.slice(0,-1).forEach((function(e){o=o[e]})),o[l[l.length-1]]=a}));var l=i.__comp;delete i.__comp;var u=i.__context;return delete i.__context,r.createElement(d.z,{value:u},r.createElement(l,(0,a.Z)({},i,n)))}})}const p=[{path:"/help/",component:f("/help/","f74"),exact:!0},{path:"/search",component:f("/search","d04"),exact:!0},{path:"/docs",component:f("/docs","f4d"),routes:[{path:"/docs/api",component:f("/docs/api","3a8"),exact:!0,sidebar:"docs"},{path:"/docs/bundling",component:f("/docs/bundling","30a"),exact:!0,sidebar:"docs"},{path:"/docs/caching",component:f("/docs/caching","ab7"),exact:!0,sidebar:"docs"},{path:"/docs/cli",component:f("/docs/cli","df2"),exact:!0,sidebar:"docs"},{path:"/docs/concepts",component:f("/docs/concepts","463"),exact:!0,sidebar:"docs"},{path:"/docs/configuration",component:f("/docs/configuration","167"),exact:!0,sidebar:"docs"},{path:"/docs/getting-started",component:f("/docs/getting-started","bb8"),exact:!0,sidebar:"docs"},{path:"/docs/local-development",component:f("/docs/local-development","8ea"),exact:!0,sidebar:"docs"},{path:"/docs/module-api",component:f("/docs/module-api","c68"),exact:!0,sidebar:"docs"},{path:"/docs/package-exports",component:f("/docs/package-exports","cae"),exact:!0,sidebar:"docs"},{path:"/docs/resolution",component:f("/docs/resolution","94c"),exact:!0,sidebar:"docs"},{path:"/docs/source-map-format",component:f("/docs/source-map-format","6c6"),exact:!0,sidebar:"docs"},{path:"/docs/troubleshooting",component:f("/docs/troubleshooting","42d"),exact:!0,sidebar:"docs"}]},{path:"/",component:f("/","c1f"),exact:!0},{path:"*",component:f("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(67294),a=r.createContext(!1);function o(e){var t=e.children,n=(0,r.useState)(!1),o=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(a.Provider,{value:o},t)}},97221:(e,t,n)=>{"use strict";var r=n(67294),a=n(73935),o=n(73727),i=n(70405),l=n(10412);const u=[n(56657),n(32497),n(3310),n(18320),n(93878),n(92509)];var s=n(723),c=n(16550),d=n(18790);function f(e){var t=e.children;return r.createElement(r.Fragment,null,t)}var p=n(83117),m=n(35742),h=n(52263),g=n(44996),v=n(86668),b=n(10833),y=n(94711),w=n(19727),E=n(43320),k=n(18780),S=n(90197);function x(){var e=(0,h.default)().i18n,t=e.defaultLocale,n=e.localeConfigs,a=(0,y.l)();return r.createElement(m.Z,null,Object.entries(n).map((function(e){var t=e[0],n=e[1].htmlLang;return r.createElement("link",{key:t,rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n})})),r.createElement("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function _(e){var t=e.permalink,n=(0,h.default)().siteConfig.url,a=function(){var e=(0,h.default)().siteConfig,t=e.url,n=e.baseUrl,r=e.trailingSlash,a=(0,c.TH)().pathname;return t+(0,k.applyTrailingSlash)((0,g.default)(a),{trailingSlash:r,baseUrl:n})}(),o=t?""+n+t:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function C(){var e=(0,h.default)().i18n.currentLocale,t=(0,v.L)(),n=t.metadata,a=t.image;return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),a&&r.createElement(b.d,{image:a}),r.createElement(_,null),r.createElement(x,null),r.createElement(S.Z,{tag:E.HX,locale:e}),r.createElement(m.Z,null,n.map((function(e,t){return r.createElement("meta",(0,p.Z)({key:t},e))}))))}var T=new Map;function A(e){if(T.has(e.pathname))return Object.assign({},e,{pathname:T.get(e.pathname)});if((0,d.f)(s.Z,e.pathname).some((function(e){return!0===e.route.exact})))return T.set(e.pathname,e.pathname),e;var t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),Object.assign({},e,{pathname:t})}var O=n(98934),L=n(58940),P=n(21073);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n\n'}(e)).replace(/{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(67294),a=n(36809);const o=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-Q1FRRC47Y6"],"anonymizeIP":true,"id":"default"}},"internaldocs-fb":{"default":{"opts":{"docs":{"path":"../docs","editUrl":"https://github.com/facebook/metro/edit/main/docs","sidebarPath":"/home/runner/work/metro/metro/website/sidebars.json","showLastUpdateTime":true,"remarkPlugins":[[null,{"strippedFilePattern":{}}],[null,{}],[null,{"version":"v1"}],null],"rehypePlugins":[]},"theme":{"customCss":"/home/runner/work/metro/metro/website/src/css/custom.scss"},"staticDocsProject":"metro","enableEditor":true,"gtag":{"trackingID":"G-Q1FRRC47Y6","anonymizeIP":true},"id":"default"},"docsDir":"/home/runner/work/metro/metro/docs","repoRootToWebsiteRoot":"home/runner/work/metro/metro/website"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"getting-started","docs":[{"id":"api","path":"/docs/api","sidebar":"docs"},{"id":"bundling","path":"/docs/bundling","sidebar":"docs"},{"id":"caching","path":"/docs/caching","sidebar":"docs"},{"id":"cli","path":"/docs/cli","sidebar":"docs"},{"id":"concepts","path":"/docs/concepts","sidebar":"docs"},{"id":"configuration","path":"/docs/configuration","sidebar":"docs"},{"id":"getting-started","path":"/docs/getting-started","sidebar":"docs"},{"id":"local-development","path":"/docs/local-development","sidebar":"docs"},{"id":"module-api","path":"/docs/module-api","sidebar":"docs"},{"id":"package-exports","path":"/docs/package-exports","sidebar":"docs"},{"id":"resolution","path":"/docs/resolution","sidebar":"docs"},{"id":"source-map-format","path":"/docs/source-map-format","sidebar":"docs"},{"id":"troubleshooting","path":"/docs/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/getting-started","label":"getting-started"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(57529);const u=JSON.parse('{"docusaurusVersion":"2.4.3","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.3"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.3"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.4.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.3"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.3"},"internaldocs-fb":{"type":"package","name":"docusaurus-plugin-internaldocs-fb","version":"1.16.2"},"docusaurus-plugin-sass":{"type":"package","name":"docusaurus-plugin-sass","version":"0.2.2"}}}');var s={siteConfig:a.default,siteMetadata:u,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(s);function d(e){var t=e.children;return r.createElement(c.Provider,{value:s},t)}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(21073),a=n(67294),o=n(10412),i=n(35742),l=n(18780),u=n(1119);function s(e){var t=e.error,n=e.tryAgain;return a.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},a.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),a.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),a.createElement(c,{error:t}))}function c(e){var t=e.error,n=(0,l.getErrorCausalChain)(t).map((function(e){return e.message})).join("\n\nCause:\n");return a.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function d(e){var t=e.error,n=e.tryAgain;return a.createElement(p,{fallback:function(){return a.createElement(s,{error:t,tryAgain:n})}},a.createElement(i.Z,null,a.createElement("title",null,"Page Error")),a.createElement(u.Z,null,a.createElement(s,{error:t,tryAgain:n})))}var f=function(e){return a.createElement(d,e)},p=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={error:null},n}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidCatch=function(e){o.default.canUseDOM&&this.setState({error:e})},n.render=function(){var e=this,t=this.props.children,n=this.state.error;if(n){var r,a={error:n,tryAgain:function(){return e.setState({error:null})}};return(null!=(r=this.props.fallback)?r:f)(a)}return null!=t?t:null},t}(a.Component)},10412:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document;const a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(70405);function o(e){return r.createElement(a.ql,e)}},39960:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>v});var r=n(83117),a=n(80102),o=n(67294),i=n(73727),l=n(18780),u=n(52263),s=n(13919),c=n(10412),d=o.createContext({collectLink:function(){}}),f=function(){return(0,o.useContext)(d)};var p=n(44996),m=["isNavLink","to","href","activeClassName","isActive","data-noBrokenLinkCheck","autoAddBaseUrl"],h=function(e){return e.startsWith("/")};function g(e,t){var n,d,g=e.isNavLink,v=e.to,b=e.href,y=e.activeClassName,w=e.isActive,E=e["data-noBrokenLinkCheck"],k=e.autoAddBaseUrl,S=void 0===k||k,x=(0,a.Z)(e,m),_=(0,u.default)().siteConfig,C=_.trailingSlash,T=_.baseUrl,A=(0,p.useBaseUrlUtils)().withBaseUrl,O=f(),L=(0,o.useRef)(null);(0,o.useImperativeHandle)(t,(function(){return L.current}));var P=v||b;var N,R=(0,s.Z)(P),I=null==P?void 0:P.replace("pathname://",""),M=void 0!==I?(N=I,S&&h(N)?A(N):N):void 0;M&&R&&(M=(0,l.applyTrailingSlash)(M,{trailingSlash:C,baseUrl:T}));var D=(0,o.useRef)(!1),F=g?i.OL:i.rU,B=c.default.canUseIntersectionObserver,U=(0,o.useRef)(),j=function(){D.current||null==M||(window.docusaurus.preload(M),D.current=!0)};(0,o.useEffect)((function(){return!B&&R&&null!=M&&window.docusaurus.prefetch(M),function(){B&&U.current&&U.current.disconnect()}}),[U,M,B,R]);var z=null!=(n=null==(d=M)?void 0:d.startsWith("#"))&&n,$=!M||!R||z;return $||E||O.collectLink(M),$?o.createElement("a",(0,r.Z)({ref:L,href:M},P&&!R&&{target:"_blank",rel:"noopener noreferrer"},x)):o.createElement(F,(0,r.Z)({},x,{onMouseEnter:j,onTouchStart:j,innerRef:function(e){L.current=e,B&&e&&R&&(U.current=new window.IntersectionObserver((function(t){t.forEach((function(t){e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(U.current.unobserve(e),U.current.disconnect(),null!=M&&window.docusaurus.prefetch(M))}))})),U.current.observe(e))},to:M},g&&{isActive:w,activeClassName:y}))}const v=o.forwardRef(g)},95999:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u,translate:()=>l});var r=n(67294);function a(e,t){var n=e.split(/(\{\w+\})/).map((function(e,n){if(n%2==1){var r=null==t?void 0:t[e.slice(1,-1)];if(void 0!==r)return r}return e}));return n.some((function(e){return(0,r.isValidElement)(e)}))?n.map((function(e,t){return(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e})).filter((function(e){return""!==e})):n.join("")}var o=n(57529);function i(e){var t,n,r=e.id,a=e.message;if(void 0===r&&void 0===a)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!=(t=null!=(n=o[null!=r?r:a])?n:a)?t:r}function l(e,t){return a(i({message:e.message,id:e.id}),t)}function u(e){var t=e.children,n=e.id,o=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");var l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});var r="default"},13919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},44996:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l,useBaseUrlUtils:()=>i});var r=n(67294),a=n(52263),o=n(13919);function i(){var e=(0,a.default)().siteConfig,t=e.baseUrl,n=e.url,i=(0,r.useCallback)((function(e,r){return function(e,t,n,r){var a=void 0===r?{}:r,i=a.forcePrependBaseUrl,l=void 0!==i&&i,u=a.absolute,s=void 0!==u&&u;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(l)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;var c=n.startsWith(t)?n:t+n.replace(/^\//,"");return s?e+c:c}(n,t,e,r)}),[n,t]);return{withBaseUrl:i}}function l(e,t){return void 0===t&&(t={}),(0,i().withBaseUrl)(e,t)}},52263:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294),a=n(58940);function o(){return(0,r.useContext)(a._)}},28084:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o,useAllPluginInstancesData:()=>i,usePluginData:()=>l});var r=n(52263),a=n(29935);function o(){return(0,r.default)().globalData}function i(e,t){void 0===t&&(t={});var n=o()[e];if(!n&&t.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return n}function l(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});var r=i(e),o=null==r?void 0:r[t];if(!o&&n.failfast)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return o}},72389:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294),a=n(98934);function o(){return(0,r.useContext)(a._)}},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=function(e){return"object"==typeof e&&!!e&&Object.keys(e).length>0};function a(e){var t=".",n={};return function e(a,o){Object.entries(a).forEach((function(a){var i=a[0],l=a[1],u=o?""+o+t+i:i;r(l)?e(l,u):n[u]=l}))}(e),n}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(67294),a=r.createContext(null);function o(e){var t=e.children,n=e.value,o=r.useContext(a),i=(0,r.useMemo)((function(){return function(e){var t=e.parent,n=e.value;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}var r=Object.assign({},t.data,null==n?void 0:n.data);return{plugin:t.plugin,data:r}}({parent:o,value:n})}),[o,n]);return r.createElement(a.Provider,{value:i},t)}},94104:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>h,gA:()=>d,WS:()=>f,_r:()=>s,Jo:()=>g,zh:()=>c,yW:()=>m,gB:()=>p});var r=n(16550),a=n(28084);var o=function(e){return e.versions.find((function(e){return e.isLast}))};function i(e,t){var n=o(e);return[].concat(e.versions.filter((function(e){return e!==n})),[n]).find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})}))}function l(e,t){var n,a,o=i(e,t),l=null==o?void 0:o.docs.find((function(e){return!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:o,activeDoc:l,alternateDocVersions:l?(n=l.id,a={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===n&&(a[e.name]=t)}))})),a):{}}}var u={},s=function(){var e;return null!=(e=(0,a.useAllPluginInstancesData)("docusaurus-plugin-content-docs"))?e:u},c=function(e){return(0,a.usePluginData)("docusaurus-plugin-content-docs",e,{failfast:!0})};function d(e){return void 0===e&&(e={}),function(e,t,n){void 0===n&&(n={});var a=Object.entries(e).sort((function(e,t){return t[1].path.localeCompare(e[1].path)})).find((function(e){var n=e[1];return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return o}(s(),(0,r.TH)().pathname,e)}function f(e){void 0===e&&(e={});var t=d(e),n=(0,r.TH)().pathname;if(t)return{activePlugin:t,activeVersion:i(t.pluginData,n)}}function p(e){return c(e).versions}function m(e){var t=c(e);return o(t)}function h(e){return l(c(e),(0,r.TH)().pathname)}function g(e){return function(e,t){var n=o(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(c(e),(0,r.TH)().pathname)}},56657:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate:function(e){var t=e.location,n=e.previousLocation;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((function(){window.gtag("event","page_view",{page_title:document.title,page_location:window.location.href,page_path:t.pathname+t.search+t.hash})}))}}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(74865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate:function(e){var t=e.location,n=e.previousLocation;if(n&&t.pathname!==n.pathname){var r=window.setTimeout((function(){a().start()}),200);return function(){return window.clearTimeout(r)}}},onRouteDidUpdate:function(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r,a,o=n(87410),i=n(36809);r=o.Z,a=i.default.themeConfig.prism.additionalLanguages,globalThis.Prism=r,a.forEach((function(e){n(82500)("./prism-"+e)})),delete globalThis.Prism},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){var t=e.width,n=void 0===t?13.5:t,o=e.height,i=void 0===o?13.5:o;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},1119:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ht});var r=n(67294),a=n(86010),o=n(44763),i=n(10833),l=n(55225),u=n(35281),s=n(19727);const c={skipToContent:"skipToContent_fXgn"};function d(){return r.createElement(l.l,{className:c.skipToContent})}var f=n(86668),p=n(59689),m=n(83117),h=n(95999),g=n(80102),v=["width","height","color","strokeWidth","className"];function b(e){var t=e.width,n=void 0===t?21:t,a=e.height,o=void 0===a?21:a,i=e.color,l=void 0===i?"currentColor":i,u=e.strokeWidth,s=void 0===u?1.2:u,c=(e.className,(0,g.Z)(e,v));return r.createElement("svg",(0,m.Z)({viewBox:"0 0 15 15",width:n,height:o},c),r.createElement("g",{stroke:l,strokeWidth:s},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const y={closeButton:"closeButton_CVFx"};function w(e){return r.createElement("button",(0,m.Z)({type:"button","aria-label":(0,h.translate)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.default)("clean-btn close",y.closeButton,e.className)}),r.createElement(b,{width:14,height:14,strokeWidth:3.1}))}const E={content:"content_knG7"};function k(e){var t=(0,f.L)().announcementBar.content;return r.createElement("div",(0,m.Z)({},e,{className:(0,a.default)(E.content,e.className),dangerouslySetInnerHTML:{__html:t}}))}const S={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function x(){var e=(0,f.L)().announcementBar,t=(0,p.nT)(),n=t.isActive,a=t.close;if(!n)return null;var o=e.backgroundColor,i=e.textColor,l=e.isCloseable;return r.createElement("div",{className:S.announcementBar,style:{backgroundColor:o,color:i},role:"banner"},l&&r.createElement("div",{className:S.announcementBarPlaceholder}),r.createElement(k,{className:S.announcementBarContent}),l&&r.createElement(w,{onClick:a,className:S.announcementBarClose}))}var _=n(93163),C=n(85936),T=n(12466);var A=n(44700),O=n(13102),L=r.createContext(null);function P(e){var t,n,a,o,i,l,u,s=e.children,c=(t=(0,_.e)(),n=(0,O.HY)(),a=(0,r.useState)(!1),o=a[0],i=a[1],l=null!==n.component,u=(0,A.D9)(l),(0,r.useEffect)((function(){l&&!u&&i(!0)}),[l,u]),(0,r.useEffect)((function(){l?t.shown||i(!0):i(!1)}),[t.shown,l]),(0,r.useMemo)((function(){return[o,i]}),[o]));return r.createElement(L.Provider,{value:c},s)}function N(e){if(e.component){var t=e.component;return r.createElement(t,e.props)}}function R(){var e=(0,r.useContext)(L);if(!e)throw new A.i6("NavbarSecondaryMenuDisplayProvider");var t=e[0],n=e[1],a=(0,r.useCallback)((function(){return n(!1)}),[n]),o=(0,O.HY)();return(0,r.useMemo)((function(){return{shown:t,hide:a,content:N(o)}}),[a,o,t])}function I(e){var t=e.header,n=e.primaryMenu,o=e.secondaryMenu,i=R().shown;return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.default)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var M=n(92949),D=n(72389);function F(e){return r.createElement("svg",(0,m.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function B(e){return r.createElement("svg",(0,m.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function j(e){var t=e.className,n=e.buttonClassName,o=e.value,i=e.onChange,l=(0,D.default)(),u=(0,h.translate)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,h.translate)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,h.translate)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.default)(U.toggle,t)},r.createElement("button",{className:(0,a.default)("clean-btn",U.toggleButton,!l&&U.toggleButtonDisabled,n),type:"button",onClick:function(){return i("dark"===o?"light":"dark")},disabled:!l,title:u,"aria-label":u,"aria-live":"polite"},r.createElement(F,{className:(0,a.default)(U.toggleIcon,U.lightToggleIcon)}),r.createElement(B,{className:(0,a.default)(U.toggleIcon,U.darkToggleIcon)})))}const z=r.memo(j),$={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function H(e){var t=e.className,n=(0,f.L)().navbar.style,a=(0,f.L)().colorMode.disableSwitch,o=(0,M.I)(),i=o.colorMode,l=o.setColorMode;return a?null:r.createElement(z,{className:t,buttonClassName:"dark"===n?$.darkNavbarColorModeToggle:void 0,value:i,onChange:l})}var Z=n(21327);function V(){return r.createElement(Z.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function W(){var e=(0,_.e)();return r.createElement("button",{type:"button","aria-label":(0,h.translate)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:function(){return e.toggle()}},r.createElement(b,{color:"var(--ifm-color-emphasis-600)"}))}function G(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(V,null),r.createElement(H,{className:"margin-right--md"}),r.createElement(W,null))}var q=n(39960),K=n(44996),Y=n(13919),Q=n(98022),X=n(39471),J=["activeBasePath","activeBaseRegex","to","href","label","html","isDropdownLink","prependBaseUrlToHref"];function ee(e){var t=e.activeBasePath,n=e.activeBaseRegex,a=e.to,o=e.href,i=e.label,l=e.html,u=e.isDropdownLink,s=e.prependBaseUrlToHref,c=(0,g.Z)(e,J),d=(0,K.default)(a),f=(0,K.default)(t),p=(0,K.default)(o,{forcePrependBaseUrl:!0}),h=i&&o&&!(0,Y.Z)(o),v=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,i,h&&r.createElement(X.Z,u&&{width:12,height:12}))};return o?r.createElement(q.default,(0,m.Z)({href:s?p:o},c,v)):r.createElement(q.default,(0,m.Z)({to:d,isNavLink:!0},(t||n)&&{isActive:function(e,t){return n?(0,Q.F)(n,t.pathname):t.pathname.startsWith(f)}},c,v))}var te=["className","isDropdownItem"],ne=["className","isDropdownItem"],re=["mobile","position"];function ae(e){var t=e.className,n=e.isDropdownItem,o=void 0!==n&&n,i=(0,g.Z)(e,te),l=r.createElement(ee,(0,m.Z)({className:(0,a.default)(o?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:o},i));return o?r.createElement("li",null,l):l}function oe(e){var t=e.className,n=(e.isDropdownItem,(0,g.Z)(e,ne));return r.createElement("li",{className:"menu__list-item"},r.createElement(ee,(0,m.Z)({className:(0,a.default)("menu__link",t)},n)))}function ie(e){var t,n=e.mobile,a=void 0!==n&&n,o=(e.position,(0,g.Z)(e,re)),i=a?oe:ae;return r.createElement(i,(0,m.Z)({},o,{activeClassName:null!=(t=o.activeClassName)?t:a?"menu__link--active":"navbar__link--active"}))}var le=n(86043),ue=n(48596),se=n(16550),ce=n(52263);var de=["items","position","className","onClick"],fe=["items","className","position","onClick"],pe=["mobile"];function me(e,t){return e.some((function(e){return function(e,t){return!!(0,ue.Mg)(e.to,t)||!!(0,Q.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function he(e){var t,n=e.items,o=e.position,i=e.className,l=(e.onClick,(0,g.Z)(e,de)),u=(0,r.useRef)(null),s=(0,r.useState)(!1),c=s[0],d=s[1];return(0,r.useEffect)((function(){var e=function(e){u.current&&!u.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[u]),r.createElement("div",{ref:u,className:(0,a.default)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===o,"dropdown--show":c})},r.createElement(ee,(0,m.Z)({"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,a.default)("navbar__link",i)},l,{onClick:l.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),d(!c))}}),null!=(t=l.children)?t:l.label),r.createElement("ul",{className:"dropdown__menu"},n.map((function(e,t){return r.createElement(rt,(0,m.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))}))))}function ge(e){var t,n,o=e.items,i=e.className,l=(e.position,e.onClick),u=(0,g.Z)(e,fe),s=(n=(0,ce.default)().siteConfig.baseUrl,(0,se.TH)().pathname.replace(n,"/")),c=me(o,s),d=(0,le.u)({initialState:function(){return!c}}),f=d.collapsed,p=d.toggleCollapsed,h=d.setCollapsed;return(0,r.useEffect)((function(){c&&h(!c)}),[s,c,h]),r.createElement("li",{className:(0,a.default)("menu__list-item",{"menu__list-item--collapsed":f})},r.createElement(ee,(0,m.Z)({role:"button",className:(0,a.default)("menu__link menu__link--sublist menu__link--sublist-caret",i)},u,{onClick:function(e){e.preventDefault(),p()}}),null!=(t=u.children)?t:u.label),r.createElement(le.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f},o.map((function(e,t){return r.createElement(rt,(0,m.Z)({mobile:!0,isDropdownItem:!0,onClick:l,activeClassName:"menu__link--active"},e,{key:t}))}))))}function ve(e){var t=e.mobile,n=void 0!==t&&t,a=(0,g.Z)(e,pe),o=n?ge:he;return r.createElement(o,a)}var be=n(94711),ye=["width","height"];function we(e){var t=e.width,n=void 0===t?20:t,a=e.height,o=void 0===a?20:a,i=(0,g.Z)(e,ye);return r.createElement("svg",(0,m.Z)({viewBox:"0 0 24 24",width:n,height:o,"aria-hidden":!0},i),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const Ee={iconLanguage:"iconLanguage_nlXk"};var ke=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function Se(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var xe=n(20830),_e=["translations"];function Ce(){return Ce=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var Le="Ctrl";var Pe=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=Oe(e,_e),i=a.buttonText,l=void 0===i?"Search":i,u=a.buttonAriaLabel,s=void 0===u?"Search":u,c=Te((0,r.useState)(null),2),d=c[0],f=c[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?f("\u2318"):f(Le))}),[]),r.createElement("button",Ce({type:"button",className:"DocSearch DocSearch-Button","aria-label":s},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(xe.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},l)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===Le?r.createElement(Se,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ne=n(35742),Re=n(66177),Ie=n(239),Me=n(43320);var De=n(73935);const Fe={button:{buttonText:(0,h.translate)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,h.translate)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,h.translate)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,h.translate)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,h.translate)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,h.translate)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,h.translate)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,h.translate)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,h.translate)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,h.translate)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,h.translate)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,h.translate)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,h.translate)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,h.translate)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,h.translate)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,h.translate)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,h.translate)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,h.translate)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,h.translate)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,h.translate)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,h.translate)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,h.translate)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,h.translate)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,h.translate)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,h.translate)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,h.translate)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,h.translate)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};var Be=["contextualSearch","externalUrlRegex"],Ue=null;function je(e){var t=e.hit,n=e.children;return r.createElement(q.default,{to:t.url},n)}function ze(e){var t=e.state,n=e.onClose,a=(0,Re.M)();return r.createElement(q.default,{to:a(t.query),onClick:n},r.createElement(h.default,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function $e(e){var t,a,o,i,l,u=e.contextualSearch,s=e.externalUrlRegex,c=(0,g.Z)(e,Be),d=(0,ce.default)().siteMetadata,f=(0,Ie.l)(),p=["language:"+(o=(0,Me._q)()).locale,o.tags.map((function(e){return"docusaurus_tag:"+e}))],h=null!=(t=null==(a=c.searchParameters)?void 0:a.facetFilters)?t:[],v=u?(i=h,[].concat((l=function(e){return"string"==typeof e?[e]:e})(p),l(i))):h,b=Object.assign({},c.searchParameters,{facetFilters:v}),y=(0,se.k6)(),w=(0,r.useRef)(null),E=(0,r.useRef)(null),k=(0,r.useState)(!1),S=k[0],x=k[1],_=(0,r.useState)(void 0),C=_[0],T=_[1],A=(0,r.useCallback)((function(){return Ue?Promise.resolve():Promise.all([n.e(426).then(n.bind(n,61426)),Promise.all([n.e(532),n.e(945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(894)]).then(n.bind(n,18894))]).then((function(e){var t=e[0].DocSearchModal;Ue=t}))}),[]),O=(0,r.useCallback)((function(){A().then((function(){w.current=document.createElement("div"),document.body.insertBefore(w.current,document.body.firstChild),x(!0)}))}),[A,x]),L=(0,r.useCallback)((function(){var e;x(!1),null==(e=w.current)||e.remove()}),[x]),P=(0,r.useCallback)((function(e){A().then((function(){x(!0),T(e.key)}))}),[A,x,T]),N=(0,r.useRef)({navigate:function(e){var t=e.itemUrl;(0,Q.F)(s,t)?window.location.href=t:y.push(t)}}).current,R=(0,r.useRef)((function(e){return c.transformItems?c.transformItems(e):e.map((function(e){return Object.assign({},e,{url:f(e.url)})}))})).current,I=(0,r.useMemo)((function(){return function(e){return r.createElement(ze,(0,m.Z)({},e,{onClose:L}))}}),[L]),M=(0,r.useCallback)((function(e){return e.addAlgoliaAgent("docusaurus",d.docusaurusVersion),e}),[d.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:S,onOpen:O,onClose:L,onInput:P,searchButtonRef:E}),r.createElement(r.Fragment,null,r.createElement(Ne.Z,null,r.createElement("link",{rel:"preconnect",href:"https://"+c.appId+"-dsn.algolia.net",crossOrigin:"anonymous"})),r.createElement(Pe,{onTouchStart:A,onFocus:A,onMouseOver:A,onClick:O,ref:E,translations:Fe.button}),S&&Ue&&w.current&&(0,De.createPortal)(r.createElement(Ue,(0,m.Z)({onClose:L,initialScrollY:window.scrollY,initialQuery:C,navigator:N,transformItems:R,hitComponent:je,transformSearchClient:M},c.searchPagePath&&{resultsFooterComponent:I},c,{searchParameters:b,placeholder:Fe.placeholder,translations:Fe.modal})),w.current))}function He(){var e=(0,ce.default)().siteConfig;return r.createElement($e,e.themeConfig.algolia)}const Ze={searchBox:"searchBox_ZlJk"};function Ve(e){var t=e.children,n=e.className;return r.createElement("div",{className:(0,a.default)(n,Ze.searchBox)},t)}var We=n(94104),Ge=n(24575),qe=["docId","label","docsPluginId"];var Ke=["sidebarId","label","docsPluginId"];var Ye=["label","to","docsPluginId"],Qe=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};var Xe=n(60373),Je=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],et=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};const tt={default:ie,localeDropdown:function(e){var t=e.mobile,n=e.dropdownItemsBefore,a=e.dropdownItemsAfter,o=(0,g.Z)(e,ke),i=(0,ce.default)().i18n,l=i.currentLocale,u=i.locales,s=i.localeConfigs,c=(0,be.l)(),d=(0,se.TH)(),f=d.search,p=d.hash,v=u.map((function(e){var n=""+("pathname://"+c.createUrl({locale:e,fullyQualified:!1}))+f+p;return{label:s[e].label,lang:s[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===l?t?"menu__link--active":"dropdown__link--active":""}})),b=[].concat(n,v,a),y=t?(0,h.translate)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):s[l].label;return r.createElement(ve,(0,m.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(we,{className:Ee.iconLanguage}),y),items:b}))},search:function(e){var t=e.mobile,n=e.className;return t?null:r.createElement(Ve,{className:n},r.createElement(He,null))},dropdown:ve,html:function(e){var t=e.value,n=e.className,o=e.mobile,i=void 0!==o&&o,l=e.isDropdownItem,u=void 0!==l&&l,s=u?"li":"div";return r.createElement(s,{className:(0,a.default)({navbar__item:!i&&!u,"menu__list-item":i},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){var t=e.docId,n=e.label,a=e.docsPluginId,o=(0,g.Z)(e,qe),i=(0,We.Iw)(a).activeDoc,l=(0,Ge.vY)(t,a);return null===l?null:r.createElement(ie,(0,m.Z)({exact:!0},o,{isActive:function(){return(null==i?void 0:i.path)===l.path||!(null==i||!i.sidebar)&&i.sidebar===l.sidebar},label:null!=n?n:l.id,to:l.path}))},docSidebar:function(e){var t=e.sidebarId,n=e.label,a=e.docsPluginId,o=(0,g.Z)(e,Ke),i=(0,We.Iw)(a).activeDoc,l=(0,Ge.oz)(t,a).link;if(!l)throw new Error('DocSidebarNavbarItem: Sidebar with ID "'+t+"\" doesn't have anything to be linked to.");return r.createElement(ie,(0,m.Z)({exact:!0},o,{isActive:function(){return(null==i?void 0:i.sidebar)===t},label:null!=n?n:l.label,to:l.path}))},docsVersion:function(e){var t=e.label,n=e.to,a=e.docsPluginId,o=(0,g.Z)(e,Ye),i=(0,Ge.lO)(a)[0],l=null!=t?t:i.label,u=null!=n?n:Qe(i).path;return r.createElement(ie,(0,m.Z)({},o,{label:l,to:u}))},docsVersionDropdown:function(e){var t=e.mobile,n=e.docsPluginId,a=e.dropdownActiveClassDisabled,o=e.dropdownItemsBefore,i=e.dropdownItemsAfter,l=(0,g.Z)(e,Je),u=(0,se.TH)(),s=u.search,c=u.hash,d=(0,We.Iw)(n),f=(0,We.gB)(n),p=(0,Xe.J)(n).savePreferredVersionName,v=f.map((function(e){var t,n=null!=(t=d.alternateDocVersions[e.name])?t:et(e);return{label:e.label,to:""+n.path+s+c,isActive:function(){return e===d.activeVersion},onClick:function(){return p(e.name)}}})),b=[].concat(o,v,i),y=(0,Ge.lO)(n)[0],w=t&&b.length>1?(0,h.translate)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):y.label,E=t&&b.length>1?void 0:et(y).path;return b.length<=1?r.createElement(ie,(0,m.Z)({},l,{mobile:t,label:w,to:E,isActive:a?function(){return!1}:void 0})):r.createElement(ve,(0,m.Z)({},l,{mobile:t,label:w,to:E,items:b,isActive:a?function(){return!1}:void 0}))}};var nt=["type"];function rt(e){var t=e.type,n=(0,g.Z)(e,nt),a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=tt[a];if(!o)throw new Error('No NavbarItem component found for type "'+t+'".');return r.createElement(o,n)}function at(){var e=(0,_.e)(),t=(0,f.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map((function(t,n){return r.createElement(rt,(0,m.Z)({mobile:!0},t,{onClick:function(){return e.toggle()},key:n}))})))}function ot(e){return r.createElement("button",(0,m.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(h.default,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function it(){var e=0===(0,f.L)().navbar.items.length,t=R();return r.createElement(r.Fragment,null,!e&&r.createElement(ot,{onClick:function(){return t.hide()}}),t.content)}function lt(){var e,t=(0,_.e)();return void 0===(e=t.shown)&&(e=!0),(0,r.useEffect)((function(){return document.body.style.overflow=e?"hidden":"visible",function(){document.body.style.overflow="visible"}}),[e]),t.shouldRender?r.createElement(I,{header:r.createElement(G,null),primaryMenu:r.createElement(at,null),secondaryMenu:r.createElement(it,null)}):null}const ut={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function st(e){return r.createElement("div",(0,m.Z)({role:"presentation"},e,{className:(0,a.default)("navbar-sidebar__backdrop",e.className)}))}function ct(e){var t=e.children,n=(0,f.L)().navbar,o=n.hideOnScroll,i=n.style,l=(0,_.e)(),u=function(e){var t=(0,r.useState)(e),n=t[0],a=t[1],o=(0,r.useRef)(!1),i=(0,r.useRef)(0),l=(0,r.useCallback)((function(e){null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,T.RF)((function(t,n){var r=t.scrollY;if(e)if(r=l?a(!1):r+s0&&r.createElement(Lt,{links:n}),logo:a&&r.createElement(It,{logo:a}),copyright:t&&r.createElement(Mt,{copyright:t})})}const Bt=r.memo(Ft);var Ut=(0,A.Qc)([M.S,p.pl,T.OC,Xe.L5,i.VC,function(e){var t=e.children;return r.createElement(O.n2,null,r.createElement(_.M,null,r.createElement(P,null,t)))}]);function jt(e){var t=e.children;return r.createElement(Ut,null,t)}function zt(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(h.default,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(dt.Cw,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(dt.aG,{error:t})))))}const $t={mainWrapper:"mainWrapper_z2l0"};function Ht(e){var t=e.children,n=e.noFooter,c=e.wrapperClassName,f=e.title,p=e.description;return(0,s.t)(),r.createElement(jt,null,r.createElement(i.d,{title:f,description:p}),r.createElement(d,null),r.createElement(x,null),r.createElement(wt,null),r.createElement("div",{id:l.u,className:(0,a.default)(u.k.wrapper.main,$t.mainWrapper,c)},r.createElement(o.Z,{fallback:function(e){return r.createElement(zt,e)}},t)),!n&&r.createElement(Bt,null))}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(83117),a=n(80102),o=n(67294),i=n(39960),l=n(44996),u=n(52263),s=n(86668),c=n(50941),d=["imageClassName","titleClassName"];function f(e){var t=e.logo,n=e.alt,r=e.imageClassName,a={light:(0,l.default)(t.src),dark:(0,l.default)(t.srcDark||t.src)},i=o.createElement(c.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?o.createElement("div",{className:r},i):i}function p(e){var t,n=(0,u.default)().siteConfig.title,c=(0,s.L)().navbar,p=c.title,m=c.logo,h=e.imageClassName,g=e.titleClassName,v=(0,a.Z)(e,d),b=(0,l.default)((null==m?void 0:m.href)||"/"),y=p?"":n,w=null!=(t=null==m?void 0:m.alt)?t:y;return o.createElement(i.default,(0,r.Z)({to:b},v,(null==m?void 0:m.target)&&{target:m.target}),m&&o.createElement(f,{logo:m,alt:w,imageClassName:h}),null!=p&&o.createElement("b",{className:g},p))}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(35742);function o(e){var t=e.locale,n=e.version,o=e.tag,i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},50941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(83117),a=n(80102),o=n(67294),i=n(86010),l=n(72389),u=n(92949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};var c=["sources","className","alt"];function d(e){var t=(0,l.default)(),n=(0,u.I)().colorMode,d=e.sources,f=e.className,p=e.alt,m=(0,a.Z)(e,c),h=t?"dark"===n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,h.map((function(e){return o.createElement("img",(0,r.Z)({key:e,src:d[e],alt:p,className:(0,i.default)(s.themedImage,s["themedImage--"+e],f)},m))})))}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>d,z:()=>y});var r=n(83117),a=n(80102),o=n(67294),i=n(10412),l=n(91442),u=["collapsed"],s=["lazy"],c="ease-in-out";function d(e){var t=e.initialState,n=(0,o.useState)(null!=t&&t),r=n[0],a=n[1],i=(0,o.useCallback)((function(){a((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:a,toggleCollapsed:i}}var f={display:"none",overflow:"hidden",height:"0px"},p={display:"block",overflow:"visible",height:"auto"};function m(e,t){var n=t?f:p;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function h(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,a=(0,o.useRef)(!1);(0,o.useEffect)((function(){var e,o=t.current;function i(){var e,t,n=o.scrollHeight,a=null!=(e=null==r?void 0:r.duration)?e:function(e){if((0,l.n)())return 1;var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}(n);return{transition:"height "+a+"ms "+(null!=(t=null==r?void 0:r.easing)?t:c),height:n+"px"}}function u(){var e=i();o.style.transition=e.transition,o.style.height=e.height}if(!a.current)return m(o,n),void(a.current=!0);return o.style.willChange="height",e=requestAnimationFrame((function(){n?(u(),requestAnimationFrame((function(){o.style.height=f.height,o.style.overflow=f.overflow}))):(o.style.display="block",requestAnimationFrame((function(){u()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function g(e){if(!i.default.canUseDOM)return e?f:p}function v(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,a=e.children,i=e.animation,l=e.onCollapseTransitionEnd,u=e.className,s=e.disableSSRStyle,c=(0,o.useRef)(null);return h({collapsibleRef:c,collapsed:r,animation:i}),o.createElement(n,{ref:c,style:s?void 0:g(r),onTransitionEnd:function(e){"height"===e.propertyName&&(m(c.current,r),null==l||l(r))},className:u},a)}function b(e){var t=e.collapsed,n=(0,a.Z)(e,u),i=(0,o.useState)(!t),l=i[0],s=i[1],c=(0,o.useState)(t),d=c[0],f=c[1];return(0,o.useLayoutEffect)((function(){t||s(!0)}),[t]),(0,o.useLayoutEffect)((function(){l&&f(t)}),[l,t]),l?o.createElement(v,(0,r.Z)({},n,{collapsed:d})):null}function y(e){var t=e.lazy,n=(0,a.Z)(e,s),r=t?b:v;return o.createElement(r,n)}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>p});var r=n(67294),a=n(72389),o=n(50012),i=n(44700),l=n(86668),u=(0,o.WA)("docusaurus.announcement.dismiss"),s=(0,o.WA)("docusaurus.announcement.id"),c=function(){return"true"===u.get()},d=function(e){return u.set(String(e))},f=r.createContext(null);function p(e){var t=e.children,n=function(){var e=(0,l.L)().announcementBar,t=(0,a.default)(),n=(0,r.useState)((function(){return!!t&&c()})),o=n[0],i=n[1];(0,r.useEffect)((function(){i(c())}),[]);var u=(0,r.useCallback)((function(){d(!0),i(!0)}),[]);return(0,r.useEffect)((function(){if(e){var t=e.id,n=s.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;s.set(t),r&&d(!1),!r&&c()||i(!1)}}),[e]),(0,r.useMemo)((function(){return{isActive:!!e&&!o,close:u}}),[e,o,u])}();return r.createElement(f.Provider,{value:n},t)}function m(){var e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>g,S:()=>h});var r=n(67294),a=n(10412),o=n(44700),i=n(50012),l=n(86668),u=r.createContext(void 0),s="theme",c=(0,i.WA)(s),d={light:"light",dark:"dark"},f=function(e){return e===d.dark?d.dark:d.light},p=function(e){return a.default.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e)},m=function(e){c.set(f(e))};function h(e){var t=e.children,n=function(){var e=(0,l.L)().colorMode,t=e.defaultMode,n=e.disableSwitch,a=e.respectPrefersColorScheme,o=(0,r.useState)(p(t)),i=o[0],u=o[1];(0,r.useEffect)((function(){n&&c.del()}),[n]);var h=(0,r.useCallback)((function(e,n){void 0===n&&(n={});var r=n.persist,o=void 0===r||r;e?(u(e),o&&m(e)):(u(a?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:t),c.del())}),[a,t]);(0,r.useEffect)((function(){document.documentElement.setAttribute("data-theme",f(i))}),[i]),(0,r.useEffect)((function(){if(!n){var e=function(e){if(e.key===s){var t=c.get();null!==t&&h(f(t))}};return window.addEventListener("storage",e),function(){return window.removeEventListener("storage",e)}}}),[n,h]);var g=(0,r.useRef)(!1);return(0,r.useEffect)((function(){if(!n||a){var e=window.matchMedia("(prefers-color-scheme: dark)"),t=function(){window.matchMedia("print").matches||g.current?g.current=window.matchMedia("print").matches:h(null)};return e.addListener(t),function(){return e.removeListener(t)}}}),[h,n,a]),(0,r.useMemo)((function(){return{colorMode:i,setColorMode:h,get isDarkTheme(){return i===d.dark},setLightTheme:function(){h(d.light)},setDarkTheme:function(){h(d.dark)}}}),[i,h])}();return r.createElement(u.Provider,{value:n},t)}function g(){var e=(0,r.useContext)(u);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>b,L5:()=>g,Oh:()=>y});var r=n(67294),a=n(94104),o=n(29935),i=n(86668),l=n(24575),u=n(44700),s=n(50012),c=function(e){return"docs-preferred-version-"+e},d={save:function(e,t,n){(0,s.WA)(c(e),{persistence:t}).set(n)},read:function(e,t){return(0,s.WA)(c(e),{persistence:t}).get()},clear:function(e,t){(0,s.WA)(c(e),{persistence:t}).del()}},f=function(e){return Object.fromEntries(e.map((function(e){return[e,{preferredVersionName:null}]})))};var p=r.createContext(null);function m(){var e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((function(){return Object.keys(e)}),[e]),o=(0,r.useState)((function(){return f(n)})),l=o[0],u=o[1];return(0,r.useEffect)((function(){u(function(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;return Object.fromEntries(t.map((function(e){return[e,(t=e,a=d.read(t,n),r[t].versions.some((function(e){return e.name===a}))?{preferredVersionName:a}:(d.clear(t,n),{preferredVersionName:null}))];var t,a})))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[l,(0,r.useMemo)((function(){return{savePreferredVersion:function(e,n){d.save(e,t,n),u((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}function h(e){var t=e.children,n=m();return r.createElement(p.Provider,{value:n},t)}function g(e){var t=e.children;return l.cE?r.createElement(h,null,t):r.createElement(r.Fragment,null,t)}function v(){var e=(0,r.useContext)(p);if(!e)throw new u.i6("DocsPreferredVersionContextProvider");return e}function b(e){var t;void 0===e&&(e=o.m);var n=(0,a.zh)(e),i=v(),l=i[0],u=i[1],s=l[e].preferredVersionName;return{preferredVersion:null!=(t=n.versions.find((function(e){return e.name===s})))?t:null,savePreferredVersionName:(0,r.useCallback)((function(t){u.savePreferredVersion(e,t)}),[u,e])}}function y(){var e=(0,a._r)(),t=v()[0];var n=Object.keys(e);return Object.fromEntries(n.map((function(n){return[n,(r=n,o=e[r],i=t[r].preferredVersionName,null!=(a=o.versions.find((function(e){return e.name===i})))?a:null)];var r,a,o,i})))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>u,b:()=>l});var r=n(67294),a=n(44700),o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){var t=e.children,n=e.name,a=e.items,o=(0,r.useMemo)((function(){return n&&a?{name:n,items:a}:null}),[n,a]);return r.createElement(i.Provider,{value:o},t)}function u(){var e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>f});var r=n(67294),a=n(13102),o=n(87524),i=n(91980),l=n(86668),u=n(44700),s=r.createContext(void 0);function c(){var e,t=(e=(0,a.HY)(),0===(0,l.L)().navbar.items.length&&!e.component),n=(0,o.i)(),u=!t&&"mobile"===n,s=(0,r.useState)(!1),c=s[0],d=s[1];(0,i.Rb)((function(){if(c)return d(!1),!1}));var f=(0,r.useCallback)((function(){d((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===n&&d(!1)}),[n]),(0,r.useMemo)((function(){return{disabled:t,shouldRender:u,toggle:f,shown:c}}),[t,u,f,c])}function d(e){var t=e.children,n=c();return r.createElement(s.Provider,{value:n},t)}function f(){var e=r.useContext(s);if(void 0===e)throw new u.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>u,n2:()=>i});var r=n(67294),a=n(44700),o=r.createContext(null);function i(e){var t=e.children,n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){var e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function u(e){var t=e.component,n=e.props,i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");var l=i[1],u=(0,a.Ql)(n);return(0,r.useEffect)((function(){l({component:t,props:u})}),[l,t,u]),(0,r.useEffect)((function(){return function(){return l({component:null,props:null})}}),[l]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(67294),a="navigation-with-keyboard";function o(){(0,r.useEffect)((function(){function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),function(){document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,t,n)=>{"use strict";n.d(t,{K:()=>l,M:()=>u});var r=n(67294),a=n(52263),o=n(91980),i="q";function l(){return(0,o.Nc)(i)}function u(){var e=(0,a.default)().siteConfig,t=e.baseUrl,n=e.themeConfig.algolia.searchPagePath;return(0,r.useCallback)((function(e){return""+t+n+"?"+i+"="+encodeURIComponent(e)}),[t,n])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(67294),a=n(10412),o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.default.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}var u=!1;function s(){var e=(0,r.useState)((function(){return u?"ssr":l()})),t=e[0],n=e[1];return(0,r.useEffect)((function(){function e(){n(l())}var t=u?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(t)}}),[]),t}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:function(e){return"theme-admonition-"+e}},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}}},91442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},24575:(e,t,n)=>{"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[a++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}n.d(t,{MN:()=>_,Wl:()=>m,_F:()=>b,cE:()=>p,jA:()=>h,hI:()=>x,lO:()=>E,vY:()=>S,oz:()=>k,s1:()=>w});var o=n(67294),i=n(16550),l=n(18790),u=n(94104),s=n(60373),c=n(1116),d=n(67392),f=n(48596),p=!!u._r;function m(e){if(e.href)return e.href;for(var t,n=a(e.items);!(t=n()).done;){var r=t.value;if("link"===r.type)return r.href;if("category"===r.type){var o=m(r);if(o)return o}}}function h(){var e=(0,i.TH)().pathname,t=(0,c.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");var n=y({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(e+" is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.");return n}var g=function(e,t){return void 0!==e&&(0,f.Mg)(e,t)},v=function(e,t){return e.some((function(e){return b(e,t)}))};function b(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||v(e.items,t))}function y(e){var t=e.sidebarItems,n=e.pathname,r=e.onlyCategories,o=void 0!==r&&r,i=[];return function e(t){for(var r,l=a(t);!(r=l()).done;){var u=r.value;if("category"===u.type&&((0,f.Mg)(u.href,n)||e(u.items))||"link"===u.type&&(0,f.Mg)(u.href,n))return o&&"category"!==u.type||i.unshift(u),!0}return!1}(t),i}function w(){var e,t=(0,c.V)(),n=(0,i.TH)().pathname;return!1!==(null==(e=(0,u.gA)())?void 0:e.pluginData.breadcrumbs)&&t?y({sidebarItems:t.items,pathname:n}):null}function E(e){var t=(0,u.Iw)(e).activeVersion,n=(0,s.J)(e).preferredVersion,r=(0,u.yW)(e);return(0,o.useMemo)((function(){return(0,d.j)([t,n,r].filter(Boolean))}),[t,n,r])}function k(e,t){var n=E(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.sidebars?Object.entries(e.sidebars):[]})),r=t.find((function(t){return t[0]===e}));if(!r)throw new Error("Can't find any sidebar with id \""+e+'" in version'+(n.length>1?"s":"")+" "+n.map((function(e){return e.name})).join(", ")+'".\nAvailable sidebar ids are:\n- '+t.map((function(e){return e[0]})).join("\n- "));return r[1]}),[e,n])}function S(e,t){var n=E(t);return(0,o.useMemo)((function(){var t=n.flatMap((function(e){return e.docs})),r=t.find((function(t){return t.id===e}));if(!r){if(n.flatMap((function(e){return e.draftIds})).includes(e))return null;throw new Error("Couldn't find any doc with id \""+e+'" in version'+(n.length>1?"s":"")+' "'+n.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+(0,d.j)(t.map((function(e){return e.id}))).join("\n- "))}return r}),[e,n])}function x(e){var t=e.route,n=e.versionMetadata,r=(0,i.TH)(),a=t.routes,o=a.find((function(e){return(0,i.LX)(r.pathname,e)}));if(!o)return null;var u=o.sidebar,s=u?n.docsSidebars[u]:void 0;return{docElement:(0,l.H)(a),sidebarName:u,sidebarItems:s}}function _(e){return e.filter((function(e){return"category"!==e.type||!!m(e)}))}},69690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>c,Cw:()=>s,QW:()=>d});var r=n(21073),a=n(83117),o=n(67294),i=n(95999),l=n(18780);const u={errorBoundaryError:"errorBoundaryError_a6uf"};function s(e){return o.createElement("button",(0,a.Z)({type:"button"},e),o.createElement(i.default,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function c(e){var t=e.error,n=(0,l.getErrorCausalChain)(t).map((function(e){return e.message})).join("\n\nCause:\n");return o.createElement("p",{className:u.errorBoundaryError},n)}var d=function(e){function t(){return e.apply(this,arguments)||this}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidCatch=function(e,t){throw this.props.onError(e,t)},n.render=function(){return this.props.children},t}(o.Component)},42489:(e,t,n)=>{"use strict";function r(e){return"title"in e[0]}n.d(t,{a:()=>r})},82128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(52263);function a(e){var t=(0,r.default)().siteConfig,n=t.title,a=t.titleDelimiter;return null!=e&&e.trim().length?e.trim()+" "+a+" "+n:n}},91980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>s,Rb:()=>l,_X:()=>u});var r=n(67294),a=n(16550),o=n(61688),i=n(44700);function l(e){!function(e){var t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((function(){return t.block((function(e,t){return n(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function u(e){return t=function(t){return null===e?null:new URLSearchParams(t.location.search).get(e)},n=(0,a.k6)(),(0,o.useSyncExternalStore)(n.listen,(function(){return t(n)}),(function(){return t(n)}));var t,n}function s(e){var t,n,o=null!=(t=u(e))?t:"",i=(n=(0,a.k6)(),(0,r.useCallback)((function(e,t,r){var a=new URLSearchParams(n.location.search);t?a.set(e,t):a.delete(e),(null!=r&&r.push?n.push:n.replace)({search:a.toString()})}),[n]));return[o,(0,r.useCallback)((function(t,n){i(e,t,n)}),[i,e])]}},67392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=function(e,t){return e===t}),e.filter((function(n,r){return e.findIndex((function(e){return t(e,n)}))!==r}))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},10833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>c,VC:()=>p});var r=n(67294),a=n(86010),o=n(35742),i=n(30226);function l(){var e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var u=n(44996),s=n(82128);function c(e){var t=e.title,n=e.description,a=e.keywords,i=e.image,l=e.children,c=(0,s.p)(t),d=(0,u.useBaseUrlUtils)().withBaseUrl,f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}var d=r.createContext(void 0);function f(e){var t=e.className,n=e.children,i=r.useContext(d),l=(0,a.default)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function p(e){var t=e.children,n=l(),o="plugin-"+n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,""),i="plugin-id-"+n.plugin.id;return r.createElement(f,{className:(0,a.default)(o,i)},t)}},44700:(e,t,n)=>{"use strict";n.d(t,{i6:()=>p,Qc:()=>h,zX:()=>d,LI:()=>c,D9:()=>f,Ql:()=>m});var r=n(28900),a=n(21073);function o(e){return o=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},o(e)}var i=n(79817);function l(e,t,n){return l=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}()?Reflect.construct.bind():function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,i.Z)(a,n.prototype),a},l.apply(null,arguments)}function u(e){var t="function"==typeof Map?new Map:void 0;return u=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return l(e,arguments,o(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(r,e)},u(e)}var s=n(67294),c=n(10412).default.canUseDOM?s.useLayoutEffect:s.useEffect;function d(e){var t=(0,s.useRef)(e);return c((function(){t.current=e}),[e]),(0,s.useCallback)((function(){return t.current.apply(t,arguments)}),[])}function f(e){var t=(0,s.useRef)();return c((function(){t.current=e})),t.current}var p=function(e){function t(t,n){var a,o,i;return(i=e.call(this)||this).name="ReactContextError",i.message="Hook "+(null!=(a=null==(o=i.stack)||null==(o=o.split("\n")[1])||null==(o=o.match((0,r.Z)(/at (?:\w+\.)?(\w+)/,{name:1})))?void 0:o.groups.name)?a:"")+" is called outside the <"+t+">. "+(null!=n?n:""),i}return(0,a.Z)(t,e),t}(u(Error));function m(e){var t=Object.entries(e);return t.sort((function(e,t){return e[0].localeCompare(t[0])})),(0,s.useMemo)((function(){return e}),t.flat())}function h(e){return function(t){var n=t.children;return s.createElement(s.Fragment,null,e.reduceRight((function(e,t){return s.createElement(t,null,e)}),n))}}},98022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(67294),a=n(723),o=n(52263);function i(e,t){var n=function(e){var t;return null==(t=!e||e.endsWith("/")?e:e+"/")?void 0:t.toLowerCase()};return n(e)===n(t)}function l(){var e=(0,o.default)().siteConfig.baseUrl;return(0,r.useMemo)((function(){return function(e){var t=e.baseUrl;function n(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0!==t.length)return t.find(n)||e(t.filter(r).flatMap((function(e){var t;return null!=(t=e.routes)?t:[]})))}(e.routes)}({routes:a.Z,baseUrl:e})}),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>p,OC:()=>u,RF:()=>d,o5:()=>f});var r=n(67294),a=n(10412),o=n(72389),i=n(44700);var l=r.createContext(void 0);function u(e){var t,n=e.children,a=(t=(0,r.useRef)(!0),(0,r.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]));return r.createElement(l.Provider,{value:a},n)}function s(){var e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}var c=function(){return a.default.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function d(e,t){void 0===t&&(t=[]);var n=s().scrollEventsEnabledRef,a=(0,r.useRef)(c()),o=(0,i.zX)(e);(0,r.useEffect)((function(){var e=function(){if(n.current){var e=c();o(e,a.current),a.current=e}},t={passive:!0};return e(),window.addEventListener("scroll",e,t),function(){return window.removeEventListener("scroll",e,t)}}),[o,n].concat(t))}function f(){var e,t,n,a=s(),o=(e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((function(t){e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((function(){var t=e.current,n=t.elem,r=t.top;if(!n)return{restored:!1};var a=n.getBoundingClientRect().top-r;return a&&window.scrollBy({left:0,top:a}),e.current={elem:null,top:0},{restored:0!==a}}),[]),(0,r.useMemo)((function(){return{save:t,restore:n}}),[n,t])),i=(0,r.useRef)(void 0),l=(0,r.useCallback)((function(e){o.save(e),a.disableScrollEvents(),i.current=function(){var e=o.restore().restored;if(i.current=void 0,e){window.addEventListener("scroll",(function e(){a.enableScrollEvents(),window.removeEventListener("scroll",e)}))}else a.enableScrollEvents()}}),[a,o]);return(0,r.useLayoutEffect)((function(){queueMicrotask((function(){return null==i.current?void 0:i.current()}))})),{blockElementScrollPositionUntilNextRender:l}}function p(){var e=(0,r.useRef)(null),t=(0,o.default)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:function(n){e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),function(){}}(n):function(e){var t=null,n=document.documentElement.scrollTop>e;return function r(){var a=document.documentElement.scrollTop;(n&&a>e||!n&&a{"use strict";n.d(t,{HX:()=>i,_q:()=>u,os:()=>l});var r=n(94104),a=n(52263),o=n(60373),i="default";function l(e,t){return"docs-"+e+"-"+t}function u(){var e=(0,a.default)().i18n,t=(0,r._r)(),n=(0,r.WS)(),u=(0,o.Oh)();var s=[i].concat(Object.keys(t).map((function(e){var r,a=(null==n?void 0:n.activePlugin.pluginId)===e?n.activeVersion:void 0,o=u[e],i=t[e].versions.find((function(e){return e.isLast}));return l(e,(null!=(r=null!=a?a:o)?r:i).name)})));return{locale:e.currentLocale,tags:s}}},55225:(e,t,n)=>{"use strict";n.d(t,{l:()=>f,u:()=>u});var r=n(83117),a=n(67294),o=n(16550),i=n(95999),l=n(85936),u="__docusaurus_skipToContent_fallback";function s(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function c(){var e=(0,a.useRef)(null),t=(0,o.k6)().action,n=(0,a.useCallback)((function(e){e.preventDefault();var t,n=null!=(t=document.querySelector("main:first-of-type"))?t:document.getElementById(u);n&&s(n)}),[]);return(0,l.S)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&s(e.current)})),{containerRef:e,onClick:n}}var d=(0,i.translate)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function f(e){var t,n=null!=(t=e.children)?t:d,o=c(),i=o.containerRef,l=o.onClick;return a.createElement("div",{ref:i,role:"region","aria-label":d},a.createElement("a",(0,r.Z)({},e,{href:"#"+u,onClick:l}),n))}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>c,_f:()=>f});var r=n(67294),a=n(61688),o="localStorage";function i(e){var t=e.key,n=e.oldValue,r=e.newValue,a=e.storage;if(n!==r){var o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}}function l(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,u||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),u=!0),null}var t}var u=!1;var s={get:function(){return null},set:function(){},del:function(){},listen:function(){return function(){}}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:t,set:t,del:t,listen:t}}(e);var n=l(null==t?void 0:t.persistence);return null===n?s:{get:function(){try{return n.getItem(e)}catch(t){return console.error("Docusaurus storage error, can't get key="+e,t),null}},set:function(t){try{var r=n.getItem(e);n.setItem(e,t),i({key:e,oldValue:r,newValue:t,storage:n})}catch(a){console.error("Docusaurus storage error, can't set "+e+"="+t,a)}},del:function(){try{var t=n.getItem(e);n.removeItem(e),i({key:e,oldValue:t,newValue:null,storage:n})}catch(r){console.error("Docusaurus storage error, can't delete key="+e,r)}},listen:function(t){try{var r=function(r){r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),function(){return window.removeEventListener("storage",r)}}catch(a){return console.error("Docusaurus storage error, can't listen for changes of key="+e,a),function(){}}}}}function d(e,t){var n=(0,r.useRef)((function(){return null===e?s:c(e,t)})).current(),o=(0,r.useCallback)((function(e){return"undefined"==typeof window?function(){}:n.listen(e)}),[n]);return[(0,a.useSyncExternalStore)(o,(function(){return"undefined"==typeof window?null:n.get()}),(function(){return null})),n]}function f(e){void 0===e&&(e=o);var t=l(e);if(!t)return[];for(var n=[],r=0;r{"use strict";n.d(t,{l:()=>i});var r=n(52263),a=n(16550),o=n(18780);function i(){var e=(0,r.default)(),t=e.siteConfig,n=t.baseUrl,i=t.url,l=t.trailingSlash,u=e.i18n,s=u.defaultLocale,c=u.currentLocale,d=(0,a.TH)().pathname,f=(0,o.applyTrailingSlash)(d,{trailingSlash:l,baseUrl:n}),p=c===s?n:n.replace("/"+c+"/","/"),m=f.replace(n,"");return{createUrl:function(e){var t=e.locale;return""+(e.fullyQualified?i:"")+function(e){return e===s?""+p:""+p+e+"/"}(t)+m}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),a=n(16550),o=n(44700);function i(e){var t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((function(){n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){return(0,r.default)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(52263);function a(){return(0,r.default)().siteConfig.themeConfig}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(67294),a=n(98022),o=n(44996),i=n(6278);function l(){var e=(0,o.useBaseUrlUtils)().withBaseUrl,t=(0,i.L)().algolia,n=t.externalUrlRegex,l=t.replaceSearchResultPathname;return(0,r.useCallback)((function(t){var r=new URL(t);if((0,a.F)(n,r.href))return t;var o=""+(r.pathname+r.hash);return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(o,l))}),[e,n,l])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=t.trailingSlash,r=t.baseUrl;if(e.startsWith("#"))return e;if(void 0===n)return e;var a,o=e.split(/[#?]/)[0],i="/"===o||o===r?o:(a=o,n?function(e){return e.endsWith("/")?e:e+"/"}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));return e.replace(o,i)}},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t].concat(e(t.cause)):[t]}},18780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},88991:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getSpecInfo=void 0;var r=n(38157);t.getSpecInfo=function(e){return(0,r.call)({module:"bloks",api:"getSpecInfo",args:{styleId:e}})}},38157:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.call=void 0;var n=!1,r=0,a={},o=["localhost"],i=".internalfb.com";var l="undefined"!=typeof window&&new URL(window.location.href).searchParams.get("parentHostname")||"https://www.internalfb.com";t.call=function(e){if(!o.includes(window.location.hostname)&&!window.location.hostname.endsWith(i))return Promise.reject(new Error("Not running on static docs"));n||(n=!0,window.addEventListener("message",(function(e){if("static-docs-bridge-response"===e.data.event){var t=e.data.id;t in a||console.error("Recieved response for id: "+t+" with no matching receiver"),"response"in e.data?a[t].resolve(e.data.response):a[t].reject(new Error(e.data.error)),delete a[t]}})));var t=r++,u=new Promise((function(e,n){a[t]={resolve:e,reject:n}})),s={event:"static-docs-bridge-call",id:t,module:e.module,api:e.api,args:e.args},c="localhost"===window.location.hostname?"*":l;return window.parent.postMessage(s,c),u}},86735:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.gk=t.getGKs=void 0;var r=n(38157);function a(){return(0,r.call)({module:"gks",api:"getGKs",args:{}})}t.getGKs=a;var o={};t.gk=function(e){return e in o?Promise.resolve(o[e]):a().then((function(t){return o[e]=-1!==t.xfb_static_docs_query.static_docs_gks.findIndex((function(t){return t.name==e})),o[e]})).catch((function(){return o[e]=!1,o[e]}))}},75707:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.reportContentSelected=t.reportFeatureUsage=t.reportContentCopied=void 0;var r=n(38157),a=function(){};t.reportContentCopied=function(e){var t=e.textContent;return(0,r.call)({module:"feedback",api:"reportContentCopied",args:{textContent:t}}).then(a).catch(a)},t.reportFeatureUsage=function(e){var t=e.featureName,n=e.id;return console.log("used feature"),(0,r.call)({module:"feedback",api:"reportFeatureUsage",args:{featureName:t,id:n}}).then(a).catch(a)},t.reportContentSelected=function(e){var t=e.textContent;return(0,r.call)({module:"feedback",api:"reportContentSelected",args:{textContent:t}}).then(a).catch(a)}},86341:function(e,t,n){"use strict";var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var a=Object.getOwnPropertyDescriptor(t,n);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,a)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&r(t,e,n);return a(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.OssOnly=t.FbInternalOnly=t.getEphemeralDiffNumber=t.hasEphemeralDiffNumber=t.isInternal=t.validateFbContentArgs=t.fbInternalOnly=t.fbContent=t.metagenServiceStatus=t.internComponent=t.checkGKs=t.inpageeditor=t.feedback=t.uidocs=t.bloks=void 0,t.bloks=o(n(88991)),t.uidocs=o(n(87688)),t.feedback=o(n(75707)),t.inpageeditor=o(n(19445)),t.checkGKs=o(n(86735)),t.internComponent=o(n(64602)),t.metagenServiceStatus=o(n(83129));var i=["internal","external"];function l(e){return s(e),c()?"internal"in e?u(e.internal):[]:"external"in e?u(e.external):[]}function u(e){return"function"==typeof e?e():e}function s(e){if("object"!=typeof e)throw new Error("fbContent() args must be an object containing keys: "+i+". Instead got "+e);if(!Object.keys(e).find((function(e){return i.find((function(t){return t===e}))})))throw new Error("No valid args found in "+JSON.stringify(e)+". Accepted keys: "+i);var t=Object.keys(e).filter((function(e){return!i.find((function(t){return t===e}))}));if(t.length>0)throw new Error("Unexpected keys "+t+" found in fbContent() args. Accepted keys: "+i)}function c(){try{return Boolean(!1)}catch(e){return console.log("process.env.FB_INTERNAL couldn't be read, maybe you forgot to add the required webpack EnvironmentPlugin config?",e),!1}}function d(){try{return null}catch(e){return console.log("process.env.PHABRICATOR_DIFF_NUMBER couldn't be read, maybe you forgot to add the required webpack EnvironmentPlugin config?",e),null}}t.fbContent=l,t.fbInternalOnly=function(e){return l({internal:e})},t.validateFbContentArgs=s,t.isInternal=c,t.hasEphemeralDiffNumber=function(){return Boolean(d())},t.getEphemeralDiffNumber=d,t.FbInternalOnly=function(e){return c()?e.children:null},t.OssOnly=function(e){return c()?null:e.children}},19445:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.submitDiff=t.DiffKind=void 0;var r,a=n(38157);!function(e){e.modify="modify",e.add="add"}(r||(t.DiffKind=r={})),t.submitDiff=function(e){var t=e.file_path,n=e.new_content,r=e.project_name,o=e.diff_number,i=e.diff_kind;return(0,a.call)({module:"inpageeditor",api:"createPhabricatorDiffApi",args:{file_path:t,new_content:n,project_name:r,diff_number:o,diff_kind:i}}).catch((function(e){throw new Error("Error occurred while trying to submit diff. Stack trace: "+e)}))}},64602:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.display=void 0;var r=n(38157),a=function(){};t.display=function(e){var t=e.componentName,n=e.posX,o=e.posY,i=e.props;return(0,r.call)({module:"interncomponent",api:"displayComponent",args:{componentName:t,posX:n,posY:o,props:i}}).then(a).catch(a)}},83129:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getServiceStatus=void 0;var r=n(38157);t.getServiceStatus=function(){return(0,r.call)({module:"metagen",api:"getServiceStatus",args:{}})}},87688:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getApi=t.docsets=void 0;var r=n(38157);t.docsets={BLOKS_CORE:"887372105406659"},t.getApi=function(e){var t=e.name,n=e.framework,a=e.docset;return(0,r.call)({module:"uidocs",api:"getApi",args:{name:t,framework:n,docset:a}})}},92509:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var a=r(n(10412)),o=n(86341),i=/^\//,l=/\/$/,u=/^https?:\/\//i,s="__internaldocs_auto_redirect",c="thefacebook.com",d="staticdocs."+c,f="internalfb.com",p="/intern/staticdocs",m="https://www.internalfb.com/intern/internaldocs/check",h="https://staticdocs.thefacebook.com/ping",g="disableRedirect",v="hideNavigation",b="[docusaurus-plugin-internaldocs-fb]";function y(e){return null!==new URLSearchParams(window.location.search).get(e)}t.default=function(){function e(e){if(!window.location.hostname.endsWith(f)){if(window.top==window.self&&window.location.hostname.endsWith("."+c)&&!y(g)){var t=new URL(window.location.href);return t.hostname=f,t.port="",window.location.hostname===d?t.pathname=p+e.pathname:t.pathname=p+window.location.hostname.split(".")[0]+e.pathname,console.log(b+" Redirecting to "+t.href),void(window.location.href=t.href)}var a=new AbortController,o=setTimeout((function(){return a.abort()}),2e3);fetch(h,{signal:a.signal}).then((function(){clearTimeout(o),fetch(m,{credentials:"include",referrerPolicy:"no-referrer-when-downgrade"}).then((function(e){return e.json()})).then((function(e){return function(e){if(!e.showBanner||!e.redirectTo||!e.template)return;var t=document.getElementById("internaldocs-banner");if(t){var a=location.href,o=new URL(a).host,u=a.slice(a.indexOf(o)+o.length),s=e.redirectTo.replace(l,"")+"/"+(u?u.replace(i,""):"");y(g)&&(console.log(b+" Disabling redirect because of query parameter"),r(!1)),e.autoRedirectEnabled&&n()&&(console.log(b+" Redirecting to "+s),window.location.href=s),function(e,t,a,o){var i=t.match(/(.*)\{\{([^}]+)\}\}(.*)/);if(!i)return;var l=i[1]||"",u=i[2]||"",s=i[3]||"";Array.from(e.childNodes).map((function(t){return e.removeChild(t)})),e.appendChild(document.createTextNode(l));var c=document.createElement("a");c.href=a,c.style.color="#3578e5",c.appendChild(document.createTextNode(u)),e.appendChild(c),e.appendChild(document.createTextNode(s));var d=document.createElement("p");d.style.fontSize="11px",d.style.marginBottom="3px";var f=document.createElement("input");f.id="internaldocs-remember-checkbox",f.type="checkbox",f.style.height="8px",f.checked=n(),f.addEventListener("change",(function(){r(Boolean(f.checked))})),d.appendChild(f),o&&e.appendChild(d);var p=document.createElement("label");p.htmlFor="internaldocs-remember-checkbox",p.appendChild(document.createTextNode("Redirect me automatically in future")),d.appendChild(p),e.style.display="block"}(t,e.template,s,e.autoRedirectEnabled)}}(e)})).catch((function(){}))})).catch((function(){}))}}function t(){setTimeout((function(){var e;null===(e=window.parent)||void 0===e||e.postMessage({event:"page-update",title:document.title,location:window.location.href,version:2},"*")}),0)}function n(){var e=localStorage.getItem(s);return"true"===e?(console.log(b+" opted in to auto redirects"),!0):"false"===e?(console.log(b+" opted out of auto redirects"),!1):(console.log(b+" using default auto-redirect behaviour: true"),!0)}function r(e){localStorage.setItem(s,e?"true":"false")}return a.default.canUseDOM&&(e(window.location),t(),document.addEventListener("copy",(function(){var e=document.getSelection();e&&o.feedback.reportContentCopied({textContent:e.toString()})})),y(v)&&document.addEventListener("click",(function(e){var t,n=e.target;(function(e){if("A"==e.tagName&&e.hasAttribute("href")){var t=e.getAttribute("href");if(null!==t&&!u.test(t))return!0}return!1})(n)&&(e.preventDefault(),null===(t=window.parent)||void 0===t||t.postMessage({event:"static-docs-link-click",location:n.getAttribute("href")},"*"))}),!0)),function(){if("undefined"!=typeof window){var e=new window.URLSearchParams(window.location.search).get("_sdoc_theme");"light"!==e&&"dark"!==e||document.documentElement.setAttribute("data-theme",e)}}(),{onRouteUpdate:function(n){e(n.location),t()},onRouteDidUpdate:function(){var e,t,n,r,a,o,i,l,u;y(v)&&(null===(e=document.querySelector("aside"))||void 0===e||e.style.setProperty("display","none"),null===(t=document.querySelectorAll(".footer"))||void 0===t||t.forEach((function(e){e.style.setProperty("display","none")})),null===(n=document.querySelectorAll(".pagination-nav"))||void 0===n||n.forEach((function(e){e.style.setProperty("display","none")})),null===(r=document.querySelectorAll(".theme-edit-this-page"))||void 0===r||r.forEach((function(e){e.style.setProperty("display","none")})),null===(a=document.querySelector("nav"))||void 0===a||a.style.setProperty("display","none"),null===(o=document.querySelector("main"))||void 0===o||o.style.setProperty("max-width","100%"),null===(i=document.querySelectorAll(".theme-doc-toc-mobile"))||void 0===i||i.forEach((function(e){e.style.setProperty("display","none")})),null===(l=document.querySelectorAll(".theme-doc-footer"))||void 0===l||l.forEach((function(e){e.style.setProperty("display","none")})),null===(u=document.querySelectorAll("#editor-trigger"))||void 0===u||u.forEach((function(e){e.style.setProperty("display","none")})))}}}()},86010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta,default:()=>o});const o=a},99318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>p,PP:()=>A,Ep:()=>f});var r=n(83117);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!s)for(;d--;d)i.unshift("..");!s||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(2177);function u(e){return"/"===e.charAt(0)?e:"/"+e}function s(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,h(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(59864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function u(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var s=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=u(t),h=u(n),g=0;g{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var u;if(void 0===t)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[n,r,a,o,i,l],c=0;(u=new Error(t.replace(/%s/g,(function(){return s[c++]})))).name="Invariant Violation"}throw u.framesToPop=1,u}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},93878:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),s=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),u(s,i(e,c,d)),1===e?(u(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){u(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),s=document.querySelector(r.parent);return u(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),s!=document.body&&c(s,"nprogress-custom-parent"),s.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),u=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function s(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;s(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);s(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),u=1;u{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=k.value.length,k=k.next){var x=k.value;if(t.length>e.length)return;if(!(x instanceof a)){var _,C=1;if(b){if(!(_=o(E,S,e,v))||_.index>=e.length)break;var T=_.index,A=_.index+_[0].length,O=S;for(O+=k.value.length;T>=O;)O+=(k=k.next).value.length;if(S=O-=k.value.length,k.value instanceof a)continue;for(var L=k;L!==t.tail&&(Od.reach&&(d.reach=I);var M=k.prev;if(N&&(M=u(t,M,N),S+=N.length),s(t,M,C),k=u(t,M,new a(f,g?r.tokenize(P,g):P,y,P)),R&&u(t,k,R),C>1){var D={cause:f+","+m,reach:I};i(e,t,n,k.prev,S,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function u(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function s(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},u=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var u=n;u=0&&p(s,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function u(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function s(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,u(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function c(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,c={},d=u(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=a,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var u=o.substring(0,l),d=s(c[a]),p=o.substring(l+a.length),m=[];if(u&&m.push(u),m.push(d),p){var h=[p];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var u=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(u=i(t[r-1])+u,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",u,null,u)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var u=0;u=o.length);u++){var s=l[u];if("string"==typeof s||s.content&&"string"==typeof s.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof s?s:s.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),v=f.substring(m+p.length),b=[];h&&b.push.apply(b,i([h])),b.push(g),v&&b.push.apply(b,i([v])),"string"==typeof s?l.splice.apply(l,[u,1].concat(b)):s.content=b}}else s.content&&i(s.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9220:()=>{!function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(Prism)},82500:(e,t,n)=>{var r={"./prism-flow":9220};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=82500},92703:(e,t,n)=>{"use strict";var r=n(50414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),a=n(27418),o=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n