Skip to content

Commit

Permalink
[docs] Add Metro configuration guide
Browse files Browse the repository at this point in the history
  • Loading branch information
huntie committed Jun 23, 2023
1 parent 392daf1 commit 59d6027
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 0 deletions.
103 changes: 103 additions & 0 deletions docs/metro.md
Original file line number Diff line number Diff line change
@@ -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:

<!--lint disable-->

```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);
```

<!--lint enable-->

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.
:::

<!--lint disable-->

```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'],
},
},
);
};
```

<!--lint enable-->

:::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**

<!--lint disable-->

```js
const config = {
resolver: {
sourceExts: ['js', 'jsx', 'ts', 'tsx'],
},
};
```
:::

<!--lint enable-->

## 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)
1 change: 1 addition & 0 deletions website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"Workflow": [
"running-on-device",
"fast-refresh",
"metro",
{
"type": "category",
"label": "Debugging",
Expand Down
97 changes: 97 additions & 0 deletions website/versioned_docs/version-0.72/metro.md
Original file line number Diff line number Diff line change
@@ -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:

<!--lint disable-->
```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);
```
<!--lint enable-->

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.
:::

<!--lint disable-->
```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'],
},
},
);
};
```
<!--lint enable-->

:::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**

<!--lint disable-->
```
const config = {
resolver: {
sourceExts: ['js', 'jsx', 'ts', 'tsx'],
},
};
```
:::
<!--lint enable-->

## 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)
1 change: 1 addition & 0 deletions website/versioned_sidebars/version-0.72-sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"Workflow": [
"running-on-device",
"fast-refresh",
"metro",
{
"type": "category",
"label": "Debugging",
Expand Down

0 comments on commit 59d6027

Please sign in to comment.