diff --git a/docs/metro.md b/docs/metro.md new file mode 100644 index 00000000000..5fd0676b8eb --- /dev/null +++ b/docs/metro.md @@ -0,0 +1,103 @@ +--- +id: metro +title: Metro +--- + +React Native uses [Metro](https://facebook.github.io/metro/) to build your JavaScript code and assets. + +## Configuring Metro + +Configuration options for Metro can be customized in your project's `metro.config.js` file. This can export either: + +- **An object (recommended)** that will be merged on top of Metro's internal config defaults. +- [**A function**](#advanced-using-a-config-function) that will be called with Metro's internal config defaults and should return a final config object. + +:::tip +Please see [**Configuring Metro**](https://facebook.github.io/metro/docs/configuration) on the Metro website for documentation on all available config options. +::: + +In React Native, your Metro config should extend either [@react-native/metro-config](https://www.npmjs.com/package/@react-native/metro-config) or [@expo/metro-config](https://www.npmjs.com/package/@expo/metro-config). These packages contain essential defaults necessary to build and run React Native apps. + +Below is the default `metro.config.js` file in a React Native template project: + + + +```js +const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); + +/** + * Metro configuration + * https://facebook.github.io/metro/docs/configuration + * + * @type {import('metro-config').MetroConfig} + */ +const config = {}; + +module.exports = mergeConfig(getDefaultConfig(__dirname), config); +``` + + + +Metro options you wish to customize can be done so within the `config` object. We strongly recommend defining all config values statically within this file. + +### Advanced: Using a config function + +Exporting a config function is an opt-in to managing the final config yourself — **Metro will not apply any internal defaults**. This pattern can be useful when needing to read the full default config object from Metro or to set options dynamically. + +:::info +The **@react-native/metro-config** package defines a **partial Metro config**, and must be manually merged with `baseConfig` when using a config function. +::: + + + +```js +const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); + +module.exports = function (baseConfig) { + const defaultConfig = mergeConfig(baseConfig, getDefaultConfig(__dirname)); + const {resolver: {assetExts, sourceExts}} = defaultConfig; + + return mergeConfig( + defaultConfig, + { + resolver: { + assetExts: assetExts.filter(ext => ext !== 'svg'), + sourceExts: [...sourceExts, 'scss', 'css', 'svg'], + }, + }, + ); +}; +``` + + + +:::tip +Using a config function is for advanced use cases. A simpler method than the above, e.g. for customising `sourceExts`, would be to access [these defaults directly from the **metro-config** package](https://github.com/facebook/metro/blob/main/packages/metro-config/src/defaults/defaults.js). + +**Alternative** + +```js +const {assetExts, sourceExts} = require('metro-config/src/defaults/defaults'); +``` + +**However!**, we recommend copying and editing when overriding these config values — placing the source of truth in your config file. + +✅ **Recommended** + + + +```js +const config = { + resolver: { + sourceExts: ['js', 'jsx', 'ts', 'tsx'], + }, +}; +``` +::: + + + +## Learn more about Metro + +- [Metro website](https://facebook.github.io/metro/) +- [Video: "Metro & React Native DevX" talk at App.js 2023](https://www.youtube.com/watch?v=c9D4pg0y9cI) diff --git a/website/sidebars.json b/website/sidebars.json index 6ab5547dda6..45cc7e83d10 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -21,6 +21,7 @@ "Workflow": [ "running-on-device", "fast-refresh", + "metro", { "type": "category", "label": "Debugging", diff --git a/website/versioned_docs/version-0.72/metro.md b/website/versioned_docs/version-0.72/metro.md new file mode 100644 index 00000000000..f6831029c42 --- /dev/null +++ b/website/versioned_docs/version-0.72/metro.md @@ -0,0 +1,97 @@ +--- +id: metro +title: Metro +--- + +React Native uses [Metro](https://facebook.github.io/metro/) to build your JavaScript code and assets. + +## Configuring Metro + +Configuration options for Metro can be customized in your project's `metro.config.js` file. This can export either: + +- **An object (recommended)** that will be merged on top of Metro's internal config defaults. +- [**A function**](#advanced-using-a-config-function) that will be called with Metro's internal config defaults and should return a final config object. + +:::tip +Please see [**Configuring Metro**](https://facebook.github.io/metro/docs/configuration) on the Metro website for documentation on all available config options. +::: + +In React Native, your Metro config should extend either [@react-native/metro-config](https://www.npmjs.com/package/@react-native/metro-config) or [@expo/metro-config](https://www.npmjs.com/package/@expo/metro-config). These packages contain essential defaults necessary to build and run React Native apps. + +Below is the default `metro.config.js` file in a React Native template project: + + +```js +const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); + +/** + * Metro configuration + * https://facebook.github.io/metro/docs/configuration + * + * @type {import('metro-config').MetroConfig} + */ +const config = {}; + +module.exports = mergeConfig(getDefaultConfig(__dirname), config); +``` + + +Metro options you wish to customize can be done so within the `config` object. We strongly recommend defining all config values statically within this file. + +### Advanced: Using a config function + +Exporting a config function is an opt-in to managing the final config yourself — **Metro will not apply any internal defaults**. This pattern can be useful when needing to read the full default config object from Metro or to set options dynamically. + +:::info +The **@react-native/metro-config** package defines a **partial Metro config**, and must be manually merged with `baseConfig` when using a config function. +::: + + +```js +const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); + +module.exports = function (baseConfig) { + const defaultConfig = mergeConfig(baseConfig, getDefaultConfig(__dirname)); + const {resolver: {assetExts, sourceExts}} = defaultConfig; + + return mergeConfig( + defaultConfig, + { + resolver: { + assetExts: assetExts.filter(ext => ext !== 'svg'), + sourceExts: [...sourceExts, 'scss', 'css', 'svg'], + }, + }, + ); +}; +``` + + +:::tip +Using a config function is for advanced use cases. A simpler method than the above, e.g. for customising `sourceExts`, would be to access [these defaults directly from the **metro-config** package](https://github.com/facebook/metro/blob/main/packages/metro-config/src/defaults/defaults.js). + +**Alternative** + +```js +const {assetExts, sourceExts} = require('metro-config/src/defaults/defaults'); +``` + +**However!**, we recommend copying and editing when overriding these config values — placing the source of truth in your config file. + +✅ **Recommended** + + +``` +const config = { + resolver: { + sourceExts: ['js', 'jsx', 'ts', 'tsx'], + }, +}; +``` +::: + + +## Learn more about Metro + +- [Metro website](https://facebook.github.io/metro/) +- [Video: "Metro & React Native DevX" talk at App.js 2023](https://www.youtube.com/watch?v=c9D4pg0y9cI) diff --git a/website/versioned_sidebars/version-0.72-sidebars.json b/website/versioned_sidebars/version-0.72-sidebars.json index 6ab5547dda6..45cc7e83d10 100644 --- a/website/versioned_sidebars/version-0.72-sidebars.json +++ b/website/versioned_sidebars/version-0.72-sidebars.json @@ -21,6 +21,7 @@ "Workflow": [ "running-on-device", "fast-refresh", + "metro", { "type": "category", "label": "Debugging",