Skip to content

Commit b106a5f

Browse files
authoredJan 5, 2025··
Add metro plugin (#895)
1 parent 26331c0 commit b106a5f

File tree

10 files changed

+117
-0
lines changed

10 files changed

+117
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
projectRoot: './src/app',
3+
transformer: {
4+
minifierPath: 'metro-minify-esbuild',
5+
assetPlugins: ["expo-asset/tools/hashAssetFiles"],
6+
babelTransformerPath: 'react-native-svg-transformer'
7+
},
8+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "@fixtures/metro",
3+
"version": "*",
4+
"dependencies": {
5+
"expo-asset": "*",
6+
"react": "*",
7+
"react-native": "*",
8+
"react-native-svg-transformer": "*"
9+
},
10+
"metro": {
11+
"transformerPath": "./custom-metro-transformer.js"
12+
}
13+
}

‎packages/knip/fixtures/plugins/metro/src/app/index.js

Whitespace-only changes.

‎packages/knip/schema.json

+4
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@
400400
"title": "markdownlint plugin configuration (https://knip.dev/reference/plugins/markdownlint)",
401401
"$ref": "#/definitions/plugin"
402402
},
403+
"metro": {
404+
"title": "metro plugin configuration (https://knip.dev/reference/plugins/metro)",
405+
"$ref": "#/definitions/plugin"
406+
},
403407
"mocha": {
404408
"title": "Mocha plugin configuration (https://knip.dev/reference/plugins/mocha)",
405409
"$ref": "#/definitions/plugin"

‎packages/knip/src/plugins/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { default as linthtml } from './linthtml/index.js';
3030
import { default as lockfileLint } from './lockfile-lint/index.js';
3131
import { default as lostPixel } from './lost-pixel/index.js';
3232
import { default as markdownlint } from './markdownlint/index.js';
33+
import { default as metro } from './metro/index.js';
3334
import { default as mocha } from './mocha/index.js';
3435
import { default as moonrepo } from './moonrepo/index.js';
3536
import { default as msw } from './msw/index.js';
@@ -121,6 +122,7 @@ export const Plugins = {
121122
'lockfile-lint': lockfileLint,
122123
'lost-pixel': lostPixel,
123124
markdownlint,
125+
metro,
124126
mocha,
125127
moonrepo,
126128
msw,
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import type { IsPluginEnabled, Plugin, ResolveConfig, ResolveEntryPaths } from '../../types/config.js';
2+
import { toDeferResolve, toProductionEntry } from '../../util/input.js';
3+
import { join } from '../../util/path.js';
4+
import { hasDependency } from '../../util/plugin.js';
5+
import type { PluginConfig } from './types.js';
6+
7+
// https://metrobundler.dev/docs/configuration
8+
9+
const title = 'Metro';
10+
11+
const enablers = ['metro', 'react-native'];
12+
13+
const isEnabled: IsPluginEnabled = options => hasDependency(options.dependencies, enablers);
14+
15+
const packageJsonPath = 'metro';
16+
17+
const config: string[] = ['metro.config.{js,cjs,json}', 'package.json'];
18+
19+
const resolveEntryPaths: ResolveEntryPaths<PluginConfig> = async config => {
20+
if (!config.projectRoot) return [];
21+
22+
const entryFilePattern = 'index.{js,jsx,ts,tsx}';
23+
const entryFilePath = join(config.projectRoot, entryFilePattern);
24+
return [toProductionEntry(entryFilePath)];
25+
};
26+
27+
const resolveConfig: ResolveConfig<PluginConfig> = async config => {
28+
const { transformerPath, transformer } = config;
29+
const inputs: string[] = [];
30+
31+
if (transformerPath) inputs.push(transformerPath);
32+
if (transformer?.assetPlugins) inputs.push(...transformer.assetPlugins);
33+
if (transformer?.minifierPath) inputs.push(transformer.minifierPath);
34+
if (transformer?.babelTransformerPath) inputs.push(transformer.babelTransformerPath);
35+
36+
return [...inputs].map(toDeferResolve);
37+
};
38+
39+
export default {
40+
title,
41+
enablers,
42+
isEnabled,
43+
packageJsonPath,
44+
config,
45+
resolveEntryPaths,
46+
resolveConfig,
47+
} satisfies Plugin;
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// https://github.com/facebook/metro/blob/main/packages/metro-config/types/configTypes.d.ts
2+
3+
export type PluginConfig = {
4+
projectRoot?: string;
5+
transformerPath?: string;
6+
transformer?: {
7+
minifierPath?: string;
8+
assetPlugins?: string[];
9+
babelTransformerPath?: string;
10+
};
11+
};

‎packages/knip/src/schema/plugins.ts

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const pluginsSchema = z.object({
4444
'lockfile-lint': pluginSchema,
4545
'lost-pixel': pluginSchema,
4646
markdownlint: pluginSchema,
47+
metro: pluginSchema,
4748
mocha: pluginSchema,
4849
moonrepo: pluginSchema,
4950
msw: pluginSchema,

‎packages/knip/src/types/PluginNames.ts

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type PluginName =
3131
| 'lockfile-lint'
3232
| 'lost-pixel'
3333
| 'markdownlint'
34+
| 'metro'
3435
| 'mocha'
3536
| 'moonrepo'
3637
| 'msw'
@@ -122,6 +123,7 @@ export const pluginNames = [
122123
'lockfile-lint',
123124
'lost-pixel',
124125
'markdownlint',
126+
'metro',
125127
'mocha',
126128
'moonrepo',
127129
'msw',
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { test } from 'bun:test';
2+
import assert from 'node:assert/strict';
3+
import { main } from '../../src/index.js';
4+
import { resolve } from '../../src/util/path.js';
5+
import baseArguments from '../helpers/baseArguments.js';
6+
import baseCounters from '../helpers/baseCounters.js';
7+
8+
const cwd = resolve('fixtures/plugins/metro');
9+
10+
test('Find dependencies with the Metro plugin', async () => {
11+
const { issues, counters } = await main({
12+
...baseArguments,
13+
cwd,
14+
});
15+
16+
assert(issues.dependencies['package.json']['react']);
17+
assert(issues.dependencies['package.json']['react-native']);
18+
19+
assert(issues.unresolved['metro.config.js']['metro-minify-esbuild']);
20+
assert(issues.unresolved['package.json']['./custom-metro-transformer.js']);
21+
22+
assert.deepEqual(counters, {
23+
...baseCounters,
24+
dependencies: 2,
25+
unresolved: 2,
26+
processed: 2,
27+
total: 2,
28+
});
29+
});

0 commit comments

Comments
 (0)
Please sign in to comment.