본문 바로가기
  • 열린 배움 프로젝트
AI.

구글 ai studio 코드로 만든 웹앱을 안드로이드 패키징하기

by From.h 2025. 12. 30.
728x90
반응형
SMALL

 

 

 

구글 ai studio 코드로 만든 웹앱을 안드로이드 패키징하기

 

 

 

 

 

 

1. tailwindcss 설치

npm install -D tailwindcss postcss autoprefixer

 

 

 

 

 

 

 

2. 프로덕션 빌드 및 테스트

# 개발 모드
npm run dev

# 프로덕션 빌드
npm run build

# 빌드 결과 미리보기
npm run preview

 

 

 

 

- 빌드 시 에러 발생 대응 내역 (또는 사전 확인 점검)

 

 

[vite:terser] terser not found 

 

Terser를 설치해야 함.

npm install -D terser

 

 

 

혹은 아래 파일 수정해서  terser 대신 esbuild 사용을 권함.

vite.config.ts

build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'react-vendor': ['react', 'react-dom'],
            'ui-vendor': ['lucide-react'],
          }
        }
      },
      sourcemap: false,
      minify: 'esbuild', // terser 대신 esbuild

 

terser 와  esbuild 비교 (압축률 속도 비교)

esbuild 95% ⚡⚡⚡ 초고속
terser 100% 🐌 느림 ⚠️

 

 

 

 

 

 

 

 

 

3. 성능 최적화 체크리스트

 

 

1) pwa 설정 /  전체화면 웹앱을 위한 플러그인

설치 및 초기화

npm install -D vite-plugin-pwa

 

vite.config.ts 코드 (pwa 부분 추가 최종본)

import path from 'path';
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';


export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, '.', '');
  
  return {
    server: {
      port: 3000,
      host: '0.0.0.0',
    },
    
    define: {
      'process.env.API_KEY': JSON.stringify(env.VITE_GEMINI_API_KEY),
      'process.env.GEMINI_API_KEY': JSON.stringify(env.VITE_GEMINI_API_KEY)
    },
    plugins: [
      react(),
      VitePWA({
        registerType: 'autoUpdate',
        manifest: {
          name: 'Age of Hundred',
          short_name: '백살까지',
          description: '100세까지 남은 시간을 추적하는 앱',
          theme_color: '#000000',
          background_color: '#000000',
          display: 'standalone',
          icons: [
            {
              src: 'icon-192.png',
              sizes: '192x192',
              type: 'image/png'
            },
            {
              src: 'icon-512.png',
              sizes: '512x512',
              type: 'image/png'
            }
          ]
        },
        workbox: {
          globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
          runtimeCaching: [
            {
              urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
              handler: 'CacheFirst',
              options: {
                cacheName: 'google-fonts-cache',
                expiration: {
                  maxEntries: 10,
                  maxAgeSeconds: 60 * 60 * 24 * 365 // 1년
                }
              }
            }
          ]
        }
      })
    ],
    resolve: {
      alias: {
        '@': path.resolve(__dirname, '.'),
      }
    },
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'react-vendor': ['react', 'react-dom'],
            'ui-vendor': ['lucide-react'],
          }
        }
      },
      sourcemap: false,
      minify: 'esbuild',
    }
  };
});

 

 

2) tailwindcss 설정  / CSS를 위한 라이브러리

tailwind v3 설치 및 초기화

npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p

 

tailwind.config.js 코드

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./index.tsx",
    "./App.tsx",
    "./components/**/*.{ts,tsx}",
    "./types.ts",
    "./translations.ts",
    "./audioEngine.ts",
    "./googleDriveService.ts",
  ],
  theme: {
    extend: {
      fontFamily: {
        'sans': ['Noto Sans KR', 'sans-serif'],
        'serif': ['Maru Buri', 'serif'],
        'condensed': ['Oswald', 'sans-serif'],
        'lexend': ['Lexend', 'sans-serif'],
      },
      animation: {
        'pulse': 'pulse var(--pulse-duration, 2s) cubic-bezier(0.4, 0, 0.6, 1) infinite',
      },
    },
  },
  plugins: [],
}

 

 

3) 기타 파일 추가 

 postcss.config.js

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

 

index.css

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  body {
    @apply font-sans bg-black text-white overflow-hidden m-0;
    letter-spacing: -0.02em;
  }
}

@layer components {
  .font-serif {
    font-family: 'Maru Buri', serif;
  }
  
  .font-condensed {
    font-family: 'Oswald', sans-serif;
    text-transform: uppercase;
  }
  
  .font-lexend {
    font-family: 'Lexend', sans-serif;
  }
  
  .no-scrollbar::-webkit-scrollbar {
    display: none;
  }
  
  .no-scrollbar {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
}

@layer utilities {
  /* Custom scrollbar */
  ::-webkit-scrollbar {
    width: 4px;
  }
  
  ::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.05);
  }
  
  ::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.2);
    border-radius: 10px;
  }
}

 

.gitignore 업데이트

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Environment variables
.env
.env.local
.env.production
.env.*.local

# Android
android/
ios/

 

package.json 업데이트

{
  "name": "age-of-hundred",
  "private": true,
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
  },
  "dependencies": {
    "react": "^19.2.3",
    "react-dom": "^19.2.3",
    "lucide-react": "^0.562.0",
    "@google/genai": "^1.34.0"
  },
  "devDependencies": {
    "@types/node": "^22.14.0",
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "@vitejs/plugin-react": "^5.0.0",
    "typescript": "~5.8.2",
    "vite": "^6.2.0",
    "tailwindcss": "^3.4.0",
    "postcss": "^8.4.0",
    "autoprefixer": "^10.4.0",
    "terser": "^5.36.0"
  }
}

 

 

 

 

 

 

