vtex-io-app-structure について
vtex-io-app-structure は、VTEX IO アプリの基盤を作成・保守する開発者向けのスキルです。`manifest.json`、ビルダー、ポリシー、依存関係に加え、アプリの命名、サービスのリソース設定、デプロイ障害の調査方法を扱います。
主な機能
- 01manifest.json とビルダーの設定
- 02外部アクセスとリソースのポリシー宣言
- 03依存関係と peerDependencies の管理
- 04service.json のリソース制限設定
- 05命名、バージョン、デプロイ設定の確認
活用シーン
- 01VTEX IO アプリを新規作成
- 02既存アプリにビルダーを追加
- 03manifest 設定に起因するデプロイ障害の調査
- 04API アクセスポリシーと依存関係の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vtex/ skills --skill vtex-io-app-structureインストール後、Claude Code で/vtex-io-app-structureを入力して読み込まれたか確認します。
詳細
アプリケーションアーキテクチャとマニフェスト設定
このスキルを使用する場面
VTEX IO アプリの基盤となる構造(manifest.json ファイル、ビルダーシステム、ポリシー宣言、依存関係管理、service.json のリソース制限、アプリのライフサイクル(リンク、公開、デプロイ))を扱う場合に、このスキルを使用します。
- VTEX IO アプリをゼロから作成する
- 既存のアプリにビルダーを追加する
- API アクセス用のポリシーを設定する
- マニフェストの設定ミスに関連するデプロイ失敗のトラブルシューティングを行う
以下の場合、このスキルは使用しないでください。
- バックエンドサービスの実装詳細(代わりに
vtex-io-service-appsを使用してください) - React コンポーネントの開発(代わりに
vtex-io-react-appsを使用してください) - GraphQL スキーマとリゾルバーの詳細(代わりに
vtex-io-graphql-apiを使用してください)
判断ルール
- すべての VTEX IO アプリは
manifest.jsonから始まります。これは、アプリの識別情報(vendor、name、version)、ビルダー、依存関係、ポリシーを定義します。 - ディレクトリに対応するビルダーを使用します。
/nodeにはnode、/reactにはreact、/graphqlにはgraphql、/adminにはadmin、/pixelにはpixel、/messagesにはmessages、/storeにはstore、/masterdataにはmasterdata、/stylesにはstylesを使用します。 - アプリが呼び出すすべての外部ホストと、アクセスするすべての VTEX Admin リソースに対してポリシーを宣言します。
/nodeではservice.jsonを使用して、メモリ(最大 512MB)、タイムアウト、自動スケーリング、ルート定義を設定します。- 依存関係には、バージョンを固定せず、semver の範囲(
3.x)を使用します。 - 存在は必要だが自動インストールは不要なアプリには、
peerDependenciesを使用します。
ビルダーのリファレンス:
| ビルダー | ディレクトリ | 用途 |
|---|---|---|
node | /node | TypeScript によるバックエンドサービス(ミドルウェア、リゾルバー、イベントハンドラー) |
react | /react | TypeScript/TSX によるフロントエンド React コンポーネント |
graphql | /graphql | GraphQL スキーマ定義(.graphql ファイル) |
admin | /admin | 管理パネルのページとナビゲーション項目 |
pixel | /pixel | ストアフロントにスクリプトを挿入するピクセル/トラッキングアプリ |
messages | /messages | 国際化 — ロケールごとのローカライズ済み文字列ファイル |
store | /store | Store Framework のテーマブロック、インターフェース、ルート |
masterdata | /masterdata | Master Data v2 のエンティティスキーマとトリガー |
styles | /styles | Store Framework テーマ向けの CSS/Tachyons 設定 |
ポリシーの種類:
- アウトバウンドアクセスのポリシー:明示的な URL(外部 API または VTEX エンドポイント)へのアクセスを許可します。
- License Manager ポリシー:リソースキーを使用して VTEX Admin リソースへのアクセスを許可します。
- アプリロールベースのポリシー:
{vendor}.{app-name}:{policy-name}形式を使用して、他の IO アプリが公開するルートまたは GraphQL クエリへのアクセスを許可します。
アーキテクチャ:
manifest.json
├── builders → determines which directories are processed
│ ├── node/ → compiled by node builder → backend service
│ ├── react/ → compiled by react builder → frontend bundles
│ ├── graphql/ → compiled by graphql builder → schema/resolvers
│ ├── store/ → compiled by store builder → theme blocks
│ ├── admin/ → compiled by admin builder → admin pages
│ ├── pixel/ → compiled by pixel builder → tracking scripts
│ └── messages/ → compiled by messages builder → i18n strings
├── policies → runtime permissions for API access
├── dependencies → other VTEX IO apps this app requires
└── peerDependencies → apps required but not auto-installed
厳守すべき制約
制約:必要なビルダーをすべて宣言する
処理可能なコードを含むアプリ内のすべてのディレクトリには、manifest.json で対応するビルダーを宣言する必要があります。/node ディレクトリがある場合は、node ビルダーを宣言する必要があります。/react ディレクトリがある場合は、react ビルダーを宣言する必要があります。
重要な理由
ビルダーを宣言しないと、VTEX IO プラットフォームはそのディレクトリを完全に無視します。バックエンドコードはコンパイルされず、React コンポーネントはレンダリングされず、GraphQL スキーマも登録されません。アプリのリンクは正常に完了しますが、機能は何もないかのように利用できません。
検出方法
/node ディレクトリにバックエンドの TypeScript コードがあるにもかかわらず、マニフェストの builders に "node": "7.x" が宣言されていない場合は、作業を止めてビルダーを追加してください。同様に、/react がある場合は "react": "3.x"、/graphql がある場合は "graphql": "1.x" などを宣言してください。
正しい例
{
"name": "my-service-app",
"vendor": "myvendor",
"version": "1.0.0",
"title": "My Service App",
"description": "A backend service app with GraphQL",
"builders": {
"node": "7.x",
"graphql": "1.x",
"docs": "0.x"
},
"dependencies": {},
"policies": []
}
誤った例
{
"name": "my-service-app",
"vendor": "myvendor",
"version": "1.0.0",
"title": "My Service App",
"description": "A backend service app with GraphQL",
"builders": {
"docs": "0.x"
},
"dependencies": {},
"policies": []
}
"node" と "graphql" のビルダーが不足しています。/node と /graphql ディレクトリは完全に無視されます。バックエンドコードはコンパイルされず、GraphQL スキーマも登録されません。アプリはエラーなしでリンクされますが、何も機能しません。
制約:すべての外部アクセスにポリシーを宣言する
外部 API の呼び出しや VTEX リソースへのアクセスには、対応するポリシーを必ず manifest.json に記述してください。これには、外部ホストへのアウトバウンド HTTP 呼び出し、VTEX Admin リソースへのアクセス、他のアプリの GraphQL API の利用が含まれます。
重要な理由
VTEX IO はセキュリティのため、アプリをサンドボックス化します。適切なポリシーが設定されていない場合、アウトバウンド HTTP リクエストはインフラストラクチャーレベルでブロックされ、403 Forbidden エラーが返されます。これはコードの問題ではなく、プラットフォームレベルの制限です。
検出方法
コードでクライアントや HTTP を介してホストに API 呼び出しを行っている箇所を見つけたら、作業を中断し、そのホストに対する outbound-access ポリシーがマニフェストに存在することを確認してください。licenseManager.canAccessResource(...) を見つけた場合は、License Manager ポリシーが存在することを確認してください。
正しい例
{
"policies": [
{
"name": "outbound-access",
"attrs": {
"host": "api.vtex.com",
"path": "/api/*"
}
},
{
"name": "outbound-access",
"attrs": {
"host": "portal.vtexcommercestable.com.br",
"path": "/api/*"
}
},
{
"name": "ADMIN_DS"
},
{
"name": "colossus-fire-event"
},
{
"name": "colossus-write-logs"
}
]
}
誤った例
{
"policies": []
}
アプリが api.vtex.com を呼び出し、Master Data を使用しているのに、ポリシー配列が空です。すべてのアウトバウンドリクエストは実行時に失敗し、デバッグが難しい 403 Forbidden エラーが発生します。
制約:アプリの命名規則に従う
アプリ名は必ずケバブケース(ハイフンで区切った小文字)にしてください。vendor は VTEX アカウント名と一致する必要があります。version は Semantic Versioning 2.0.0 に従う必要があります。
重要な理由
無効な名前のアプリは VTEX App Store に公開できません。特殊文字や大文字を含む名前は builder-hub に拒否されます。vendor が一致しない場合、アカウントでアプリを管理できません。
検出方法
アプリ名に大文字、アンダースコア、特殊文字が含まれている場合、または数字で始まる場合は、作業を中断して名前を修正してください。
正しい例
{
"name": "order-status-dashboard",
"vendor": "mycompany",
"version": "2.1.3"
}
誤った例
{
"name": "Order_Status_Dashboard",
"vendor": "mycompany",
"version": "2.1"
}
名前に大文字やアンダースコアが含まれていると拒否されます。version の「2.1」は有効な semver ではありません。「2.1.0」にする必要があります。
推奨パターン
VTEX IO CLI で初期化します。
vtex init
適切なテンプレートを選択します:service-example、graphql-example、react-app-template、または store-theme。
推奨するマニフェスト設定:
{
"name": "product-review-service",
"vendor": "mycompany",
"version": "0.1.0",
"title": "Product Review Service",
"description": "Backend service for managing product reviews with GraphQL API",
"builders": {
"node": "7.x",
"graphql": "1.x",
"docs": "0.x"
},
"dependencies": {
"vtex.search-graphql": "0.x"
},
"policies": [
{
"name": "outbound-access",
"attrs": {
"host": "api.vtex.com",
"path": "/api/*"
}
},
{
"name": "ADMIN_DS"
},
{
"name": "colossus-fire-event"
},
{
"name": "colossus-write-logs"
}
]
}
バックエンドアプリに推奨される service.json:
{
"memory": 256,
"timeout": 30,
"minReplicas": 2,
"maxReplicas": 10,
"workers": 4,
"routes": {
"reviews": {
"path": "/_v/api/reviews",
"public": false
},
"review-by-id": {
"path": "/_v/api/reviews/:id",
"public": false
}
}
}
推奨するディレクトリー構成:
my-app/
├── manifest.json
├── package.json
├── node/
│ ├── package.json
│ ├── tsconfig.json
│ ├── service.json
│ ├── index.ts # Service entry point
│ ├── clients/
│ │ └── index.ts # Client registry
│ ├── middlewares/
│ │ └── validate.ts # HTTP middleware
│ └── resolvers/
│ └── reviews.ts # GraphQL resolvers
├── graphql/
│ ├── schema.graphql # Query/Mutation definitions
│ └── types/
│ └── Review.graphql
├── messages/
│ ├── en.json
│ ├── pt.json
│ └── es.json
└── docs/
└── README.md
複数のビルダーを使用する包括的なアプリ向けの manifest.json 全体:
{
"name": "product-review-suite",
"vendor": "mycompany",
"version": "1.0.0",
"title": "Product Review Suite",
"description": "Complete product review system with backend, frontend, and admin panel",
"mustUpdateAt": "2026-01-01",
"builders": {
"node": "7.x",
"react": "3.x",
"graphql": "1.x",
"admin": "0.x",
"messages": "1.x",
"store": "0.x",
"docs": "0.x"
},
"dependencies": {
"vtex.styleguide": "9.x",
"vtex.store-components": "3.x",
"vtex.css-handles": "0.x"
},
"peerDependencies": {
"vtex.store": "2.x"
},
"policies": [
{
"name": "outbound-access",
"attrs": {
"host": "api.vtex.com",
"path": "/api/*"
}
},
{
"name": "ADMIN_DS"
},
{
"name": "colossus-fire-event"
},
{
"name": "colossus-write-logs"
}
],
"settingsSchema": {
"title": "Product Review Suite Settings",
"type": "object",
"properties": {
"enableModeration": {
"title": "Enable review moderation",
"type": "boolean"
},
"reviewsPerPage": {
"title": "Reviews per page",
"type": "number"
}
}
}
}
よくある失敗例
- 未使用のビルダーを宣言する:「念のため」ビルダーを追加すると、ビルドプロセスに余計な負荷がかかります。未使用のビルダーディレクトリーは、ビルド時の警告の原因になることがあります。アプリが実際に使用するビルダーのみを宣言してください。
- ワイルドカードのアウトバウンドポリシー:
"host": "*"や"path": "/*"を使用するとセキュリティリスクが生じ、アプリの審査で拒否されるほか、セキュリティ監査も難しくなります。外部サービスごとに個別のポリシーを宣言してください。 - 依存関係のバージョンを固定する:
"vtex.store-components": "3.165.0"のように正確なバージョンを指定すると、バグ修正を受け取れなくなります。xワイルドカードを使ったメジャーバージョンの範囲を指定してください:"vtex.store-components": "3.x"。
レビューチェックリスト
- すべてのコードディレクトリー(
/node、/react、/graphqlなど)に対応するビルダーがmanifest.jsonにありますか? - すべての外部ホストと VTEX リソースが
policiesに宣言されていますか? - アプリ名はケバブケースで、vendor はアカウント名と一致し、version は有効な semver ですか?
-
nodeビルダーを使用するアプリにservice.jsonがありますか? - 依存関係には正確なバージョンではなく、メジャーバージョンの範囲(
3.x)を指定していますか? - プレースホルダーの値(vendor、アプリ名、ポリシー)は実際の値に置き換えられていますか?