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
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
Hunting Vulnerabilities in Symfony with LLMs
vinceamstoutz
0
540
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5k
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
13
3.7k
ふつうのFeature Flag実践入門
irof
7
3.8k
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
190
OSもどきOS
arkw
0
560
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
510
DynamoDBには集計系のクエリがないけどなんとかしたい
musan
1
140
The NotImplementedError Problem in Ruby
koic
1
740
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
120
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
730
Featured
See All Featured
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
Why Our Code Smells
bkeepers
PRO
340
58k
Bash Introduction
62gerente
615
220k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
200
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
580
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Odyssey Design
rkendrick25
PRO
2
690
Heart Work Chapter 1 - Part 1
lfama
PRO
7
36k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
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