expo-build-properties 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/build/android.d.ts +9 -4
- package/build/android.js +66 -27
- package/build/fileContentsUtils.d.ts +28 -0
- package/build/fileContentsUtils.js +60 -0
- package/build/ios.d.ts +1 -1
- package/build/ios.js +5 -1
- package/build/pluginConfig.d.ts +66 -20
- package/build/pluginConfig.js +6 -4
- package/build/withBuildProperties.d.ts +4 -5
- package/build/withBuildProperties.js +10 -4
- package/package.json +2 -5
- package/src/android.ts +74 -32
- package/src/fileContentsUtils.ts +73 -0
- package/src/ios.ts +5 -1
- package/src/pluginConfig.ts +72 -35
- package/src/withBuildProperties.ts +18 -6
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.5.0 — 2023-02-03
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Add support for enabling [React Native new architecture mode](https://reactnative.dev/docs/new-architecture-intro). ([#20861](https://github.com/expo/expo/pull/20861) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
18
|
+
|
|
19
|
+
## 0.4.1 - 2022-11-24
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- Fixed `extraProguardRules` be overwritten from multiple `withBuildProperties` execution. ([#20106](https://github.com/expo/expo/pull/20106) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
13
25
|
## 0.4.0 — 2022-10-25
|
|
14
26
|
|
|
15
27
|
### 🛠 Breaking changes
|
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Add plugin to `app.json`. For example:
|
|
|
43
43
|
|
|
44
44
|
Contributions are very welcome! Please refer to guidelines described in the [contributing guide][contributing].
|
|
45
45
|
|
|
46
|
-
[docs-main]: https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/build-properties.
|
|
46
|
+
[docs-main]: https://github.com/expo/expo/blob/main/docs/pages/versions/unversioned/sdk/build-properties.mdx
|
|
47
47
|
[docs-stable]: https://docs.expo.dev/versions/latest/sdk/build-properties/
|
|
48
48
|
[contributing]: https://github.com/expo/expo#contributing
|
|
49
49
|
[config-plugins]: https://docs.expo.dev/guides/config-plugins/
|
package/build/android.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { ConfigPlugin } from '
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
2
|
import type { PluginConfigType } from './pluginConfig';
|
|
3
3
|
export declare const withAndroidBuildProperties: ConfigPlugin<PluginConfigType>;
|
|
4
4
|
/**
|
|
5
5
|
* Appends `props.android.extraProguardRules` content into `android/app/proguard-rules.pro`
|
|
6
6
|
*/
|
|
7
7
|
export declare const withAndroidProguardRules: ConfigPlugin<PluginConfigType>;
|
|
8
|
+
/**
|
|
9
|
+
* Purge generated proguard contents from previous prebuild.
|
|
10
|
+
* This plugin only runs once in the prebuilding phase and should execute before any `withAndroidProguardRules` calls.
|
|
11
|
+
*/
|
|
12
|
+
export declare const withAndroidPurgeProguardRulesOnce: ConfigPlugin;
|
|
8
13
|
/**
|
|
9
14
|
* Update `newProguardRules` to original `proguard-rules.pro` contents if needed
|
|
10
15
|
*
|
|
11
16
|
* @param contents the original `proguard-rules.pro` contents
|
|
12
|
-
* @param newProguardRules new proguard rules to add. If the value is null, the
|
|
13
|
-
* @returns return
|
|
17
|
+
* @param newProguardRules new proguard rules to add. If the value is null, the returned value will be original `contents`.
|
|
18
|
+
* @returns return updated contents
|
|
14
19
|
*/
|
|
15
|
-
export declare function updateAndroidProguardRules(contents: string, newProguardRules: string | null
|
|
20
|
+
export declare function updateAndroidProguardRules(contents: string, newProguardRules: string | null, updateMode: 'append' | 'overwrite'): string;
|
package/build/android.js
CHANGED
|
@@ -3,13 +3,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.updateAndroidProguardRules = exports.withAndroidProguardRules = exports.withAndroidBuildProperties = void 0;
|
|
7
|
-
const config_plugins_1 = require("
|
|
8
|
-
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
|
|
6
|
+
exports.updateAndroidProguardRules = exports.withAndroidPurgeProguardRulesOnce = exports.withAndroidProguardRules = exports.withAndroidBuildProperties = void 0;
|
|
7
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
9
8
|
const fs_1 = __importDefault(require("fs"));
|
|
10
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const fileContentsUtils_1 = require("./fileContentsUtils");
|
|
11
11
|
const { createBuildGradlePropsConfigPlugin } = config_plugins_1.AndroidConfig.BuildProperties;
|
|
12
12
|
exports.withAndroidBuildProperties = createBuildGradlePropsConfigPlugin([
|
|
13
|
+
{
|
|
14
|
+
propName: 'newArchEnabled',
|
|
15
|
+
propValueGetter: (config) => config.android?.newArchEnabled?.toString(),
|
|
16
|
+
},
|
|
13
17
|
{
|
|
14
18
|
propName: 'android.minSdkVersion',
|
|
15
19
|
propValueGetter: (config) => config.android?.minSdkVersion?.toString(),
|
|
@@ -61,8 +65,8 @@ const withAndroidProguardRules = (config, props) => {
|
|
|
61
65
|
const extraProguardRules = props.android?.extraProguardRules ?? null;
|
|
62
66
|
const proguardRulesFile = path_1.default.join(config.modRequest.platformProjectRoot, 'app', 'proguard-rules.pro');
|
|
63
67
|
const contents = await fs_1.default.promises.readFile(proguardRulesFile, 'utf8');
|
|
64
|
-
const newContents = updateAndroidProguardRules(contents, extraProguardRules);
|
|
65
|
-
if (newContents) {
|
|
68
|
+
const newContents = updateAndroidProguardRules(contents, extraProguardRules, 'append');
|
|
69
|
+
if (contents !== newContents) {
|
|
66
70
|
await fs_1.default.promises.writeFile(proguardRulesFile, newContents);
|
|
67
71
|
}
|
|
68
72
|
return config;
|
|
@@ -70,35 +74,70 @@ const withAndroidProguardRules = (config, props) => {
|
|
|
70
74
|
]);
|
|
71
75
|
};
|
|
72
76
|
exports.withAndroidProguardRules = withAndroidProguardRules;
|
|
77
|
+
/**
|
|
78
|
+
* Purge generated proguard contents from previous prebuild.
|
|
79
|
+
* This plugin only runs once in the prebuilding phase and should execute before any `withAndroidProguardRules` calls.
|
|
80
|
+
*/
|
|
81
|
+
const withAndroidPurgeProguardRulesOnce = (config) => {
|
|
82
|
+
return (0, config_plugins_1.withDangerousMod)(config, [
|
|
83
|
+
'android',
|
|
84
|
+
async (config) => {
|
|
85
|
+
const RUN_ONCE_NAME = 'expo-build-properties-android-purge-proguard-rules-once';
|
|
86
|
+
/**
|
|
87
|
+
* The `withRunOnce` plugin will delay this plugin's execution.
|
|
88
|
+
* To make sure this plugin executes before any `withAndroidProguardRules`.
|
|
89
|
+
* We use the `withRunOnce` internal History functions to do the check.
|
|
90
|
+
* Example calls to demonstrate the case:
|
|
91
|
+
* ```ts
|
|
92
|
+
* config = withBuildProperties(config as ExpoConfig, {
|
|
93
|
+
* android: {
|
|
94
|
+
* kotlinVersion: "1.6.10",
|
|
95
|
+
* },
|
|
96
|
+
* });
|
|
97
|
+
* config = withBuildProperties(config as ExpoConfig, {
|
|
98
|
+
* android: {
|
|
99
|
+
* enableProguardInReleaseBuilds: true,
|
|
100
|
+
* extraProguardRules: "-keep class com.mycompany.** { *; }",
|
|
101
|
+
* },
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
if (config_plugins_1.History.getHistoryItem(config, RUN_ONCE_NAME)) {
|
|
106
|
+
return config;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
config_plugins_1.History.addHistoryItem(config, { name: RUN_ONCE_NAME });
|
|
110
|
+
}
|
|
111
|
+
const proguardRulesFile = path_1.default.join(config.modRequest.platformProjectRoot, 'app', 'proguard-rules.pro');
|
|
112
|
+
const contents = await fs_1.default.promises.readFile(proguardRulesFile, 'utf8');
|
|
113
|
+
const newContents = updateAndroidProguardRules(contents, '', 'overwrite');
|
|
114
|
+
if (contents !== newContents) {
|
|
115
|
+
await fs_1.default.promises.writeFile(proguardRulesFile, newContents);
|
|
116
|
+
}
|
|
117
|
+
return config;
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
120
|
+
};
|
|
121
|
+
exports.withAndroidPurgeProguardRulesOnce = withAndroidPurgeProguardRulesOnce;
|
|
73
122
|
/**
|
|
74
123
|
* Update `newProguardRules` to original `proguard-rules.pro` contents if needed
|
|
75
124
|
*
|
|
76
125
|
* @param contents the original `proguard-rules.pro` contents
|
|
77
|
-
* @param newProguardRules new proguard rules to add. If the value is null, the
|
|
78
|
-
* @returns return
|
|
126
|
+
* @param newProguardRules new proguard rules to add. If the value is null, the returned value will be original `contents`.
|
|
127
|
+
* @returns return updated contents
|
|
79
128
|
*/
|
|
80
|
-
function updateAndroidProguardRules(contents, newProguardRules) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (newProguardRules) {
|
|
84
|
-
mergeResults = (0, generateCode_1.mergeContents)({
|
|
85
|
-
tag: mergeTag,
|
|
86
|
-
src: contents,
|
|
87
|
-
newSrc: newProguardRules,
|
|
88
|
-
anchor: /^/,
|
|
89
|
-
offset: contents.length,
|
|
90
|
-
comment: '#',
|
|
91
|
-
});
|
|
129
|
+
function updateAndroidProguardRules(contents, newProguardRules, updateMode) {
|
|
130
|
+
if (newProguardRules == null) {
|
|
131
|
+
return contents;
|
|
92
132
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
133
|
+
const options = { tag: 'expo-build-properties', commentPrefix: '#' };
|
|
134
|
+
let newContents = contents;
|
|
135
|
+
if (updateMode === 'overwrite') {
|
|
136
|
+
newContents = (0, fileContentsUtils_1.purgeContents)(contents, options);
|
|
98
137
|
}
|
|
99
|
-
if (
|
|
100
|
-
|
|
138
|
+
if (newProguardRules !== '') {
|
|
139
|
+
newContents = (0, fileContentsUtils_1.appendContents)(newContents, newProguardRules, options);
|
|
101
140
|
}
|
|
102
|
-
return
|
|
141
|
+
return newContents;
|
|
103
142
|
}
|
|
104
143
|
exports.updateAndroidProguardRules = updateAndroidProguardRules;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A set of helper functions to update file contents. This is a simplified version to the config-plugins internal generateCode functions.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for a generated section
|
|
6
|
+
*/
|
|
7
|
+
export interface SectionOptions {
|
|
8
|
+
/**
|
|
9
|
+
* A meaningful tag to differentiate the generated section
|
|
10
|
+
*/
|
|
11
|
+
tag: string;
|
|
12
|
+
/**
|
|
13
|
+
* Defines comment for the generated code.
|
|
14
|
+
* E.g. '//' for js code or '#' for shell script
|
|
15
|
+
*/
|
|
16
|
+
commentPrefix: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Append new contents to src with generated section comments
|
|
20
|
+
*
|
|
21
|
+
* If there is already a generated section, this function will append the new contents at the end of the section.
|
|
22
|
+
* Otherwise, this function will generate a new section at the end of file.
|
|
23
|
+
*/
|
|
24
|
+
export declare function appendContents(src: string, contents: string, sectionOptions: SectionOptions): string;
|
|
25
|
+
/**
|
|
26
|
+
* Purge a generated section
|
|
27
|
+
*/
|
|
28
|
+
export declare function purgeContents(src: string, sectionOptions: SectionOptions): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A set of helper functions to update file contents. This is a simplified version to the config-plugins internal generateCode functions.
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.purgeContents = exports.appendContents = void 0;
|
|
10
|
+
const assert_1 = __importDefault(require("assert"));
|
|
11
|
+
/**
|
|
12
|
+
* Append new contents to src with generated section comments
|
|
13
|
+
*
|
|
14
|
+
* If there is already a generated section, this function will append the new contents at the end of the section.
|
|
15
|
+
* Otherwise, this function will generate a new section at the end of file.
|
|
16
|
+
*/
|
|
17
|
+
function appendContents(src, contents, sectionOptions) {
|
|
18
|
+
const start = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, true);
|
|
19
|
+
const end = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, false);
|
|
20
|
+
const regex = new RegExp(`(\\n${escapeRegExp(end)})`, 'gm');
|
|
21
|
+
const match = regex.exec(src);
|
|
22
|
+
if (match) {
|
|
23
|
+
(0, assert_1.default)(src.indexOf(start) >= 0);
|
|
24
|
+
return src.replace(regex, `\n${contents}$1`);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const sectionedContents = `${start}\n${contents}\n${end}`;
|
|
28
|
+
return `${src}\n${sectionedContents}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.appendContents = appendContents;
|
|
32
|
+
/**
|
|
33
|
+
* Purge a generated section
|
|
34
|
+
*/
|
|
35
|
+
function purgeContents(src, sectionOptions) {
|
|
36
|
+
const start = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, true);
|
|
37
|
+
const end = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, false);
|
|
38
|
+
const regex = new RegExp(`\\n${escapeRegExp(start)}\\n[\\s\\S]*\\n${escapeRegExp(end)}`, 'gm');
|
|
39
|
+
return src.replace(regex, '');
|
|
40
|
+
}
|
|
41
|
+
exports.purgeContents = purgeContents;
|
|
42
|
+
/**
|
|
43
|
+
* Create comments for generated section
|
|
44
|
+
*/
|
|
45
|
+
function createSectionComment(commentPrefix, tag, isBeginComment) {
|
|
46
|
+
if (isBeginComment) {
|
|
47
|
+
return `${commentPrefix} @generated begin ${tag} - expo prebuild (DO NOT MODIFY)`;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return `${commentPrefix} @generated end ${tag}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Escape a string for regular expression
|
|
55
|
+
*
|
|
56
|
+
* Reference from {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping}
|
|
57
|
+
*/
|
|
58
|
+
function escapeRegExp(input) {
|
|
59
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
60
|
+
}
|
package/build/ios.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigPlugin } from '
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
2
|
import type { PluginConfigType } from './pluginConfig';
|
|
3
3
|
export declare const withIosBuildProperties: ConfigPlugin<PluginConfigType>;
|
|
4
4
|
export declare const withIosDeploymentTarget: ConfigPlugin<PluginConfigType>;
|
package/build/ios.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.withIosDeploymentTarget = exports.withIosBuildProperties = void 0;
|
|
4
|
-
const config_plugins_1 = require("
|
|
4
|
+
const config_plugins_1 = require("expo/config-plugins");
|
|
5
5
|
const { createBuildPodfilePropsConfigPlugin } = config_plugins_1.IOSConfig.BuildProperties;
|
|
6
6
|
exports.withIosBuildProperties = createBuildPodfilePropsConfigPlugin([
|
|
7
|
+
{
|
|
8
|
+
propName: 'newArchEnabled',
|
|
9
|
+
propValueGetter: (config) => config.ios?.newArchEnabled?.toString(),
|
|
10
|
+
},
|
|
7
11
|
{
|
|
8
12
|
propName: 'ios.useFrameworks',
|
|
9
13
|
propValueGetter: (config) => config.ios?.useFrameworks,
|
package/build/pluginConfig.d.ts
CHANGED
|
@@ -1,55 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Interface representing base build properties configuration.
|
|
3
3
|
*/
|
|
4
4
|
export interface PluginConfigType {
|
|
5
|
+
/**
|
|
6
|
+
* Interface representing available configuration for Android native build properties.
|
|
7
|
+
* @platform android
|
|
8
|
+
*/
|
|
5
9
|
android?: PluginConfigTypeAndroid;
|
|
10
|
+
/**
|
|
11
|
+
* Interface representing available configuration for iOS native build properties.
|
|
12
|
+
* @platform ios
|
|
13
|
+
*/
|
|
6
14
|
ios?: PluginConfigTypeIos;
|
|
7
15
|
}
|
|
8
16
|
/**
|
|
9
|
-
*
|
|
17
|
+
* Interface representing available configuration for Android native build properties.
|
|
18
|
+
* @platform android
|
|
10
19
|
*/
|
|
11
20
|
export interface PluginConfigTypeAndroid {
|
|
12
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Enable React Native new architecture for Android platform.
|
|
23
|
+
*/
|
|
24
|
+
newArchEnabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Override the default `minSdkVersion` version number in **build.gradle**.
|
|
27
|
+
* */
|
|
13
28
|
minSdkVersion?: number;
|
|
14
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Override the default `compileSdkVersion` version number in **build.gradle**.
|
|
31
|
+
*/
|
|
15
32
|
compileSdkVersion?: number;
|
|
16
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Override the default `targetSdkVersion` version number in **build.gradle**.
|
|
35
|
+
*/
|
|
17
36
|
targetSdkVersion?: number;
|
|
18
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Override the default `buildToolsVersion` version number in **build.gradle**.
|
|
39
|
+
*/
|
|
19
40
|
buildToolsVersion?: string;
|
|
20
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Override the Kotlin version used when building the app.
|
|
43
|
+
*/
|
|
21
44
|
kotlinVersion?: string;
|
|
22
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Enable [Proguard or R8](https://developer.android.com/studio/build/shrink-code) in release builds to obfuscate Java code and reduce app size.
|
|
47
|
+
*/
|
|
23
48
|
enableProguardInReleaseBuilds?: boolean;
|
|
24
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Append custom [Proguard rules](https://www.guardsquare.com/manual/configuration/usage) to **android/app/proguard-rules.pro**.
|
|
51
|
+
*/
|
|
25
52
|
extraProguardRules?: string;
|
|
26
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Interface representing available configuration for Android Gradle plugin [PackagingOptions](https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/PackagingOptions).
|
|
55
|
+
*/
|
|
27
56
|
packagingOptions?: PluginConfigTypeAndroidPackagingOptions;
|
|
28
57
|
}
|
|
29
58
|
/**
|
|
30
|
-
*
|
|
59
|
+
* Interface representing available configuration for iOS native build properties.
|
|
60
|
+
* @platform ios
|
|
31
61
|
*/
|
|
32
62
|
export interface PluginConfigTypeIos {
|
|
33
63
|
/**
|
|
34
|
-
*
|
|
35
|
-
|
|
36
|
-
|
|
64
|
+
* Enable React Native new architecture for iOS platform.
|
|
65
|
+
*/
|
|
66
|
+
newArchEnabled?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Override the default iOS "Deployment Target" version in the following projects:
|
|
69
|
+
* - in CocoaPods projects,
|
|
70
|
+
* - `PBXNativeTarget` with "com.apple.product-type.application" `productType` in the app project.
|
|
37
71
|
*/
|
|
38
72
|
deploymentTarget?: string;
|
|
39
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Enable [`use_frameworks!`](https://guides.cocoapods.org/syntax/podfile.html#use_frameworks_bang)
|
|
75
|
+
* in `Podfile` to use frameworks instead of static libraries for Pods.
|
|
76
|
+
*/
|
|
40
77
|
useFrameworks?: 'static' | 'dynamic';
|
|
41
78
|
}
|
|
42
79
|
/**
|
|
43
|
-
*
|
|
80
|
+
* Interface representing available configuration for Android Gradle plugin [PackagingOptions](https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/PackagingOptions).
|
|
81
|
+
* @platform android
|
|
44
82
|
*/
|
|
45
83
|
export interface PluginConfigTypeAndroidPackagingOptions {
|
|
46
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Array of patterns for native libraries where only the first occurrence is packaged in the APK.
|
|
86
|
+
*/
|
|
47
87
|
pickFirst?: string[];
|
|
48
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Array of patterns for native libraries that should be excluded from being packaged in the APK.
|
|
90
|
+
*/
|
|
49
91
|
exclude?: string[];
|
|
50
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Array of patterns for native libraries where all occurrences are concatenated and packaged in the APK.
|
|
94
|
+
*/
|
|
51
95
|
merge?: string[];
|
|
52
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Array of patterns for native libraries that should not be stripped of debug symbols.
|
|
98
|
+
*/
|
|
53
99
|
doNotStrip?: string[];
|
|
54
100
|
}
|
|
55
101
|
/**
|
package/build/pluginConfig.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.validateConfig = void 0;
|
|
|
7
7
|
const ajv_1 = __importDefault(require("ajv"));
|
|
8
8
|
const semver_1 = __importDefault(require("semver"));
|
|
9
9
|
/**
|
|
10
|
-
* The minimal supported versions. These values should align to SDK
|
|
10
|
+
* The minimal supported versions. These values should align to SDK.
|
|
11
11
|
* @ignore
|
|
12
12
|
*/
|
|
13
13
|
const EXPO_SDK_MINIMAL_SUPPORTED_VERSIONS = {
|
|
@@ -27,6 +27,7 @@ const schema = {
|
|
|
27
27
|
android: {
|
|
28
28
|
type: 'object',
|
|
29
29
|
properties: {
|
|
30
|
+
newArchEnabled: { type: 'boolean', nullable: true },
|
|
30
31
|
minSdkVersion: { type: 'integer', nullable: true },
|
|
31
32
|
compileSdkVersion: { type: 'integer', nullable: true },
|
|
32
33
|
targetSdkVersion: { type: 'integer', nullable: true },
|
|
@@ -50,6 +51,7 @@ const schema = {
|
|
|
50
51
|
ios: {
|
|
51
52
|
type: 'object',
|
|
52
53
|
properties: {
|
|
54
|
+
newArchEnabled: { type: 'boolean', nullable: true },
|
|
53
55
|
deploymentTarget: { type: 'string', pattern: '\\d+\\.\\d+', nullable: true },
|
|
54
56
|
useFrameworks: { type: 'string', enum: ['static', 'dynamic'], nullable: true },
|
|
55
57
|
},
|
|
@@ -57,12 +59,12 @@ const schema = {
|
|
|
57
59
|
},
|
|
58
60
|
},
|
|
59
61
|
};
|
|
62
|
+
// note(Kudo): For the implementation, we check items one by one because Ajv does not well support custom error message.
|
|
60
63
|
/**
|
|
61
|
-
*
|
|
64
|
+
* Checks if specified versions meets Expo minimal supported versions.
|
|
62
65
|
* Will throw error message whenever there are invalid versions.
|
|
63
|
-
* For the implementation, we check items one by one because ajv does not well support custom error message.
|
|
64
66
|
*
|
|
65
|
-
* @param config
|
|
67
|
+
* @param config The validated config passed from Ajv.
|
|
66
68
|
* @ignore
|
|
67
69
|
*/
|
|
68
70
|
function maybeThrowInvalidVersions(config) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
2
|
import { PluginConfigType } from './pluginConfig';
|
|
3
3
|
/**
|
|
4
|
-
* Config plugin
|
|
5
|
-
*
|
|
6
|
-
* @param
|
|
7
|
-
* @param props Configuration for the config plugin
|
|
4
|
+
* Config plugin allowing customizing native Android and iOS build properties for managed apps.
|
|
5
|
+
* @param config Expo config for application.
|
|
6
|
+
* @param props Configuration for the build properties plugin.
|
|
8
7
|
*/
|
|
9
8
|
export declare const withBuildProperties: ConfigPlugin<PluginConfigType>;
|
|
10
9
|
export default withBuildProperties;
|
|
@@ -5,15 +5,21 @@ const android_1 = require("./android");
|
|
|
5
5
|
const ios_1 = require("./ios");
|
|
6
6
|
const pluginConfig_1 = require("./pluginConfig");
|
|
7
7
|
/**
|
|
8
|
-
* Config plugin
|
|
9
|
-
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param props Configuration for the config plugin
|
|
8
|
+
* Config plugin allowing customizing native Android and iOS build properties for managed apps.
|
|
9
|
+
* @param config Expo config for application.
|
|
10
|
+
* @param props Configuration for the build properties plugin.
|
|
12
11
|
*/
|
|
13
12
|
const withBuildProperties = (config, props) => {
|
|
14
13
|
const pluginConfig = (0, pluginConfig_1.validateConfig)(props || {});
|
|
15
14
|
config = (0, android_1.withAndroidBuildProperties)(config, pluginConfig);
|
|
16
15
|
config = (0, android_1.withAndroidProguardRules)(config, pluginConfig);
|
|
16
|
+
// Assuming `withBuildProperties` could be called multiple times from different config-plugins,
|
|
17
|
+
// the `withAndroidProguardRules` always appends new rules by default.
|
|
18
|
+
// That is not ideal if we leave generated contents from previous prebuild there.
|
|
19
|
+
// The `withAndroidPurgeProguardRulesOnce` is for this purpose and it would only run once in prebuilding phase.
|
|
20
|
+
//
|
|
21
|
+
// plugins order matter: the later one would run first
|
|
22
|
+
config = (0, android_1.withAndroidPurgeProguardRulesOnce)(config);
|
|
17
23
|
config = (0, ios_1.withIosBuildProperties)(config, pluginConfig);
|
|
18
24
|
config = (0, ios_1.withIosDeploymentTarget)(config, pluginConfig);
|
|
19
25
|
return config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-build-properties",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Config plugin to customize native build properties on prebuild",
|
|
5
5
|
"main": "build/withBuildProperties.js",
|
|
6
6
|
"types": "build/withBuildProperties.d.ts",
|
|
@@ -37,11 +37,8 @@
|
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"expo-module-scripts": "^3.0.0"
|
|
39
39
|
},
|
|
40
|
-
"jest": {
|
|
41
|
-
"preset": "expo-module-scripts"
|
|
42
|
-
},
|
|
43
40
|
"peerDependencies": {
|
|
44
41
|
"expo": "*"
|
|
45
42
|
},
|
|
46
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "1815e2eaad8c753588c7b1eb74420174a28e01f4"
|
|
47
44
|
}
|
package/src/android.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { AndroidConfig, ConfigPlugin, withDangerousMod } from '
|
|
2
|
-
import {
|
|
3
|
-
mergeContents,
|
|
4
|
-
removeContents,
|
|
5
|
-
MergeResults,
|
|
6
|
-
} from '@expo/config-plugins/build/utils/generateCode';
|
|
1
|
+
import { AndroidConfig, ConfigPlugin, History, withDangerousMod } from 'expo/config-plugins';
|
|
7
2
|
import fs from 'fs';
|
|
8
3
|
import path from 'path';
|
|
9
4
|
|
|
5
|
+
import { appendContents, purgeContents } from './fileContentsUtils';
|
|
10
6
|
import type { PluginConfigType } from './pluginConfig';
|
|
11
7
|
|
|
12
8
|
const { createBuildGradlePropsConfigPlugin } = AndroidConfig.BuildProperties;
|
|
13
9
|
|
|
14
10
|
export const withAndroidBuildProperties = createBuildGradlePropsConfigPlugin<PluginConfigType>(
|
|
15
11
|
[
|
|
12
|
+
{
|
|
13
|
+
propName: 'newArchEnabled',
|
|
14
|
+
propValueGetter: (config) => config.android?.newArchEnabled?.toString(),
|
|
15
|
+
},
|
|
16
16
|
{
|
|
17
17
|
propName: 'android.minSdkVersion',
|
|
18
18
|
propValueGetter: (config) => config.android?.minSdkVersion?.toString(),
|
|
@@ -72,8 +72,59 @@ export const withAndroidProguardRules: ConfigPlugin<PluginConfigType> = (config,
|
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
const contents = await fs.promises.readFile(proguardRulesFile, 'utf8');
|
|
75
|
-
const newContents = updateAndroidProguardRules(contents, extraProguardRules);
|
|
76
|
-
if (newContents) {
|
|
75
|
+
const newContents = updateAndroidProguardRules(contents, extraProguardRules, 'append');
|
|
76
|
+
if (contents !== newContents) {
|
|
77
|
+
await fs.promises.writeFile(proguardRulesFile, newContents);
|
|
78
|
+
}
|
|
79
|
+
return config;
|
|
80
|
+
},
|
|
81
|
+
]);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Purge generated proguard contents from previous prebuild.
|
|
86
|
+
* This plugin only runs once in the prebuilding phase and should execute before any `withAndroidProguardRules` calls.
|
|
87
|
+
*/
|
|
88
|
+
export const withAndroidPurgeProguardRulesOnce: ConfigPlugin = (config) => {
|
|
89
|
+
return withDangerousMod(config, [
|
|
90
|
+
'android',
|
|
91
|
+
async (config) => {
|
|
92
|
+
const RUN_ONCE_NAME = 'expo-build-properties-android-purge-proguard-rules-once';
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The `withRunOnce` plugin will delay this plugin's execution.
|
|
96
|
+
* To make sure this plugin executes before any `withAndroidProguardRules`.
|
|
97
|
+
* We use the `withRunOnce` internal History functions to do the check.
|
|
98
|
+
* Example calls to demonstrate the case:
|
|
99
|
+
* ```ts
|
|
100
|
+
* config = withBuildProperties(config as ExpoConfig, {
|
|
101
|
+
* android: {
|
|
102
|
+
* kotlinVersion: "1.6.10",
|
|
103
|
+
* },
|
|
104
|
+
* });
|
|
105
|
+
* config = withBuildProperties(config as ExpoConfig, {
|
|
106
|
+
* android: {
|
|
107
|
+
* enableProguardInReleaseBuilds: true,
|
|
108
|
+
* extraProguardRules: "-keep class com.mycompany.** { *; }",
|
|
109
|
+
* },
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
if (History.getHistoryItem(config, RUN_ONCE_NAME)) {
|
|
114
|
+
return config;
|
|
115
|
+
} else {
|
|
116
|
+
History.addHistoryItem(config, { name: RUN_ONCE_NAME });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const proguardRulesFile = path.join(
|
|
120
|
+
config.modRequest.platformProjectRoot,
|
|
121
|
+
'app',
|
|
122
|
+
'proguard-rules.pro'
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const contents = await fs.promises.readFile(proguardRulesFile, 'utf8');
|
|
126
|
+
const newContents = updateAndroidProguardRules(contents, '', 'overwrite');
|
|
127
|
+
if (contents !== newContents) {
|
|
77
128
|
await fs.promises.writeFile(proguardRulesFile, newContents);
|
|
78
129
|
}
|
|
79
130
|
return config;
|
|
@@ -85,34 +136,25 @@ export const withAndroidProguardRules: ConfigPlugin<PluginConfigType> = (config,
|
|
|
85
136
|
* Update `newProguardRules` to original `proguard-rules.pro` contents if needed
|
|
86
137
|
*
|
|
87
138
|
* @param contents the original `proguard-rules.pro` contents
|
|
88
|
-
* @param newProguardRules new proguard rules to add. If the value is null, the
|
|
89
|
-
* @returns return
|
|
139
|
+
* @param newProguardRules new proguard rules to add. If the value is null, the returned value will be original `contents`.
|
|
140
|
+
* @returns return updated contents
|
|
90
141
|
*/
|
|
91
142
|
export function updateAndroidProguardRules(
|
|
92
143
|
contents: string,
|
|
93
|
-
newProguardRules: string | null
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (newProguardRules) {
|
|
99
|
-
mergeResults = mergeContents({
|
|
100
|
-
tag: mergeTag,
|
|
101
|
-
src: contents,
|
|
102
|
-
newSrc: newProguardRules,
|
|
103
|
-
anchor: /^/,
|
|
104
|
-
offset: contents.length,
|
|
105
|
-
comment: '#',
|
|
106
|
-
});
|
|
107
|
-
} else {
|
|
108
|
-
mergeResults = removeContents({
|
|
109
|
-
tag: mergeTag,
|
|
110
|
-
src: contents,
|
|
111
|
-
});
|
|
144
|
+
newProguardRules: string | null,
|
|
145
|
+
updateMode: 'append' | 'overwrite'
|
|
146
|
+
): string {
|
|
147
|
+
if (newProguardRules == null) {
|
|
148
|
+
return contents;
|
|
112
149
|
}
|
|
113
150
|
|
|
114
|
-
|
|
115
|
-
|
|
151
|
+
const options = { tag: 'expo-build-properties', commentPrefix: '#' };
|
|
152
|
+
let newContents = contents;
|
|
153
|
+
if (updateMode === 'overwrite') {
|
|
154
|
+
newContents = purgeContents(contents, options);
|
|
155
|
+
}
|
|
156
|
+
if (newProguardRules !== '') {
|
|
157
|
+
newContents = appendContents(newContents, newProguardRules, options);
|
|
116
158
|
}
|
|
117
|
-
return
|
|
159
|
+
return newContents;
|
|
118
160
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A set of helper functions to update file contents. This is a simplified version to the config-plugins internal generateCode functions.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import assert from 'assert';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for a generated section
|
|
9
|
+
*/
|
|
10
|
+
export interface SectionOptions {
|
|
11
|
+
/**
|
|
12
|
+
* A meaningful tag to differentiate the generated section
|
|
13
|
+
*/
|
|
14
|
+
tag: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Defines comment for the generated code.
|
|
18
|
+
* E.g. '//' for js code or '#' for shell script
|
|
19
|
+
*/
|
|
20
|
+
commentPrefix: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Append new contents to src with generated section comments
|
|
25
|
+
*
|
|
26
|
+
* If there is already a generated section, this function will append the new contents at the end of the section.
|
|
27
|
+
* Otherwise, this function will generate a new section at the end of file.
|
|
28
|
+
*/
|
|
29
|
+
export function appendContents(src: string, contents: string, sectionOptions: SectionOptions) {
|
|
30
|
+
const start = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, true);
|
|
31
|
+
const end = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, false);
|
|
32
|
+
|
|
33
|
+
const regex = new RegExp(`(\\n${escapeRegExp(end)})`, 'gm');
|
|
34
|
+
const match = regex.exec(src);
|
|
35
|
+
if (match) {
|
|
36
|
+
assert(src.indexOf(start) >= 0);
|
|
37
|
+
return src.replace(regex, `\n${contents}$1`);
|
|
38
|
+
} else {
|
|
39
|
+
const sectionedContents = `${start}\n${contents}\n${end}`;
|
|
40
|
+
return `${src}\n${sectionedContents}`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Purge a generated section
|
|
46
|
+
*/
|
|
47
|
+
export function purgeContents(src: string, sectionOptions: SectionOptions) {
|
|
48
|
+
const start = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, true);
|
|
49
|
+
const end = createSectionComment(sectionOptions.commentPrefix, sectionOptions.tag, false);
|
|
50
|
+
|
|
51
|
+
const regex = new RegExp(`\\n${escapeRegExp(start)}\\n[\\s\\S]*\\n${escapeRegExp(end)}`, 'gm');
|
|
52
|
+
return src.replace(regex, '');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create comments for generated section
|
|
57
|
+
*/
|
|
58
|
+
function createSectionComment(commentPrefix: string, tag: string, isBeginComment: boolean) {
|
|
59
|
+
if (isBeginComment) {
|
|
60
|
+
return `${commentPrefix} @generated begin ${tag} - expo prebuild (DO NOT MODIFY)`;
|
|
61
|
+
} else {
|
|
62
|
+
return `${commentPrefix} @generated end ${tag}`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Escape a string for regular expression
|
|
68
|
+
*
|
|
69
|
+
* Reference from {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping}
|
|
70
|
+
*/
|
|
71
|
+
function escapeRegExp(input: string) {
|
|
72
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
73
|
+
}
|
package/src/ios.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IOSConfig, ConfigPlugin, withXcodeProject, XcodeProject } from '
|
|
1
|
+
import { IOSConfig, ConfigPlugin, withXcodeProject, XcodeProject } from 'expo/config-plugins';
|
|
2
2
|
|
|
3
3
|
import type { PluginConfigType } from './pluginConfig';
|
|
4
4
|
|
|
@@ -6,6 +6,10 @@ const { createBuildPodfilePropsConfigPlugin } = IOSConfig.BuildProperties;
|
|
|
6
6
|
|
|
7
7
|
export const withIosBuildProperties = createBuildPodfilePropsConfigPlugin<PluginConfigType>(
|
|
8
8
|
[
|
|
9
|
+
{
|
|
10
|
+
propName: 'newArchEnabled',
|
|
11
|
+
propValueGetter: (config) => config.ios?.newArchEnabled?.toString(),
|
|
12
|
+
},
|
|
9
13
|
{
|
|
10
14
|
propName: 'ios.useFrameworks',
|
|
11
15
|
propValueGetter: (config) => config.ios?.useFrameworks,
|
package/src/pluginConfig.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Ajv, { JSONSchemaType } from 'ajv';
|
|
|
2
2
|
import semver from 'semver';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* The minimal supported versions. These values should align to SDK
|
|
5
|
+
* The minimal supported versions. These values should align to SDK.
|
|
6
6
|
* @ignore
|
|
7
7
|
*/
|
|
8
8
|
const EXPO_SDK_MINIMAL_SUPPORTED_VERSIONS = {
|
|
@@ -18,71 +18,106 @@ const EXPO_SDK_MINIMAL_SUPPORTED_VERSIONS = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Interface representing base build properties configuration.
|
|
22
22
|
*/
|
|
23
23
|
export interface PluginConfigType {
|
|
24
|
+
/**
|
|
25
|
+
* Interface representing available configuration for Android native build properties.
|
|
26
|
+
* @platform android
|
|
27
|
+
*/
|
|
24
28
|
android?: PluginConfigTypeAndroid;
|
|
29
|
+
/**
|
|
30
|
+
* Interface representing available configuration for iOS native build properties.
|
|
31
|
+
* @platform ios
|
|
32
|
+
*/
|
|
25
33
|
ios?: PluginConfigTypeIos;
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
/**
|
|
29
|
-
*
|
|
37
|
+
* Interface representing available configuration for Android native build properties.
|
|
38
|
+
* @platform android
|
|
30
39
|
*/
|
|
31
40
|
export interface PluginConfigTypeAndroid {
|
|
32
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Enable React Native new architecture for Android platform.
|
|
43
|
+
*/
|
|
44
|
+
newArchEnabled?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Override the default `minSdkVersion` version number in **build.gradle**.
|
|
47
|
+
* */
|
|
33
48
|
minSdkVersion?: number;
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Override the default `compileSdkVersion` version number in **build.gradle**.
|
|
51
|
+
*/
|
|
36
52
|
compileSdkVersion?: number;
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Override the default `targetSdkVersion` version number in **build.gradle**.
|
|
55
|
+
*/
|
|
39
56
|
targetSdkVersion?: number;
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Override the default `buildToolsVersion` version number in **build.gradle**.
|
|
59
|
+
*/
|
|
42
60
|
buildToolsVersion?: string;
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Override the Kotlin version used when building the app.
|
|
63
|
+
*/
|
|
45
64
|
kotlinVersion?: string;
|
|
46
|
-
|
|
47
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Enable [Proguard or R8](https://developer.android.com/studio/build/shrink-code) in release builds to obfuscate Java code and reduce app size.
|
|
67
|
+
*/
|
|
48
68
|
enableProguardInReleaseBuilds?: boolean;
|
|
49
|
-
|
|
50
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Append custom [Proguard rules](https://www.guardsquare.com/manual/configuration/usage) to **android/app/proguard-rules.pro**.
|
|
71
|
+
*/
|
|
51
72
|
extraProguardRules?: string;
|
|
52
|
-
|
|
53
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Interface representing available configuration for Android Gradle plugin [PackagingOptions](https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/PackagingOptions).
|
|
75
|
+
*/
|
|
54
76
|
packagingOptions?: PluginConfigTypeAndroidPackagingOptions;
|
|
55
77
|
}
|
|
56
78
|
|
|
57
79
|
/**
|
|
58
|
-
*
|
|
80
|
+
* Interface representing available configuration for iOS native build properties.
|
|
81
|
+
* @platform ios
|
|
59
82
|
*/
|
|
60
83
|
export interface PluginConfigTypeIos {
|
|
61
84
|
/**
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
85
|
+
* Enable React Native new architecture for iOS platform.
|
|
86
|
+
*/
|
|
87
|
+
newArchEnabled?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Override the default iOS "Deployment Target" version in the following projects:
|
|
90
|
+
* - in CocoaPods projects,
|
|
91
|
+
* - `PBXNativeTarget` with "com.apple.product-type.application" `productType` in the app project.
|
|
65
92
|
*/
|
|
66
93
|
deploymentTarget?: string;
|
|
67
|
-
|
|
68
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Enable [`use_frameworks!`](https://guides.cocoapods.org/syntax/podfile.html#use_frameworks_bang)
|
|
96
|
+
* in `Podfile` to use frameworks instead of static libraries for Pods.
|
|
97
|
+
*/
|
|
69
98
|
useFrameworks?: 'static' | 'dynamic';
|
|
70
99
|
}
|
|
71
100
|
|
|
72
101
|
/**
|
|
73
|
-
*
|
|
102
|
+
* Interface representing available configuration for Android Gradle plugin [PackagingOptions](https://developer.android.com/reference/tools/gradle-api/7.0/com/android/build/api/dsl/PackagingOptions).
|
|
103
|
+
* @platform android
|
|
74
104
|
*/
|
|
75
105
|
export interface PluginConfigTypeAndroidPackagingOptions {
|
|
76
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Array of patterns for native libraries where only the first occurrence is packaged in the APK.
|
|
108
|
+
*/
|
|
77
109
|
pickFirst?: string[];
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Array of patterns for native libraries that should be excluded from being packaged in the APK.
|
|
112
|
+
*/
|
|
80
113
|
exclude?: string[];
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Array of patterns for native libraries where all occurrences are concatenated and packaged in the APK.
|
|
116
|
+
*/
|
|
83
117
|
merge?: string[];
|
|
84
|
-
|
|
85
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Array of patterns for native libraries that should not be stripped of debug symbols.
|
|
120
|
+
*/
|
|
86
121
|
doNotStrip?: string[];
|
|
87
122
|
}
|
|
88
123
|
|
|
@@ -92,6 +127,7 @@ const schema: JSONSchemaType<PluginConfigType> = {
|
|
|
92
127
|
android: {
|
|
93
128
|
type: 'object',
|
|
94
129
|
properties: {
|
|
130
|
+
newArchEnabled: { type: 'boolean', nullable: true },
|
|
95
131
|
minSdkVersion: { type: 'integer', nullable: true },
|
|
96
132
|
compileSdkVersion: { type: 'integer', nullable: true },
|
|
97
133
|
targetSdkVersion: { type: 'integer', nullable: true },
|
|
@@ -117,6 +153,7 @@ const schema: JSONSchemaType<PluginConfigType> = {
|
|
|
117
153
|
ios: {
|
|
118
154
|
type: 'object',
|
|
119
155
|
properties: {
|
|
156
|
+
newArchEnabled: { type: 'boolean', nullable: true },
|
|
120
157
|
deploymentTarget: { type: 'string', pattern: '\\d+\\.\\d+', nullable: true },
|
|
121
158
|
useFrameworks: { type: 'string', enum: ['static', 'dynamic'], nullable: true },
|
|
122
159
|
},
|
|
@@ -125,12 +162,12 @@ const schema: JSONSchemaType<PluginConfigType> = {
|
|
|
125
162
|
},
|
|
126
163
|
};
|
|
127
164
|
|
|
165
|
+
// note(Kudo): For the implementation, we check items one by one because Ajv does not well support custom error message.
|
|
128
166
|
/**
|
|
129
|
-
*
|
|
167
|
+
* Checks if specified versions meets Expo minimal supported versions.
|
|
130
168
|
* Will throw error message whenever there are invalid versions.
|
|
131
|
-
* For the implementation, we check items one by one because ajv does not well support custom error message.
|
|
132
169
|
*
|
|
133
|
-
* @param config
|
|
170
|
+
* @param config The validated config passed from Ajv.
|
|
134
171
|
* @ignore
|
|
135
172
|
*/
|
|
136
173
|
function maybeThrowInvalidVersions(config: PluginConfigType) {
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ConfigPlugin } from 'expo/config-plugins';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
withAndroidBuildProperties,
|
|
5
|
+
withAndroidProguardRules,
|
|
6
|
+
withAndroidPurgeProguardRulesOnce,
|
|
7
|
+
} from './android';
|
|
4
8
|
import { withIosBuildProperties, withIosDeploymentTarget } from './ios';
|
|
5
9
|
import { PluginConfigType, validateConfig } from './pluginConfig';
|
|
6
10
|
|
|
7
11
|
/**
|
|
8
|
-
* Config plugin
|
|
9
|
-
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param props Configuration for the config plugin
|
|
12
|
+
* Config plugin allowing customizing native Android and iOS build properties for managed apps.
|
|
13
|
+
* @param config Expo config for application.
|
|
14
|
+
* @param props Configuration for the build properties plugin.
|
|
12
15
|
*/
|
|
13
16
|
export const withBuildProperties: ConfigPlugin<PluginConfigType> = (config, props) => {
|
|
14
17
|
const pluginConfig = validateConfig(props || {});
|
|
15
18
|
|
|
16
19
|
config = withAndroidBuildProperties(config, pluginConfig);
|
|
20
|
+
|
|
17
21
|
config = withAndroidProguardRules(config, pluginConfig);
|
|
22
|
+
// Assuming `withBuildProperties` could be called multiple times from different config-plugins,
|
|
23
|
+
// the `withAndroidProguardRules` always appends new rules by default.
|
|
24
|
+
// That is not ideal if we leave generated contents from previous prebuild there.
|
|
25
|
+
// The `withAndroidPurgeProguardRulesOnce` is for this purpose and it would only run once in prebuilding phase.
|
|
26
|
+
//
|
|
27
|
+
// plugins order matter: the later one would run first
|
|
28
|
+
config = withAndroidPurgeProguardRulesOnce(config);
|
|
29
|
+
|
|
18
30
|
config = withIosBuildProperties(config, pluginConfig);
|
|
19
31
|
config = withIosDeploymentTarget(config, pluginConfig);
|
|
20
32
|
|