4. Capacitor로 안드로이드 앱 변환

1) capacitor 설치

npm install @capacitor/core @capacitor/cli
npm install @capacitor/android

 

2) 초기화

npx cap init "Age of Hundred" "com.plizm.ageofhundred" --web-dir=dist

 

3) 빌드

npm run build

 

4) 안드로드 추가

npx cap add android
 

 

5) 동기화

npx cap sync

 

 

 

 

 

 

5. 안드로이드에서 오픈

 

1) device Mangager / 

 - 우측에 하나 있으면 ,play 버튼

 

Sync tool 관련 다운로드가 실행된다. 

- 우측에는 에뮬레이터가 실행됨

 

완료되면 상단  play 버튼이 활성화 된다.

 

 

짜란 이렇게 우측 에뮬레이터에 앱 화면이 뜬다.

 

기능 테스트 성공.

 

 

 

 

 

2. 폰 연결 및 테스트

1) 설정  / 개발자옵션 / USB 디버깅 옵션 활성화 ( 폰 - PC 연결)

 

 

상단에서 기기를 선택하고, Play 버튼 클릭

 

 

실제로 화면에서는 가로폭 숫자가 커지면 짤리는 문제

위아래 폭도 조금 문제가 있고, 

글자 폰트도 좀 더 커진 것 같다. 우측 화면줄이는 아이콘도 없애야겠고,

 

중앙 숫자에는 clamp()가 적용되어있는데, 이것이 안드로이드에서 작동안하는 것 같음.

Tailwind 반응형 클래스 사용으로 바꿔줌.

하지만 역시나 적용이 안됨.

ai studio에서 최종적으로 안드로이드 패키징 시에 문제가 없도록 아래 프롬프트를 실행

'안드로이드 디바이스에서 빌드 후 발생할 수 있는 문제점을 미리 체크해두자.'

 

 

 

 

 

 

AI 답변

 

안드로이드 패키징(PWA 또는 WebView) 시 발생할 수 있는 주요 기술적 호스트 이슈들을 점검하고, 이를 해결하기 위한 최종 보완 작업을 수행하겠습니다.

(i) 업데이트 및 보완 사항

  1. 시스템 폰트 스케일링 완전 방어:
    • index.html -webkit-text-size-adjust: none을 추가하여 안드로이드 설정의 "글자 크기" 옵션이 레이아웃을 무너뜨리지 않도록 강제합니다.
  2. 모바일 터치 최적화:
    • touch-action: none manipulation을 적절히 배치하여 더블 탭 확대 기능을 끄고, 스와이프(단위 변경) 감도를 안정화합니다.
  3. 뷰포트 및 세이프 에어리어(Safe Area) 강화:
    • viewport-fit=cover 설정을 유지하며, 안드로이드 상단 노치와 하단 내비게이션 바 영역(env(safe-area-inset-*))이 모든 인터페이스 요소에 정확히 반영되도록 레이아웃 클래스를 점검합니다.
  4. 오디오 컨텍스트 활성화 로직:
    • 안드로이드 크롬 기반 환경에서 오디오는 반드시 사용자 상호작용 후 시작되어야 합니다. SplashScreen에서 Enter 클릭 시 AudioContext를 미리 재개(resume)하는 코드를 보강합니다.

(ii) 동작 및 시각적 변화

  • 텍스트 안정성: 시스템 폰트가 크더라도 타이머 숫자가 화면 밖으로 삐져나가지 않고 정해진 비율을 유지합니다.
  • 부드러운 스크롤/스와이프: 스와이프 시 발생하는 모바일 특유의 바운스 효과나 확대/축소 간섭이 사라져 네이티브 앱 같은 조작감을 제공합니다.
  • 풀스크린 최적화: 하단 바와 노치 영역에 텍스트가 겹치지 않도록 세이프 마진이 엄격하게 적용됩니다.

 

 

 

 

 

 

이렇게 다시 ai studio로 돌아가 최종적인 수정을 마쳤다.

그리고 다시 새로 다운로드 하고, 

다시 아래 과정을 반복하여 빌드 테스트에 성공!

 

 

 

 

 

 

안드로이드 빌드 테스트 요약

새로운 폴더를 불러온다는 전제하에 (모든 것은 cmd 모드에서 실행할 것)

 

 

파일은 제 프로젝트에 한하여 참고했던 전체 ai답변 내용임. by claude

프로덕션 배포를 위한 프로젝트 설정 v8.pdf
0.38MB
Android Studio에서 APK 빌드 및 배포 가이드.pdf
0.33MB

 

 

 

 

 

주요 내용은 아래의 과정임.

 

 

1. tailwind 3.0 을 설치한다. 초기화한다.

npm install -D tailwindcss@3 postcss autoprefixer
npx tailwindcss init -p

 

 

 

 

2. 로컬 웹브라우저에서 확인한다.

npm run dev

 

 

 

 

3. 안드로이드 패키지 빌드한다.

 

 1) pwa 플러그인 설치 (전체화면을 위해 사용한 플러그인)

npm install -D vite-plugin-pwa

 

 

2) capacitor 설치 및 초기화, 빌드, 안드로이드 추가, 동기화 (안드로이드 변환을 위한 장치)

# Capacitor 설치
npm install @capacitor/core @capacitor/cli
npm install @capacitor/android

# 초기화
npx cap init "Age of Hundred" "com.plizm.ageofhundred" --web-dir=dist

# 빌드
npm run build

# Android 추가
npx cap add android

# 동기화
npx cap sync

# Android Studio 열기
npx cap open android

 

 

 

 

 

 

 

폰 USB 연결 테스트 완료

 

 

 

 

 

728x90
반응형
LIST