-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
metro.transform.js
139 lines (125 loc) · 4.04 KB
/
metro.transform.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* eslint-disable no-console */
/* eslint-disable import/no-nodejs-modules */
/* eslint-disable import/no-commonjs */
const path = require('path');
const {
removeFencedCode,
lintTransformedFile,
} = require('@metamask/build-utils');
const { ESLint } = require('eslint');
const defaultTransformer = require('metro-react-native-babel-transformer');
const svgTransformer = require('react-native-svg-transformer');
// Code fence removal variables
const fileExtsToScan = ['.js', '.jsx', '.cjs', '.mjs', '.ts', '.tsx'];
const availableFeatures = new Set([
'flask',
'preinstalled-snaps',
'external-snaps',
'beta',
'keyring-snaps',
]);
const mainFeatureSet = new Set(['preinstalled-snaps']);
const flaskFeatureSet = new Set([
'flask',
'preinstalled-snaps',
'external-snaps',
'keyring-snaps',
]);
/**
* Gets the features for the current build type, used to determine which code
* fences to remove.
*
* @returns {Set<string>} The set of features to be included in the build.
*/
function getBuildTypeFeatures() {
const buildType = process.env.METAMASK_BUILD_TYPE ?? 'main';
switch (buildType) {
case 'main':
return mainFeatureSet;
case 'flask':
return flaskFeatureSet;
default:
throw new Error(
`Invalid METAMASK_BUILD_TYPE of ${buildType} was passed to metro transform`,
);
}
}
/**
* The Metro transformer function. Notably, handles code fence removal.
* See https://github.com/MetaMask/core/tree/main/packages/build-utils for details.
*/
module.exports.transform = async ({ src, filename, options }) => {
if (filename.endsWith('.svg')) {
return svgTransformer.transform({ src, filename, options });
}
/**
* Params based on builds we're code splitting
* i.e: flavorDimensions "version" productFlavors from android/app/build.gradle
*/
if (
!path.normalize(filename).split(path.sep).includes('node_modules') &&
fileExtsToScan.includes(path.extname(filename))
) {
const [processedSource, didModify] = removeFencedCode(filename, src, {
all: availableFeatures,
active: getBuildTypeFeatures(),
});
if (didModify) {
await lintTransformedFile(getESLintInstance(), filename, processedSource);
}
return defaultTransformer.transform({
src: processedSource,
filename,
options,
});
}
return defaultTransformer.transform({ src, filename, options });
};
/**
* The singleton ESLint instance.
*
* @type {ESLint}
*/
let eslintInstance;
/**
* Gets the singleton ESLint instance, initializing it if necessary.
* Initializing involves reading the ESLint configuration from disk and
* modifying it according to the needs of code fence removal.
*
* @returns {ESLint} The singleton ESLint instance.
*/
function getESLintInstance() {
if (!eslintInstance) {
const eslintrc = require('./.eslintrc.js');
eslintrc.overrides.forEach((override) => {
const rules = override.rules ?? {};
// We don't want linting to fail for purely stylistic reasons.
rules['prettier/prettier'] = 'off';
// Sometimes we use `let` instead of `const` to assign variables depending on
// the build type.
rules['prefer-const'] = 'off';
override.rules = rules;
});
// also override the rules section
// We don't want linting to fail for purely stylistic reasons.
eslintrc.rules['prettier/prettier'] = 0;
// Sometimes we use `let` instead of `const` to assign variables depending on
// the build type.
eslintrc.rules['prefer-const'] = 0;
// Remove all test-related overrides. We will never lint test files here.
eslintrc.overrides = eslintrc.overrides.filter(
(override) =>
!(
(override.extends &&
override.extends.find(
(configName) =>
configName.includes('jest') || configName.includes('mocha'),
)) ||
(override.plugins &&
override.plugins.find((pluginName) => pluginName.includes('jest')))
),
);
eslintInstance = new ESLint({ baseConfig: eslintrc, useEslintrc: false });
}
return eslintInstance;
}