Ionic项目结构 #
一、项目目录概览 #
1.1 完整目录结构 #
text
myApp/
├── src/ # 源代码目录
│ ├── app/ # 应用主目录
│ ├── assets/ # 静态资源
│ ├── environments/ # 环境配置
│ ├── theme/ # 主题样式
│ ├── global.scss # 全局样式
│ ├── index.html # 入口HTML
│ ├── main.ts # 入口脚本
│ ├── polyfills.ts # Polyfills
│ ├── test.ts # 测试配置
│ └── zone-flags.ts # Zone标志
├── .browserslistrc # 浏览器兼容配置
├── .editorconfig # 编辑器配置
├── .gitignore # Git忽略配置
├── .npmrc # npm配置
├── angular.json # Angular配置
├── capacitor.config.ts # Capacitor配置
├── ionic.config.json # Ionic配置
├── karma.conf.js # Karma测试配置
├── package.json # 项目依赖
├── tsconfig.app.json # 应用TypeScript配置
├── tsconfig.json # TypeScript主配置
├── tsconfig.spec.json # 测试TypeScript配置
└── tslint.json # TSLint配置
二、源代码目录(src) #
2.1 应用目录(app) #
Angular项目结构:
text
src/app/
├── app.component.ts # 根组件
├── app.component.html # 根模板
├── app.component.scss # 根样式
├── app.module.ts # 根模块
├── app-routing.module.ts # 路由配置
├── core/ # 核心模块
│ ├── core.module.ts
│ ├── services/ # 全局服务
│ │ ├── api.service.ts
│ │ ├── auth.service.ts
│ │ └── storage.service.ts
│ ├── guards/ # 路由守卫
│ │ └── auth.guard.ts
│ ├── interceptors/ # HTTP拦截器
│ │ └── auth.interceptor.ts
│ └── models/ # 数据模型
│ └── user.model.ts
├── shared/ # 共享模块
│ ├── shared.module.ts
│ ├── components/ # 共享组件
│ │ └── header/
│ ├── directives/ # 共享指令
│ │ └── highlight.directive.ts
│ └── pipes/ # 共享管道
│ └── filter.pipe.ts
├── features/ # 功能模块
│ ├── home/
│ │ ├── home.module.ts
│ │ ├── home.page.ts
│ │ ├── home.page.html
│ │ └── home.page.scss
│ ├── detail/
│ └── settings/
└── tabs/ # 标签页模块
├── tabs.module.ts
├── tabs.page.ts
└── tabs.router.module.ts
React项目结构:
text
src/
├── app/ # 应用配置
│ └── store.ts # 状态管理
├── components/ # 组件目录
│ ├── common/ # 通用组件
│ │ ├── Header.tsx
│ │ └── Footer.tsx
│ └── features/ # 功能组件
│ └── UserCard.tsx
├── hooks/ # 自定义Hooks
│ ├── useAuth.ts
│ └── useApi.ts
├── pages/ # 页面目录
│ ├── Home.tsx
│ ├── Detail.tsx
│ └── Settings.tsx
├── services/ # 服务目录
│ ├── api.ts
│ └── auth.ts
├── theme/ # 主题样式
│ └── variables.css
├── types/ # 类型定义
│ └── index.d.ts
├── utils/ # 工具函数
│ └── helpers.ts
├── App.tsx # 根组件
├── App.css # 根样式
├── main.tsx # 入口文件
└── routing.tsx # 路由配置
Vue项目结构:
text
src/
├── assets/ # 静态资源
├── components/ # 组件目录
│ ├── common/ # 通用组件
│ └── features/ # 功能组件
├── composables/ # 组合式函数
│ ├── useAuth.ts
│ └── useApi.ts
├── pages/ # 页面目录
│ ├── Home.vue
│ ├── Detail.vue
│ └── Settings.vue
├── router/ # 路由配置
│ └── index.ts
├── stores/ # 状态管理
│ └── user.ts
├── theme/ # 主题样式
│ └── variables.css
├── types/ # 类型定义
│ └── index.d.ts
├── utils/ # 工具函数
│ └── helpers.ts
├── App.vue # 根组件
└── main.ts # 入口文件
2.2 静态资源目录(assets) #
text
src/assets/
├── icon/ # 图标
│ ├── favicon.ico
│ └── logo.png
├── images/ # 图片
│ ├── backgrounds/
│ └── avatars/
├── fonts/ # 字体
│ └── custom-font.woff2
└── data/ # 静态数据
└── config.json
引用资源:
typescript
// TypeScript中引用
import logo from 'src/assets/icon/logo.png';
// 模板中引用
<img [src]="logo" alt="Logo">
// CSS中引用
background-image: url('src/assets/images/bg.png');
2.3 环境配置目录(environments) #
text
src/environments/
├── environment.ts # 开发环境
└── environment.prod.ts # 生产环境
environment.ts:
typescript
export const environment = {
production: false,
apiUrl: 'http://localhost:3000/api',
enableDebug: true
};
environment.prod.ts:
typescript
export const environment = {
production: true,
apiUrl: 'https://api.example.com',
enableDebug: false
};
使用环境变量:
typescript
import { environment } from 'src/environments/environment';
@Injectable({ providedIn: 'root' })
export class ApiService {
private apiUrl = environment.apiUrl;
constructor(private http: HttpClient) {}
getUsers() {
return this.http.get(`${this.apiUrl}/users`);
}
}
2.4 主题目录(theme) #
text
src/theme/
├── variables.scss # CSS变量定义
├── common.scss # 通用样式
└── mixins.scss # Sass混入
variables.scss:
scss
:root {
--ion-color-primary: #3880ff;
--ion-color-secondary: #5260ff;
--ion-color-tertiary: #6a64ff;
--ion-color-success: #2dd36f;
--ion-color-warning: #ffc409;
--ion-color-danger: #eb445a;
--ion-color-dark: #222428;
--ion-color-medium: #92949c;
--ion-color-light: #f4f5f8;
}
@media (prefers-color-scheme: dark) {
:root {
--ion-background-color: #1a1a1a;
--ion-text-color: #ffffff;
}
}
三、配置文件详解 #
3.1 package.json #
json
{
"name": "my-app",
"version": "0.0.1",
"author": "Your Name",
"homepage": "https://yourwebsite.com",
"scripts": {
"ng": "ng",
"start": "ionic serve",
"build": "ionic build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"cap:init": "cap init",
"cap:add:ios": "cap add ios",
"cap:add:android": "cap add android",
"cap:sync": "cap sync",
"cap:run:ios": "cap run ios",
"cap:run:android": "cap run android"
},
"dependencies": {
"@angular/common": "^17.0.0",
"@angular/core": "^17.0.0",
"@capacitor/core": "^6.0.0",
"@ionic/angular": "^8.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^17.0.0",
"@angular/cli": "^17.0.0",
"@capacitor/cli": "^6.0.0",
"@ionic/angular-toolkit": "^11.0.0",
"@types/node": "^20.0.0",
"typescript": "~5.2.0"
}
}
3.2 ionic.config.json #
json
{
"name": "my-app",
"integrations": {
"capacitor": {}
},
"type": "angular",
"id": "abc123"
}
3.3 capacitor.config.ts #
typescript
import { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'My App',
webDir: 'www',
bundledWebRuntime: false,
server: {
androidScheme: 'https'
},
plugins: {
SplashScreen: {
launchShowDuration: 2000,
backgroundColor: '#3880ff',
showSpinner: false
},
Keyboard: {
resize: 'body',
resizeOnFullScreen: true
}
}
};
export default config;
3.4 angular.json #
json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"app": {
"projectType": "application",
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
}
],
"styles": [
"src/theme/variables.scss",
"src/global.scss"
],
"scripts": []
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build"
}
}
}
}
}
}
3.5 tsconfig.json #
json
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022", "dom"],
"paths": {
"@/*": ["src/*"],
"@app/*": ["src/app/*"],
"@env/*": ["src/environments/*"]
}
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
四、入口文件详解 #
4.1 index.html #
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>My App</title>
<base href="/">
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="color-scheme" content="light dark">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<link rel="icon" type="image/png" href="assets/icon/favicon.png">
<link rel="apple-touch-icon" href="assets/icon/apple-touch-icon.png">
<meta name="theme-color" content="#3880ff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
</head>
<body>
<app-root></app-root>
</body>
</html>
4.2 main.ts #
typescript
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.log(err));
4.3 global.scss #
scss
/* 全局样式 */
@import "~@ionic/angular/css/core.css";
@import "~@ionic/angular/css/normalize.css";
@import "~@ionic/angular/css/structure.css";
@import "~@ionic/angular/css/typography.css";
@import "~@ionic/angular/css/display.css";
@import "~@ionic/angular/css/padding.css";
@import "~@ionic/angular/css/float-elements.css";
@import "~@ionic/angular/css/text-alignment.css";
@import "~@ionic/angular/css/text-transformation.css";
@import "~@ionic/angular/css/flex-utils.css";
/* 自定义全局样式 */
ion-content {
--background: var(--ion-background-color);
}
ion-toolbar {
--background: var(--ion-color-primary);
--color: #ffffff;
}
/* 通用工具类 */
.text-center {
text-align: center;
}
.mt-10 {
margin-top: 10px;
}
.mb-10 {
margin-bottom: 10px;
}
五、模块组织最佳实践 #
5.1 核心模块(Core Module) #
typescript
// core/core.module.ts
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { ApiService } from './services/api.service';
import { AuthService } from './services/auth.service';
import { StorageService } from './services/storage.service';
import { AuthGuard } from './guards/auth.guard';
import { AuthInterceptor } from './interceptors/auth.interceptor';
@NgModule({
imports: [
CommonModule,
HttpClientModule
],
providers: [
ApiService,
AuthService,
StorageService,
AuthGuard,
AuthInterceptor
]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new Error('CoreModule已经加载,只能在AppModule中导入');
}
}
}
5.2 共享模块(Shared Module) #
typescript
// shared/shared.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';
import { HighlightDirective } from './directives/highlight.directive';
import { FilterPipe } from './pipes/filter.pipe';
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
IonicModule
],
declarations: [
HeaderComponent,
FooterComponent,
HighlightDirective,
FilterPipe
],
exports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
IonicModule,
HeaderComponent,
FooterComponent,
HighlightDirective,
FilterPipe
]
})
export class SharedModule {}
5.3 功能模块(Feature Module) #
typescript
// features/user/user.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { UserListPage } from './pages/user-list/user-list.page';
import { UserDetailPage } from './pages/user-detail/user-detail.page';
import { UserService } from './services/user.service';
const routes: Routes = [
{ path: '', component: UserListPage },
{ path: ':id', component: UserDetailPage }
];
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
declarations: [
UserListPage,
UserDetailPage
],
providers: [
UserService
]
})
export class UserModule {}
六、原生平台目录 #
6.1 iOS目录 #
text
ios/
├── App/
│ ├── App/
│ │ ├── Assets.xcassets/ # 资源文件
│ │ ├── AppDelegate.swift # 应用代理
│ │ ├── Info.plist # 应用配置
│ │ └── capacitor.config.json
│ ├── App.xcworkspace/ # Xcode工作空间
│ └── Podfile # CocoaPods配置
└── Podfile.lock
6.2 Android目录 #
text
android/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── assets/ # 资源文件
│ │ │ ├── java/ # Java代码
│ │ │ ├── res/ # Android资源
│ │ │ └── AndroidManifest.xml
│ │ └── debug/
│ ├── build.gradle # 构建配置
│ └── capacitor.build.gradle
├── gradle/
├── build.gradle # 项目构建配置
├── settings.gradle # 项目设置
└── gradlew # Gradle包装器
七、构建输出目录 #
7.1 Web输出(www) #
text
www/
├── assets/ # 静态资源
├── index.html # 入口文件
├── main.js # 主脚本
├── polyfills.js # Polyfills
├── runtime.js # 运行时
├── styles.js # 样式
└── *.js.map # Source Maps
7.2 构建命令 #
bash
# 开发构建
ionic build
# 生产构建
ionic build --prod
# 指定平台
ionic build --platform=ios
ionic build --platform=android
八、最佳实践 #
8.1 目录命名规范 #
| 类型 | 规范 | 示例 |
|---|---|---|
| 目录 | 小写+连字符 | user-profile |
| 组件 | 大驼峰+目录 | user-card/ |
| 服务 | 小写+点 | user.service.ts |
| 页面 | 小写+点+page | home.page.ts |
| 模块 | 小写+点+module | user.module.ts |
8.2 模块划分原则 #
text
原则:
1. 核心模块只加载一次
2. 共享模块可被多次导入
3. 功能模块按需懒加载
4. 每个功能模块独立完整
8.3 代码组织建议 #
text
建议:
1. 相关文件放同一目录
2. 按功能而非类型组织
3. 保持目录结构扁平
4. 使用索引文件导出
九、总结 #
9.1 关键要点 #
| 要点 | 说明 |
|---|---|
| src目录 | 所有源代码存放位置 |
| app目录 | 应用核心代码 |
| assets目录 | 静态资源文件 |
| environments目录 | 环境配置 |
| theme目录 | 主题样式 |
9.2 下一步 #
了解了项目结构后,接下来让我们学习 UI组件,掌握Ionic丰富的界面组件!
最后更新:2026-03-28