
- TOP
- ã¿ã°äžèЧ
- Claude Code
Claude Code
ã€ãã³ã
ãã¬ãžã³
æè¡ããã°
ããã«ã¡ã¯ãé§
ã¡ã¢ïŒéçºããŒã ãšã³ãžãã¢ã® id:hayayanai ã§ãïŒ æè¿ã VoidZero ãã Vite+ ããªãªãŒã¹ãããŸããã Vite+ 㯠Vite 8ãVitestãOxlintãOxfmt ãªã©ãçµ±åãããWeb ã®ããã®çµ±åããŒã«ãã§ãŒã³ãã§ãã é§
ã¡ã¢ïŒã¯çŸåš Vue + Vite 7 + Vitest + ESLintïŒããŒã ç¬èªã«ãŒã«æãïŒ+ Prettier + Stylelint ã§éçºãããŠãããVite+ ã®ããŒã«ã¯ãŸã å°å
¥ããŠããŸããã AI ã§éçºãé«éåããçŸä»£ãæ°ååéããšè¬³ã Vite+ ã®ããŒã«ãã§ãŒã³ã¯æ°ã«ãªããŸãã ãã ãããããåããŒã«ãã©ãããã Vue 察å¿ããŠããã®ããã©ãèšå®ããã°è¯ãã®ããããããªãã£ãã®ã§ããã³ãã¬ã䜿ã£ãŠç¢ºèªããããšã«ããŸããã Vite+ çµç±ã® vp create vue ãšåŸæ¥ã® pnpm create vue@latest ã§çæããããããžã§ã¯ãèšå®ãæ¯èŒããVue ãããžã§ã¯ãç¹æã®æ³šæç¹ãæŽçããŸãã æ€èšŒç°å¢ ãããžã§ã¯ãã®äœæ Vite+ çµç± åŸæ¥ã® create-vue çæãããèšå®ãã¡ã€ã«ã®æ¯èŒ Vite+ ãããžã§ã¯ãã®æ§æ åŸæ¥ã® create-vue ãããžã§ã¯ãã®æ§æ å
±é: eslint.config.ts å
±é: Lint å®è¡é Linter æ¯èŒ: Oxlint vs ESLint æ€èšŒçšã³ã³ããŒãã³ã Oxlint ã®çµæ ESLint ã®çµæ CSS/Style Lint ã«ã€ã㊠åãã§ãã¯ã®éã ãã¹ã Formatter æ¯èŒ: Oxfmt vs Prettier Vue SFC ã®ãã©ãŒãããå¯Ÿå¿ å
šäœæ¯èŒè¡š ãŸãšã Linter åãã§ã㯠Formatter CSS Lint æ€èšŒç°å¢ vp v0.1.16 (Vite+) create-vue v3.22.2 (pnpm create vue@latest) Node.js v24.14.1 pnpm v10.33.0 ãããžã§ã¯ãã®äœæ Vite+ çµç± vp create vue vue-viteplus â Which package manager would you like to use? pnpm â pnpm@10.33.0 installed â Which agents are you using? Claude Code â Which editor are you using? VSCode â Set up pre-commit hooks to run formatting, linting, and type checking with auto-fixes? Yes Generating project⊠Running: pnpm dlx create-vue â Vue.js - The Progressive JavaScript Framework â â Project name (target directory): â vue-viteplus â â Use TypeScript? â Yes â â Select features to include in your project: â Vitest (unit testing), Linter (error prevention), Prettier (code formatting) â â Select experimental features to include in your project: â Replace Prettier with Oxfmt â â Skip all example code and start with a blank Vue project? â No Scaffolding project in /Users/yanai/project/vue-viteplus... â â Done. â Merged vue-viteplus/.oxlintrc.json into vue-viteplus/vite.config.ts â Merged vue-viteplus/.oxfmtrc.json into vue-viteplus/vite.config.ts Wrote agent instructions to CLAUDE.md Rewrote imports in 4 files â Merged staged config into vue-viteplus/vite.config.ts â Dependencies installed â Code formatted â Scaffolded vue-viteplus åºåãèŠããš Running: pnpm dlx create-vue ãšãããå
éšã§ create-vue ãåŒãã§ããããšãåãããŸããcreate-vue ã§ãããžã§ã¯ããçæããåŸã«ãVite+ ã以äžã®å€æããããŠããŸãã .oxlintrc.json â vite.config.ts ã® lint ãããã¯ã«ããŒãž .oxfmtrc.json â vite.config.ts ã® fmt ãããã¯ã«ããŒãž vite / vitest ã® import ãã¹ã vite-plus ã«æžãæã pre-commit ããã¯ïŒ vp staged ïŒã®èšå®ãçµ±å ã€ãŸã vp create vue 㯠create-vue ã®ã©ãããŒã§ãçæç©ã Vite+ åãã«å€æããŠããã ãã®ããã§ãã åŸæ¥ã® create-vue pnpm create vue@latest vue-create-vue â Vue.js - The Progressive JavaScript Framework â â Use TypeScript? â Yes â â Select features to include in your project: â Vitest (unit testing), Linter (error prevention), Prettier (code formatting) â â Select experimental features to include in your project: â none â â Skip all example code and start with a blank Vue project? â No Scaffolding project in /Users/yanai/project/vue-create-vue... â â Done. ãã¡ãã¯åŸæ¥éãã®ã·ã³ãã«ãª Scaffold ã§ããcreate-vue åŽã§ããReplace Prettier with Oxfmtãã®éžæè¢ãåºãŸãããä»å㯠Oxfmt ãšã®æ¯èŒã®ãã Prettier ãéžã³ãŸããã çæãããèšå®ãã¡ã€ã«ã®æ¯èŒ 以éã®ã³ãŒããããã¯ã¯äž»èŠéšåã®æç²ã§ãã Vite+ ãããžã§ã¯ãã®æ§æ package.json { " scripts ": { " dev ": " vp dev ", " build ": " run-p type-check \" build-only {@} \" -- ", " build-only ": " vp build ", " type-check ": " vue-tsc --build ", " test:unit ": " vp test ", " lint ": " run-s lint:* ", " lint:oxlint ": " vp lint . --fix ", " lint:eslint ": " eslint . --fix --cache ", " format ": " vp fmt src/ " } , " devDependencies ": { " eslint ": " ^10.1.0 ", " eslint-plugin-vue ": " ~10.8.0 ", " eslint-plugin-oxlint ": " ~1.57.0 ", " eslint-config-prettier ": " ^10.1.8 ", " vite ": " catalog: ", " vite-plus ": " catalog: ", " vitest ": " catalog: " } } vite.config.ts: import { defineConfig } from "vite-plus" import vue from "@vitejs/plugin-vue" export default defineConfig( { staged : { "*" : "vp check --fix" , } , fmt : { semi : false , singleQuote : true , } , lint : { plugins : [ "eslint" , "typescript" , "unicorn" , "oxc" , "vue" , "vitest" ] , env : { browser : true } , categories : { correctness : "error" } , options : { typeAware : true , typeCheck : true } , } , plugins : [ vue() ] , } ) defineConfig ã 'vite-plus' ããã€ã³ããŒãããŠããŠãVite ã®èšå®ã«å ã lint ïŒOxlintïŒã fmt ïŒOxfmtïŒã staged ïŒpre-commit ããã¯ïŒã®èšå®ã1ã€ã®ãã¡ã€ã«ã«ãŸãšãŸã£ãŠããŸãã vite ãš vitest ã¯ã pnpm-workspace.yaml ã® catalog: ã«ãã @voidzero-dev ã®ãã®ã«è§£æ±ºãããŠããŸãã åŸæ¥ã® create-vue ãããžã§ã¯ãã®æ§æ package.json { " scripts ": { " dev ": " vite ", " build ": " run-p type-check \" build-only {@} \" -- ", " build-only ": " vite build ", " type-check ": " vue-tsc --build ", " test:unit ": " vitest ", " lint ": " run-s lint:* ", " lint:oxlint ": " oxlint . --fix ", " lint:eslint ": " eslint . --fix --cache ", " format ": " prettier --write --experimental-cli src/ " } , " devDependencies ": { " eslint ": " ^10.1.0 ", " eslint-plugin-vue ": " ~10.8.0 ", " eslint-plugin-oxlint ": " ~1.57.0 ", " eslint-config-prettier ": " ^10.1.8 ", " oxlint ": " ~1.57.0 ", " prettier ": " 3.8.1 ", " vite ": " ^8.0.3 ", " vitest ": " ^4.1.2 " } } .oxlintrc.json: { " plugins ": [ " eslint ", " typescript ", " unicorn ", " oxc ", " vue ", " vitest " ] , " env ": { " browser ": true } , " categories ": { " correctness ": " error " } } .prettierrc.json: { " $schema ": " https://json.schemastore.org/prettierrc ", " semi ": false , " singleQuote ": true , " printWidth ": 100 } å
±é: eslint.config.ts åè¿°ã®éã vp create vue ã¯å
éšã§ create-vue ãå®è¡ããŠãããããeslint.config.ts ã¯äž¡ãããžã§ã¯ãã§åäžã§ãã import { defineConfigWithVueTs, vueTsConfigs, } from "@vue/eslint-config-typescript" import pluginVue from "eslint-plugin-vue" import pluginVitest from "@vitest/eslint-plugin" import pluginOxlint from "eslint-plugin-oxlint" import skipFormatting from "eslint-config-prettier/flat" export default defineConfigWithVueTs( { name : "app/files-to-lint" , files : [ "**/*.{vue,ts,mts,tsx}" ] } , ...pluginVue.configs[ "flat/essential" ], vueTsConfigs.recommended, { ...pluginVitest.configs.recommended, files : [ "src/**/__tests__/*" ] } , ...pluginOxlint.buildFromOxlintConfigFile( ".oxlintrc.json" ), skipFormatting ) ãã ããVite+ ãããžã§ã¯ãã§ã¯ãã® eslint.config.ts ã«èœãšã穎ããããŸãã Vite+ ã®å
¬åŒã¬ã€ã ã§ã¯ .oxlintrc.json ã®äœ¿çšã¯æšå¥šãããŠãããã vite.config.ts ã® lint ãããã¯ãžèšå®ãéçŽããæ¹éã§ããå®éã vp create vue ã§ .oxlintrc.json 㯠vite.config.ts ãžããŒãžãããåŸã«åé€ãããŠããŸãã ããã eslint.config.ts ã® buildFromOxlintConfigFile(".oxlintrc.json") ã¯ãã®ãŸãŸæ®ã£ãŠããŸããååšããªããã¡ã€ã«ãåç
§ãããš eslint-plugin-oxlint: could not find oxlint config file: .oxlintrc.json ãšèŠåãåºãŠç©ºé
åãè¿ããããã«ãŒã«éè€ã®ç¡å¹åãå¹ããŸããã ã€ãŸããOxlint ãš ESLint ã§åãéåãéè€å ±åãããç¶æ
ã«ãªããŸãã åé¿çã¯2ã€ãããŸãã ïŒã€ç®ã¯ vite.config.ts ãã lint ãããã¯ãçŽæ¥ã€ã³ããŒãããæ¹æ³ã§ãã eslint.config.ts 㯠TypeScript ã§ãããã vite.config.ts ã® default export ãã .lint ãåãåºã㊠buildFromOxlintConfig ã«æž¡ããŸãã // eslint.config.ts import viteConfig from './vite.config' // 倿Žå: ãã¡ã€ã«ãååšããªãããæ©èœããªã ...pluginOxlint.buildFromOxlintConfigFile( ".oxlintrc.json" ), // 倿ŽåŸ: vite.config.ts ã® lint ãããã¯ããã®ãŸãŸæž¡ã ...pluginOxlint.buildFromOxlintConfig(viteConfig.lint), ïŒã€ç®ã¯ vite.config.ts ã® lint ãããã¯ãåé€ãã .oxlintrc.json ã«èšå®ãäžæ¬åããæ¹æ³ã§ãã vite-plus ã® issue ã«ãããšãçŸç¶ã®å®è£
ã§ã¯ .oxlintrc.json çã®å°çšèšå®ãã¡ã€ã«ãåªå
ããã vite.config.ts ã¯ãã©ãŒã«ããã¯ãšããŠäœ¿ãããŸãã .oxlintrc.json ãããã°ãã¡ããèªã¿èŸŒãŸããŸãã { " plugins ": [ " eslint ", " typescript ", " unicorn ", " oxc ", " vue ", " vitest " ] , " env ": { " browser ": true } , " categories ": { " correctness ": " error " } , " options ": { " typeAware ": true , " typeCheck ": true } } eslint.config.ts ã®ä¿®æ£ãäžèŠã§æžã¿ãŸãããVite+ ã®ã vite.config.ts ã«éçŽãããæ¹éãšã¯å€ããŸãã å
±é: Lint å®è¡é 2026幎4ææç¹ã§ãcreate-vue 㯠Oxlint ãããã©ã«ãã§å梱ããŠããŸããåè¿°ã® package.json ã«ããéãã pnpm lint ïŒ run-s lint:* ïŒã§ lint:oxlint â lint:eslint ã®é ã«çŽåå®è¡ãããŸãã create-vue åŽã§ã¯ eslint-plugin-oxlint ã .oxlintrc.json ãèªã¿åããOxlint ãšéè€ãã ESLint ã«ãŒã«ãèªåã§ç¡å¹åããŠãããŸãã # Vite+ vp run lint # â vp lint . --fix ... OxlintïŒvpçµç±ïŒ # â eslint . --fix --cache ... ESLintïŒçŽæ¥åŒã³åºãïŒ # create-vue pnpm lint # â oxlint . --fix ... OxlintïŒçŽæ¥åŒã³åºãïŒ # â eslint . --fix --cache ... ESLintïŒçŽæ¥åŒã³åºãïŒ vp lint 㯠Oxlint ã ããå®è¡ããçµã¿èŸŒã¿ã³ãã³ãã§ãESLint 㯠Vite+ ã«çµ±åãããŠããŸããã ãã®ããããã³ãã¬ãŒãã§ã¯ ESLint ã eslint ã³ãã³ãã§çŽæ¥åŒã¶æ§æã«ãªã£ãŠããŸãã Vite+ ã®ã¿ã¹ã¯ã©ã³ããŒã掻çšãããå Žåã¯ã vite.config.ts ã® run.tasks ã«å®çŸ©ãç§»è¡ãããšè¯ãããã§ãã run.tasks ã§å®çŸ©ããã¿ã¹ã¯ã¯ããã©ã«ãã§ãã£ãã·ã¥ãæå¹ãªãããå
¥åãã¡ã€ã«ã«å€æŽããªããã°åå®è¡ãã¹ããããããŸãã ãªãã run.tasks ã®ã¿ã¹ã¯å㯠package.json ã® scripts ãšéè€ã§ããªããããç§»è¡ããå Žå㯠package.json åŽã® lint ã¹ã¯ãªãããåé€ããŸãã // package.json ã® lint é¢é£ã¹ã¯ãªããã run.tasks ã«ç§»è¡ããäŸ run: { tasks: { lint: { command: 'vp lint . --fix && eslint . --fix --cache' , input: [{ auto : true } , '!.eslintcache' ] , } , } , } , eslint ã® --cache ã䜿ããš .eslintcache ãæžãåºããã vp run ããããå
¥åã®å€æŽãšèŠãªããŠã¿ã¹ã¯ãã£ãã·ã¥ããããããŸããã input ã§ '!.eslintcache' ãæå®ãããã£ãã·ã¥ãã¡ã€ã«ã倿޿€ç¥ã®å¯Ÿè±¡å€ã«ããããšã§äœµçšã§ããŸãã ãã£ãã·ã¥æ©èœã«ã€ããŠã¯ ESLint ã§ã¯ãªãã¿ã¹ã¯ã©ã³ããŒåŽã®ãã®ã§ååãããããŸãããã --cache ã®æç¡ã«ããå·®ç°ã¯ä»åæªæ€èšŒã§ãã Linter æ¯èŒ: Oxlint vs ESLint æ€èšŒçšã³ã³ããŒãã³ã æ€èšŒçšã«ãæå³çã« Lint éåãä»èŸŒãã Vue ã³ã³ããŒãã³ããçšæããŸããã < script setup lang = "ts" > import { ref } from "vue" // unused expression (correctness) const x = 1 x // prefer-as-const (typescript) let y = "hello" as "hello" const items = ref ([ { id : 1 , name : "Apple" } , { id : 2 , name : "Banana" } , ]) </ script > < template > <!-- v-for without :key --> < li v- for = "item in items" > {{ item.name }} </ li > <!-- v-if and v-for on same element --> < div v- for = "item in items" v-if= "item.id > 0" :key= "item.id" > {{ item.name }} </ div > </ template > < style scoped> .unused-class { color : redd; } </ style > Oxlint ã®çµæ # Vite+ vp lint src/components/LintTest.vue x eslint(no-unused-expressions): Expected expression to be used , - [src/components/LintTest.vue: 6 : 1 ] 5 | const x = 1 6 | x : ^ `---- x typescript-eslint(prefer-as-const): Expected a ` const ` assertion instead of a literal type annotation. , - [src/components/LintTest.vue: 9 : 20 ] 8 | // prefer-as-const (typescript) 9 | let y = 'hello' as 'hello' : ^^^^^^^ ` ---- Found 0 warnings and 2 errors. Finished in 369ms on 1 file with 132 rules using 10 threads. # create-vue pnpm exec oxlint -c .oxlintrc.json src/components/LintTest.vue ...ïŒåäžã® 2 ä»¶ïŒ Found 0 warnings and 2 errors. Finished in 24ms on 1 file with 116 rules using 10 threads. Oxlint 㯠<script> å
ã®éåãæ€åºããŸãããã <template> / <style> ã®åé¡ã¯ã¹ã«ãŒãããŠããŸããOxlint 㯠.vue ãã¡ã€ã«ã® <script> ãããã¯ãã Lint ããªãããã§ãã oxc ã®äºææ§ããŒãž ã«ãããéããVue/Svelte/Astro çã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ script ãããã¯ã®ã¿ã察象ã§ãã vue ãã©ã°ã€ã³ãæå¹ã«ããŠããscript ãããã¯å
ã® Vue é¢é£ã«ãŒã«ïŒref ã®äœ¿ãæ¹ãªã©ïŒããåããŸããã SFC ãã³ãã¬ãŒãã® Lint 察å¿ã¯ oxc#15761 ã§è¿œè·¡ãããŠããŸããããŸã å®è£
ãããŠããŸããã ãŸããOxlint ã«ã¯ ESLint ã® JS ãã©ã°ã€ã³ãèªã¿èŸŒã JS plugins æ©èœããããŸãããeslint-plugin-vue ã¯åããŸããã JS plugins ã® å¶éäºé
ã«ãCustom file formats and parsers (e.g. Svelte, Vue, Angular)ãã¯æªå¯Ÿå¿ãšæèšãããŠããŸãã eslint-plugin-vue ã¯ã«ã¹ã¿ã ããŒãµãŒïŒ vue-eslint-parser ïŒã§ .vue ãã¡ã€ã«å
šäœãããŒã¹ããŠãã³ãã¬ãŒãã® AST ãã«ãŒã«ã«æž¡ãä»çµã¿ã®ããããã®å¶éã«è©²åœããŠããŸãã ã«ãŒã«æ°ã®å·®ïŒ132 vs 116ïŒã¯ã typeAware: true ã§åæ
å ±ã䜿ã£ããã§ãã¯ïŒfloating promise ã®æ€åºçïŒã远å ãããããã§ãã ãªããVite+ ãã³ãã¬ãŒãã® typeCheck: true 㯠Vue ãããžã§ã¯ãã§ã¯å®è³ªçã«äœ¿ããªãããã§ãã vp lint src/ ã®ããã«ãã£ã¬ã¯ããªãæå®ãããš .ts ãã¡ã€ã«ããã§ãã¯å¯Ÿè±¡ã«ãªããŸãã ãããã .ts ãã .vue ãã€ã³ããŒãããŠããç®æã§ tsgo ãã¢ãžã¥ãŒã«è§£æ±ºã«å€±æã TS2307: Cannot find module ãšã©ãŒãåºãŸãã äžã®æ€èšŒã§ãã¡ã€ã«ãçŽæ¥æå®ããŠããã®ã¯ãã®åé¡ãåé¿ããããã§ãã ESLint ã®çµæ # Vite+ïŒeslint-plugin-oxlint ãæ©èœããŠããªãïŒ vp exec eslint src/components/LintTest.vue src/components/LintTest.vue 6 : 1 error Expected an assignment or function call and instead saw an expression @typescript-eslint/no-unused-expressions 9 : 5 error 'y' is never reassigned. Use 'const' instead prefer-const 9 : 5 error 'y' is assigned a value but never used @typescript-eslint/no-unused-vars 9 : 20 error Expected a `const` instead of a literal type assertion @typescript-eslint/prefer-as-const 19 : 3 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key 22 : 30 error The 'items' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for â 6 problems ( 6 errors, 0 warnings) # create-vueïŒeslint-plugin-oxlint ãæ£åžžåäœïŒ pnpm exec eslint src/components/LintTest.vue src/components/LintTest.vue 9 : 5 error 'y' is never reassigned. Use 'const' instead prefer-const 9 : 5 error 'y' is assigned a value but never used @typescript-eslint/no-unused-vars 19 : 3 error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key 22 : 30 error The 'items' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for â 4 problems ( 4 errors, 0 warnings) Vite+ åŽã¯ Oxlint ã§æ€åºãããŠãã no-unused-expressions ãš prefer-as-const ã ESLint ããå ±åãããŠ6ä»¶ãåè¿°ã®éãã«ãŒã«éè€ã®ç¡å¹åãå¹ããŠããŸããã create-vue åŽã¯ eslint-plugin-oxlint ãæ£åžžåäœããOxlint ãšã®éè€ã«ãŒã«ã ESLint åŽã§ç¡å¹åããããã4ä»¶ã ã©ã¡ããã eslint-plugin-vue ã«ãã <template> å
ã® Vue åºæã®åé¡ãæ€åºãããŠããŸãã CSS/Style Lint ã«ã€ã㊠æ€èšŒçšã³ã³ããŒãã³ãã® <style> ã« color: redd; ãšããã¿ã€ããä»èŸŒã¿ãŸããããOxlint ã§ã ESLint ã§ãåŒã£ããããŸããã§ããã ã©ã¡ãã®ãã³ãã¬ãŒãã CSS ã® Lint ã¯å¯Ÿè±¡å€ã®ããã§ãã Vue å
¬åŒã®ããŒãªã³ã°ã¬ã€ãã® Linting ã»ã¯ã·ã§ã³ ã§ãæ¡å
ãããŠããã®ã¯ eslint-plugin-vue ã«ãã JavaScript/ãã³ãã¬ãŒãã® Lint ã ãã§ãCSS/Style ã® Lint ã«ã¯è§ŠããŠããŸããã CSS ã® Lint ãå¿
èŠãªãããããŸã§åæ§ Stylelint ãš Vue ãã©ã°ã€ã³ãå¥éå
¥ããããšã«ãªãããã§ãã åãã§ãã¯ã®éã pnpm type-check ã¯ã©ã¡ãã vue-tsc --build ã§åãã§ãã Vite+ åŽã¯ vite.config.ts ã« typeAware: true ïŒåèªè Lint ã«ãŒã«ã®æå¹åïŒãš typeCheck: true ïŒtsgo çµç±ã®åãã§ãã¯åæå®è¡ïŒã®èšå®ããããŸãã ãã ãåè¿°ã®éã tsgo 㯠.vue ãèªããªãããã .vue ã®åãã§ãã¯ã«ã¯åŒãç¶ã vue-tsc ãå¿
èŠã§ãã ãã¹ã ã©ã¡ãã Vitest ã§ãã Vite+ ã§ã¯ã€ã³ããŒããã¹ã 'vitest' ãã 'vite-plus/test' ã«ãã³ãã³ãã vitest ãã vp test ã«å€ãããŸãããèšå®å
容ããã¹ãã®æžãæ¹ã¯åãã§ãã Formatter æ¯èŒ: Oxfmt vs Prettier Oxfmt 㯠Prettier ãšã®åºåäºæã謳ã£ãŠãããJavaScript/TypeScript ã® conformance test ã 100% ãã¹ããŠããŸãã Vue SFC ã®ãã©ãŒãããå¯Ÿå¿ <template> ãš <style> ããã©ãŒãããã§ããã®ãæ°ã«ãªã£ãããããããšåŽ©ãã Vue ãã¡ã€ã«ã§è©ŠããŸããã <!-- ãã©ãŒãããå --> < template >< div class = "foo" >< p v-if= "true" > hello </ p ></ div ></ template > < style scoped>.foo{ color : red ; font-size : 16px ; display : flex ; justify-content : center }</ style > <!-- ãã©ãŒãããåŸïŒOxfmt / Prettier ã©ã¡ããåäžã®çµæïŒ --> < template > < div class = "foo" >< p v-if= "true" > hello </ p ></ div > </ template > < style scoped> .foo { color : red ; font-size : 16px ; display : flex ; justify-content : center ; } </ style > Oxfmt ã§ã Prettier ã§ã <template> ãš <style> ããã©ãŒãããã§ããåºåçµæã¯åäžã§ãããä¹ãæããŠåé¡ãªãããã§ãã å
¬åŒããã¥ã¡ã³ã ã«ãããš Prettier ã®çŽ30åã®é床ãšã®ããšãå°èŠæš¡ãããžã§ã¯ãã ãšäœæå·®ã¯ãããŸããããå€§èŠæš¡ãããžã§ã¯ãã§ã¯å·®ãåºããã§ãã å
šäœæ¯èŒè¡š é
ç® Vite+ ( vp create vue ) create-vue ( pnpm create vue@latest ) Linter Oxlint ( vp lint ) + ESLint Oxlint + ESLint ESLint èšå® åäž ïŒãã ã eslint-plugin-oxlint ã®ä¿®æ£ãå¿
èŠïŒ åäž Vue template lint ESLint çµç±ã§å¯Ÿå¿ ESLint çµç±ã§å¯Ÿå¿ CSS lint ãªã ãªã typeCheck tsgo ã .vue ãèªããå®è³ªäœ¿ããªã ãªã ãã¹ã Vitest ( vp test ) Vitest Formatter Oxfmt ( vp fmt ) Prettier (Oxfmtãæ¡å
ããã) ãã«ã Vite ( vp build ) Vite ( vite build ) èšå®ã®çµ±å vite.config.ts ã«éçŽ åå¥ãã¡ã€ã« ( .oxlintrc.json , .prettierrc.json ) Pre-commit ãã㯠.vite-hooks/pre-commit â vp staged ãªã (èŠå¥éèšå®) ãŸãšã vp create vue ãš pnpm create vue@latest ã§çæããããããžã§ã¯ããæ¯èŒããçµæããŸãšããŸãã Linter Oxlint 㯠.vue ã® <script> ãããã¯ãã Lint ã§ããªã <template> ã <style> ã¯å¯Ÿè±¡å€ Vue template ã® Lint ã«ã¯åŒãç¶ã ESLintïŒeslint-plugin-vueïŒãå¿
èŠ ãã㯠Vite+ ã§ã create-vue ã§ãåã create-vue 㯠Oxlint ãããã©ã«ãã§å梱ããŠãã ESLint 飿ºã®èœãšã穎 Vite+ ãã³ãã¬ãŒãã§ã¯ .oxlintrc.json ãããŒãžåŸã«åé€ãããããšãžã®å¯Ÿå¿ãç¡ããã«ãŒã«éè€ã®ç¡å¹åãå£ãã vite.config.ts ã® lint ãããã¯ã import ãããã .oxlintrc.json ã«äžæ¬åããããšã§å¯ŸåŠã§ãã Lint å®è¡ ã©ã¡ãã Oxlint â ESLint ã®çŽåå®è¡ åãã§ã㯠typeCheck: true 㯠Vue ãããžã§ã¯ãã§ã¯å®è³ªäœ¿ããªã tsgo ã .vue ãã€ã³ããŒããã .ts ãã¡ã€ã«ã§ TS2307 ãšã©ãŒãåºããã .vue ã®åãã§ãã¯ã«ã¯åŒãç¶ã vue-tsc ãå¿
èŠ Formatter Oxfmt 㯠Prettier ãšåäžã®åºå <template> / <style> ããã©ãŒãããã§ãã Prettier ããã®ä¹ãæãã§å°ãããšã¯ãªããã CSS Lint ã©ã¡ãã®ãã³ãã¬ãŒããå¯Ÿè±¡å€ å¿
èŠãªã Stylelint ãå¥éå
¥ããããšã«ãªã Vite+ ãéžã¶ã¡ãªãã㯠Linter/Formatter åäœã®å·®åãããã vite.config.ts ãžã®èšå®äžå
åãš vp ã³ãã³ãã«ããçµ±åã«ããããã§ããã Vue åºæã® Lint ãåãã§ãã¯ã«ã€ããŠã¯ãŸã ESLint + vue-tsc é ŒããªãããOxlint ã® Vue ãã³ãã¬ãŒã察å¿ã tsgo ã® .vue ãµããŒããæŽãã°ãèšå®ã楜ã«ãªãããã§ãã ä»åã¯ãã³ãã¬ãŒãã®èšå®æ¯èŒã ãã§ããããæ°ã«ãªãã®ã¯ãã¯ãå®éã®ãããžã§ã¯ãã§ã®é床差ã§ãã æ¬¡å㯠Vue ãã¡ã€ã«ãçŽ2000åååšããé§
ã¡ã¢ïŒã®ããã³ããšã³ãã§ãLint/Format/ãã«ããã©ããããéããªãã宿ž¬ããŠã¿ãŸãããæ¥œãã¿ã«ïŒ
ããã«ã¡ã¯ãAmazon Web Services Japan ã®ãœãªã¥ãŒã·ã§ã³ã¢ãŒããã¯ããç°äž éçµµ ã§ãã æ¬ããã°ã¯ã2026 幎 4 æã5 æã«ãããŠå
šåœ 5 æ ç¹ã»èš 8 åã§éå¬ããã AWS Local Executive Roadshow ãã·ãªãŒãºã®ç¬¬ 3 åã¬ããŒãã§ããã·ãªãŒãºã®èæ¯ãå
šäœåã«ã€ããŠã¯ã ååã®å€§éªã»ååã¬ããŒã ãã芧ãã ããã 倧éªã§ã® 2 æ¥éã®ã€ãã³ãã«ç¶ãã2026 幎 4 æ 22 æ¥ã¯åå€å±ã«ãŠãAI ãèªç€Ÿã®æ¥åã«æŽ»ããããäŒæ¥ã®ãšã°ãŒã¯ãã£ãã»æ
å ±ã·ã¹ãã éšéã®çæ§ããè¿ãããã å®è·µäŒæ¥ã«åŠã¶çæ AI å°å
¥ã®åæ ãç ãããŒã¿ãäŒæ¥äŸ¡å€ã«å€ããã ããšé¡ããã€ãã³ããéå¬ããŸããã ã€ãã³ãã®æµã åœæ¥ã¯ãŸããAmazon Web Services Japan ã®ãœãªã¥ãŒã·ã§ã³ã¢ãŒããã¯ãå€å± æ¥ãããAWS ã§äžæ©å
ãžïŒçæ AI æä»£ã®ããžãã¹å€é©ã®æã¡æããšé¡ãããªãŒããã³ã°ã»ãã·ã§ã³ããå±ãããŸãããçæ AI ãåãå·»ãäžçãšæ¥æ¬ã®ç°å¢ãAWS ã®çæ AI ããŒããã©ãªãªããã㊠AI ãèªç€Ÿã®æ¥åã«æŽ»ããããã客æ§ãã©ã®ããã«çæ AI ã§æ¥åãšããžãã¹ãå€ããŠããããã«ã€ããŠã Amazon Quick ã®ãã¢ã亀ããªããã玹ä»ããŠããŸããã»ãã·ã§ã³ã®è©³çްã«ã€ããŠã¯ ååã®å€§éªã»äºæ¥äŒç€Ÿç·šã®ã¬ããŒã ãã芧ãã ããã åç: å€å±ã«ãããªãŒããã³ã°ã»ãã·ã§ã³ AWS åŽã®ã»ãã·ã§ã³ãéããŠçæ AI 掻çšã®å
šäœåãšã€ã¡ãŒãžãã€ããã§ããã ããããšãããã«ãã£ã¹ã«ãã·ã§ã³ãžãšé²ã¿ãŸãããããããã¯ãäžéšãæ ç¹ã« 270 幎以äžã®æŽå²ãæã¡ãªãããçµå¶ã»çŸå Žã®åæ¹ããçæ AI 掻çšã«ææŠãããŠãã 1 瀟ã®äºäŸãã玹ä»ããŸãã äºäŸç޹ä»ïŒã¿ãããšãŒæ ªåŒäŒç€Ÿæ§ ãçµå¶ãšçŸå Žã䞡茪ã§é²ãã Amazon QuickSight ã«ããããŒã¿æŽ»çšã äºäŸç޹ä»ã¯ ã¿ãããšãŒæ ªåŒäŒç€Ÿ æ§ã§ãã1751 å¹ŽïŒæ±æžæä»£ã®å®æŠå
幎ïŒã«åå€å±ã§åµæ¥ããã 270 幎以äžã®æŽå²ãæã€ç¹ç¶ã¢ãã¬ã«äŒæ¥ã§ãããã¹ã¿ã€ã«äºæ¥ã§ã¯æç¥çäžå®®åžã«èªç€Ÿå·¥å Žããæã¡ã§ãäŒçµ±çãªè±åœåŒçŽ¡çžŸæ©ãçããããã®ã¥ãããè¡ãããŠããŸããã¢ãã¬ã«äºæ¥ã§ã¯äŒç»ã»è£œé ã»è²©å£²ã«å ãããªããŒã«äºæ¥ãšããŠèªç€Ÿãã©ã³ãã®å±éããããŠãããæ±äº¬èšŒåžååŒæã»åå€å±èšŒåžååŒæã«äžå ŽãããŠããäŒæ¥ã§ããåŸæ¥å¡æ°ã¯540 å(2026幎2ææ«)ããã¥ãŒãšãŒã¯ã«æ ç¹ããæã¡ã®ã°ããŒãã«äŒæ¥ã§ããããŸãã åœæ¥ã¯ãçµå¶èŠç¹ãšçŸå ŽèŠç¹ã®äž¡é¢ãããäºã€ã®ãããžã§ã¯ãã«ã€ããŠããã«ãã£ã¹ã«ãã·ã§ã³åœ¢åŒã§ã話ãããã ããŸãããAWS å°å¶ãã¢ãã¬ãŒã¿ãŒãåããããããã®ãããžã§ã¯ãã®èæ¯ããææãŸã§ã䌺ããŸããã æ¥å KPI ããã·ã¥ããŒãåãããžã§ã¯ã äžã€ãã®ãšããœãŒãã¯ãå·è¡åœ¹å¡ã®å¹³ç°æ§ãçµå¶ã®èŠç¹ã§æšé²ããããæ¥å KPI ããã·ã¥ããŒããããžã§ã¯ãã«ã€ããŠã§ãã ã¢ãã¬ã«æ¥çã¯è·äººçã»å±äººçãªæ¥ååŸåããããåãçµéšã«é Œããã¡ãªé¢ããããŸããçµå¶ãšããŠã売äžãå©çãšãã£ã KGI ãããã£ãšç²åºŠã®çްããæ¥å KPI ã§çµç¹ã®ç¶æ
ãå®éçã«ææ¡ããå¶æ¥æŽ»åã®æ¹åã«ç¹ããããšããæãããããžã§ã¯ãã®åºçºç¹ã§ããããã åœæã¯ãåçµç¹ã®ããŒã¿ã Excel ã«æ£åšããVBA ãã¯ãã§éèšããŠãããããåŠçã«æéãããã£ãããã¯ããæ³å®ã©ããåäœããªããªã©ã®èª²é¡ããããŸããã ãã®èª²é¡ã«å¯ŸããŠã Amazon QuickSight ãå°å
¥ããåºå¹¹ã·ã¹ãã ã NAS ã®ããŒã¿ãäžå
çã«å¯èŠåã»åæã§ããåºç€ãæ§ç¯ãããŸããããã ãå°å
¥ã«ããã£ãŠäžçªèŠåŽãããã®ããçŸå Žã®ã¢ã¬ã«ã®ãŒåå¿ãã ã£ããšãããŸãããããŸã§åãããŒãžã£ãŒãåã
ã®ããæ¹ã§ç®¡çæ¥åãåããŠãããšããã«ãçµ±äžã®ããã·ã¥ããŒããå°å
¥ãããšããæœçãã®ãã®ã«å¯ŸããŠããæéãå¢ããããšããåãæ¢ãããåçºããã£ããšã®ããšã§ãã ãã®å£ãä¹ãè¶ããããã«ããšã«ãã䜿ãåæã«ãã ãã£ãŠãããžã§ã¯ããé²ããããŸããã䟿å©ãã宿ããŠãããããšã§çè§£ãåŸãŠãå©çšãä¿é²ããããšèããããªã«ããŠã³æ©èœã®èšèšã«ç¹ã«æ³šåãããŸããã 倧ããªããŒã¿ãã詳现ãªããŒã¿ãžã𿮵éçã«æãäžããããšãã§ããæèŠçãªæäœã§ç®çã®ããŒã¿ã«ãã©ãçããããèšèš ããŸããããæ®æ®µã®åç·ãã®ãŸãŸã§äœ¿ãããããšã§çŸå Žã®æµææãäžããããšã«ç¹ããŸããããŸãã ããŒã¿ã®æ¬ æãè£ãããã«Webçµç±ã®ããŒã¿å
¥åã®ä»çµã¿ãæ§ç¯ ããããã·ã¥ããŒãã«è¡šç€ºãããããŒã¿ã®ä¿¡é Œæ§ãæ
ä¿ãã工倫ãè¡ãããŸããã çµæãšããŠãURL ã«ã¢ã¯ã»ã¹ããã°çµå¶ããŒã¿ããã確èªã§ããç¶æ
ã«ãªãã çŸå Žã®ãããŒãžã£ãŒãæ¬æ¥ã®æææ±ºå®æ¥åã«éäž ã§ããç°å¢ãæŽãã€ã€ãããšã®ããšã§ããä»åŸã¯ãåæã®ç²ŸåºŠåäžããåæããèµ·ãããã¢ã¯ã·ã§ã³ãæ¥çžŸã«ã©ãå¯äžãããã®å¹ææ€èšŒãããŠããããããšã話ããã ããŸããã éèŠäºæž¬ããŒã¿ã®ããã·ã¥ããŒãæ§ç¯ãããžã§ã¯ã ããŒã±ãã£ã³ã°ããŒã å
ŒDX æšé²ããŒã ã®å±±å£æ§ãçŸå Žã®å®è·µè
ãšããŠæšé²ããããããžã§ã¯ãã§ãã 山壿§ãèªèº«ã¯ãšã³ãžãã¢ã§ã¯ãªããããã°ã©ã ãæžãããçµéšã¯ãããŸããã§ããããã ããèªåãã¡ã®æã§ãªããšã掻æ§åããããããšããæããããéèŠäºæž¬ããŒã¿ã Amazon QuickSight ã§å¯èŠåããããã·ã¥ããŒãã®å
補æ§ç¯ã«åãçµãŸããŸãããæ¢åããŒã¿ã«ã¯ãè€æ°ã®æ
å ±ïŒè²ã»æã»çŽ æãªã©ïŒãäžã€ã®ã«ã©ã ã«ãŸãšããŠæ ŒçŽãããŠããããåå¥ã®å€ã§æœåºã§ããªãïŒäŸãã°äœè²ã売ããŠãããïŒãšãã£ãåæã¯ã§ããªãïŒãéèŠäºæž¬ã®æ°å€ã絶察å€ã®ã¿ã®ããã倿ã®åºæºããªãã¢ã¯ã·ã§ã³ã«ç¹ãããªãããšããäºã€ã®èª²é¡ããããŸããã éçºã«ããã£ãŠãåœå㯠Generative AI Use Cases ïŒ AWSãæäŸãããã£ããããŒã¹ã®çæAIã¢ããªã±ãŒã·ã§ã³ïŒã§ SQL ãçæãããŠããŸããããéçºãé£èªããŸããããã£ããããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã§ãå¿
èŠãªããŒã¿ïŒDBã®ããŒãã«æ
å ±ãå
šäœèšèšãæ¢åããŒã¿ãªã©ïŒãAIã«äžããªããäœæ¥ããããããšãããšãéçºãé²ãã»ã©ã³ã³ããã¹ãã®å¶éã«éããŠããŸãããã®éœåºŠæ°ããäŒè©±ãç«ã¡äžãçŽãå¿
èŠãçããäœæ¥äžã®ç
©éããçãã§ããŸãããããã«ãæ¬æ¥ã¯å¿
èŠãªã³ã³ããã¹ããæž¡ããããªãç¶æ³ãçºçãããããªããšAIãåºåããSQLãæ¬æ¥ã®ç®çãšç°ãªããã®ã«ãªãããšãã£ãåé¡ãçºçããŠããŸããã ãã®ãããªçµç·¯ããããã£ãããããããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã«éçãæããããã³ãŒãã£ã³ã°ãšãŒãžã§ã³ãã® Claude Code ã Amazon Bedrock çµç±ã§å©çšããæ¹éã«åãæ¿ããããŸãããã³ãŒãã£ã³ã°ãšãŒãžã§ã³ãã§ããã°ãAI ãšãŒãžã§ã³ãããŠãŒã¶ãŒæç€ºã«å¿ããŠå¿
èŠãªããŒã«ã«ãã¡ã€ã«ãèªåŸçã«åç
§ãã«ãããããä»ãŸã§äœæããŠããããŒãã«æ
å ±ãã·ã¹ãã èšèšããšã©ãŒå
容ãŸã§ã AI ãèªåã§ææ¡ããŠãããéçºå¹çã倧ããåäžããŸããã ããŒã¿ã®èª²é¡ã«ã€ããŠã¯ãæ¢åã®ããŒã¿ã®ETLã«ãåãçµãŸããŸãããå
·äœçã«ã¯ãäžã€ã®ã«ã©ã ã«æ··åšããŠããè²ã»æã»çŽ æãªã©ã®ããŒã¿ãè²å¥ã»çŽ æå¥ã»ã·ã«ãšããå¥ãªã©ã«ããããã®ã«ã©ã ã«åããŠå¯Ÿå¿ãã絶察å€ã§è¡šç€ºãããŠããéèŠäºæž¬å€ã âââ³âè©äŸ¡ãåçã«è¡šç€ºãããä»çµã¿ã«å€æŽãããŸããããã®éãClaude Code ãåãªãã³ãŒãçæããŒã«ãšããŠã§ã¯ãªãã ç®çãå
±æããæ¢åã®ããŒã¿ãçããããã«ã©ããªæ¹æ³ãããããäžç·ã«æ¢ããé Œããçžè«çžæããšããŠæŽ»çš ãããŸããããããããèŠãæ¹ã¯ã©ãããããã®åãæ¹ã ãšããŒã¿ã厩ããªãããââ ãžã§ã³ã¬ã®ããŒã¹ã厩ããªãããã«äžã€ãã€æ¢ããŠãããããªè©Šè¡é¯èª€ããAI ãšå¯Ÿè©±ããªããç¹°ãè¿ããã ãšã®ããšã§ãã çµæãšããŠã éåžžã§ããã°å€æ³šã§æ°ã¶æã»æ°çŸäžã»ã©ãããã·ã¹ãã ããéãšã³ãžãã¢ã®å±±å£æ§ãèªèº«ãæ°é±éã§æ§ç¯ ãããŸãããããã«ãããŒã¿æ§é ãæ·±æãããŠããéçšã§ã ãã³ããŒåŽã§ãã©ãã¯ããã¯ã¹åããŠãã課é¡ã«æ°ã¥ããæ¹åææ¡ã«ç¹ãããã ãšãã坿¬¡çãªå¹æããã£ããšã®ããšã§ããä»åŸã¯èªç€Ÿã«èç©ããã売äžã»åšåº«ããŒã¿ã®åã蟌ã¿ãã Amazon Quick ïŒAmazon QuickSight ãé²åããŠçãŸãã Agentic AI ãã©ãããã©ãŒã ïŒã® AI ãã£ããæ©èœã®æŽ»çšãæ€èšãããŠããŸãã ãäºäººããåå è
ãžã®ã¢ããã€ã¹ æåŸã«ããäºäººããåå è
ãžã®ã¢ããã€ã¹ãããã ããŸããã å¹³ç°æ§ããã¯ãã ãŸãã¯çŸæ¥åãå¯èŠåããŠããŒã¿ã§èŠãããäœå¶ãæŽããããšãç¬¬äžæ©ãå®ç§ãç®æãã®ã§ã¯ãªããçµå¶å±€ãçŸå Žã«å¯ŸããŠãå°ãã詊ããŠå€±æããåŠã¶ãããšã蚱容ããçŸå Žã®å€é©ãåŸæŒãããã¹ã¿ã³ã¹ãéèŠ ããšããã¡ãã»ãŒãžãããã ããŸããã 山壿§ããã¯ãã ãšã«ããããžã¿ã«äžã«ããŒã¿ãèç©ããããšã«æ³šåããŠã»ãããããžã¿ã«ããŒã¿ã¯äŒæ¥ã®è²¡ç£ã«ãªã ããšããã¡ãã»ãŒãžãåãåéã®ããŒã¿ã§ããããžã¿ã«ãã¢ããã°ãã§å°æ¥ã®è³ç£äŸ¡å€ã倧ããå€ãããä»®ã«ããŒã¿ã®äžèº«ãå€å°æŽçãããŠããªããŠããAI ãæŽ»çšããã°éãšã³ãžãã¢ã§ãçæ³çãªåœ¢ã«æŽåœ¢ã§ããã ã¢ããã°ããããžã¿ã«ãžã®ç§»è¡æ¹æ³èªäœããAI ã«çžè«ããŠã¿ãŠã»ãã ããšã話ãããã ããŸããã åç: ã¿ãããšãŒæ ªåŒäŒç€Ÿ å¹³ç°æ§ã»å±±å£æ§ãAWS å°å¶ã«ããããã«ãã£ã¹ã«ãã·ã§ã³ çµå¶ãšçŸå Žã®äž¡èŒªã§åãçµãŸããã話ã«ç¶ããŠãããããããŒã¿æŽ»çšã®åãçµã¿ãäŒŽèµ°æ¯æŽããããŒãããŒæ§ããã®ã»ãã·ã§ã³ã§ãã ããŒãããŒã»ãã·ã§ã³ïŒã¯ã©ã¹ã¡ãœããæ ªåŒäŒç€Ÿæ§ ãçæ AI 掻çšã®ããã®ããŒã¿åéã ã客æ§äºäŸã®ããšã«ã¯ãAWS ãã¬ãã¢ãã£ã¢ãµãŒãã¹ããŒãããŒã§ãã ã¯ã©ã¹ã¡ãœããæ ªåŒäŒç€Ÿ ããŒã¿äºæ¥æ¬éš ããŒã ãªãŒã㌠/ ãããžã§ã¯ããããŒãžã£ãŒã®äžéŽš å倪 æ§ããããçæ AI 掻çšã®ããã®ããŒã¿åéããšé¡ããã»ãã·ã§ã³ããå±ãããã ããŸãããåå€å±ãªãã£ã¹ãæ ç¹ã«ãã客æ§ã®ããŒã¿åºç€æ§ç¯ãããŒã¿æŠç¥æ¯æŽãæ
åœãããŠããäžéŽšæ§ãããããŒã¿ããªãã³çµå¶ãæ¯ããããŒã¿åºç€æŽåã®èãæ¹ãã話ãããã ããŸããã ããŒã¿åéãããŒã¿ããªãã³çµå¶ãšçæ AI 掻çšã®å
±éã®åå°ã§ãããšããç¹ãç¹ã«åŒ·èª¿ããŸãããããžãã¹ã®å éã®ããã«ã¯ãäŒæ¥ãæã€ããŒã¿è³ç£ãçæ AI ãšçµã¿åãããããšã§å·®å¥åã«ã€ãªããããã®ããã«ãå±äººåããŠããæ
å ±ãããã°ããããå¹ççã«ããŒã¿åããåéããŠããä»çµã¿ãéèŠã ãšè¿°ã¹ãããŸããã ããŒã¿åºç€æŽåã®é²ãæ¹ãšããŠã¯ãäŒæ¥æåã«åãããŠã Needs ïŒéèŠããããšããããããŒã¿åºç€æŽåãé²ããŠããïŒ ãš Seeds ïŒã§ãããšããããããŒã¿åºç€æŽåãå§ããïŒ ã® 2 ã€ã®ã¢ãããŒãã®ã©ã¡ããåãããšããããã¯ã©ã¹ã¡ãœããæ§ãæäŸããããŒã¿æŽ»çšåºç€æ§ç¯ã»éçšãµãŒãã¹ãããŒã¿æŽ»çšã³ã³ãµã«ãã£ã³ã°ãããŒã¿æŽ»çšåæç ä¿®ãçæ AI ç·åæ¯æŽãµãŒãã¹ãªã©æ§ã
ãªæ¯æŽã®ããæ¹ã玹ä»ããã ããŸããã åç: ã¯ã©ã¹ã¡ãœããæ ªåŒäŒç€Ÿ äžéŽšæ§ã«ããã»ãã·ã§ã³ ãŸãšã ã»ãã·ã§ã³åŸã«ã¯åå è
å士ã®ã°ã«ãŒããã£ã¹ã«ãã·ã§ã³ããããã¯ãŒãã³ã°ã®æéãèšããèªç€Ÿã® AI 掻çšã«ããã課é¡ã«ã€ããŠæŽ»çºãªè°è«ã亀ããããŸããã åå€å±ã§ãç»å£ããã ããã¿ãããšãŒæ§ãšã¯ã©ã¹ã¡ãœããæ§ã«å
±éããŠããã®ã¯ã ããŒã¿ãããã«éããæŽ»ãããç¶æ
ã«æŽããã ãšããåå°ã®éèŠæ§ãšã å°ããæåäœéšãå°ããã€ç©ã¿éãã ãšããé²ãæ¹ã®ãã¹ããã©ã¯ãã£ã¹ã§ãããAI ãæŽ»çšããŠããäŒæ¥æ§ã¯ãããŒã¿ãåšå²ã®å·»ãèŸŒã¿æ¹ãªã© AI 以å€ã®éšåã«ããã©ã¯ãã£ã¹ãæã£ãŠããããããšãäŒããã»ãã·ã§ã³ã§ããã ãã®ããã°ã·ãªãŒãºã§ã¯ãæ¬ã€ãã³ãã®éå¬ã¬ããŒããåæ ç¹ã®éå¬é ã«ãå±ãããŠãããŸããä»åãå±ãããåå€å±ã»3 æ¥ç®ã«ç¶ããæ¬¡åã¯ç¿æ¥éå¬ã®åå€å±ã»AI ã§é¡§å®¢ãæ¯æŽãã IT äŒæ¥ç·šãäºå®ããŠããŸãã®ã§ãã©ãããæ¥œãã¿ã«ã ãããŠèªè
ã®çæ§ãžââããæ¬ããã°ãèªãã§ããã¡ã®äŒç€Ÿã®åãçµã¿ããã²çºä¿¡ãããããAWS ãšäžç·ã«èªç€Ÿã®ç ãããŒã¿ã䟡å€ã«å€ãããããAI ã§æ¥æ¬ããã£ãšå
æ°ã«ããŠããããããšæããŠããã ãããªãããã²æ
åœå¶æ¥ããããã¯ãè¿ãã® AWS ã¡ã³ããŒãŸã§ãæ°è»œã«ã声ãããã ããã é¢é£ããã° å®è·µäŒæ¥ã«åŠã¶çæ AI å°å
¥ã®åæ ãç ãããŒã¿ãäŒæ¥äŸ¡å€ã«å€ããã â AWS Local Executive Roadshow 倧éªç·šïŒ#1/8ïŒéå¬ã¬ããŒã å®è·µäŒæ¥ã«åŠã¶çæ AI å°å
¥ã®åæ ãç ãããŒã¿ãäŒæ¥äŸ¡å€ã«å€ããã â AWS Local Executive Roadshow 倧éªç·šïŒ#2/8ïŒéå¬ã¬ããŒã ã¿ãããšãŒãçæ AI ãæŽ»çšã瀟å
æ¥åå¹çåãš 450 æéè¶
ã®å·¥æ°åæžãå®çŸãAmazon Bedrock ãè¡£æãã¶ã€ã³çã«é©çšãããžã¿ã«äººæè²æãæšé² äžå
ã»äžå°äŒæ¥ã§ãåºããçæ AIãäŒæ¥ã®æé·ã«ãè²¢ç® å·çè
Amazon Web Services Japan ååäŒç€Ÿ ãœãªã¥ãŒã·ã§ã³ã¢ãŒããã¯ããç°äž éçµµ
3è¡ã§èŠçŽãããš CUJïŒCritical User JourneyïŒããŒã¹ã®ããã·ã¥ããŒããäœãåæãšããŠãå CUJ ã«çŽã¥ã Critical API ã客芳çã«ç¹å®ããå¿
èŠããããŸãã Playwright ã® route API ã«ãã fault injection ã䜿ããE2E ãã¹ããã Critical API ãèªåæœåºããä»çµã¿ãäœããŸãã ããçšåºŠæ±çšçã«äœ¿ããããªã®ã§ npm ã«ã眮ããŠããŸãïŒ critical-api-finder ã¯ããã« SREã®å¯ºå³¶ã§ãã ç¹å®ã® API ã®ãšã©ãŒãã¬ã€ãã³ã·ãŒã®æªåããã©ã®ãŠãŒã¶äœéšã«åœ±é¿ããŠããã®ãã容æã«å€æã§ããããã«ãªããããšæã£ãããšã¯ãããŸãããïŒ MNTSQ ã¯ããã¹ãŠã®åæããã§ã¢ã«ããããããã·ã§ã³ã«ãå¥çŽæ¥åãæ¯æŽãããããã¯ããæäŸããŠããŸãã SRE ããŒã ã§ã¯ã顧客åãã«æäŸããŠãããããã¯ãã«ãããŠéèŠãªæäœã®ãŠãŒã¶äœéšã®å£åãæ©æã«æ€ç¥ããç¶ç¶çã«è¿œãããã«ãCUJïŒCritical User JourneyïŒããŒã¹ã®ããã·ã¥ããŒããäœããŸããã ãã®æ§ç¯ã®éçšã§ãå CUJ ã«çŽã¥ã Critical API ã Playwright ã®E2E ãã¹ãããèªåæœåºããããã®ããŒã«ãäœããŸãããæ¬èšäºã§ã¯ããã®ããŒã«ãäžå¿ã«ãããã·ã¥ããŒãæ§ç¯ã®æµããšåãããŠç޹ä»ããŸãã 3è¡ã§èŠçŽãããš ã¯ããã« CUJ ãšã¯ ããã·ã¥ããŒãæ§ç¯ã®æµã 人æã§ä»åããé£ãã Playwright ã䜿ã£ãã¢ãããŒã åäœã€ã¡ãŒãž ä»çµã¿ 1. import ã®æžãæã 2. baseline å®è¡ â API ãªã¹ãã®åé 3. ãã¹ã®æ£èŠå 4. ãããã¯ã«ãŒã ããã·ã¥ããŒããžã®çµã¿èŸŒã¿ æåŸã« CUJ ãšã¯ CUJ ã¯ããŠãŒã¶ããããã¯ããéããŠéæãããäžæ žçãªæäœã®æµããæããŸãã MNTSQã§ã¯ãå¥çŽæžãã¢ããããŒãããããå¥çŽã¬ãã¥ãŒãäŸé Œããããšãã£ãæäœã代衚ç㪠CUJ ã«ããããŸãã å CUJ ã«ã€ããŠãé¢é£ãã API ã®ã¡ããªã¯ã¹ïŒãšã©ãŒã¬ãŒããP95 ã¬ã€ãã³ã·çïŒãäžæã®ç»é¢ã§èŠãããããã«ããŠããŸãã ããã·ã¥ããŒãæ§ç¯ã®æµã ãã®ããã·ã¥ããŒãã®æ§ç¯ã¯ã以äžã®ãããªæµãã§é²ããŸããã PDM ã«éèŠãªç»é¢æäœïŒãŠãŒã¶ãæ¯æ¥å¿
ãè¡ãæäœããå£ãããæ¥åãæ¢ãŸãã¬ãã«ã®æäœïŒããã¢ãªã³ã° å CUJ ã«çŽã¥ã API ã®ç¹å®ã»æŽç ããã·ã¥ããŒãã®æ§ç¯ æ¬èšäºã®äž»é¡ã¯ããã® 2 çªç®ã®ãAPI ã®ç¹å®ã»æŽçããã©ãé²ããããšãã話ã§ãããã®ç¹å®ã»æŽçãé²ãããªãã§ããŸãåé¡ã«ãªãã®ããã©ã® API ãã¡ããªã¯ã¹ã®å¯Ÿè±¡ã«ãããããšããä»åãã§ãã ãšããã®ããMNTSQ ã®ã¢ããªã§ã¯ã1 ã€ã®ç»é¢æäœã®è£åŽã§ãäž»åã®åŠçããè£å©çãªãã®ãŸã§æ°å€ãã® API ãåããŠããŸãã å¥çŽæžæ¬äœã®ä¿åãã¡ã¿ããŒã¿ã®ç»é²ã®ããã«ã倱æããã®ãŸãŸãžã£ãŒããŒã®äžæã«çŽçµãã API ãŠãŒã¶ã¢ã€ã³ã³ã®ååŸãéç¥ãããžä»¶æ°ã®ããŒãªã³ã°ã®ããã«ã倱æããŠããŠãŒã¶æäœèªäœã¯ç¶ç¶ã§ãã API ããããåºå¥ããã«ãã¹ãŠããã·ã¥ããŒãã«äžŠã¹ãŠããŸããšãéèŠãªå€åããã€ãºã«åãããŠããŸããŸããéçšããããããã€æå³ã®ããããã·ã¥ããŒãã«ããããã«ã¯ãããããæ¢ãŸããšãžã£ãŒããŒãå®éã§ããªã APIïŒCritical APIïŒããæ£ç¢ºã«ç¹å®ããçµã蟌ãå¿
èŠããããŸããã 人æã§ä»åããé£ãã ãã Critical 㪠API ã®ä»åããããããšãããšãæå€ãšæ ¹æ ãæãããã®ãé£ããããšã«æ°ã¥ããŸããã ãã¢ãªã³ã°ã®éç : éçºè
ã«ç¢ºèªããŠããããã³ããšã³ãã®ãšã©ãŒãã³ããªã³ã°ã®è©³çްïŒãã® API ãã³ã±ãŠãç»é¢ã¯æ¢ãŸããªããçïŒãŸã§æ£ç¢ºã«ç¶²çŸ
ããã®ã¯è² æ
ã倧ãããå±äººåãé¿ããããŸããã LLM ã«æšå®ãããé£ãã : Claude Code ã«ã³ãŒãããŒã¹ãèªãŸã㊠Critical 㪠API ãæšå®ãããæ¹æ³ã詊ããŸãããå®è¡æã®æ¯ãèãã§ã¯ãªãã³ãŒãäžã®æèããæšå®ãã以äžãç»é¢é·ç§»åŸã«è£ã§çºç«ããããªãã§ããç³»ã®ãããªãå®éã«åãããªããšèŠããªããäŸåé¢ä¿ã¯åãããŒãããããå€å®æ ¹æ ã®åçŸæ§ãæ
ä¿ãã«ããçµæã§ããã ã¡ã³ããã³ã¹æ§ : ãããã¯ãã®æ¹ä¿®ã«åãã㊠API ã®äŸåé¢ä¿ã¯å€ããããããã®éœåºŠæåã§èª¿æ»ãçŽãã®ã¯çŸå®çã§ã¯ãããŸããã ããã§ãã人éã倿ããã®ã§ã¯ãªããå®éã« API ã 1 ã€ãã€æ¢ããŠã¿ãŠãæåã®å€åãæ©æ¢°çã«èŠ³æž¬ããã°ããã®ã§ã¯ãªããããšèããŸããã Playwright ã䜿ã£ãã¢ãããŒã ãã£ãšãåçŽãªæ¹æ³ã¯ãChrome DevTools ã® "Block request URL" æ©èœã䜿ã£ãŠ 1 ã€ã〠API ããããã¯ããç»é¢æäœãæåã§ç¢ºãããŠããããæ¹ã§ãããã ããCUJ ã²ãšã€ãããæ°ååã® API ããããšããããæ¯åæäœæ¥ã§ç¹°ãè¿ãã®ã¯çŸå®çã§ã¯ãããŸãããæäœæ¥ã®è² æ
ã¯ãã¡ããã人ã®å€å®ãå
¥ãããšã§å±äººåãåçŸæ§ã®åé¡ãåçºããŠããŸããŸãã ããã§çç®ããã®ã Playwright ã® Network API ã§ãã page.route / context.route ã䜿ããšããã©ãŠã¶ã®ãããã¯ãŒã¯éä¿¡ãã¹ã¯ãªããåŽããååããããæ¹å€ãããã§ããŸããããšãã°ãç¹å®ã® URL ãã¿ãŒã³ã«åèŽãããªã¯ãšã¹ãã ã 500 ãè¿ãããšãã£ãæäœãæ°è¡ã§æžããŸãã await context.route( "**/api/contracts" , async ( route ) => { await route.fulfill( { status : 500 , body : JSON . stringify ( { error : "blocked" } ) } ); } ); ããã䜿ãã°ãE2E ãã¹ãã 1 床æžããŠããã ãã§ã ãã¹ãã 1 床走ãããŠããžã£ãŒããŒäžã«åŒã°ãã API ããã¹ãŠèšé²ãã èšé²ãã API ã 1 ã€ã〠500 ã§ç絡ããªããããã¹ããåå®è¡ãã ãã¹ããèœã¡ã API ã Criticalãéã£ã API ãé Critical ãšå€å®ãã ãšããæµããå®å
šã«èªååã§ããŸããå€å®ã®æ ¹æ ã¯ããã¹ããéãïŒéããªãããšããäºå€ã®å®¢èгçãªã·ã°ãã«ã§ã人éã®è§£éãæã¿ãŸããããããã¯ãã«æ¹ä¿®ãå
¥ã£ãŠäŸåé¢ä¿ãå€ãã£ãŠãããã¹ããæŽæ°ããŠåãçŽãã°ææ°ã® Critical API ãªã¹ããæã«å
¥ããŸãã ãŸããPlaywrightãæ¡çšããèæ¯ãšããŠã¯ãã¡ããã© MNTSQ ã§ã¯ Autify ãã Playwright ãžã® E2Eãã¹ãã®ç§»è¡ãããžã§ã¯ããé²ãã§ãããQA ãæžããã¹ãããã®ãŸãŸã€ã³ããããšããŠäœ¿ããèŠèŸŒã¿ãããããšããäºæ
ããããŸããã åäœã€ã¡ãŒãž ãã®ã¢ãããŒããããŒã«ãšããŠãŸãšãããã®ã critical-api-finder ã§ããPlaywright ã®ãã¹ããã¡ã€ã«ãçšæããŠã³ãã³ããå©ãã ãã§åããŸãã npm install -D @playwright/test critical-api-finder npx critical-api-find tests/contract-upload.spec.ts å®è¡ãããšãããŒã«ãå
éšã§ãã¹ããN+1åç¹°ãè¿ãå®è¡ããŸãïŒæåã® 1 åã§ API ãèšé² â å API ã 1 ã€ãã€ãããã¯ããªããåå®è¡ïŒãçµãããš critical-api-results/verify-contract-upload.json ã«çµæãåºåãããŸãïŒ { " journeyId ": " contract-upload ", " testPath ": " tests/contract-upload.spec.ts ", " entries ": [ { " method ": " POST ", " pattern ": " /api/contracts ", " critical ": true } , { " method ": " GET ", " pattern ": " /api/contracts/:id ", " critical ": true } , { " method ": " GET ", " pattern ": " /api/v2/user/me ", " critical ": false } , { " method ": " GET ", " pattern ": " /api/v2/notifications/count ", " critical ": false } ] } ä»çµã¿ ããŒã«å
éšã¯å€§ãã 4 ã€ã®ã³ã³ããŒãã³ãããæããŸãã â» ã³ãŒãã¯ç°¡ç¥åããŠèŒããŠããŸãã 1. import ã®æžãæã ãã¹ããã¡ã€ã«ãçŽæ¥æžãæããããªãã®ã§ãCLI 㯠sibling fileïŒ tests/contract-upload.spec.ts â tests/contract-upload.critical.spec.ts ïŒãšããŠè€è£œããããã§ã @playwright/test ã® import ã ãã critical-api-finder èªèº«ã«å·®ãæ¿ããŸãã // ãã¹ããã¡ã€ã«äžã®ãã® import ã⊠import { test , expect } from "@playwright/test" ; // èªåçã«ãã¡ãã«æžãæãã import { test , expect } from "critical-api-finder" ; æžãæãã¯æ£èŠè¡šçŸããŒã¹ã®åçŽçœ®æã§ãã const IMPORT_RE = /^([\t ]*import\b[^;]*?\bfrom\s+['"])@playwright\/test(['"])/gm ; const REQUIRE_RE = /^([\t ]*(?:const|let|var)\b[^;]*?\brequire\s*\(\s*['"])@playwright\/test(['"]\s*\))/gm ; export function rewriteImports ( source : string ): string { return source . replace (IMPORT_RE, `$1critical-api-finder$2` ) . replace (REQUIRE_RE, `$1critical-api-finder$2` ); } critical-api-finder 㯠@playwright/test ã®å
¬é API ãå
š re-export ããŠããã®ã§ããŠãŒã¶ã®ãã¹ãã¯ã³ãŒã倿ŽãŒãã§ããã¡ãã®æ¡åŒµ fixtureïŒroute handler å
¥ãïŒãåŒãç¶ãã§åããŸãã 2. baseline å®è¡ â API ãªã¹ãã®åé æåã® 1 åã¯ãããã¯ãªãã§ãã¹ããèµ°ããã context.route ã§å
š API ãååããŠãªã¹ãåããŸãã await context.route( "**/api/**" , async ( route ) => { const method = route.request(). method (); const pathname = new URL (route.request(). url ()). pathname ; const normalized = normalizePathname(pathname); appendFileSync(collectFile, ` ${ method } ${ normalized } \n ` ); await route.continue(); } ); ããã§ã¯ route.continue() ã§çŽ éããããã ããªã®ã§ããã¹ãã®æåã«ã¯åœ±é¿ãäžããŸããã芳枬ãããªã¯ãšã¹ãã¯ããšã§éè€æé€ããŠããããã¯ã«ãŒãã®å¯Ÿè±¡ãªã¹ããšããŠäœ¿ããŸãã 3. ãã¹ã®æ£èŠå API ã® path ã«ã¯ããªãœãŒã¹ ID ã®ããã«å®è¡ã®ãã³ã«å€ãå€ããåçã»ã°ã¡ã³ããå«ãŸããããšããããŸããããšãã°ã芳枬æã« /api/contracts/12345 ã ã£ã path ããæ¬¡ã®å®è¡ã§ã¯ /api/contracts/67890 ã®ããã«å¥ã®å€ã«ãªã£ãŠããŠããã®ãŸãŸãããã¯å¯Ÿè±¡ãšããŠèšé²ããŠãããŠãåœãããªãããšããããšãèµ·ãããŸãã ããã§ã芳枬ãã path ã以äžã®ã«ãŒã«ã§æ£èŠåããŸãã ã»ã°ã¡ã³ã ãã¬ãŒã¹ãã«ã æ°å€ id ( /12345 ) :id UUID :uuid ISO date ( /2026-04-22 ) :date é·ã hex hash (20+ æ¡) :hash å®è£
ã¯é åºä»ãã®çœ®æã«ãŒã«ã䞊ã¹ãã ãã®ã·ã³ãã«ãªãã®ã§ãã const RULES = [ // UUIDïŒæ°å€ id ããå
ã«å€å®ïŒ { regex : /\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?=\/|$)/gi , replacement : "/:uuid" } , // ISO date { regex : /\/\d{4}-\d{2}-\d{2}(?=\/|$)/g , replacement : "/:date" } , // é·ã hex hash { regex : /\/[0-9a-f]{20,}(?=\/|$)/gi , replacement : "/:hash" } , // æ°å€ id { regex : /\/\d+(?=\/|$)/g , replacement : "/:id" } , ] ; function normalizePathname ( pathname : string ): string { let result = pathname; for ( const { regex , replacement } of RULES) { result = result. replace (regex, replacement); } return result; } ããã«ããã /api/contracts/12345 ã /api/contracts/67890 ãåã /api/contracts/:id ãšããè«ççãªãšã³ããã€ã³ãåäœã«éçŽãããŸãããããã¯æã¯éã«ãã®ãã¬ãŒã¹ãã«ããæ£èŠè¡šçŸã«å±éããåœè©²ãã¿ãŒã³ã«åèŽãããªã¯ãšã¹ãã ãã 500 ã«ããããšããæµãã§ãã 4. ãããã¯ã«ãŒã æ£èŠåãããã¿ãŒã³ã 1 ã€ãã€åãåºããŠãPlaywright ãåå®è¡ããŸããroute handler ã¯åãå Žæã§ãããä»åºŠã¯å¯Ÿè±¡ãã¿ãŒã³ã«åèŽãããªã¯ãšã¹ãã ãã 500 ã§ short-circuit ããŸãã await context.route( "**/api/**" , async ( route ) => { const pathname = new URL (route.request(). url ()). pathname ; // ãããã¯å¯Ÿè±¡ãã¿ãŒã³ã«åèŽãããªã¯ãšã¹ãã ã 500 ã«ãã if (blockedRegex. test (pathname)) { await route.fulfill( { status : 500 , contentType : "application/json" , body : JSON . stringify ( { error : "Blocked by critical-api-finder" } ), } ); return ; } await route.continue(); } ); ããã§ãã¹ããèœã¡ãã° Criticalãéãã°é Critical ãšå€å®ããŸãããªããæ¯ã€ãã¬ãŒã·ã§ã³ã§ --retries=0 --max-failures=1 ã匷å¶ããããšã§ãPlaywright project åŽã® retry èšå®ã«ãããããããã¯ããç¬éã« exitããããç¡é§ãªå詊è¡ãé²ãã§ããŸãã ããã·ã¥ããŒããžã®çµã¿èŸŒã¿ å®éã«E2Eãã¹ãã«ãã®ããŒã«ãåœãŠãŠ Critical API ã®ãªã¹ããåãåºãããã®ãŸãŸããã·ã¥ããŒãã®ã¡ããªã¯ã¹å¯Ÿè±¡ãšããŠçµã¿èŸŒã¿ãŸãããããã·ã¥ããŒã㯠Datadog äžã« Terraform ã§ç®¡çããŠãããCUJ ã®å®çŸ©ã¯æ¬¡ã®ãããªåœ¢ã§æžããŠããŸãã locals { cuj_dashboards = { sample_journey = { title = "ãŠãŒã¶äœéš: ãµã³ãã«ãžã£ãŒããŒ" service = "sample-service" trace_name = "rack" steps = [ { name = "ã¹ããã 1" endpoints = [{ display_name = "POST /api/sample/foo" resource_name = "resources::v2::fooapi_post_/foo" }] } , { name = "ã¹ããã 2" endpoints = [ { display_name = "GET /api/sample/foo/:id" resource_name = "resources::v2::fooapi_get_/foo/:id" } , { display_name = "GET /api/sample/bar" resource_name = "resources::v2::barapi_get_/bar" } , ] } , ] } # ä»ã® CUJ ãåã圢ã§äžŠã¹ã } } module "cuj_dashboard" { for_each = local.cuj_dashboards # CUJããã·ã¥ããŒã詳现ã管çããããã®ã¢ãžã¥ãŒã«ãæ¬çã§ã¯ãªãããæ¬çš¿ã§ã¯é€å€ source = "./modules/cuj_dashboard" dashboard_title = each.value.title service = each.value.service trace_name = each.value.trace_name steps = each.value.steps } ããã«ãã£ãŠ CUJ ããšã«ããã·ã¥ããŒããçæãããã¹ãããåäœã§ãšã©ãŒã¬ãŒãã»ã¬ã€ãã³ã·ã»ãªã¯ãšã¹ãæ°ã䞊ã¶åœ¢ã«ãªããŸãã æåŸã« ããã·ã¥ããŒãã«èŒãã Critical API ã®ãªã¹ããã人ã®å€æã§ã¯ãªãããã¹ãã®éãïŒéããªãããšãã客芳çãªã·ã°ãã«ããåŒããããã«ãªããå±äººåãšã¡ã³ããã³ã¹ã®åé¡ã¯å€§ããç·©åã§ããŸããã 坿¬¡çãªçºèŠãšããŠãPlaywrightããååž°ãé²ãããã®E2Eãã¹ãããŒã«ããšããçšé以å€ã«ã䜿ãããã ãšããæ°ã¥ãããããŸãããfault injection ãšã®çµã¿åããã«ã¯ãäŸåé¢ä¿ã®æœåºä»¥å€ã«ããããããªå¿çšãå¹ãããã§ãäŸãã°å人ãããã¯ãçšã®å®äžãããªè匱æ§èšºæããŒã«ãã«ãªã¹ãšã³ãžãã¢ãªã³ã°ããŒã«ãªã©ã䌌ããããªä»çµã¿ã§èªäœã§ãããã ãšæããŸããããã®ãããã¯ä»åŸãæ¢ã£ãŠãããããšæã£ãŠããŸãã åããããªèª²é¡ã«åãçµãã§ããæ¹ã¯ããã²èŠããŠã¿ãŠãã ããã(ãã£ãŒãããã¯ã»PRãæè¿ããŠããŸã) ãªããžããªïŒ github.com/kterashi02/critical-api-finder




















