Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
webpackが何故必要で、 何故分かりづらいのか
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
tomof
November 20, 2016
Programming
5.2k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
webpackが何故必要で、 何故分かりづらいのか
tomof
November 20, 2016
More Decks by tomof
See All by tomof
RedwoodJSを試してみた
tomof
0
160
JAMstack_conf_2019 JAMstack at scale Report
tomof
0
140
Other Decks in Programming
See All in Programming
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
13k
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
180
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.7k
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
660
Lessons from Spec-Driven Development
simas
PRO
0
210
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
13
5.5k
技術記事、 専門家としてのプログラマ、 言語化
mizchi
13
6.2k
Oxcを導入して開発体験が向上した話
yug1224
4
320
Agentic UI
manfredsteyer
PRO
0
170
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.4k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
A2UI という光を覗いてみる
satohjohn
1
140
Featured
See All Featured
Six Lessons from altMBA
skipperchong
29
4.3k
A better future with KSS
kneath
240
18k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Everyday Curiosity
cassininazir
0
230
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
850
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
We Have a Design System, Now What?
morganepeng
55
8.2k
Transcript
webpack͕ԿނඞཁͰɺ Կނ͔ΓͮΒ͍ͷ͔ @tomof 1
࣍ 1. Կނwebpackͳͷ͔ʁ 2. webpackೖ 3. webpackԿނ͜Μͳʹ͔ΓͮΒ͍ͷ͔? 4. ·ͱΊ 2
1. Կނwebpackͳͷ͔ʁ 3
طଘͷπʔϧԿ͕ବͩͬͨͷ͔ʁ 4
5 େنͳϓϩδΣΫτʹ ద͍ͯ͠ͳ͍
զʑɺ1ͭͷڊେͳϑΝΠϧʹ࿈݁͢ΔΑ͏ɺ ڭҭ͞Εͯ͠·ͬͨʂʂ 6
طଘͷπʔϧΛͬͯ ղܾͰ͖ͳ͔ͬͨͷ͔ʁ 7
8 ֦ுΛࢼΈ͕ͨ ্ख͘ߦ͔ͳ͔ͬͨ
webpackͷత • ґଘੑͷ͋ΔπϦʔߏΛɺಡΈࠐΈ࣌ͷඞཁੑʹԠͯ͡ νϟϯΫ(chunk/ݻ·Γ)ຖʹׂ͢Δɻ • ॳճͷಡΈࠐΈ࣌ؒΛ͘͢Δ(อͭ)ɻ • શͯͷ੩తΞηοτΛϞδϡʔϧʹ͢Δ͜ͱ͕ग़དྷΔɻ • େنϓϩδΣΫτʹదͨ͠Έɻ
9
खಈͰղܾͰ͖ͳ͍͔ʁ • ґଘੑͷղܾɺඇಉظಡΈࠐΈ • ؾ͕ڰ͍ͦ͏…ɻ 10
webpackʹҕͶΔࣗಈԽͷઃఆ • ׂͨ͠ϑΝΠϧαΠζ͕খ͗͢͞Δ߹ɺ ׂ͠ͳ͍ͱ͍͏ઃఆ • ը૾αΠζ͕খ͚͞ΕΠϯϥΠϯԽɺ େ͖͚ΕURLͰಡΈࠐΈɻ 11 background-image: url('../img/puppy.jpg');
background-image: url(‘data:image/png;base64, iVB0Rw0…’); size େ size গ
• webpack your bags ͷ Maxime Fabre ࢯ – طଘͷπʔϧͰຬ͍ͯͨ͠͠ɺ࠷ॳʹwebpackͷ֓ཁʹΛ
௨ͨ࣌͠ʹΠϥοͱͯ͠λϒΛดͨ͡ɻ – ࠓશͯΛwebpackʹҕͶͯ͠·͑ͱͳ͍ͬͯΔɻ 12 webpackΛͬͨਓͷײ
2. webpackೖ 13
webpackΛ༻͢Δʹ? 1. webpackΛΠϯετʔϧ 2. webpack.config.jsʹઃఆΛॻ͖ࠐΉ 3. webpack͔Βఏڙ͞ΕΔrequireؔʹΑͬ ͯɺϞδϡʔϧͷಡΈࠐΈΛߦ͏ɻ 4. ϏϧυίϚϯυΛ࣮ߦ
14
webpack.config.js • ࠷ऴతʹ module.exports ʹΦϒδΣΫΛࢦఆ͢Δ 15 module.exports = { entry:
…, output: {…}, module: { loaders: [ … ], }, plugins: […], ɹ… };
webpack.config.js • ΤϯτϦϙΠϯτ = JavaScript࣮ߦͷೖΓޱͱͳΔϑΝΠϧΛࢦఆ 16 module.exports = { entry:
…, output: {…}, module: { loaders: [ … ], }, plugins: […], ɹ… };
webpack.config.js 17 module.exports = { entry: …, output: {…}, module:
{ loaders: [ … ], }, plugins: […], ɹ… }; • ग़ྗϑΝΠϧͷઃఆ
webpack.config.js • ϩʔμʔͷઃఆ 18 module.exports = { entry: …, output:
{…}, module: { loaders: [ … ], }, plugins: […], ɹ… };
webpack.config.js • ϓϥάΠϯͷઃఆ 19 module.exports = { entry: …, output:
{…}, module: { loaders: [ … ], }, plugins: […], ɹ… };
ϏϧυίϚϯυΛ࣮ߦ 20
webpack༻ޠ • νϟϯΫ • ϩʔμʔ • ϓϥάΠϯ • HMR (Hot
Module Replacement) 21
νϟϯΫ 22 1νϟϯΫ=࠷ऴతʹ1ϑΝΠϧʹग़ྗ͞ΕΔͱݶΒͳ͍? (͜͜ͰɺϓϥάΠϯ͕ɺCSSΛൈ͖ग़ͯ͠ผϑΝΠϧʹ) • ίʔυͷݻ·Γ
ϩʔμʔ 23 • Ϟδϡʔϧͱͯ͠ಡΈࠐΊΔΑ͏ʹ͢ΔͨΊͷΈ • loaderͷଞʹpreLoader(લ)ɺpostLoader(ޙ)͕͋Δ – preLoader : ओʹlintܥͷॲཧͰ༻͞ΕΔ
– postLoader : ओʹίʔυΧόϨοδͷॲཧͰ༻͞ΕΔ
ϩʔμʔͷઃఆྫ 24 module: { loaders: [ { test: /\.js/, loader:
'babel', include: __dirname + '/src', }, { test: /\.scss/, loader: 'style!css!sass' }, … ]
ϩʔμʔͷνΣʔϯ 25 • νΣʔϯͰܨ͛Δ͜ͱ͕Մೳɻ ྫ)ɹ'style!css!sass' 1. SassΛCSSʹม 2. CSSΛJavaScriptʹจࣈྻͱͯ͠ಡΈࠐΉ 3.
ಡΈࠐΜͩจࣈྻΛ<style>λάͱͯ͠<head>ʹՃ .sass .css HTML <style> body: {…} header: {…} 1 2 3
ϩʔμʔΛconfigʹઃఆ͢Δ͜ͱͰ… 26 require("!style!css!./style.css"); require("./style.css");
ϓϥάΠϯ͕ߦ͏͜ͱʢ̍ʣ 27 • ϩʔμʔʹΑͬͯग़ྗ͞ΕͨϑΝΠϧʹରͯ͠Կ͔Λ ߦ͏ –ɹѹॖԽ ɾಡԽ –ɹڞ௨͢ΔίʔυΛҰవΊʹͯ͠ผϑΝΠϧʹൈ͖ग़͢ –ɹಛఆͷαΠζʹຬͨͳ͍ϑΝΠϧͷׂΛऔΓΊΔ
28 • ϩʔμʔͷׂ͔Β֎ΕΔ͜ͱΛ୲͏ –ɹग़ྗϑΥϧμΛΫϦʔϯΞοϓ͢Δ –ɹwebpackͷग़ྗ༰ʹ߹ΘͤͯಈతʹHTMLΛੜ͢Δ ϓϥάΠϯ͕ߦ͏͜ͱʢ̎ʣ
HMR 29 • Hot Module Replacement • ΦʔτϦϩʔυϖʔδશମΛ࠶ಡࠐΈ͢Δ͕ɺHMR࠶ಡ ࠐ͢Δ͜ͱແ͘ɺมߋ͞ΕͨՕॴ͚ͩΛಈతʹஔ͢Δɻ •
ྫ͑ɺ͋ΔखॱΛز͔ͭ౿ΜͰදࣔͨ͠μΠΞϩάͷॲ ཧΛมߋͨ͠߹ʹɺͦͷखॱΛ܁Γฦ͢ඞཁ͕ແ͘ͳΔɻ
web-dev-serverͬͯʁ 30 • Expressϕʔεͷ։ൃ༻αʔόʔ • ΦʔτϦϩʔυHMRΛαϙʔτ • /webpack-dev-server/ʹiframeΛ༻ͨ͠ ಛผͳڥΛఏڙ
web-dev-serverΛ༻͢Δʹʁ 1. webpack-dev-serverΛΠϯετʔϧ 2. webpack.config.js·ͨίϚϯυϥΠϯҾʹઃఆ Λࢦఆͯ͠ɺίϚϯυͰαʔόʔΛ্ཱͪ͛Δɻ 3. localhost:8080 ·ͨɺ localhost:8080/webpack-dev-server/
Ͱ֬ೝ (8080σϑΥϧτઃఆͷϙʔτ൪߸) 31
3. webpackԿނ͜Μͳʹ ɹ͔ΓͮΒ͍ͷ͔? 32
33 ͔ΓͮΒ͍ݪҼ • ઃఆͷࢦఆ –ɹઃఆͷΩʔɾͳͲʹҰ؏ੑ͕ແ͍ɻ –ɹϓϥάΠϯͷಈ࡞͕͍͜͠ɻ • υΩϡϝϯτྨ –ɹቕΓͦ͏ͳϙΠϯτ͔ΓͮΒ͍ϙΠϯτΛ ڧௐͨ͠ΓɺԿނͦ͏ͳͷ͔ʁͱ͍ͬͨઆ໌͕
ෆ͍ͯ͠Δɻ
34 entry: ‘./src’, entry: ‘./src/*’, ʁ gulp.src(“./path/to/**/*.js”) ʹ ͍ۙײ͡ʁ webpack.config.jsͷentryύεࢦఆʹቕͬͨ
entry: ‘./src/*’, entry: ‘./src’, 35 ʁ webpack.config.jsͷentryύεࢦఆʹቕͬͨ ҧͬͨ
entry: ‘./src’, entry: ‘./src/index.js’, 36 webpack.config.jsͷentryύεࢦఆʹቕͬͨ
37 webpack.config.jsͷentryύεࢦఆʹቕͬͨ ͦͷҰํͰ… output: { … path: ‘./builds’ … },
outputͷpathͳͲɺϑΥϧμΛࣔ͢ઃఆ͋Δɻ
38 entry: ‘./src’, ࣮”main”ͱ͍͏νϟϯΫ໊͕ࣗಈతʹ͚ΒΕ͍ͯΔɻ output: { filename: '[name]-bundle.js', … },
νϟϯΫ໊ͷ໊͚ͱ༻ํ๏͕આ໌ෆ main-bundle.js
39 entry: { main: './src', vendor: ["jquery", "mustache"], admin: './admin'
}, νϟϯΫ໊ͷ໊͚ͱ༻ํ๏͕આ໌ෆ entry: ‘./src’, νϡʔτϦΞϧͰΑ͘༻͍ΒΕΔྫ͕ͩ… ࣮ફͰ͜ͷΑ͏ʹͳΔͷͰ
40 entry: { main: './src', vendor: ["jquery", "mustache"], admin: './admin'
}, νϟϯΫ໊ͷ໊͚ͱ༻ํ๏͕આ໌ෆ entry: ‘./src’, νϡʔτϦΞϧͰΑ͘༻͍ΒΕΔྫ͕ͩ… ࣮ફͰ͜ͷΑ͏ʹͳΔͷͰ ҙʹࢦఆՄೳͳνϟϯΫ໊
41 • ϩʔμʔͷνΣʔϯɺԿނӈ͔Βࠨͳͷ͔ʁ ϩʔμʔઃఆͷॻ͖ํ ɹ ’style!css!sass’
42 • ͜͏͍͏͜ͱͳͷ͔ʁ ϩʔμʔઃఆͷॻ͖ํ style( css( sass( ) ) )
ͦ͠͏ͳΒɺҰݴॻ͍ͯ͘ΕΕ͍͍ͷʹ…ɻ
ઃఆͷΩʔɾ͕͔ΓͮΒ͍ 43 module: { loaders: [ { test: /\.js/, loader:
'babel', include: __dirname + '/src', }, { test: /\.scss/, loader: 'style!css!sass' }, … ]
ઃఆͷΩʔɾ͕͔ΓͮΒ͍ 44 module: { loaders: [ { test: /\.js/, loader:
'babel', include: __dirname + '/src', }, { test: /\.scss/, loader: 'style!css!sass' }, … ] ͳͥɺtest ͳͷ͔ʁ
ઃఆͷΩʔɾ͕͔ΓͮΒ͍ 45 JavaScriptͷਖ਼نදݱͷtest()ϝιουʹ༝དྷʁ © 2005-2016 Mozilla Developer Network & ߩݙऀ֤ਓ
ϓϥάΠϯ͕͍͠… 46 • ࣮ફͰආ͚ͯ௨Εͳ͍͚Ͳཧղ͕͍͠ϓϥάΠϯ –ɹCommonsChunkPluginɹ(webpackެࣜ) –ɹextract-text-webpack-plugin
CommonsChunkPlugin 47 • ֤νϟϯΫͰڞ௨(ॏෳ)͢ΔϞδϡʔϧΛൈ͖ग़ͯ͠ผ ϑΝΠϧʹ·ͱΊͯ͘ΕΔϓϥάΠϯ • αʔυύʔςΟͷϞδϡʔϧ͚ͩΛ·ͱΊͨ vendor.jsΛ࡞Δͷʹ༻͞ΕΔ͕ɺ͜Ε͕ ඇৗʹ͔ΓͮΒ͔ͬͨɻ
CommonsChunkPlugin 48 • ͪͳΈʹɺ͜ͷϓϥάΠϯΛ༻͠ͳ͍ͱ… webpack࠷ݶͷ࠷దԽ͔͠ߦΘͳ͍ͨΊɺ
CommonsChunkPlugin 49 • ڞ௨ͯ͠༻͞ΕΔϥΠϒϥϦϞδϡʔϧ͕ ෳͷνϟϯΫͰಡΈࠐ·Εͯ͠·͏ɻ
CommonsChunkPlugin 50 Ծʹɺ͜ΜͳΤϯτϦʔϙΠϯτ͕͋ͬͨͱͯ͠ɺ entry: { pageA: "./pageA", pageB: "./pageB", pageC:
"./pageC", adminPageA: "./adminPageA", adminPageB: "./adminPageB", adminPageC: "./adminPageC", }, ࣍ͷΑ͏ͳCommonsChunkPluginࢦఆ͕ ͋ͬͨͱ͢Δͱɺ
CommonsChunkPlugin 51 var webpack = require('webpack'); … plugins: [ …
new webpack.optimize.CommonsChunkPlugin({ name: "admin-commons", chunks: ["adminPageA", "adminPageB"] }), new webpack.optimize.CommonsChunkPlugin({ name: "commons", chunks: ["pageA", "pageB", "admin-commons"], minChunks: 2 }), new webpack.optimize.CommonsChunkPlugin({ name: "c-commons", chunks: ["pageC", "adminPageC"] }), ],
CommonsChunkPlugin 52 var webpack = require('webpack'); … plugins: [ …
new webpack.optimize.CommonsChunkPlugin({ name: "admin-commons", chunks: ["adminPageA", "adminPageB"] }), new webpack.optimize.CommonsChunkPlugin({ name: "commons", chunks: ["pageA", "pageB", "admin-commons"], minChunks: 2 }), new webpack.optimize.CommonsChunkPlugin({ name: "c-commons", chunks: ["pageC", "adminPageC"] }), ],
CommonsChunkPlugin 53 adminPageA adminUkl adminAcontroller projectUkl adminPageB adminUkl adminBcontroller projectUkl
CommonsChunkPlugin 54 admin-commons adminUkl projectUkl adminPageA adminAcontroller adminPageB adminBcontroller
CommonsChunkPlugin 55 var webpack = require('webpack'); … plugins: [ …
new webpack.optimize.CommonsChunkPlugin({ name: "admin-commons", chunks: ["adminPageA", "adminPageB"] }), new webpack.optimize.CommonsChunkPlugin({ name: "commons", chunks: ["pageA", "pageB", "admin-commons"], minChunks: 2 }), new webpack.optimize.CommonsChunkPlugin({ name: "c-commons", chunks: ["pageC", "adminPageC"] }), ],
CommonsChunkPlugin 56 admin-commons adminUkl projectUkl pageA projectUkl pageAcontroller pageB projectUkl
pageBcontroller
CommonsChunkPlugin 57 admin-commons adminUkl pageA pageAcontroller pageB pageBcontroller commons projectUkl
CommonsChunkPluginͷओͳΦϓγϣϯ • nameɿڞ௨νϟϯΫͷ໊લ ͪͳΈʹnamesଘࡏ͢Δ(ྻΛࢦఆ) • chunksɿରͱ͢ΔνϟϯΫ ʢলུ͢ΔͱɺશͯͷνϟϯΫ͕ରʂ) • minChunksɿ͜ͷͷνϟϯΫͰ༻͞Ε͍ͯͨΒର
(2ճʙνϟϯΫ or Infinity or ؔ) 58
αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ 59 vendor
60 <script src="builds/vendor.js"></script> <script src=“builds/app.js"></script> vendor.jsʹɺ७ਮʹ3rdύʔςΟͷίʔυ͕ ࿈݁͞Εͨͷ͚ͩΛؚΊ͍ͨɻ αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠
61 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ entry: { main: './src', vendor: ["jquery", "moment", "underscore"],
admin: './admin' },
62 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ entry: { main: './src', vendor: ["jquery", "moment", "underscore"],
admin: './admin' },
63 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ plugins: [ … new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename:
'vendor.js', minChunks: Infinity, }), … ]
64 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ plugins: [ … new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename:
'vendor.js', minChunks: Infinity, }), … ] Infinity !?
65 vendor CommonsChunkPlugin Infinity vendorҎ֎ͷϞδϡʔϧ vendorҎ֎ͷϞδϡʔϧ vendorҎ֎ͷϞδϡʔϧ
66 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ͍ͨ͠ plugins: [ … new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename:
'vendor.js', minChunks: Infinity, }), … ] chunks͕লུ͞Ε͍ͯΔͷͰɺ શͯͷνϟϯΫ͕ରͰ͋Δ͜ͱʹҙʂ chunks: …,
CommonsChunkPlugin 67 app app appController pageA pageAcontroller admin adminController admin
શͯͷνϟϯΫ͔Β
CommonsChunkPlugin 68 app app appController pageA pageAcontroller admin adminController admin
vendor νϟϯΫͷ ϞδϡʔϧΛ(࣮࣭)ൈ͖ग़͚ͩ͢(?)
69 extract-text-webpack-plugin • ࠷ऴతͳόϯυϧ͔Βಛఆͷछྨͷ ίϯςϯπΛूΊɺ ଞͷͷͱύΠϓ͢Δɻ • ΄ͱΜͲ͕ɺCSSͷͨΊʹ༻͞ΕΔɻ • ϖʔδͷॳظදࣔ࣌ʹɺCSS͕ಈతʹಡΈࠐ·ΕΔ͜ͱ
ʹΑͬͯى͖Δνϥ͖ͭͷࢭɻ
70 extract-text-webpack-plugin var ExtractPlugin = require('extract-text-webpack-plugin'); var plugins = [
… new ExtractPlugin(‘bundle.css'), … ];
71 extract-text-webpack-plugin module: { loaders: [ … { test: /\.scss/,
loader: ExtractPlugin.extract('style', 'css!sass'), }, … ], },
72 extract-text-webpack-plugin module: { loaders: [ … { test: /\.scss/,
loader: ExtractPlugin.extract('style', 'css!sass'), }, … ], }, ൈ͖ग़͢͜ͱ͕Մೳͳ߹ʹ ߦ͏͜ͱ ൈ͖ग़͢͜ͱ͕ ग़དྷͳ͔ͬͨ߹ʹ ՃͰߦ͏͜ͱ
4. ·ͱΊ 73
νϡʔτϦΞϧϒϩάهࣄʹҙ • ͜ΕΒʹԊͬͯࢼ͚ͩ͢Ͱɺటপʹ·Δɻ • େࣄͳઆ໌ิ͕ল͔Ε͍ͯΔ͜ͱ͕ଟ͍ɻ 74
ެࣜυΩϡϝϯτΛಡΈղ͘ 75
ެࣜυΩϡϝϯτΛಡΈղ͘ 76 ίϝϯτΛؚΊ…ʢٽʣ
webpack2 / ৽υΩϡϝϯταΠτ 77
͝ਗ਼ௌɺ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ 78