$30 off During Our Annual Pro Sale. View Details »

webpackが何故必要で、 何故分かりづらいのか

tomof
November 20, 2016

webpackが何故必要で、 何故分かりづらいのか

tomof

November 20, 2016
Tweet

More Decks by tomof

Other Decks in Programming

Transcript

  1. webpack͕ԿނඞཁͰɺ Կނ෼͔ΓͮΒ͍ͷ͔ @tomof 1

  2. ໨࣍ 1. Կނwebpackͳͷ͔ʁ 2. webpackೖ໳ 3. webpack͸Կނ͜Μͳʹ΋෼͔ΓͮΒ͍ͷ͔? 4. ·ͱΊ 2

  3. 1. Կނwebpackͳͷ͔ʁ 3

  4. طଘͷπʔϧ͸Կ͕ବ໨ͩͬͨͷ͔ʁ 4

  5. 5 େن໛ͳϓϩδΣΫτʹ͸ ద͍ͯ͠ͳ͍

  6. զʑ͸ɺ1ͭͷڊେͳϑΝΠϧʹ࿈݁͢ΔΑ͏ɺ ڭҭ͞Εͯ͠·ͬͨʂʂ 6

  7. طଘͷπʔϧΛ࢖ͬͯ ղܾͰ͖ͳ͔ͬͨͷ͔ʁ 7

  8. 8 ֦ுΛࢼΈ͕ͨ ্ख͘ߦ͔ͳ͔ͬͨ

  9. webpackͷ໨త • ґଘੑͷ͋ΔπϦʔߏ଄ΛɺಡΈࠐΈ࣌ͷඞཁੑʹԠͯ͡
 νϟϯΫ(chunk/ݻ·Γ)ຖʹ෼ׂ͢Δɻ • ॳճͷಡΈࠐΈ࣌ؒΛ୹͘͢Δ(อͭ)ɻ • શͯͷ੩తΞηοτΛϞδϡʔϧʹ͢Δ͜ͱ͕ग़དྷΔɻ • େن໛ϓϩδΣΫτʹదͨ͠࢓૊Έɻ

    9
  10. खಈͰղܾͰ͖ͳ͍͔ʁ • ґଘੑͷղܾɺඇಉظಡΈࠐΈ • ؾ͕ڰ͍ͦ͏…ɻ 10

  11. webpackʹҕͶΔࣗಈԽͷઃఆ • ෼ׂͨ͠ϑΝΠϧαΠζ͕খ͗͢͞Δ৔߹͸ɺ
 ෼ׂ͠ͳ͍ͱ͍͏ઃఆ • ը૾αΠζ͕খ͚͞Ε͹ΠϯϥΠϯԽɺ
 େ͖͚Ε͹URLͰಡΈࠐΈɻ 11 background-image: url('../img/puppy.jpg');

    background-image: url(‘data:image/png;base64, iVB0Rw0…’); size େ size গ
  12. • webpack your bags ͷ Maxime Fabre ࢯ – طଘͷπʔϧͰຬ଍͍ͯͨ͠͠ɺ࠷ॳʹwebpackͷ֓ཁʹ໨Λ

    ௨ͨ࣌͠ʹΠϥοͱͯ͠λϒΛดͨ͡ɻ – ࠓ͸શͯΛwebpackʹҕͶͯ͠·͑ͱͳ͍ͬͯΔɻ 12 webpackΛ࢖ͬͨਓͷײ૝
  13. 2. webpackೖ໳ 13

  14. webpackΛ࢖༻͢Δʹ͸? 1. webpackΛΠϯετʔϧ 2. webpack.config.jsʹઃఆΛॻ͖ࠐΉ 3. webpack͔Βఏڙ͞ΕΔrequireؔ਺ʹΑͬ ͯɺϞδϡʔϧͷಡΈࠐΈΛߦ͏ɻ 4. ϏϧυίϚϯυΛ࣮ߦ

    14
  15. webpack.config.js • ࠷ऴతʹ module.exports ʹΦϒδΣΫΛࢦఆ͢Δ 15 module.exports = {
 entry:

    …,
 output: {…},
 module: {
 loaders: [ …
 ],
 }, plugins: […], ɹ…
 };
  16. webpack.config.js • ΤϯτϦϙΠϯτ = JavaScript࣮ߦͷೖΓޱͱͳΔϑΝΠϧΛࢦఆ 16 module.exports = {
 entry:

    …,
 output: {…},
 module: {
 loaders: [ …
 ],
 }, plugins: […], ɹ…
 };
  17. webpack.config.js 17 module.exports = {
 entry: …,
 output: {…},
 module:

    {
 loaders: [ …
 ],
 }, plugins: […], ɹ…
 }; • ग़ྗϑΝΠϧͷઃఆ
  18. webpack.config.js • ϩʔμʔͷઃఆ 18 module.exports = {
 entry: …,
 output:

    {…},
 module: {
 loaders: [ …
 ],
 }, plugins: […], ɹ…
 };
  19. webpack.config.js • ϓϥάΠϯͷઃఆ 19 module.exports = {
 entry: …,
 output:

    {…},
 module: {
 loaders: [ …
 ],
 }, plugins: […], ɹ…
 };
  20. ϏϧυίϚϯυΛ࣮ߦ 20

  21. webpack༻ޠ • νϟϯΫ • ϩʔμʔ • ϓϥάΠϯ • HMR (Hot

    Module Replacement) 21
  22. νϟϯΫ 22 1νϟϯΫ=࠷ऴతʹ1ϑΝΠϧʹग़ྗ͞ΕΔͱ͸ݶΒͳ͍? (͜͜Ͱ͸ɺϓϥάΠϯ͕ɺCSSΛൈ͖ग़ͯ͠ผϑΝΠϧʹ෼཭) • ίʔυͷݻ·Γ

  23. ϩʔμʔ 23 • Ϟδϡʔϧͱͯ͠ಡΈࠐΊΔΑ͏ʹ͢ΔͨΊͷ࢓૊Έ • loaderͷଞʹpreLoader(લ)ɺpostLoader(ޙ)͕͋Δ – preLoader : ओʹlintܥͷॲཧͰ࢖༻͞ΕΔ

    – postLoader : ओʹίʔυΧόϨοδͷॲཧͰ࢖༻͞ΕΔ
  24. ϩʔμʔͷઃఆྫ 24 module: {
 loaders: [
 {
 test: /\.js/,
 loader:

    'babel',
 include: __dirname + '/src',
 },
 {
 test: /\.scss/,
 loader: 'style!css!sass'
 },
 …
 ]
  25. ϩʔμʔͷνΣʔϯ 25 • νΣʔϯͰܨ͛Δ͜ͱ͕Մೳɻ ྫ)ɹ'style!css!sass' 1. SassΛCSSʹม׵ 2. CSSΛJavaScriptʹจࣈྻͱͯ͠ಡΈࠐΉ 3.

    ಡΈࠐΜͩจࣈྻΛ<style>λάͱͯ͠<head>಺ʹ௥Ճ .sass .css HTML <style> body: {…} header: {…} 1 2 3
  26. ϩʔμʔΛconfigʹઃఆ͢Δ͜ͱͰ… 26 require("!style!css!./style.css"); require("./style.css");

  27. ϓϥάΠϯ͕ߦ͏͜ͱʢ̍ʣ 27 • ϩʔμʔʹΑͬͯग़ྗ͞ΕͨϑΝΠϧʹରͯ͠Կ͔Λ ߦ͏ –ɹѹॖԽ ɾ೉ಡԽ –ɹڞ௨͢ΔίʔυΛҰవΊʹͯ͠ผϑΝΠϧʹൈ͖ग़͢ –ɹಛఆͷαΠζʹຬͨͳ͍ϑΝΠϧͷ෼ׂΛऔΓ΍ΊΔ

  28. 28 • ϩʔμʔͷ໾ׂ͔Β֎ΕΔ͜ͱΛ୲͏ –ɹग़ྗϑΥϧμ಺ΛΫϦʔϯΞοϓ͢Δ –ɹwebpackͷग़ྗ಺༰ʹ߹ΘͤͯಈతʹHTMLΛੜ੒͢Δ ϓϥάΠϯ͕ߦ͏͜ͱʢ̎ʣ

  29. HMR 29 • Hot Module Replacement • ΦʔτϦϩʔυ͸ϖʔδશମΛ࠶ಡࠐΈ͢Δ͕ɺHMR͸࠶ಡ ࠐ͢Δ͜ͱແ͘ɺมߋ͞ΕͨՕॴ͚ͩΛಈతʹஔ׵͢Δɻ •

    ྫ͑͹ɺ͋ΔखॱΛز͔ͭ౿ΜͰදࣔͨ͠μΠΞϩά಺ͷॲ ཧΛมߋͨ͠৔߹ʹɺͦͷखॱΛ܁Γฦ͢ඞཁ͕ແ͘ͳΔɻ
  30. web-dev-serverͬͯʁ 30 • Expressϕʔεͷ։ൃ༻αʔόʔ • ΦʔτϦϩʔυ΍HMRΛαϙʔτ • /webpack-dev-server/ʹiframeΛ࢖༻ͨ͠
 ಛผͳ؀ڥΛఏڙ

  31. web-dev-serverΛ࢖༻͢Δʹ͸ʁ 1. webpack-dev-serverΛΠϯετʔϧ 2. webpack.config.js·ͨ͸ίϚϯυϥΠϯҾ਺ʹઃఆ Λࢦఆͯ͠ɺίϚϯυͰαʔόʔΛ্ཱͪ͛Δɻ 3. localhost:8080 ·ͨ͸ɺ
 localhost:8080/webpack-dev-server/

    Ͱ֬ೝ
 (8080͸σϑΥϧτઃఆͷϙʔτ൪߸) 31
  32. 3. webpack͸Կނ͜Μͳʹ΋ ɹ෼͔ΓͮΒ͍ͷ͔? 32

  33. 33 ෼͔ΓͮΒ͍ݪҼ • ઃఆͷࢦఆ –ɹઃఆͷΩʔɾ஋ͳͲʹҰ؏ੑ͕ແ͍ɻ –ɹϓϥάΠϯͷಈ࡞͕΍΍͍͜͠ɻ • υΩϡϝϯτྨ –ɹቕΓͦ͏ͳϙΠϯτ΍෼͔ΓͮΒ͍ϙΠϯτΛ
 ڧௐͨ͠ΓɺԿނͦ͏ͳͷ͔ʁͱ͍ͬͨઆ໌͕


    ෆ଍͍ͯ͠Δɻ
  34. 34 entry: ‘./src’, entry: ‘./src/*’, ʁ gulp.src(“./path/to/**/*.js”) ʹ ͍ۙײ͡ʁ webpack.config.jsͷentryύεࢦఆʹቕͬͨ

  35. entry: ‘./src/*’, entry: ‘./src’, 35 ʁ webpack.config.jsͷentryύεࢦఆʹቕͬͨ ҧͬͨ

  36. entry: ‘./src’, entry: ‘./src/index.js’, 36 webpack.config.jsͷentryύεࢦఆʹቕͬͨ

  37. 37 webpack.config.jsͷentryύεࢦఆʹቕͬͨ ͦͷҰํͰ… output: {
 …
 path: ‘./builds’ …
 },

    outputͷpathͳͲɺϑΥϧμΛࣔ͢ઃఆ΋͋Δɻ
  38. 38 entry: ‘./src’, ࣮͸”main”ͱ͍͏νϟϯΫ໊͕ࣗಈతʹ෇͚ΒΕ͍ͯΔɻ output: {
 filename: '[name]-bundle.js',
 … },

    νϟϯΫ໊ͷ໊෇͚ͱ࢖༻ํ๏͕આ໌ෆ଍ main-bundle.js
  39. 39 entry: {
 main: './src',
 vendor: ["jquery", "mustache"],
 admin: './admin'


    }, νϟϯΫ໊ͷ໊෇͚ͱ࢖༻ํ๏͕આ໌ෆ଍ entry: ‘./src’, νϡʔτϦΞϧ౳ͰΑ͘༻͍ΒΕΔྫ͕ͩ… ࣮ફͰ͸͜ͷΑ͏ʹͳΔͷͰ͸
  40. 40 entry: {
 main: './src',
 vendor: ["jquery", "mustache"],
 admin: './admin'


    }, νϟϯΫ໊ͷ໊෇͚ͱ࢖༻ํ๏͕આ໌ෆ଍ entry: ‘./src’, νϡʔτϦΞϧ౳ͰΑ͘༻͍ΒΕΔྫ͕ͩ… ࣮ફͰ͸͜ͷΑ͏ʹͳΔͷͰ͸ ೚ҙʹࢦఆՄೳͳνϟϯΫ໊
  41. 41 • ϩʔμʔͷνΣʔϯ͸ɺԿނӈ͔Βࠨͳͷ͔ʁ ϩʔμʔઃఆͷॻ͖ํ ɹ ’style!css!sass’

  42. 42 • ͜͏͍͏͜ͱͳͷ͔ʁ ϩʔμʔઃఆͷॻ͖ํ style( css( sass( ) ) )

    ΋ͦ͠͏ͳΒɺҰݴॻ͍ͯ͘ΕΕ͹͍͍ͷʹ…ɻ
  43. ઃఆͷΩʔɾ஋͕෼͔ΓͮΒ͍ 43 module: {
 loaders: [
 {
 test: /\.js/,
 loader:

    'babel',
 include: __dirname + '/src',
 },
 {
 test: /\.scss/,
 loader: 'style!css!sass'
 },
 …
 ]
  44. ઃఆͷΩʔɾ஋͕෼͔ΓͮΒ͍ 44 module: {
 loaders: [
 {
 test: /\.js/,
 loader:

    'babel',
 include: __dirname + '/src',
 },
 {
 test: /\.scss/,
 loader: 'style!css!sass'
 },
 …
 ] ͳͥɺtest ͳͷ͔ʁ
  45. ઃఆͷΩʔɾ஋͕෼͔ΓͮΒ͍ 45 JavaScriptͷਖ਼نදݱͷtest()ϝιουʹ༝དྷʁ © 2005-2016 Mozilla Developer Network & ߩݙऀ֤ਓ

  46. ϓϥάΠϯ͕೉͍͠… 46 • ࣮ફͰආ͚ͯ͸௨Εͳ͍͚Ͳཧղ͕೉͍͠ϓϥάΠϯ –ɹCommonsChunkPluginɹ(webpackެࣜ) –ɹextract-text-webpack-plugin

  47. CommonsChunkPlugin 47 • ֤νϟϯΫͰڞ௨(ॏෳ)͢ΔϞδϡʔϧΛൈ͖ग़ͯ͠ผ ϑΝΠϧʹ·ͱΊͯ͘ΕΔϓϥάΠϯ • αʔυύʔςΟ੡ͷϞδϡʔϧ͚ͩΛ·ͱΊͨ
 vendor.jsΛ࡞Δͷʹ΋࢖༻͞ΕΔ͕ɺ͜Ε͕
 ඇৗʹ෼͔ΓͮΒ͔ͬͨɻ

  48. CommonsChunkPlugin 48 • ͪͳΈʹɺ͜ͷϓϥάΠϯΛ࢖༻͠ͳ͍ͱ…
 webpack͸࠷௿ݶͷ࠷దԽ͔͠ߦΘͳ͍ͨΊɺ

  49. CommonsChunkPlugin 49 • ڞ௨ͯ͠࢖༻͞ΕΔϥΠϒϥϦ΍Ϟδϡʔϧ͕
 ෳ਺ͷνϟϯΫͰಡΈࠐ·Εͯ͠·͏ɻ

  50. CommonsChunkPlugin 50 Ծʹɺ͜ΜͳΤϯτϦʔϙΠϯτ͕͋ͬͨͱͯ͠ɺ entry: {
 pageA: "./pageA",
 pageB: "./pageB",
 pageC:

    "./pageC",
 adminPageA: "./adminPageA",
 adminPageB: "./adminPageB",
 adminPageC: "./adminPageC",
 }, ࣍ͷΑ͏ͳCommonsChunkPluginࢦఆ͕
 ͋ͬͨͱ͢Δͱɺ
  51. 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"]
 }),
 ],
  52. 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"]
 }),
 ],
  53. CommonsChunkPlugin 53 adminPageA adminUkl adminAcontroller projectUkl adminPageB adminUkl adminBcontroller projectUkl

  54. CommonsChunkPlugin 54 admin-commons adminUkl projectUkl adminPageA adminAcontroller adminPageB adminBcontroller

  55. 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"]
 }),
 ],
  56. CommonsChunkPlugin 56 admin-commons adminUkl projectUkl pageA projectUkl pageAcontroller pageB projectUkl

    pageBcontroller
  57. CommonsChunkPlugin 57 admin-commons adminUkl pageA pageAcontroller pageB pageBcontroller commons projectUkl

  58. CommonsChunkPluginͷओͳΦϓγϣϯ • nameɿڞ௨νϟϯΫͷ໊લ 
 ͪͳΈʹnames΋ଘࡏ͢Δ(഑ྻΛࢦఆ) • chunksɿର৅ͱ͢ΔνϟϯΫ
 ʢলུ͢ΔͱɺશͯͷνϟϯΫ͕ର৅ʂ) • minChunksɿ͜ͷ਺ͷνϟϯΫͰ࢖༻͞Ε͍ͯͨΒର৅


    (2ճʙνϟϯΫ਺ or Infinity or ؔ਺) 58
  59. αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ 59 vendor

  60. 60 <script src="builds/vendor.js"></script>
 <script src=“builds/app.js"></script> vendor.jsʹ͸ɺ७ਮʹ3rdύʔςΟͷίʔυ͕ ࿈݁͞Εͨ΋ͷ͚ͩΛؚΊ͍ͨɻ αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠

  61. 61 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ entry: {
 main: './src',
 vendor: ["jquery", "moment", "underscore"],


    admin: './admin'
 },
  62. 62 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ entry: {
 main: './src',
 vendor: ["jquery", "moment", "underscore"],


    admin: './admin'
 },
  63. 63 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ plugins: [
 …
 new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
 filename:

    'vendor.js',
 minChunks: Infinity,
 }), … ]
  64. 64 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ plugins: [
 …
 new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
 filename:

    'vendor.js',
 minChunks: Infinity,
 }), … ] Infinity !?
  65. 65 vendor CommonsChunkPlugin Infinity vendorҎ֎ͷϞδϡʔϧ vendorҎ֎ͷϞδϡʔϧ vendorҎ֎ͷϞδϡʔϧ

  66. 66 αʔυύʔςΟϥΠϒϥϦ͚ͩΛ෼཭͍ͨ͠ plugins: [
 …
 new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
 filename:

    'vendor.js',
 minChunks: Infinity,
 }), … ] chunks͕লུ͞Ε͍ͯΔͷͰɺ શͯͷνϟϯΫ͕ର৅Ͱ͋Δ͜ͱʹ΋஫ҙʂ chunks: …,
  67. CommonsChunkPlugin 67 app app appController pageA pageAcontroller admin adminController admin

    શͯͷνϟϯΫ͔Β
  68. CommonsChunkPlugin 68 app app appController pageA pageAcontroller admin adminController admin

    vendor νϟϯΫͷ ϞδϡʔϧΛ(࣮࣭)ൈ͖ग़͚ͩ͢(?)
  69. 69 extract-text-webpack-plugin • ࠷ऴతͳόϯυϧ͔Βಛఆͷछྨͷ
 ίϯςϯπΛूΊɺ ଞͷ΋ͷͱύΠϓ͢Δɻ • ΄ͱΜͲ͕ɺCSSͷͨΊʹ࢖༻͞ΕΔɻ • ϖʔδͷॳظදࣔ࣌ʹɺCSS͕ಈతʹಡΈࠐ·ΕΔ͜ͱ

    ʹΑͬͯى͖Δνϥ͖ͭͷ๷ࢭɻ
  70. 70 extract-text-webpack-plugin var ExtractPlugin = require('extract-text-webpack-plugin'); var plugins = [


    …
 new ExtractPlugin(‘bundle.css'), …
 ];
  71. 71 extract-text-webpack-plugin module: {
 loaders: [
 …
 {
 test: /\.scss/,


    loader: ExtractPlugin.extract('style', 'css!sass'),
 },
 …
 ],
 },
  72. 72 extract-text-webpack-plugin module: {
 loaders: [
 …
 {
 test: /\.scss/,


    loader: ExtractPlugin.extract('style', 'css!sass'),
 },
 …
 ],
 }, ൈ͖ग़͢͜ͱ͕Մೳͳ৔߹ʹ ߦ͏͜ͱ ൈ͖ग़͢͜ͱ͕ ग़དྷͳ͔ͬͨ৔߹ʹ ௥ՃͰߦ͏͜ͱ
  73. 4. ·ͱΊ 73

  74. νϡʔτϦΞϧ΍ϒϩάهࣄʹ஫ҙ • ͜ΕΒʹԊͬͯࢼ͚ͩ͢Ͱ͸ɺటপʹ͸·Δɻ • େࣄͳઆ໌΍ิ଍͕ল͔Ε͍ͯΔ͜ͱ͕ଟ͍ɻ 74

  75. ެࣜυΩϡϝϯτΛಡΈղ͘ 75

  76. ެࣜυΩϡϝϯτΛಡΈղ͘ 76 ίϝϯτΛؚΊ…ʢٽʣ

  77. webpack2 / ৽υΩϡϝϯταΠτ 77

  78. ͝ਗ਼ௌɺ͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ 78