Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_i...
Search
Masahiko Sakakibara
July 25, 2025
Programming
710
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
No Install CMS戦略 〜 5年先を見据えたフロントエンド開発を考える / no_install_cms
https://techramenconf.net/
登壇資料です
Masahiko Sakakibara
July 25, 2025
More Decks by Masahiko Sakakibara
See All by Masahiko Sakakibara
決済端末ビジネスを、決済会社だけのものにしない/stripe_terminal_business
rdlabo
0
59
JavaScriptで始める店舗インフラ決済構築/stripe_terminal_workshop
rdlabo
0
54
本当に欲しかったのはモノレポツールではなく、tsconfigの設定だった / monorepo-tsconfig
rdlabo
1
410
Reactフレームワークプロダクトを モバイルアプリにして、もっと便利に。 ユーザに価値を届けよう。/React Framework with Capacitor
rdlabo
0
590
プライベートプロダクト戦略 - フロントエンドカンファレンス沖縄 / private_product_frontend
rdlabo
3
4.9k
GitHubをCMSとして使う話/ using_github_as_CMS
rdlabo
0
720
JavaScriptから デバイスの力を100%引き出すための Web APIとCapacitor入門 / power_from_javascript
rdlabo
0
640
Capacitor4_release
rdlabo
0
740
Web技術で稼ぐため選択肢を俯瞰しよう/options_to_earn_web_technology
rdlabo
0
170
Other Decks in Programming
See All in Programming
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.4k
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
iOSDC2026登壇資料.pdf
riofujimon
0
210
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
230
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
340
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
140
プロダクトコードからライブラリの境界を見つける
elmetal
PRO
0
100
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.5k
CodeRabbitの効果検証と過ごしてみた3ヶ月
armondando
0
140
phperだってパンチカードでコーディングしたい
o0h
PRO
0
200
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
190
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
130
Featured
See All Featured
Practical Orchestrator
shlominoach
192
12k
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
The Cult of Friendly URLs
andyhume
79
7k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Product Roadmaps are Hard
iamctodd
55
13k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Fireside Chat
paigeccino
43
4k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
350
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Transcript
/P*OTUBMM$.4ઓུ ʙઌΛݟਾ͑ͨϑϩϯτΤϯυ։ൃΛߟ͑Δ
ࣗݾհ ࡗݪণ Ұൠࣾஂ๏ਓϦϨʔγϣϯσβΠϯ ݚڀॴදཧࣄ *POJD%FWFMPQFS&YQFSU 4USJQF$PNNVOJUZ&YQFSU
UJQTZT
৯දࣔҹ εϚϗͱϓϦϯλ͚ͩͰ৯දࣔϥ ϕϧΛͭ͘ΕΔຊॳͷઐ༻ΞϓϦ
XJOFDPEF ଟछྨଟྔͷϫΠϯΛෳڌͰཧͰ ͖Δຊ།ҰͷΞϓϦɻ
Ͳ͏ҧ͍·͔͢ʁ ϒϥβ 18" J04ΞϓϦ
8FCඪ४Λϕʔεʹͨ͠ϚϧνϓϥοτϑΥʔϜల։ 888
ຊͱҧ͏͚Ͳɺ࣋ͪؼͬͯ΄͍͜͠ͱ ϞόΠϧ6*Λ࠶ݱ͢ΔͨΊͷ6*ϑϨʔϜϫʔΫ 8FCΞηοτΛϞόΠϧΞϓϦʹ͢ΔϥΠϒϥϦ *POJD'SBNFXPSL $BQBDJUPS
5IFBOTXFS JOBOVUTIFMM JTCFDBVTF UIBU`TXIFSFUIFTBSF 5IFBOTXFS JOBOVUTIFMM JTCFDBVTF UIBU`TXIFSFUIFTBSF ͑؆୯ɻͦ͜ʹϢʔβ͕͍Δ͔ΒͰ͢ɻ IUUQTNFEJVNDPNGSFFDPEFDBNQJCVJMUBQXBBOEQVCMJTIFEJU
JOBQQTUPSFTIFSFTXIBUJMFBSOFEDCGEBGC
$.4ߏங᠘͕͍ͬͺ͍
ιϑτΣΞͷϝϯςφϯε IUUQTFOEP fl JGFEBUF
ϓϥάΠϯͷ࠾༻
όοΫΞοϓͷϝϯςφϯε %#ਧ͖ඈͼ·ͨ͠ɻ ࠷ऴόοΫΞοϓͬͯࡢͰ͢ΑͶʁʂ ઌ݄͔ΒόοΫΞοϓͱΕͯ·ͤΜͰͨ͠ɻ σΟεΫ༰ྔ͕͍ͬͺ͍ͩͬͨΑ͏Ͱ͢ɻ Ͳ͏ͨ͠Β͍͍ΜͰ͔͢ʁʂʁʂ Ͳ͏ʹͳΓ·ͤΜɾɾɾɻ
ΞΫηεूதͨ࣌͠ͷରԠ 8FCαΠτ͕ݟΕͳ͍Μ͚ͩͲͲ͏ͯ͠ʁ ͔ͤͬ͘ςϨϏʹऔΓ্͛ΒΕͨͷʹɻ ΞΫηε͕ूதͯ͠αʔό͕མ͔ͪͨΒͰ͢Ͷɻ མͪண͘·Ͱ͔ͭ͠Ͱ͖ͳ͍Ͱ͢ɻ Ͳ͏ͨ͠Β͍͍ΜͰ͔͢ʁʂʁʂ ͕ͬͭΓαʔόʹ͓͍ۚΕͯ࠶ൃࢭΛʂ
Ϣʔβ͕ϨΠΞτΛյ͢ Ͳ͜Λߋ৽ͨ͠Β͍͍ʁ "ͱ#ͷϑΟʔϧυΛߋ৽͍ͯͩ͘͠͞ɻ $ͷϑΟʔϧυΛߋ৽ͨ͠Β͜ΘΕͨʂ $ͷϑΟʔϧυΛߋ৽͔ͨ͠ΒͰ͢ɻ
ύεϫʔυཧͬͯͪΌΜͱ͞ΕͯΔʁ ύεϫʔυΈΜͳͰಉ͡Ͱ͍͍Ͱ͔͢ʁ ୀ৬͋Δͱࢥ͏ͷͰɺݸਓ୯ҐͰ͓ئ͍͠·͢ Εͯ͠·͏͔ɻᝦʹॻ͍ͯɺ1$ʹ షΓ͚͓ͯ͜͏ 🙈🙉🙊
ϗεςΟϯάྉۚ ֹ݄ Φʔτεέʔϧ 1)1.Z42- /FUMJGZ 0ԁʙ ͋Γ ෆՄ 'JSFCBTF )PTUJOH
0ԁʙ ͋Γ ෆՄ 4ࣾ 425ԁʙ ͳ͠ Մ "ࣾ 20999.70ԁʙ ͳ͠ Մ
Ϣʔβ͕ߋ৽͢ΔࣗࣾαΠτͰɺ$.4ߏஙɻ ͦΕɺඞཁͰ͔͢ʁ
ཧͯ͠ߟ͑Α͏ ͳͥ$.4ߏங͕ඞཁʁ ̍ɽ)5.-Λॻ͚ͳ͍Ϣʔβ͕ߋ৽Ͱ͖ΔΑ͏ʹ͢ΔͨΊ ̎ɽಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛཧ͢ΔͨΊ ɹɹʢྫɿχϡʔεαΠτʣ ̏ɽ&$αΠτߏஙͳͲෳࡶͳखॱ͕ඞཁͳͷΛखܰʹߏங͢ΔͨΊ
͜Ε(JU)VCͰղܾͰ͖Δʂ
Ϩετϥϯϧϕφτϯ IUUQTHJUIVCDPNMFCFOBUPOCFOBUPOOFU
ίϯηϯτϚʔέοτ IUUQTHJUIVCDPNDPODFOUNBSLFUDPNXFCTJUF
ࢢܦӦϓϩϑΣογϣφϧεΫʔϧ
̍ɽ)5.-Λॻ͚ͳ͍Ϣʔβ͕ߋ৽Ͱ͖ΔΑ͏ʹ͢ΔͨΊ ؆୯ͳϖϥΠνͩͬͨΒɺ͜ͷϨϕϧͰ͍͚Δɻ ఆٳใ͚ͩ$.4Ͱهࣄ࡞ͬͯΔҙٛͱɾɾɾɻ
ϑϨϯνͷΦʔφʔγΣϑ ʮ͜ΕݟͨΒߋ৽Ͱ͖ͨΑʯ
·ͪͮ͘Γձࣾͷελοϑ ʮΩʔࣗମΛؒҧͬͯআͨ͠Βɺࣦഊͨͬͯ͠ϝʔϧ͖ͨʯ
·ͪͮ͘Γձࣾͷελοϑ ॻ͖͙͑Β͍Ͱ͖ΔΑɻ
࣮ྫ̍ɿࣗ࡞ςϯϓϨʔτ <ul class="list-news"></ul> export interface IItem { selector: string; template:
string; data: Array<{ title?: string; ja?: string; price?: string; body?: string; image?: string }>; } export const news: IItem = { selector: '<ul class="list-news"></ul>', template: '<li><label class="form-label">{{ title }}</label><p>{{ body }}</ p></li>', data: [ { title: 'ίϩφײછ༧ରࡦ', body: 'ίϩφײછ༧ରࡦͱͯ͠ɺۭؾͷೖΕସ͑ɺִؒʹ༨༟ͷ͋Δ੮ͷ͝ҊɺΞΫϦ ϧ൘ɺ٬ελοϑͷϚεΫண༻ͳͲͷରԠΛ͓ͯ͠٬༷Λ͓ܴ͍͑ͨ͠·͢ɻ<br>ళɺ৽ܕίϩ φΠϧεରࡦೝূళͰ͢ɻ<br>2࣌ؒఔͰͷ͓৯ࣄΛ͓ئ͍͍ͨ͠·͢ɻ', }, ], }; )5.- 5ZQF4DSJQU
࣮ྫ̍ɿ͜Μͳ/PEFΛ࣮ߦͯ͠#VJME const targets = ['index.html']; const items: IItem[] = [news,
redWine, whiteWine, champagneWine, announcement]; const build = () => { execSync(`rm -r -f ${process.cwd() + '/www'}`); mkdirSync(process.cwd() + '/www'); execSync(`cp -r ${process.cwd() + '/src/template'}/* ${process.cwd() + '/www'}`); for (const templateFile of targets) { let template = readFileSync(process.cwd() + '/www/' + templateFile).toString('utf-8'); for (const item of items) { const insertData: string[] = []; for (const line of item.data) { let template = item.template; for (const [key, value] of Object.entries(line)) { const re_url = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/ gi; const replaceText = (value as string).replace(re_url, '<a href="$1" target="_blank" rel="noreferrer">$1</a>'); template = template.replace(new RegExp(`{{ ${key} }}`, 'g'), replaceText as string); } insertData.push(template); } const changeSelector = item.selector.replace(/></g, `>${insertData.join('')}<`); template = template.replace(item.selector, changeSelector); } writeFileSync(process.cwd() + '/www/' + templateFile, template); } }; build(); createWineSearchIndex(); apiBuild(); 5ZQF4DSJQU
࣮ྫ̎ɿ+BWB4DSJQUϑϨʔϜϫʔΫ <h4> <img src="assets/svg/list.svg" class="svg" decoding="async" /> ͓Βͤ </h4> <ul
class="list-news"> {news.map(d => <li><label class="form-label" innerHTML={d.title}></label><p innerHTML={d.body}></p> </li>)} </ul> +49 ͜Ε͚ͩͰॻ͚ͪΌ͏ɻ؆୯ʂ
ಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛཧ͢ΔͨΊ ϔουϨε$.4Λͬͯಈతʹσʔλऔಘ͠Α͏ 8PSE1SFTTDPN NJDSP$.4 LJOUPOF
ಉҰςϯϓϨʔτͰྔ࢈ͨ͠هࣄΛཧ͢ΔͨΊ { path: ':id', component: ArticlePage, }, this.route.paramMap.subscribe(as ync (params:
ParamMap) => { this.articleId = parseInt(params.get('id'), 10); const {article} = await this.articleService.getCategory( this.articleId ); this.article = article; }); <article> <h3 [innerHTML]="item.title"></ h3> <p class="attribute"> <ion-note>{{ item.date | date: "yyyyMM݄dd" }}</ion-note> <ion-note *ngIf="item.count"> / {{ item.count }}Point</ion-note> </p> <p class="excerpt" [innerHTML]="item.excerpt"></p> </article>
44(443QSFSFOEFSJPΛͬͯϨϯμϦϯάͰ͖Δ ༰ $43 ϢʔβڥͰHTMLΛϨϯμϦϯά 44( αʔόϗεςΟϯάલʹHTMLΛϨϯμϦϯά 443 ϦΫΤετ࣌ʹHTMLΛϨϯμϦϯά QSFSFOEFSJP ಛఆIP͔ΒͷϦΫΤετ͚࣌ͩɺαʔό͕ϨϯμϦ
ϯάࡁΈHTMLΛฦ٫
ߏ͕͍͠ͷγϯϓϧʹͭ͘ΕΔ
$%/Λͬͨ৴͕༰қʹͳΓߴʹ
ٕज़ͷ՝ٕज़Ͱղܾ͠Α͏ ಈతݴޠ͕ΔαʔόͷόοΫΞοϓαʔόෛՙͷίϯτ ϩʔϧηΩϡϦςΟϢʔβ͕յͨ͠ΒͲ͏͠Α͏FUD ϦεΫϚωʔδϝϯτ͠ͳ͕Β$.4ߏங͋Γ͚ͩͲɺ੩తαΠ τԽ͢Δ͜ͱͰ͜ΕΒͷΛΓӽ͑ΕΔՄೳੑ͕͋ΔͷͰҰ ߟ͑ͯΈ·ͤΜ͔ɻ 8FCΞηοτΛ৴͢Δ͚ͩͷͨΊʹɺຊʹඞཁʁ
ઌͷ͜ͱΛߟ͑Α͏ ʢ8FCαΠτ͕΄͍͠Ͱ͢ɻޙ͓ళ͕ ɹͲ͏ͳͬͯΔ͔Θ͔Βͳ͍ʣ ʢೲͨ͠ΒऴΘΓɻϝϯςܖͱΕΔͱخ͍͠ʣ ͓ؒئ͍͢Δ͜ͱͳ͔͔ͬͨΒ ϝϯςܖͷܧଓΊ͓ͯ͜͏ ʢܖऴΘΓͳͷͰɺҰࣜͯ͠ऴΘΓ·͢Ͷʣ