ð€ãæ¯åå šéšãã«ãããã®ãã£ãããªãïŒãããçãŸããã¹ããŒããããã€ã·ã¹ãã ã®å¥è·¡
ãèšäº1ã€ä¿®æ£ããã ããªã®ã«ããªãã§å šãµã€ããã«ãããªãããããªãã®ïŒããšããæãããçãŸããã倿޿€ç¥åã¹ããŒããããã€ã®éçºç§è©±ãæéãã³ã¹ãã90%åæžããéæ³ã®ã·ã¹ãã ã
ð¡ ããªãã§æ¯åå šéšãã«ãïŒæéã®ç¡é§ïŒãããã®åºçº
ããããæ©ã¿ããããŸãããïŒ
- ãèšäº1ã€çŽããã ããªã®ã«ã10åããã«ãã«æéããã...ã ð©
- ãç»å1æå€ããã ãã§å šãµã€ããªãã«ã...ã ð€
- ãæ¯ååããã¡ã€ã«åŠçããŠãæããããŠããªãããã£ãããªã...ã ð
ç§ãæ¯æ¥ãããªæãã§ãããç¹ã«èšäºãæžããŠã¯ãããã€ããŠãããã誀åçºèŠãã§ãŸãå šéšãã«ã...
ããã®ãŸãŸããæéãããããã£ãŠãè¶³ããªãïŒã
ãããªæããšã¹ãã¬ã¹ããçãŸããã®ããã¹ããŒããããã€ã·ã¹ãã ã§ãã
çµæïŒãã«ãæé90%åæžãéçºå¹ç3ååäž ð
ãã®èšäºã§ã¯ãåããããªæ©ã¿ãæ±ããŠããããªãã«ãç§ãè¡ãšæ±ãšæ¶ã§ç·šã¿åºãããè³¢ããããã€ã·ã¹ãã ãã®å šè²ããäŒãããŸãã
æ·±å€ãã³ãŒããŒãšãèåã«å²ãŸããªããã·ã¹ãã ãéçºããç§
ð€ ãã¹ããŒããããã€ã£ãŠäœïŒãã身è¿ãªäŸã§
æ®éã®ãããã€ïŒåŸæ¥æ¹åŒïŒ
æ³åããŠã¿ãŠãã ãããããªãããåŒåœå±ããã®åºé·ã ãšããŠïŒ
æ¯æã®æºåïŒ
- ããããåŒåœã®ããããã1åå¢ãããã ããªã®ã«...
- ããããå šã¡ãã¥ãŒäœãçŽãã ïŒã
- ã®ãåŒãåæãåŒåœãçŒéåŒåœããã³ããŒã°åŒåœ...å šéšæåããäœãçŽã
- æ6æã«æ¥ãŠãéåº10æ... 4æéããã ð±
ãããåŸæ¥ã®ãããã€ã§ãã1ã€ã®èšäºãä¿®æ£ããã ãã§ãå šèšäºãååŠçããŠããŸãã
ã¹ããŒããããã€ïŒæ¹è¯çïŒ
è³¢ãæºåïŒ
- ããããåŒåœã®ããããã1åå¢ãããã ããªã...
- ãããããåŒåœã ãäœãçŽããã
- ä»ã®åŒåœã¯ãã®ãŸãŸäœ¿ãã
- æ9æã«æ¥ãŠãéåº10æ... 1æéã§çµäº âš
ãããã¹ããŒããããã€ã§ãã倿Žãããéšåã ããè³¢ãæ€ç¥ããŠãå¿ èŠæå°éã®åŠçã§å®äºã
ð ãã©ããã£ãŠå€æŽãæ€ç¥ããã®ïŒãã®ä»çµã¿
Gitæ§ã«èãäœæŠ
ç§ãã¡ã®ç§å¯å µåšã¯Gitã§ããGitã¯ãäœãå€ãã£ããããå®ç§ã«èŠããŠãããŠããåªç§ãªç§æžã¿ãããªãã®ã
// ãäœãå€ãã£ãïŒããšGitã«èã
const changedFiles = execSync('git diff --name-only').toString();
// ãèšäºãã¡ã€ã«(.mdx)ãå€ãã£ãïŒã
const changedMdxFiles = changedFiles.filter(file =>
file.startsWith('content/articles/') && file.endsWith('.mdx')
);
æ¥åžžäŸãã§èšããšïŒ
- Git: ãæšæ¥ãšæ¯ã¹ãŠããã®ãã¡ã€ã«ãšãã®ãã¡ã€ã«ãå€ãã£ãŠãŸããã
- ç§ãã¡: ãããããã®ãã¡ã€ã«ã ãåŠçãããïŒã
- çµæ: æéãåŽåãå€§å¹ ç¯çŽ ð
æ¹è¯çïŒ3段éã®å€æŽæ€ç¥ã·ã¹ãã
ç§ã®ã¹ããŒããããã€ã¯3ã€ã®æ¹æ³ã§å€æŽãæ€ç¥ããããã«å®å šæ§ãåäžãããŸããïŒ
ð§ æ¹è¯ãã€ã³ãïŒ
- Setã䜿ã£ãå¹ççãªéè€é€å»
- getGitFilesãã«ããŒé¢æ°ã§å®å šãªåŠç
- 空æååãã§ãã¯ã®åŒ·å
1段éç®ïŒã¹ããŒãžã³ã°ãšãªã¢ããã§ãã¯
// æ¹è¯çïŒå®å
šãªåŠçã§ãšã©ãŒãé²ã
const getGitFiles = (command) => {
try {
const output = execSync(command, { encoding: 'utf8' });
const trimmed = output.trim();
if (!trimmed) return []; // 空æååã¯æ©æãªã¿ãŒã³
return trimmed.split('\n').filter(file => file.length > 0);
} catch (error) {
return []; // ãšã©ãŒæã¯ç©ºé
åãè¿ã
}
};
const stagedFiles = getGitFiles('git diff --cached --name-only');
2段éç®ïŒäœæ¥äžã®å€æŽããã§ãã¯
// ãä»ãç·šéäžã®ãã¡ã€ã«ããïŒã
const workingFiles = getGitFiles('git diff --name-only');
3段éç®ïŒææ°ã³ããããšã®å·®åããã§ãã¯
// ãæåŸã®ã³ãããããäœãå€ãã£ãïŒãïŒä»ã«å€æŽããªãå Žåã®ã¿ïŒ
if (changedFiles.size === 0) {
const commitFiles = getGitFiles('git diff HEAD~1 --name-only');
}
ããã£ãŠäœãããããã£ãŠïŒ
- ã©ããªç¶æ³ã§ã倿ŽãèŠéããªã
- ãšã©ãŒã§æ¢ãŸããªãå®å šèšèš
- éè€ãã¡ã€ã«ãèªåé€å»ã§å¹çç
- 空æååã«ãã誀åäœã鲿¢
ð ïž å®éã®ã¹ããŒããããã€ã³ãŒã
ã¡ã€ã³ã·ã¹ãã ïŒdeploy-with-build.mjsïŒ
import { execSync } from 'child_process';
async function deployWithBuild() {
try {
console.log('ð Starting smart deploy...');
// Git ã§å€æŽããããã¡ã€ã«ãååŸïŒè€æ°ã®ãœãŒã¹ããïŒ
const changedFiles = new Set();
// ãã«ããŒé¢æ°: Gitã³ãã³ãã®åºåãå®å
šã«åŠç
const getGitFiles = (command) => {
try {
const output = execSync(command, { encoding: 'utf8' });
const trimmed = output.trim();
if (!trimmed) return [];
return trimmed.split('\n').filter(file => file.length > 0);
} catch (error) {
return [];
}
};
// 1. ã¹ããŒãžã³ã°ããã倿Ž
const stagedFiles = getGitFiles('git diff --cached --name-only');
stagedFiles.forEach(file => changedFiles.add(file));
// 2. äœæ¥ãã£ã¬ã¯ããªã®å€æŽïŒæªã¹ããŒãžã³ã°ïŒ
const workingFiles = getGitFiles('git diff --name-only');
workingFiles.forEach(file => changedFiles.add(file));
// 3. ææ°ã³ããããšã®å·®åïŒä»ã«å€æŽããªãå Žåã®ã¿ïŒ
if (changedFiles.size === 0) {
const commitFiles = getGitFiles('git diff HEAD~1 --name-only');
commitFiles.forEach(file => changedFiles.add(file));
if (commitFiles.length === 0) {
console.log('â ïž No git changes detected from any source...');
}
}
const changedFilesArray = Array.from(changedFiles);
// MDXãã¡ã€ã«ã®å€æŽããã§ãã¯
const changedMdxFiles = changedFilesArray.filter(file =>
file.startsWith('content/articles/') && file.endsWith('.mdx')
);
if (changedMdxFiles.length > 0) {
console.log(`ð Found ${changedMdxFiles.length} changed MDX files:`);
changedMdxFiles.forEach(file => console.log(` - ${file}`));
// èšäºãã«ãã¹ã¯ãªãããå®è¡
console.log('ð Running article build script...');
execSync('node scripts/build-articles.mjs', { stdio: 'inherit' });
// 倿Žããããã¡ã€ã«ãåã¹ããŒãžã³ã°ïŒJSONãã¡ã€ã«ãæŽæ°ãããããïŒ
console.log('ðŠ Staging updated JSON files...');
execSync('git add app/data/articles.generated.json public/data/articles.json', { stdio: 'inherit' });
} else {
console.log('â¹ïž No MDX files changed, skipping article build...');
}
// ãããã€å®è¡
console.log('ð Deploying to Cloudflare Pages...');
execSync('npx wrangler pages deploy', { stdio: 'inherit' });
console.log('â
Deploy completed successfully!');
} catch (error) {
console.error('â Deploy failed:', error.message);
process.exit(1);
}
}
// å®è¡
deployWithBuild().catch(console.error);
package.jsonèšå®
{
"scripts": {
"deploy": "npm run build && wrangler pages deploy",
"deploy:smart": "node scripts/deploy-with-build.mjs"
}
}
äœ¿ãæ¹ïŒ
# ð åŸæ¥æ¹åŒïŒå
šéšãã«ãïŒ
npm run deploy
# â¡ ã¹ããŒãæ¹åŒïŒå€æŽéšåã®ã¿ïŒ
npm run deploy:smart
ð ãã©ã®ããã广ãããã®ïŒã宿ž¬ããŒã¿
ããã©ãŒã»ã¢ãã¿ãŒæ¯èŒ
| æäœ | åŸæ¥ããã〠| ã¹ããŒãããã〠| åæžå¹æ |
|---|---|---|---|
| èšäº1ã€ä¿®æ£ | 5å30ç§ | 45ç§ | 86%åæž â¡ |
| ç»å1æå€æŽ | 5å30ç§ | 20ç§ | 94%åæž ð |
| CSSåŸ®èª¿æŽ | 5å30ç§ | 30ç§ | 91%åæž âš |
| èšäº5ã€è¿œå | 6å00ç§ | 1å20ç§ | 78%åæž ðª |
æéã§ã®å¹æ
ç§ã®å ŽåïŒèšäºãé±3åæŽæ°ïŒïŒ
- åŸæ¥æ¹åŒ: æé66åïŒ1æé6åïŒã®ãã«ãæé
- ã¹ããŒãæ¹åŒ: æé8åã®ãã«ãæé
- ç¯çŽæé: 58å/æ ð
1幎éã ãš...
- ç¯çŽæé: çŽ12æé
- ãã®æéã§æ°ããèšäºã12èšäºãæžããïŒ
ð¯ å°å ¥æ¹æ³ïŒããªãã®ãããžã§ã¯ãã§ã䜿ãã
Step 1: ã¹ã¯ãªãããã¡ã€ã«äœæ
scripts/deploy-with-build.mjsãäœæïŒ
import { execSync } from 'child_process';
async function smartDeploy() {
console.log('ð Smart deploy starting...');
// ããªãã®ãããžã§ã¯ãã«åãããŠå€æŽæ€ç¥ããžãã¯ã調æŽ
const changedFiles = execSync('git diff --name-only', { encoding: 'utf8' })
.trim().split('\n').filter(file => file);
// ç¹å®ã®ãã¡ã€ã«ã¿ã€ãã倿Žãããæã ããã«ã
const needsBuild = changedFiles.some(file =>
file.endsWith('.md') ||
file.endsWith('.mdx') ||
file.startsWith('src/content/')
);
if (needsBuild) {
console.log('ð Content changed, building...');
execSync('npm run build', { stdio: 'inherit' });
} else {
console.log('â¹ïž No content changes, skipping build...');
}
// ããªãã®ãããã€ã³ãã³ãã«å€æŽ
console.log('ð Deploying...');
execSync('npm run deploy:static', { stdio: 'inherit' });
}
smartDeploy().catch(console.error);
Step 2: package.jsonæŽæ°
{
"scripts": {
"deploy:smart": "node scripts/deploy-with-build.mjs"
}
}
Step 3: 䜿ã£ãŠã¿ã
npm run deploy:smart
ð¡ ãããªãå¿çšã¢ã€ãã¢
1. ãã¡ã€ã«ã¿ã€ãå¥ã®åŠç
const changes = {
articles: changedFiles.filter(f => f.includes('/articles/') && f.endsWith('.mdx')),
images: changedFiles.filter(f => f.includes('/images/')),
styles: changedFiles.filter(f => f.endsWith('.css') || f.endsWith('.scss'))
};
if (changes.articles.length > 0) {
execSync('node scripts/build-articles.mjs');
}
if (changes.images.length > 0) {
execSync('node scripts/optimize-images.mjs');
}
if (changes.styles.length > 0) {
execSync('npm run build:css');
}
2. ç°å¢å¥ãããã€
const env = process.env.NODE_ENV || 'production';
if (env === 'development') {
console.log('ð§ Development deploy - minimal processing');
// éçºç°å¢ã¯æå°éã®åŠç
} else {
console.log('ð Production deploy - full optimization');
// æ¬çªç°å¢ã¯æé©åãå«ã
}
3. éç¥ã·ã¹ãã
if (changedMdxFiles.length > 0) {
console.log(`ð¢ Updated articles: ${changedMdxFiles.join(', ')}`);
// Slackéç¥ãã¡ãŒã«éç¥ãªã©ã远å
// await notifySlack(`èšäºæŽæ°: ${changedMdxFiles.length}ä»¶`);
}
â ïž ããããªæã¯æ³šæïŒããã€ã³ã
1. ååãããã€ã¯å¿ ãå šãã«ã
// ååããã§ãã¯
const hasBuiltBefore = fs.existsSync('build/timestamp');
if (!hasBuiltBefore) {
console.log('ðïž First time build - processing all files');
execSync('npm run build', { stdio: 'inherit' });
fs.writeFileSync('build/timestamp', Date.now().toString());
} else {
// ã¹ããŒããããã€ããžãã¯
}
2. äŸåé¢ä¿ã®å€æŽã¯å šãã«ã
const configChanged = changedFiles.some(file =>
file === 'package.json' ||
file === 'vite.config.js' ||
file === 'remix.config.js'
);
if (configChanged) {
console.log('âïž Config changed - full rebuild required');
execSync('npm run build', { stdio: 'inherit' });
return;
}
3. ãšã©ãŒãã³ããªã³ã°
try {
execSync('git diff --name-only', { encoding: 'utf8' });
} catch (error) {
console.log('â ïž Git not available, defaulting to full build');
execSync('npm run build', { stdio: 'inherit' });
}
ð ããªããžã®ã¡ãã»ãŒãžïŒå¹çåãç®æã仲éãžïŒ
ãæ¬åœã«å¹æããã®ïŒããšçåãªããªããž
ãã®èšäºãèªãã§ãããŠãããããšãããããŸãã
ãã£ãšä»ããããªæ°æã¡ã§ã¯ãªãã§ããïŒ
ããªããè€éãã...ã
ããã¡ã®ãããžã§ã¯ãã§ã䜿ããããªïŒã
ãèšå®ééããããµã€ããå£ããã...ã
ãã®äžå®ããã¡ããã¡ãããããŸãã
ç§ãæåã¯ãå€ãªããšããŠå šéšå£ãããã©ãããããã£ãŠæãã£ãã§ãã
ã§ã倧äžå€«ãå°ããå§ããã
âš ãã®èšäºã§æã«å ¥ãããã®ïŒ
- ð§ ç¥èïŒã¹ããŒããããã€ã®ä»çµã¿ãããã£ã
- ð éå ·ïŒå®éã«äœ¿ããã³ãŒããšã¢ã€ãã¢
- ðª åæ°ïŒããã£ãŠã¿ããããšããæ°æã¡
ð ããããããããšïŒ
- ãŸãã¯å¥ãã©ã³ãã§è©ŠãïŒã¡ã€ã³ãã©ã³ãã¯è§Šããå®å šã«ãã¹ã
- å°ããå§ããïŒæåã¯1ã€ã®ãã¡ã€ã«ã¿ã€ããã
- èšé²ãã€ããïŒã©ã®ãããæéãççž®ããããæž¬ã£ãŠã¿ã
ããªãã®æåãæ¥œãã¿ã§ã
æ°é±éåŸã®ããªãïŒ
- ããã®æãå°å ¥ããŠè¯ãã£ãã
- ããããã€ãæ©ããªã£ãŠããã£ãšèšäºãæžãæéãã§ããã
- ãããŒã ã¡ã³ããŒãããæè¬ãããã
ãããªé¢šã«ãªã£ãŠãã¯ãã
倱æããŠã倧äžå€«ãç§ãäœåºŠã倱æããŸããã
ã§ãã倱æãããã³ã«åŠãã§ãæçµçã«ããè¯ãã·ã¹ãã ãã§ããŸããã
ããªãã®éçºããã£ãšæ¥œãããªãããšãé¡ã£ãŠããŸãïŒ ð
ããå°å ¥ã§å°ã£ãããšãããã°ãé æ ®ãªãã³ã¡ã³ãããŠãã ãããäžç·ã«è§£æ±ºããŸãããïŒ
P.S. åããŠã¹ããŒããããã€ãã45ç§ã§å®äºããŸãããã£ãŠè¡šç€ºãããæã®æåã¯å¿ããããŸãããããªãã«ããã®ç¬éãå³ãã£ãŠãããããã§ãã
ãã®èšäºã圹ã«ç«ã£ããã·ã§ã¢ããŠãã ãã
ð ããã°ã©ãã³ã°ã»éçº ã®é¢é£èšäº
ðãããã³ãŒãèªãŸãªããŠããïŒãAIãšãŒãžã§ã³ãéçºã§æ¿å€ããéçºçŸå Žã®è¡æäœéšè«
ãã«ãã¿ã¹ã¯å¯Ÿå¿AIãšãŒãžã§ã³ããéçºçŸå Žãæ ¹åºããå€ãããã³ãŒãèªè§£å°çããã®è§£æŸã䞊åéçºã®å§åçå¹çåããããŠéçºè ã®ç²åŽæ¿æžã®çã ããäœéšãé蟌ããŠèªããŸãã
ç¶ããèªãðãClaude Code CLI ã§EAäœæãã¹ã¿ãŒãã«ãªãããã®å®è·µçã³ããšèœãšã穎åé¿æ³
ãClaude Code䜿ã£ãŠããã©EAãããŸãäœããªã...ããããªããªããžïŒ2025å¹Žææ°ã®CLIæäœãã¯ããã¯ãå¹ççãªæç€ºåºãæ¹æ³ããããããã©ãã«è§£æ±ºæ³ãå®äœéšããŒã¹ã§å®å šè§£èª¬ãåå¿è ã§ãäžçŽè ã®ãããªEAãäœããç§å¯ã®ã³ãæããŸãã
ç¶ããèªãðããªãã§èšäºãåæ ãããžãã®ïŒïŒã3æéã®æ ŒéããçãŸãããããã€ã·ã¹ãã å®å šæ¹è¯èš
ãèšäºæžããã®ã«ãµã€ãã«åºãŠããªã...ããããªå°çããéãäžãã£ããè¡ãšæ±ãšæ¶ã®ãããã€ã·ã¹ãã æ¹è¯ãããžã§ã¯ããimportå°çããfetch倩åœãžã®éã®ããå šéšèŠããŸãã
ç¶ããèªã