u
This commit is contained in:
1 parent
94983ed1ea
commit
7b5ab1ab04
59 files changed
+8911
-14495
No files matched your search
@@ -2,7 +2,268 @@
|
||||
|
||||
# 初始化项目
|
||||
|
||||
创建项目命令:
|
||||
|
||||
```bash
|
||||
pnpm create expo-app@latest --template blank-typescript
|
||||
```
|
||||
|
||||
[官网模板](https://docs.expo.dev/more/create-expo/)如下:
|
||||
|
||||
| 模板名称 | 描述 |
|
||||
| ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| [`default`](https://github.com/expo/expo/tree/main/templates/expo-template-default) | 默认模板,用于构建多页面应用。包含推荐工具,如 **Expo CLI**、**Expo Router** 路由库,并启用 **TypeScript** 配置。适合大多数应用。 |
|
||||
| [`blank`](https://github.com/expo/expo/tree/main/templates/expo-template-blank) | 最简模板,仅安装最基本依赖,不包含导航配置。 |
|
||||
| [`blank-typescript`](https://github.com/expo/expo/tree/main/templates/expo-template-blank-typescript) | 空白模板,但启用了 **TypeScript** 支持。 |
|
||||
| [`tabs`](https://github.com/expo/expo/tree/main/templates/expo-template-tabs) | 启用基于文件的路由系统(Expo Router),并默认使用 **TypeScript**,适合多标签页结构的应用。 |
|
||||
| [`bare-minimum`](https://github.com/expo/expo/tree/main/templates/expo-template-bare-minimum) | 带有原生目录(`android` 与 `ios`)的空白模板,创建时会自动运行 [`npx expo prebuild`](https://docs.expo.dev/workflow/prebuild)。适合需要直接修改原生代码的项目。 |
|
||||
|
||||
**启动项目:**
|
||||
|
||||
```bash
|
||||
npx expo start
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# 基础配置
|
||||
|
||||
## 集成 [antfu-eslint](https://github.com/antfu/eslint-config)
|
||||
|
||||
|
||||
|
||||
安装:
|
||||
|
||||
```bash
|
||||
pnpm i -D eslint @antfu/eslint-config eslint-plugin-format
|
||||
```
|
||||
|
||||
新建 `eslint.config.js` 文件:
|
||||
|
||||
```js
|
||||
// eslint.config.js
|
||||
import antfu from '@antfu/eslint-config'
|
||||
|
||||
export default antfu({
|
||||
formatters: {
|
||||
css: true, // 启用 CSS 格式化
|
||||
html: true, // 启用 HTML 格式化
|
||||
markdown: 'prettier', // Markdown 使用 Prettier 格式化
|
||||
},
|
||||
stylistic: {
|
||||
indent: 2, // 缩进为 2 个空格(可选 4 或 'tab')
|
||||
quotes: 'single', // 使用单引号(可选 'double')
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': 'off', // 关闭未使用变量的报错
|
||||
'@typescript-eslint/no-use-before-define': 'off', // 关闭 TS 的“定义前使用”警告
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
配置 vscode 模板,修改 `.vscode/settings.json` :
|
||||
|
||||
> 注意安装 eslint 插件
|
||||
|
||||
```json
|
||||
{
|
||||
// Disable the default formatter, use eslint instead
|
||||
"prettier.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
|
||||
// Auto fix
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
|
||||
// Silent the stylistic rules in you IDE, but still auto fix them
|
||||
"eslint.rules.customizations": [
|
||||
{ "rule": "style/*", "severity": "off", "fixable": true },
|
||||
{ "rule": "format/*", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-indent", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-spacing", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-spaces", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-order", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-dangle", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-newline", "severity": "off", "fixable": true },
|
||||
{ "rule": "*quotes", "severity": "off", "fixable": true },
|
||||
{ "rule": "*semi", "severity": "off", "fixable": true }
|
||||
],
|
||||
|
||||
// Enable eslint for all supported languages
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"vue",
|
||||
"html",
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc",
|
||||
"yaml",
|
||||
"toml",
|
||||
"xml",
|
||||
"gql",
|
||||
"graphql",
|
||||
"astro",
|
||||
"svelte",
|
||||
"css",
|
||||
"less",
|
||||
"scss",
|
||||
"pcss",
|
||||
"postcss"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 集成 [nativewind](https://www.nativewind.dev/v5/getting-started/installation) (存在BUG,先不使用)
|
||||
|
||||
1. 安装[Nativewind](https://www.nativewind.dev/v5/getting-started/installation#1-install-nativewind)
|
||||
|
||||
```bash
|
||||
pnpm install nativewind@preview react-native-css react-native-reanimated react-native-safe-area-context
|
||||
```
|
||||
|
||||
2. 安装**Tailwind CSS**
|
||||
|
||||
```bash
|
||||
pnpm install --save-dev tailwindcss @tailwindcss/postcss postcss
|
||||
```
|
||||
|
||||
3. 新建 `postcss.config.mjs` 文件:
|
||||
|
||||
```js
|
||||
export default {
|
||||
plugins: {
|
||||
"@tailwindcss/postcss": {},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
4. 创建 `global.css` 并在 `index.ts` 文件中引入
|
||||
|
||||
```css
|
||||
@import "tailwindcss/theme.css" layer(theme);
|
||||
@import "tailwindcss/preflight.css" layer(base);
|
||||
@import "tailwindcss/utilities.css";
|
||||
|
||||
@import "nativewind/theme";
|
||||
```
|
||||
|
||||
5. 创建 `metro.config.js` 文件:
|
||||
|
||||
```js
|
||||
const { getDefaultConfig } = require("expo/metro-config");
|
||||
const { withNativewind } = require("nativewind/metro");
|
||||
|
||||
/** @type {import('expo/metro-config').MetroConfig} */
|
||||
const config = getDefaultConfig(__dirname);
|
||||
|
||||
module.exports = withNativewind(config);
|
||||
```
|
||||
|
||||
6. 固定 lightningcss 版本,在 `package.json` 里添加:
|
||||
|
||||
```json
|
||||
{
|
||||
"resolutions": {
|
||||
"lightningcss": "1.30.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
7. 添加 `ts` 支持,新建 `nativewind-env.d.ts` 文件(任意名称):
|
||||
|
||||
```ts
|
||||
/// <reference types="react-native-css/types" />
|
||||
|
||||
// NOTE: This file should not be edited and should be committed with your source code. It is generated by react-native-css. If you need to move or disable this file, please see the documentation.
|
||||
```
|
||||
|
||||
8. 检验是否生效
|
||||
|
||||
```tsx
|
||||
import { Text, View } from "react-native";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<View className="flex-1 items-center justify-center bg-white">
|
||||
<Text className="text-xl font-bold text-blue-500">
|
||||
Welcome to Nativewind!
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 集成[@expo/vector-icons](https://docs.expo.dev/guides/icons/#expovector-icons)
|
||||
|
||||
该插件默认跟着expo安装了。可以直接使用。
|
||||
|
||||
图标网站地址:https://icons.expo.fyi/Index
|
||||
|
||||
如果需要没有想要的图标,可以用下面的方式:
|
||||
|
||||
安装svg依赖
|
||||
|
||||
```bash
|
||||
npx expo install react-native-svg
|
||||
```
|
||||
|
||||
|
||||
|
||||
然后在components下面创建一个Icons.tsx文件,用来管理所有的图标
|
||||
|
||||
```tsx
|
||||
import Svg, { Circle, Rect, Path } from 'react-native-svg';
|
||||
|
||||
interface IconProps {
|
||||
size?: string | number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
// 测试图标
|
||||
export const DemoIcon: React.FC<IconProps> = ({ size = 30, color = '#fff', ...rest }) => {
|
||||
return (
|
||||
<Svg height="50%" width="50%" viewBox="0 0 100 100" {...rest}>
|
||||
<Circle cx="50" cy="50" r="45" stroke="blue" strokeWidth="2.5" fill="green" />
|
||||
<Rect x="15" y="15" width={size} height={size} stroke="red" strokeWidth="2" fill="yellow" />
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
|
||||
// 招聘
|
||||
export const ZhaoPinIcon: React.FC<IconProps> = ({ size = 30, color = '#fff', ...rest }) => {
|
||||
return (
|
||||
<Svg viewBox="0 0 1024 1024" p-id="5316" width={size} height={size} {...rest}>
|
||||
<Path d="M473.6 732.8c-9.6 0-25.6 3.2-48 6.4v112h-83.2v-102.4c-73.6 9.6-150.4 19.2-172.8 22.4L160 681.6c9.6-3.2 22.4-3.2 41.6-6.4V278.4h-19.2V188.8h272v89.6h-28.8v368c19.2-3.2 28.8-3.2 38.4-6.4l3.2 48 6.4 44.8zM288 278.4v70.4h51.2V278.4H288z m0 224h51.2v-67.2H288v67.2z m51.2 153.6v-67.2H288v73.6l51.2-6.4z m259.2-54.4l-3.2 25.6h220.8c0 9.6-9.6 112-12.8 131.2-6.4 76.8-32 89.6-121.6 99.2l-54.4 6.4-25.6-86.4 64-3.2c41.6-3.2 54.4-6.4 57.6-35.2 3.2-9.6 3.2-19.2 3.2-32h-233.6l16-102.4H448v-73.6h416v73.6l-265.6-3.2z m233.6-99.2H467.2V211.2H608V160l80 3.2v48H832v291.2zM547.2 288v32H608V288h-60.8z m0 140.8H608v-32h-60.8v32zM688 288v32h60.8V288h-60.8z m60.8 140.8v-32h-60.8v32h60.8z" p-id="5317" fill={color} />
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## [定义 src 路径别名 @](https://docs.expo.dev/guides/typescript/)
|
||||
|
||||
修改 `tsconfig.json` 文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "expo/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -300,4 +561,105 @@ keytool -genkey -v -keystore android-release.keystore -alias my-key-alias -keyal
|
||||
|
||||
|
||||
|
||||
### 5. 编译
|
||||
### 5. 打包
|
||||
|
||||
- 编译成 Google Play 商店用的 .aab 文件
|
||||
|
||||
```bash
|
||||
./gradlew bundleRelease
|
||||
```
|
||||
|
||||
- 直接安装的 .apk 文件
|
||||
|
||||
```bash
|
||||
./gradlew assembleRelease
|
||||
```
|
||||
|
||||
**注意:**这个时候可能会下载 `gradle` 、`apk` 等资源,网络速度可能过慢。
|
||||
|
||||
**解决方法:**在 `android/gradle.properties` 添加网络代理:
|
||||
|
||||
```bash
|
||||
systemProp.http.proxyHost=127.0.0.1
|
||||
systemProp.http.proxyPort=7897
|
||||
systemProp.https.proxyHost=127.0.0.1
|
||||
systemProp.https.proxyPort=7897
|
||||
```
|
||||
|
||||
打包结果在 `android/app/build/outputs/apt/release` 包下。
|
||||
|
||||
|
||||
|
||||
# 打包体积优化
|
||||
|
||||
默认初始项目打包就有 **80MB** 左右,是因为 expo 默认将 armeabi-v7a、arm64-v8a、x86、x86_64 这些架构的包都打包进来了。
|
||||
|
||||
| 架构名称 | 位数 | 设备类型 | 应用场景 | 备注 |
|
||||
| --------------- | ----- | ------------------------------------------ | -------------- | ------------------------------------ |
|
||||
| **armeabi-v7a** | 32 位 | 老旧的 ARM 芯片手机(如部分安卓 5/6 设备) | 兼容旧设备 | 已逐渐被淘汰,但仍有少数旧机型使用 |
|
||||
| **arm64-v8a** | 64 位 | 主流安卓手机(大多数真机) | ✅ 主力目标平台 | 目前最主流、性能最佳的架构 |
|
||||
| **x86** | 32 位 | 早期安卓模拟器(Intel 架构) | 开发调试 | 真机几乎不会用 |
|
||||
| **x86_64** | 64 位 | 现代安卓模拟器 | 开发调试 | 用于 Android Studio 模拟器或测试环境 |
|
||||
|
||||
## 方法1(简单)
|
||||
|
||||
找到 `android/gradle.properties` 文件,找到 `reactNativeArchitectures` ,根据需要删除即可
|
||||
|
||||
```properties
|
||||
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
||||
```
|
||||
|
||||
## 方法2(原生方法 选择更多)
|
||||
|
||||
在 `android/app/build.gradle` 文件中添加或修改以下配置:
|
||||
|
||||
```
|
||||
android {
|
||||
// 其他配置...
|
||||
|
||||
splits {
|
||||
abi {
|
||||
enable true // 启用按 CPU 架构拆分
|
||||
reset() // 重置默认架构列表
|
||||
include 'arm64-v8a', 'armeabi-v7a'
|
||||
universalApk false // 是否生成包含所有架构的通用 APK(false 表示只生成分架构的独立包)
|
||||
// 还有一个 exclude 配置是排除指定架构的
|
||||
}
|
||||
}
|
||||
|
||||
// 其他配置...
|
||||
}
|
||||
```
|
||||
|
||||
**说明:**
|
||||
|
||||
- `enable true`:启用架构拆分功能。
|
||||
- `reset()`:清空默认的架构配置,避免重复。
|
||||
- `include`:指定要生成的架构包,比如只打 `arm64-v8a` 和 `armeabi-v7a`。
|
||||
- `universalApk false`:不生成通用包(即包含所有架构的 APK)。
|
||||
|
||||
**举例:**
|
||||
|
||||
执行打包命令后,将生成多个包,例如:
|
||||
|
||||
```
|
||||
app-arm64-v8a-release.apk
|
||||
app-armeabi-v7a-release.apk
|
||||
```
|
||||
|
||||
每个 APK 只包含对应架构的二进制文件,体积更小。
|
||||
|
||||
如果把 `universalApk` 设置为 `true`,则只会生成一个:
|
||||
|
||||
```
|
||||
app-universal-release.apk
|
||||
```
|
||||
|
||||
这个包能在 `arm64-v8a` 和 `armeabi-v7a` 架构的设备上运行,但体积最大。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user