Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ビルドプロセスの自動化で効率アップ

 ビルドプロセスの自動化で効率アップ

Grunt.jsの紹介スライドです。package.jsonの扱いや、grunt自身の0.4.0対応が弱い部分が残りますが、数ヶ月前というところでご容赦くだされば、おおまかな概要を示しています。

1644fba8a219c89987390ef4f23d06bf?s=128

Ayumu Sato

November 10, 2012
Tweet

Transcript

  1. Ϗϧυϓϩηεͷ 1 ࣗಈԽͰ ޮ཰Ξοϓ (SVOUKTΛར༻ͨࣗ͠ಈԽ !BIPNV

  2. ࣗݾ঺հ ͞ͱ͏͋ΏΉ !BIPNV αΠόʔΤʔδΣϯτ  ϚʔΫΞοϓ ΤϯδχΞͰ͢ ໊ݹ԰ग़਎͕ͩͶ ৄ͘͠͸IUUQBIPNV 2

  3. ໨࣍  Ϗϧυϓϩηεͱࠇ͍ը໘  (SVOUKT  ઃఆϑΝΠϧͱ࢖͍ํ  ϓϥάΠϯͷ঺հͱࣗ࡞ 

    ·ͱΊ 3
  4. Ϗϧυϓϩηεͱࠇ͍ը໘ 4

  5. Ϗϧυϓϩηεʁ 5

  6. ͞·͟·ͳϏϧυ 6 $44 ϓϦϓϩηοα $PNQJMF $PGGFF4DSJQUͳͲ BMU+4ͷ$PNQJMF ϑΝΠϧͷ݁߹ $PODBUFOBUF ը૾ͷ

    ϩεϨεѹॖ $PNQSFTTJPO %BUB63*ม׵ *OMJOF&NCFE ίʔυ࠷খԽ .JOJGZ 0QUJNJ[F
  7. खஈɾ໨త͸૿͑Δ͹͔Γ ࠓ೔͜͜·Ͱ঺հ͞Εͨ಺༰͚ͩͰ΋ɺ ଟ͘ͷ࡞ۀΛٻΊΒΕ͍ͯΔ 7

  8. 7 υΩϡϝϯτ ੜ੒ Ωϟογϡ ϚχϑΣετ ؅ཧ +BWB4DSJQUͷ ςετ࣮ߦ ؀ڥʹϑΝΠϧ Ξοϓϩʔυ

    $44 ϓϦϓϩηοα $PNQJMF $PGGFF4DSJQUͳͲ BMU+4ͷ$PNQJMF ϑΝΠϧͷ݁߹ $PODBUFOBUF ը૾ͷ ϩεϨεѹॖ $PNQSFTTJPO %BUB63*ม׵ *OMJOF&NCFE ίʔυ࠷খԽ .JOJGZ 0QUJNJ[F
  9. ΞϨ΋ίϨ΋ ·ͱΊͯࣗಈԽ͍ͨ͠ ෼ࢄͨ͠࡞ۀͱखؒΛͻͱ·ͱΊʹ͢Δ 8

  10. ͳͥࣗಈԽͳͷ͔ʁ 9

  11. ܁Γฦ͠ΛݮΒ͍ͨ͠ 10  ώϡʔϚϯΤϥʔΛ܁Γฦͨ͘͠ͳ͍  खಈίϯύΠϧΛ܁Γฦͨ͘͠ͳ͍  $44Ͱಉ͡هड़Λ܁Γฦͨ͘͠ͳ͍  )551ϦΫΤετΛ܁Γฦͨ͘͠ͳ͍

  12. ͢΂ͯ͸ ܁Γฦ͠ͷ࠷దԽ %PO`U3FQBU:PVSTFMG 11

  13. ࣗಈԽʹΑͬͯ ੜ·ΕΔ͕࣌ؒେ੾ ໨ͷલͷ࡞ۀΛ࠷దԽ͢Δ͜ͱͰ ຊ౰ʹඞཁͳ͜ͱʹ࣌ؒΛ͔ͭ͏͜ͱ͕Ͱ͖Δ 12

  14. ͳͥࠇ͍ը໘ͳͷ͔ʁ 13

  15. 'PS6TJOH7BMVJOH5PPMT 14  Ձ஋͋Δπʔϧ΋ɺ͸͡Ί͸$-*πʔϧ  (6*πʔϧʹͳΔͷ͸ɺ΄ΜͷҰѲΓ  $-*πʔϧ͸ɺҰॠͰ๲େͳ࢓ࣄΛ͢Δ  ࢖͍͜ͳͤ͹࠷΋ޮ཰ԽͰ͖Δखஈ

     ஌͍ͬͯΕ͹ɺͦΕ͚ͩͰ෢ثʹͳΔ
  16. ւͷ޲͜͏ͷτϨϯυײ 15

  17. 5IF$PNNBOE-JOF ίϚϯυϥΠϯར༻ͷඞཁੑ͕ ޿͘ೝ஌͞Ε࢝Ί͍ͯΔ 16

  18. ࠇ͍ը໘ඞܞ࣌୅ ͕ɺ͘Δ͔΋͠Εͳ͍ 17

  19. ࠇ͍ը໘͸͔ͬ͜Α͘ͳΔʂ 18

  20. ·ͣ͸ઃఆΛ։͘ͱ͜Ζ͔Β 19

  21. 'PS8JOEPXT  $ZHXJO  ͍·͙͢ίϚϯυϓϩϯϓτΛࣺͯͯɺ $ZHXJOΛ࢖͏΂͖̍̌ ͷཧ༝  (FUUJOHHSVOUUPXPSLPOXJOEPXTXJUI DZHXJOBOEHJU

    20
  22. (SVOUKT 21

  23. OPEF+4Ͱಈ͘Ϗϧυπʔϧ ϏϧυϓϩηεͷࣗಈԽɾҰݩԽͷ΄͔ʹ΋ɺ ϩʔΧϧ։ൃ؀ڥͷߏஙͳͲ΋ 22

  24. 5BTL#BTFE#VJME5PPM 23 OPEF+4 (SVOU 5BTL 5BTL 5BTL

  25. 5BTL#BTFE#VJME5PPM 23 OPEF+4 (SVOU 5BTL 5BTL 5BTL ϓϥάΠϯ෦෼

  26. 5BTL#BTFE#VJME5PPM 23 OPEF+4 (SVOU 5BTL 5BTL 5BTL ίϚϯυϥΠϯͰ ࣮ߦ 5BTLͷ

    ࣮ߦ݁ՌΛಘΔ ‣֤छίϯύΠϧͷ࣮ߦ ‣ॲཧࡁΈϑΝΠϧͷ࡞੒ ‣ͳͲͳͲ
  27. (SVOUKTͷಛ௃  IUUQHSVOUKTDPN  ઃఆ΋ϓϥάΠϯ΋͢΂ͯ+BWB4DSJQU  ઃఆ෦෼ͷ+4͸؆ܿʹهड़Ͱ͖Δ  ϓϥάΠϯ͕ଟ਺ެ։͞Ε͍ͯΔ 

    ΤσΟλʹґଘͤͣར༻Ͱ͖Δ  ઃఆϑΝΠϧ͕͋Ε͹؆୯ʹ؀ڥڞ༗Ͱ͖Δ 24
  28. ։ൃΞΫςΟϏςΟ  TUBCMFEFWFMPQB  ඇৗʹ੝Μʹߋ৽͞Ε͍ͯΔ  ։ൃίϛϡχςΟ͕޿͕͍ͬͯΔ  K2VFSZͷϏϧυπʔϧͱͯ͠࠾༻ 25

  29. Πϯετʔϧํ๏ εςοϓͰ͙͢Ͱ͖·͢ 26

  30. OPEF+4ͷΠϯετʔϥʔ 27

  31. ΠϯετʔϥʔΛ࣮ߦ 28

  32. (SVOUKTΛΠϯετʔϧ 29 npm install -g grunt

  33. ͜ΕͰ४උ0, 30

  34. ઃఆϑΝΠϧͱ࢖͍ํ 31

  35. ࡞੒ϑΝΠϧ HSVOUKT QBDLBHFKTPO

  36. σϞϑΝΠϧެ։த IUUQTHJUIVCDPNBIPNVGSPOUSFOE HSVOUEFNP 33

  37. HSVOUKT 34 ϝΠϯͷઃఆϑΝΠϧ

  38. ϑΝΠϧͷ݁߹ 35

  39. +4ͱ$44ͷ݁߹ઃఆ 36 grunt.initConfig({ concat: { js: { src: [ 'js/lib/jquery.js',

    'js/app/main.js', 'js/app/sub.js' ], dest: 'js/all.js' }, css: { src: ['css/main.css', 'css/sub.css'], dest: 'css/all.css' } }, } HSVOUKT
  40. +BWB4DSJQUͷϏϧυ 37

  41. +BWB4DSJQUͷϏϧυઃఆ module.exports = function(grunt) { grunt.initConfig({ concat: { dist: {

    src: ['js/jquery.js', 'js/app/main.js', 'js/app/sub.js'], dest: 'js/all.js' } }, min: { dist: { src: 'js/all.js', dest: 'js/all.min.js' } } }); grunt.registerTask('jsbuild', ['concat', 'min']); }; 38 HSVOUKT
  42. 39 λεΫΛෳ߹ͯ͠ࢦఆ // Alias Task // grunt.registerTask(taskName, taskList) grunt.registerTask('jsbuild', ['concat',

    'min']); concat + min = jsbuild HSVOUKT
  43. 40 AHSVOUKTCVJMEAͷ࣮ߦ݁Ռ % grunt jsbuild # concat λεΫ͕ߦΘΕͯɺjs/all.js ͕ੜ੒͞Εͨ Running

    "concat:dist" (concat) task File "js/all.js" created. # ͞Βʹ min λεΫͰɺѹॖ͕ߦΘΕͨ Running "min:dist" (min) task File "js/all.min.js" created. Uncompressed size: 56545 bytes. Compressed size: # ͓͠·͍ Done, without errors. ࠇ͍ը໘
  44. 41 ϑΝΠϧͷߋ৽ݕ஌

  45. ϑΝΠϧͷߋ৽ݕ஌ͱΞΫγϣϯ watch: { css: { // ͜ΕΒͷϑΝΠϧ͕ߋ৽͞ΕͨΒ files: ['css/*.less'], //

    ҎԼͷλεΫΛ࣮ߦ͢Δ tasks: 'less' }, js: { files: ['js/app/*.js', 'index.html'], tasks: 'lint concat min' } } 42 HSVOUKT
  46. 43 AHSVOUXBUDIAͷ࣮ߦ݁Ռ % grunt watch # ϑΝΠϧͷߋ৽؂ࢹΛ։࢝ Running "watch" task

    Waiting...OK # ݕ஌ʂ File "css/main.less" changed. # lessλεΫ͕࣮ߦ͞ΕͯɺίϯύΠϧ Running "less:dist" (less) task File css/main.css created. ࠇ͍ը໘
  47. 44 ϩʔΧϧ։ൃ؀ڥ

  48. 45 ։ൃ؀ڥͱͯ͠૊Έ߹Θͤͨઃఆ grunt.initConfig({ /*ʢલུɾ͜Ε·Ͱͷwatch΍֤λεΫͷઃఆʣ*/ server: { port: 8000, // ੩తϩʔΧϧαʔόΛཱͯΔϙʔτ

    base: '.' }, reload: { port: 35729 // LiveReloadαʔόͷϙʔτ }, }); // develop λεΫͱͯ͠ෳ߹ grunt.registerTask( 'develop', ['server', 'reload', 'watch'] ); HSVOUKT
  49. 46 AHSVOUXBUDIAͷ࣮ߦ݁Ռ % grunt devlop # localhost:8000Λىಈ Running "server" task

    Starting static web server on port 8000. # LiveReloadαʔόʔΛىಈ Running "reload" task Proxying http://localhost:8000/ reload server running at http://localhost:35729 # ϑΝΠϧͷߋ৽Λ։࢝ Running "watch" task Waiting.. ࠇ͍ը໘
  50. ϓϥάΠϯͷಋೖ 47 OQNΛར༻ͯ͠Πϯετʔϧ͢Δ

  51. OQNͬͯʁ 48

  52. /PEF1BDLBHF.BOBHFS 49  OPEFͰಈ͘ύοέʔδ͕ଟ਺ొ࿥͞Ε͍ͯΔ  OQNίϚϯυΛ௨ͯ͠ར༻Ͱ͖Δ  3VCZͰ͍͏HFNͱ͔ͷΠϝʔδ

  53. ͷϓϥάΠϯ ݱࡏOQNʹ͓͍ͯ AHSVOUQMVHJOAλά͕͍ͭͨύοέʔδͷ਺ 50

  54. ͜Ε΋εςοϓͰ͙͢Ͱ͖Δ 51 ϓϥάΠϯͷར༻ํ๏

  55. HSVOUKTDPNͰݕࡧ 52

  56. ϓϥάΠϯΛΠϯετʔϧ 53 # ݟ͚ͭͨϓϥάΠϯΛnpmͰΠϯετʔϧ % npm install grunt-data-uri npm http

    GET https://registry.npmjs.org/grunt-data-uri npm http 200 https://registry.npmjs.org/grunt-data-uri npm http GET https://registry.npmjs.org/mime npm http 200 https://registry.npmjs.org/mime grunt-data-uri@0.0.1 node_modules/grunt-data-uri !"" mime@1.2.7 ࠇ͍ը໘
  57. ϓϥάΠϯΛϩʔυ // grunt.loadNpmTasks(packageName) grunt.loadNpmTasks('grunt-data-uri'); // ͦͷλεΫͷઃఆΛॻ͖଍ͤ͹ok grunt.initConfig({ dataUri: { dist:

    { src: ['css/raw/*.css'], dest: 'css' } } }); 54 HSVOUKT
  58. QBDLBHFKTPO 55 ؀ڥͷڞ༗

  59. 56 QBLDBHFKTPOΛ࡞੒   QBLDBHFKTPOʹอଘ   ઃఆϑΝΠϧΛڞ༗͢Δ  QBLDBHFKTPO͔Β෮ݩ

  60. // ͜ΜͳJSONΛίϐϖͯ͠ϑΝΠϧ࡞੒ { "name": "ABCϓϩδΣΫτ", "description": "ϓϩδΣΫτ։ൃ؀ڥͷఆٛͰ͢", "version": "1.0.0", "author":

    "࠽৔ɹଠ࿠", "main": "grunt.js", "dependencies": {}, "optionalDependencies": { "grunt": "~0.3.16" } } 57 QBDLBHFKTPOΛ࡞੒ QBDLBHFKTPO
  61. QBDLBHFKTPOʹอଘ # install --saveͰ # ϓϥάΠϯͷΠϯετʔϧ࣌ʹɺpackage.jsonͷґଘఆٛʹ௥Ճ % npm install --save

    grunt-xxxxx # remove --saveͰ # ΞϯΠϯετʔϧͱಉ࣌ʹɺpackage.jsonͷґଘఆ͔ٛΒ࡟আ % npm remove --save grunt-xxxxx 58 ࠇ͍ը໘
  62. ઃఆϑΝΠϧΛڞ༗͢Δ  HSVOUKT  QBDLBHFKTPO  ϑΝΠϧ͋Ε͹0, 59

  63. QBDLBHFKTPO͔Β෮ݩ # package.json͕͋ΔσΟϨΫτϦͰ࣮ߦ͢Δͱ # ه࿥͞Ε͍ͯΔϓϥάΠϯΛɺͦͷ৔ʹࣗಈͰ෮ݩ(Πϯετʔϧ)͢Δ % npm link 60 ࠇ͍ը໘

  64. ͜͜·Ͱ͕ઃఆํ๏  HSVOUKTࣗମ͸+BWB4DSJQUͱ͍͏ΑΓɹɹɹɹɹ ɹ ͘͘͝͝؆୯ͳઃఆϑΝΠϧ  QBDLBHFKTPOΛ͏·͘࢖͏ͱɹɹɹɹɹɹɹ ؀ڥڞ༗͕͠΍͘͢ɺϙʔλϏϦςΟ΋ྑ͍  ࣍͸ϓϥάΠϯͷ঺հ

    61
  65. ϓϥάΠϯͷ঺հͱࣗ࡞ 62

  66. ϓϥάΠϯͷ঺հ 63 େ఍͸(JU)VCʹϦϙδτϦ͕͋ΔͷͰ 3&"%.&ΛಡΊ͹෼͔ΔΑ͏ʹͳ͍ͬͯΔ

  67. ϏϧτΠϯλεΫ 64  DPODBUςΩετϑΝΠϧͷ݁߹  NJO+BWB4DSJQUͷ.JOJGZ  TFSWFSϩʔΧϧαʔόʔ  XBUDIϑΝΠϧͷߋ৽ݕ஌

     ͳͲͳͲ
  68. HSVOUDPOUSJC  IUUQTHJUIVCDPNHSVOUKTHSVOUDPOUSJC  ΦϑΟγϟϧ؅ཧ͞Ε͍ͯΔ٧Ί߹Θͤ  ެࣜϝϯςφϯε͞Ε͍ͯΔͷͰࢀߟʹͳΔ  CVNQɾDMFBOɾDPGGFFɾDPNQSFTTɹɹɹ DPQZɾIBOEMFCBSTɾKBEFɾKTUɾMFTTɹ

    NJODTTɾTUZMVTɾZVJEPD 65
  69. HSVOUDPNQBTT  IUUQTHJUIVCDPNLBIMJMHSVOUDPNQBTT  $PNQBTTΛ(SVOU͔Βར༻͢Δ  $44ϓϦϓϩηοαܥ͸֤छ͋Δ ˞ -&44HSVOUDPOUSJCMFTT ˞

    4UZMVTHSVOUDPOUSJCTUZMVT 66
  70. HSVOUJNH  IUUQTHJUIVCDPNIFMESHSVOUJNH  ը૾ϦιʔεͷϩεϨεѹॖ  ACSFXJOTUBMMPQUJQOHKQFHA͕ඞཁ  ߴѹॖઃఆͰ*NBHF0QUJNͱಉ͘͡Β͍ 

    BIPNVHSVOUJNH KQFHѹॖ཰ߴΊͨ൛ 67
  71. HSVOUDTTP  IUUQTHJUIVCDPNULHSVOUDTTP  $44ϑΝΠϧͷ.JOJGZ  ѹॖ཰ʹ༏Εͨ$440ͱ͍͏ϥΠϒϥϦ  BVUIPS!UL ˞

    $440ͱHSVOUDTTP].0- 68
  72. HSVOUEBUBVSJ  IUUQTHJUIVCDPNBIPNVHSVOUEBUBVSJ  $44಺ͷը૾ύεΛ%BUB63*ʹࣗಈม׵  VSM QBUIUPJNH Λର৅ʹͯ͠ஔ׵ 

    BVUIPS!BIPNV ˞ σʔλ63*εΩʔϜ].0- 69
  73. HSVOUSFMPBE  IUUQTHJUIVCDPNXFCYMHSVOUSFMPBE  ϒϥ΢βͷࣗಈϦϩʔυ  ͍ΘΏΔ-JWF3FMPBEͷ࣮૷  -JWF3FMPBEͷ$ISPNF֦ுͱซ༻Ͱ͖Δ ˞

    લग़ͷ%&.0Ͱ΋ར༻͍ͯͨ͠΋ͷ 70
  74. HSVOUGUQEFQMPZ  IUUQTHJUIVCDPN[POBLHSVOUGUQEFQMPZ  '51Λར༻ͨ͠ϑΝΠϧͷ΍ΓऔΓ  ؆қͳσϓϩΠϓϩηεʹͳΔϓϥάΠϯ ˞ )FSPLVHSVOUIFSPLVEFQMPZ ˞

    "NB[PO4HSVOUT 71
  75. HSVOUUFNQMBUFS  IUUQTHJUIVCDPNSPDLXPPEHSVOUUFNQMBUFS  +BWB4DSJQUςϯϓϨʔτΛίϯύΠϧ  FKTɾNVTUBDIFɾVOEFSTDPSFͳͲ  ܭछྨͷςϯϓϨʔτΤϯδϯʹରԠ ˞

    ίϯύΠϧؔ਺ΦϒδΣΫτ΁ͷม׵ 72
  76. HSVOUSFRVJSFKT  3FRVJSF+40QUJNJ[FS SKT ʹରԠ  ".%ϞδϡʔϧΛղܾͯ͠࠷దԽ͢Δ  BMNPOEͱ͍͏ϥΠϒϥϦʹ΋ରԠͯ͠༏ल ˞

    3FRVJSFKT ˞ 3FRVJSF+4ʹΑΔίʔυͷ෼ׂͱ࠷దԽ 73
  77. HSVOUNPDIB  IUUQTHJUIVCDPNLNJZBTIJSPHSVOUNPDIB  .PDIBͷ)FBEMFTTςετ࣮ߦ  1IBOUPN+4ʹґଘ͍ͯ͠Δ ˞ ΋ͪΖΜ26OJU΍+BTNJOFͷϓϥάΠϯ΋ ˞

    ςετܥ͸XBUDIͱ૊Έ߹ΘͤͯࣗಈԽ 74
  78. ϓϥάΠϯͷࣗ࡞ 75 ݪଇɺΑ͘ࣅͨϓϥάΠϯΛվ଄͢Δͷ͕ϥΫ OPEF+4Λॻ͘͜ͱʹͳΓ·͢

  79. ࣗ࡞ϓϥάΠϯͷઃఆͱϩʔυ grunt.initConfig({ sample: { dist: { src: ['js/**/*.js'], // ೖྗݩ

    dest: 'js/all.js', // ग़ྗઌ option: { // ΦϓγϣϯͳͲʢ೚ҙʣ hoge: 'fuga', peke: 'piyo' } } } }); // grunt.jsϑΝΠϧ಺ʹهड़ // tasksσΟϨΫτϦͷதΛ͢΂ͯಡΈࠐΈ grunt.loadTasks('tasks'); 76 HSVOUKT
  80. UBTLTTBNQMFKT module.exports = function(grunt) { grunt.registerMultiTask('sample', 'own task', function() {

    var option = this.data.option, src = this.file.src, dest = this.file.dest, // ඇಉظॲཧ͕ඞཁͳͱ͖ʹ࢖༻ doneΛcallbackʹ͢Δ // var done = this.async(); // path/to/**/*.js Λղܾͯ֘͠౰ϑΝΠϧΛ഑ྻͰฦ͢ srcFiles = grunt.file.expandFiles(src); /*...λεΫͷॲཧ...*/ }); }; 77 TBNQMFKT
  81. ࢀߟૉࡐ  σϞαϯϓϧUBTLTTBNQMFKT  ศརϔϧύʔूHSVOUMJCDPOUSJC  ໛ൣίʔυྫHSVOUDPOUSJCDPGGFF  EPDTQMVHJOTNE 

    EPDTBQJ@UBTLNE  EPDTBQJ@pMFNE 78
  82. ิ଍Bʹ͍ͭͯ  ଟ͘ͷ"1*͕มߋ͞ΕΔ  ϓϥάΠϯͷϝϯςφϯεঢ়گʹ஫ҙ͕ඞཁ  ઃఆϑΝΠϧ໊͕(SVOUpMFKTʹมߋ  $PGGFF4DSJQUͰઃఆ΍λεΫΛॻ͚ΔΑ͏ʹ ˞

    ৄ͘͠HSVOUEPDTNJHSBUJPO@HVJEFNE 79
  83. ·ͱΊ 80

  84. ϏϧυͷࣗಈԽ  (SVOU͸Ϗϧυπʔϧͱͯ͠ศརʂ  OQNʹ͸ଞͷͻͱ͕࡞ͬͨɺɹɹɹɹɹɹɹɹ ࣗಈԽͷͨΊͷϓϥάΠϯ͕୔ࢁ͋Γ·͢ʂ  շదʹ։ൃͰ͖Δ؀ڥ͕μΠδʂ  ࠇ͍ը໘ͱ஥ྑ͘͠·͠ΐ͏ʂ

     ԿΑΓ 81
  85. ࣮ફ͢Δ͜ͱ͕େࣄ πʔϧ͸ਅʹͩ͜ΘΔ΂͖໰୊Ͱ͸ͳ͍ ແཧͳ͘໨ͷલͷ܁Γฦ͠ΛݮΒͦ͏ 82

  86. -JWF3FMPBE 83

  87. $PEF,JU 84

  88. ຊ౰ʹ େࣄͳ͜ͱʹ࣌ؒΛʂ 85

  89. ࣍ੈ୅πʔϧ 86 $-*ͷੈքͰ͸ɺ͞Βʹ࣍ͷಈ͖͕࢝·͍ͬͯͨΓ

  90. :FPNBO#SVODI 87  4LFMFUPOͷ࡞੒΍4DBGGPMEJOH  ύοέʔδίϯϙʔωϯτ؅ཧ  ϩʔΧϧ։ൃ؀ڥͷఏڙ  ΑΓߴ౓ͳࣗಈϏϧυͷఏڙɹͳͲͳͲ

  91. $PNQBSF5BCMF 88

  92. ͖ͭͮ͸8FCͰʂ 89 :FPNBO.PEFSOXPSLqPXTGPSXFCBQQT #SVODI])5.-BQQMJDBUJPOBTTFNCMFS :FPNBOϤʔϚϯϋϒΖ͙ :FPNBOͱ#SVODIΛ͞Θ͞Θͨ͠ϋϒΖ͙

  93. ͋Γ͕ͱ͏͍͟͝·ͨ͠ http:/ /aho.mu 90

  94. 91  IUUQXXXqJDLSDPNQIPUPTKVSWFUTPO  IUUQXXXqJDLSDPNQIPUPTKBTPOXSZBO  IUUQXXXqJDLSDPNQIPUPTCJOBSZBQF  IUUQXXXqJDLSDPNQIPUPTKVIBOTPOJO 

    IUUQXXXqJDLSDPNQIPUPTLFWJO  .BOZ5IBOLT 1IPUP$SFEJUT