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

Composerプラグインを作ってみよう /phpcon2016

2295fec4d38f59366f983d38628e6ca0?s=47 Hiraku NAKANO
November 03, 2016

Composerプラグインを作ってみよう /phpcon2016

PHPカンファレンス2016 トラック1 の発表資料です。

2295fec4d38f59366f983d38628e6ca0?s=128

Hiraku NAKANO

November 03, 2016
Tweet

Transcript

  1. composerϓϥάΠϯΛ
 ࡞ͬͯΈΑ͏ PHPΧϯϑΝϨϯε2016 τϥοΫ1

  2. ࣗݾ঺հ • த໺ ୓ (@Hiraku) • https://github.com/hirak • ීஈ͸ϝϧΧϦͰαʔόʔαΠυΤϯδχΞ
 ΍ͬͯ·͢

    • झຯ͸ComposerΛ଎͘͢Δ͜ͱ
  3. hirak/prestissimo • ͱ͍͏ComposerϓϥάΠϯΛ࡞͍ͬͯ·͢ • githubͰ2000starήοτ͠·ͨ͠

  4. Composerͱ͸Կ͔ʁ

  5. None
  6. Composerͱ͸ • PHPϥΠϒϥϦͷґଘؔ܎ղܾπʔϧ • 2011ࠒʹ։ൃελʔτ / PHP5.3Ҏ߱ʹରԠ • autoloaderͷࣗಈੜ੒ •

    ଟ༷ͳϦϙδτϦܗࣜʹରԠ • ϓϥάΠϯػߏ • https://getcomposer.org/
  7. ࢖͍͸͡ΊΔͷ͸؆୯ https://getcomposer.org/download/ pharϑΝΠϧΛҰݸμ΢ϯϩʔυ͢Δ͚ͩɻ
 installerܦ༝Λਪ঑ʢϋογϡ஋ͷݕূʣ $ curl -sL https://getcomposer.org/installer | php

    (実態はこんな感じ) $ curl -O composer https://getcomposer.org/download/1.1.3/composer.phar
  8. $ composer ______ / ____/___ ____ ___ ____ ____ ________

    _____ / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/ Composer version 1.1.2 2016-05-31 19:48:11 Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question --profile Display timing and memory usage information --no-plugins Whether to disable plugins. -d, --working-dir=WORKING-DIR If specified, use the given directory as working directory. -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
  9. Α͘࢖͏αϒίϚϯυ 対話形式でプロジェクトをセットアップ $ composer init ライブラリの追加 $ composer require 'vendor/package'

    ライブラリのアップデート $ composer update composer.jsonに従ってまとめてインストール $ composer install
  10. શͯΛϩʔΧϧʹΠϯετʔϧ • ./composer.json • ඞཁͳϥΠϒϥϦΛఆٛ • ޙ͸ composer install •

    ./vendor/ ʹϥΠϒϥϦͱ autoload.php ͕ ഑ஔ͞ΕΔ
  11. ࠷ۙͷComposer • 4/5ʹॳͷstable൛1.0.0ϦϦʔε
 (ຊൃද࣌఺ͷ࠷৽͸ 1.2.1) • pathϦϙδτϦͷରԠڧԽ • ϓϥάΠϯͰαϒίϚϯυੜ΍ͤΔΑ͏ʹ •

    ࡞ऀͷJordi Boggiano͕7݄ʹདྷ೔
  12. None
  13. None
  14. ࣭໰ʮPHPҎ֎ͷݴޠͰComposer Λ࣮૷͢ΔΞΠσΞ͸Ͳ͏ࢥ͏ʁʯ • ࠓͷComposer͸͋·Γ଎͘ͳ͍ • ྫ͑͹ฒྻॲཧʹڧ͍ݴޠͰ࣮૷͢Ε͹΋ͬ ͱߴ଎ʹͰ͖ΔͷͰ͸…

  15. @seldaek PHPͰॻ͍ͯ͋Δ͔Βͦ͜ɺ
 PHPͰ֦ுͰ͖ΔΑ͏ʹͳͬͯΔ

  16. ComposerΛ֦ு͢Δɺͱ͸

  17. ֦ுͯ͠Ͱ͖Δ͜ͱ • composerίϚϯυͷલޙͰ೚ҙͷॲཧΛ࣮ߦ
 (ΠϕϯτϑοΫܕ) • αϒίϚϯυΛComposerʹੜ΍͢
 (αϒίϚϯυܕ)

  18. ComposerϓϥάΠϯͰͷྫ

  19. None
  20. $ composer global require hirak/prestissimo

  21. hirak/prestissimo (੿࡞) • ΠϕϯτϑοΫܕ • composerຊମͷμ΢ϯϩʔυʹׂΓࠐΜͰɺ ઌʹฒྻμ΢ϯϩʔυ͢Δ͜ͱͰinstallίϚϯ υΛߴ଎Խ • ͦͷଞ͸طଘίϚϯυʹӨڹΛ༩͑ͳ͍

  22. ͲΕ͙Β͍଎͘ͳΔͷ͔ • ύοέʔδͱωοτϫʔΫ؀ڥʹΑΔͷͰҰ ֓ʹݴ͑ͳ͍ • LaravelϓϩδΣΫτͷ৽ن࡞੒ͩͱɺ • 269.36sec → 24.32sec

    • 10ഒҎ্଎͍
  23. None
  24. $ composer global require fxp/composer-asset-plugin

  25. fxp/composer-asset-plugin • ΠϕϯτϑοΫܕ • composer.jsonʹbower΍npmͷύοέʔδ Λॻ͍ͯɺcomposerଆͰΠϯετʔϧͰ͖Δ Α͏ʹ͢Δ • ΁ɺมଶͩʔʔʔʂʂʂʢ๙Ίݴ༿ʣ

  26. composer.json͕͜͏ͳΔ "require": { "fxp/composer-asset-plugin": "^1.2", "npm-asset/jquery": "2.2.0", "npm-asset/bootstrap": "3.3.7" }

    • npm-asset/xxxx͸packagistʹొ࿥͞Ε͍ͯͳ͍ɻ
 npmΛΫϩʔϧͯ͠औͬͯ͘Δ • vendor/npm-asset ΍ vendor/bower-asset ΁഑ஔ͞ΕΔ • node.jsͳ͠Ͱasset؅ཧ͕Ͱ͖ͯศརʂ
  27. None
  28. $ composer global require webysther/composer- plugin-qa

  29. webysther/composer-plugin-qa • αϒίϚϯυܕ • vendor/bin/XXXXͳ։ൃ༻ίϚϯυΛ composerͷαϒίϚϯυͰ࣮ߦͰ͖ΔΑ͏ʹ ͢Δ

  30. vendor/bin/phpunit
 ͬͯଧͭͷμα͍໰୊ • phpunit͸ϩʔΧϧΠϯετʔϧ͢Δ΂͖ • ͔͠͠PATH͕௨ͬͯͳ࣮ͯ͘ߦ͕໘౗ • composerͷαϒίϚϯυܦ༝Ͱݺ΂Δͱศར • composer

    qa:test Ͱphpunit͕࣮ߦ͞Εͯ
 ศར
  31. ༗໊ͳͷ΄ͱΜͲೖͬͯΔ

  32. ͳͥɺComposerΛ
 ֦ு࣮ͯ͠ݱ͢Δͷ͔ʁ

  33. composer͕஌͍ͬͯΔ΋ͷ • ϓϩδΣΫτͷϝλ৘ใ • Ͳ͜ʹͲͷΫϥεϑΝΠϧ͕͋Δ͔ • ϓϩδΣΫτຊମͷιʔείʔυΛࣗ༝ʹݺ ͼग़ͤΔ

  34. composer͕͍࣋ͬͯΔ΋ͷ • symfony/console΍symfony/finderͳͲͷఆ൪ ίϚϯυϥΠϯϥΠϒϥϦΛ࠷ॳ͔Βಉࠝ • ѹ౗తͳϢʔβʔ਺ʹཪଧͪ͞ΕͨҠ২ੑ • ͍ͭͰʹɺϓϥάΠϯͷܗʹ͓͚ͯ͠͹഑෍΋ ָ͍͢͝

  35. (prestissimo͸ϓϥάΠϯͱ ͯ͠͸अಓͳྫ)

  36. ϓϥάΠϯҎલͷ֦ுํ๏

  37. scriptsͱ͸ • composer.jsonʹscriptsͱ͍͏ϓϩύςΟΛ࡞Δ • ೚ҙͷεΫϦϓτΛ࣮ߦͰ͖Δ • ΠϕϯτϑοΫͰࣗಈ࣮ߦ / खಈ࣮ߦ •

    ରԠ͢ΔΠϕϯτ͕ͳ͚Ε͹ɺcomposerͷαϒίϚϯυ ʹͳΔ • https://getcomposer.org/doc/articles/scripts.md
  38. ͍͍ͩͨ͜Μͳײ͡ { "scripts": { "test": "phpunit", "postinstall": "rm -rf ./cache",

    "migrate": "App\Db\Migration::run" } } WFOEPSCJOʹ1"5) ͕௨ͬͯΔͷͰݺ΂Δ γΣϧεΫϦϓτͰ΋ 0, BVUPMPBE͕௨ͬͯΕ͹1)1ͷ TUBUJDϝιουͰ΋ॻ͚Δ
  39. ݺͼग़͠ $ composer test $ composer migrate $ composer install

    # postinstallが自動発動 $ composer run postinstall # 明示発動
  40. scriptsͩͱਏ͍ͱ͜Ζ • ଞͷcomposerϓϩδΣΫτͰ΋࢖͍·Θͨ͠ ͍ͳΒɺcomposer.jsonΛίϐϖ͢Δ͔͠ͳ͍ • ϓϥάΠϯԽ͓ͯ͘͠ͱɺrequire͢Δ͚ͩͰ ࢖͍·ΘͤΔΑ͏ʹͳΔ

  41. ComposerϓϥάΠϯ ύοέʔδԽͨ͠scripts ʹ

  42. ComposerϓϥάΠϯΛ࡞Δ

  43. ComposerϓϥάΠϯͷ࡞Γํ • https://getcomposer.org/doc/articles/ plugins.md • ͪΐͬͱ࡞๏͕͋Δ͚ͩͰɺ࡞Δ΋ͷ͸ී௨ ͷcomposerϥΠϒϥϦͱಉ͡

  44. ༻ҙ͢Δ΋ͷ • composer.pharͱͦΕ͕ಈ͘؀ڥ • composerͷιʔείʔυ • ͖͋ΒΊͳ͍৺ʢॏཁʣ

  45. େମͷྲྀΕ ࡞Ζ͏ͱ͍ͯ͠Δ QMVHJOύοέʔδ ࣮ݧ୆ͷ DPNQPTFSύοέʔδ ιʔείʔυ൛ DPNQPTFS pathͰrequireͤ͞Δ ࣮ࡍʹૢ࡞
 ͯ͠ಈ࡞֬ೝ

    ಈ͔ͳ͔ͬͨΒ
 मਖ਼
  46. େମͷྲྀΕ ࡞Ζ͏ͱ͍ͯ͠Δ QMVHJOύοέʔδ ࣮ݧ୆ͷ DPNQPTFSύοέʔδ ιʔείʔυ൛ DPNQPTFS pathͰrequireͤ͞Δ ࣮ࡍʹૢ࡞
 ͯ͠ಈ࡞֬ೝ

    ಈ͔ͳ͔ͬͨΒ
 मਖ਼
  47. ιʔείʔυ൛composer
 ͷεεϝ • ޷͖ͳ͚ͩvar_dumpσόοάͰ͖Δ • ελοΫτϨʔε΋ಡΈ΍͘͢ͳΔ • ࠷ޙ͸ιʔείʔυΛಡ·͟ΔΛಘͳ͍෦෼ ͕ଟ͍

  48. ιʔείʔυͷ··composer Λಈ͔͢ $ git clone git://github.com/composer/composer.git $ cd composer $

    php path/to/composer.phar install --no-dev $ bin/composer --version Composer version @package_branch_alias_version@ (@package_version@) @release_date@
  49. ιʔείʔυͷ··composer Λಈ͔͢ $ git clone git://github.com/composer/composer.git $ cd composer $

    php path/to/composer.phar install --no-dev $ bin/composer --version Composer version @package_branch_alias_version@ (@package_version@) @release_date@
  50. composer.pharΛϏϧυ͢Δʹ͸ composer.phar͕ඞཁ • ʮ෰Λങ͍ʹߦ͘෰͕ͳ͍ʯΈ͍ͨͳ
 ηϧϑϗεςΟϯάঢ়ଶ • ڀۃͷυοάϑʔσΟϯάମ੍

  51. େମͷྲྀΕ ࡞Ζ͏ͱ͍ͯ͠Δ QMVHJOύοέʔδ ࣮ݧ୆ͷ DPNQPTFSύοέʔδ ιʔείʔυ൛ DPNQPTFS pathͰrequireͤ͞Δ ࣮ࡍʹૢ࡞
 ͯ͠ಈ࡞֬ೝ

    ಈ͔ͳ͔ͬͨΒ
 मਖ਼
  52. ϓϥάΠϯͷcomposerϓϩ δΣΫτΛ࡞Δ • $ composer init • type Λ composer-plugin

    ʹ͢Δ • require ʹ composer-plugin-api ΛೖΕΔɻ࠷৽൛^1.0Ͱྑ͍ • Ϣχοτςετ΋ॻ͖͍ͨͳΒɺrequire-devʹ"composer/ composer"ΛՃ͑Δ • extra.classʹىಈΫϥε໊Λొ࿥
  53. composer.jsonͷྫ { "name": "my/plugin-package", "type": "composer-plugin", "require": { "composer-plugin-api": "^1.0"

    }, "require-dev": { "composer/composer": "1.2.0", "phpunit/phpunit": "^5.3" }, "autoload": { "psr-4": {"My\\": "src/"} }, "extra": { "class": "My\\Plugin" } }
  54. େମͷྲྀΕ ࡞Ζ͏ͱ͍ͯ͠Δ QMVHJOύοέʔδ ࣮ݧ୆ͷ DPNQPTFSύοέʔδ ιʔείʔυ൛ DPNQPTFS pathͰrequireͤ͞Δ ࣮ࡍʹૢ࡞
 ͯ͠ಈ࡞֬ೝ

    ಈ͔ͳ͔ͬͨΒ
 मਖ਼
  55. ࣮ݧ୆ͷcomposerϓϩδΣΫ τΛ࡞Δ • ద౰ͳύεͰcomposer init͢Δ • த਎͸ۭͬΆͰ΋ϑϨʔϜϫʔΫΠϯετʔ ϧঢ়ଶͰ΋ͳΜͰ΋ྑ͍ • ϓϥάΠϯΛ࣮ࡍʹ࢖͏৔໘Λ૝ఆ

  56. pathͰpluginΛrequire͢Δ { "name": "my/somepj", "type": "library", "repositories": [ { "type":

    "path", "url": "../plugin-package" } ], "require": { "my/plugin-package": "@dev" } }
  57. pathϦϙδτϦͷಛੑ • ͨͩͷγϯϘϦοΫϦϯΫΛுΔ͚ͩ • ͳͷͰߋ৽͕ϦΞϧλΠϜʹ൓ө͞ΕΔ • όʔδϣϯ؅ཧ͸ແཧͳͷͰ"@dev"Λࢦఆ

  58. ޙ͸ͻͨ͢Βࢼߦࡨޡ

  59. <?php namespace My; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; class

    Plugin implements PluginInterface { private $composer; private $io; public function activate(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; } } جຊܕ
  60. <?php namespace My; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; use

    Composer\EventDispatcher\EventSubscriberInterface; use Composer\EventDispatcher\Event; class Plugin implements PluginInterface, EventSubscriberInterface { private $composer; private $io; public function activate(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; } public static function getSubscribedEvents() { return array( 'post-autoload-dump' => 'onPostAutoloadDump', ); } public function onPostAutoloadDump(Event $ev) { $this->io->write('onPostAutoloadDump'); } } Πϕϯτϋϯυϥܕ ΠϯλʔϑΣʔεΛҰͭ௥Ճ ϑοΫ͢ΔΠϕϯτΛྻڍ ࣮ߦ͞ΕΔॲཧͷຊମ
  61. <?php namespace My; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Plugin\PluginInterface; use

    Composer\Plugin\Capable; class Plugin implements PluginInterface, Capable { private $composer; private $info; public function activate(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; } public function getCapabilities() { return array( 'Composer\Plugin\Capability\CommandProvider' => 'My\Commands', ); } } αϒίϚϯυܕ ΠϯλʔϑΣʔεΛҰͭ௥Ճ $PNNBOEҰཡΛ
 ද͢ΫϥεΛઃఆ
  62. <?php namespace My; use Composer\Plugin\Capability\CommandProvider; class Commands implements CommandProvider {

    public function getCommands() { return array( new HelloCommand ); } } αϒίϚϯυܕ(2) ഑ྻͰίϚϯυΛ
 ྻڍ
  63. <?php namespace My; use Composer\Command\BaseCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class

    HelloCommand extends BaseCommand { protected function configure() { $this->setName('hello'); } protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln('Hello, world!!'); } } αϒίϚϯυܕ(3) TZNGPOZDPOTPMF ͷίϚϯυΛ࡞Δͷͱ ͍͍ͩͨಉ͡
  64. ͓֮͑ͯ͘ͱྑ͍΋ͷ • ϓϥάΠϯ͸ComposerຊମͱಉҰϓϩηεͰಈ࡞ • ෇ਵ͢ΔϥΠϒϥϦ࢖͍์୊ • symfony/console, finder, json-schema... •

    require͠ͳͯ͘Α͍ • composer.jsonͩͬͯಡΊΔͧ
  65. ϓϥάΠϯ։ൃͷ όουϊ΢ϋ΢

  66. None
  67. ʊਓਓਓਓਓਓʊ ʼɹҙຯෆ໌ɹʻ ʉY^Y^Y^Y^Yʉ

  68. Τϥʔ͕ҙຯෆ໌ • composer͸ඪ४ͷΤϥʔϋϯυϥ͕๫ྗత • E_NOTICE/E_DEPRECATEDͳͲͷΤϥʔ͕શ ͯϒϥοΫϗʔϧͷΑ͏ʹٵ͍ࠐ·Εɺ ErrorExceptionʹม׵͞ΕΔ • ελοΫτϨʔε͘ΕΑʂʂ

  69. ։ൃத͚ͩॻ͖׵͑ͯ͠·͑ src/Composer/Util/ErrorHandler.php //... public static function register(IOInterface $io = null)

    { // set_error_handler(array(__CLASS__, 'handle')); error_reporting(E_ALL | E_STRICT); self::$io = $io; }
  70. None
  71. Τϥʔͷى͖ͨߦ͕
 Θ͔Δ…ʂʂ

  72. ༨ஊͰ͚͢Ͳ • set_error_handler(...); ͢Δͱ͖͸ୈೋҾ਺ࢦ ఆ͠·͠ΐ͏Ͷ • શΤϥʔΛϒϥοΫϗʔϧͷΑ͏ʹٵ͍ࠐΉ ͷ͸ catch (\Exception

    $e) ͱಉ͡…ʂ • Pokémon Catching (CATCH 'EM ALL)
  73. ͋ͱ͸ࠔͬͨΒ • ιʔεΛಡΉ • composerଆʹvar_dumpΔ • ଞͷϓϥάΠϯΛpackagistͰ୳ͯ͠ιʔεΛಡΉ • σόοΨͰݟΔ
 (cliπʔϧͳͷͰphpdbg͕࢖͍΍͍͢)

  74. (͜͜·Ͱલஔ͖)

  75. ͦΖͦΖ ຊ୊

  76. ๯಄ͷεϥΠυΛ ͍֮͑ͯ·͔͢ʁ

  77. Composerͱ͸Կ͔ʁ

  78. ϥΠϒϥϦͷ
 ґଘؔ܎ղܾπʔϧ

  79. ͦΕ͚ͩʁ • ϓϥάΠϯΛݟΔͱɺଞʹ΋৭ʑͰ͖Δ͜ͱ͕Θ͔Δ • CLIπʔϧͷϑϨʔϜϫʔΫͰ΋͋Δ • λεΫϥϯφʔʹ΋ͳΔ • ։ൃπʔϧʹ΋ɺؤுΕ͹σϓϩΠπʔϧʹ΋ •

    ͜Ε͸ҰମԿͩʁ
  80. ϥΠϒϥϦͷ
 ґଘؔ܎ղܾπʔϧ

  81. ComposerͷӅΕͨ໾ׂ • ϥΠϒϥϦΛ؅ཧ͢ΔͨΊʹ͸ʮϥΠϒϥϦʯ ͱ͸Կ͔Λఆٛ͠ͳͯ͘͸ͳΒͳ͔ͬͨ • ͦΕ͕Composer༻ޠͰݴ͏ͱ͜Ζͷ
 ύοέʔδ

  82. ຊ౰͸ Composerͱ͸Կ͔ʁ

  83. ύοέʔδΛ࡞ΔͨΊͷ ϑϨʔϜϫʔΫ

  84. PHPʹ͓͚ΔϓϩάϥϜͷ୯Ґ 1. 1ຕͷεΫϦϓτ 2. require ʹΑΔϑΝΠϧ෼ׂ 3. ؔ਺ / ΫϥεԽ

    4. ύοέʔδ 5. αʔϏε (Microservices) 8FCΞϓϦέʔγϣϯ
 ϑϨʔϜϫʔΫͷର৅ $PNQPTFS͸͜͜ʹ
 ఆٛΛ༩͑ͨ
  85. ͲΜͳෳࡶͳιϑτ΢ΣΞ΋ɺ ύοέʔδͷ֓೦ʹམͱ͠ࠐΊΔ ϝλ QBDLBHF ΂ΜΓ QBDLBHF QBDLBHF ΦϨΦϨ QBDLBHF ద౰

    QBDLBHF ࡶڕ QBDLBHF ࠷ߴ QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF QBDLBHF
  86. զʑ͸ԿΛ࡞͍ͬͯͨͷ͔ • ύοέʔδΛ࡞͍ͬͯͨ • Composer͸ԿͰ΋ύοέʔδͱΈͳ͢ • ʮPHPͰԿ͔Λ࡞Δʯ
 ʮComposerύοέʔδΛ࡞Δʯ
 ͍͍ͩͨಉ͡ҙຯ

  87. ͍·΍ Composerͱ͸Կ͔ʁ

  88. ϓϩδΣΫτͷશͯΛ
 ঠѲ͢Δଘࡏ

  89. ʊਓਓਓਓਓਓਓਓʊ ʼɹcomposer.jsonɹʻ ʉY^Y^Y^Y^Y^Y^Yʉ

  90. ൴͸ͳΜͰ΋஌͍ͬͯΔ • ύοέʔδ͕ԿͰͲ͏͍͏໾ׂͳͷ͔ • ඞཁͱ͍ͯ͠ΔϥΠϒϥϦ • ϓϩάϥϜͷىಈํ๏

  91. ͡Ό͋ɺComposerʹدͤΑ͏

  92. ϓϩδΣΫτΛ೺Ѳ্ͨ͠Ͱ
 ಈ࡞͢Δπʔϧ • ComposerϓϥάΠϯܗࣜͳΒ࣮ݱ͠΍͍͢ • ࠓޙɺWebΞϓϦέʔγϣϯϑϨʔϜϫʔΫ ΍։ൃπʔϧ΋ɺcomposerϓϥάΠϯͷܗࣜ ͕૿͑Δ͔΋ɻ

  93. ·ͱΊ • Composer͸ύοέʔδͷϑϨʔϜϫʔΫͩ • composer.jsonʹ৘ใΛू໿͠ɺશͯཧղ͞ ͤɺͦͷ্Ͱ։ൃ͢Δ • ·ͣ͸scriptsΛ࡞ͬͯΈͯʂ • ͦͷ্ͰϓϥάΠϯԽͯ͠ΈΔͱ͍͍Α