Slide 1

Slide 1 text

զ͕Ոͷ XFCϑϩϯτΤϯυ։ൃɾϏϧυ؀ڥͷวྺ - The itinerant history of our web frontend dev & build environment - /BPLJ:"."%" !XBLBNTIB 8F"SF+BWB4DSJQUFST!UI

Slide 2

Slide 2 text

Introduction w XBLBNTIB͕͜Ε·Ͱ࢖༻͖ͯͨ͠XFCϑϩϯτΤϯυ։ൃʹ͓͚Δ Ϗϧυ؀ڥͷวྺΛ͝঺հ w ͦΕͧΕͷ֓ཁ΍Ϣʔεέʔε͸໪࿦ɺͳͥͦΕΛ࢖͏ͷΛ΍Ίͨͷ͔ ʹ͍ͭͯ΋ݴٴ

Slide 3

Slide 3 text

OPX

Slide 4

Slide 4 text

Build static websites with an easy-to-use framework - 2013.early ~ 2014.early - Middleman

Slide 5

Slide 5 text

Middleman 3VCZ੡ͷʰ੩తXFCαΠτδΣωϨʔλʱ 4JOBUSBͱ͍͏3VCZ੡%4-ʹґଘ 3VCZ 4JOBUSB

Slide 6

Slide 6 text

Middleman ֦ுϝλݴޠͱͯ͠)BNM4$44 4BTT $P⒎FF4DSJQU͕ ࠷ॳ͔Β࢖༻Մೳ

Slide 7

Slide 7 text

Middleman 3VCZ(FNTʹͯ഑෍͞Ε͍ͯΔͨΊ ίϚϯυϥΠϯͻͱͭͰΠϯετʔϧ׬ྃ $ gem install middleman $ middleman init my-project $ middleman server $ middleman build

Slide 8

Slide 8 text

$ gem install middleman $ middleman init my-project $ middleman server $ middleman build w ๛෋ͳϔϧύʔϝιου w 3BJMTͱಉ͡΋ͷ͕΄΅࢖༻Մೳ w ࠷ॳ͔ΒϏϧυ؀ڥ͕׬੒͍ͯ͠ΔͷͰ௒ઈ͓खܰ w ֤छϝλݴޠͷίϯύΠϧ w -JWF3FMPBE w "TTFU1JQFMJOF +4 $44ͷ݁߹ϛχϑΝΠԽ w FUDʜ

Slide 9

Slide 9 text

w ϓϩμΫτͷXFCϑϩϯτΤϯυ։ൃͱ͍͏ΑΓ͸ ϓϩτλΠϐϯά؀ڥͱͯ͠׆༻ w 6*ݕূͷͨΊͷϞοΫΞοϓ w σϞ༻ w ͜Ε͕͔͋ͬͨΒࠓ೔ͷࣗ෼͕͍Δͱݴͬͯ΋աݴͰ ͸ͳ͍ w "MU+4 "MU$44ͰίʔσΟϯά͠ɺϩʔΧϧαʔόͰಈ࡞֬ೝ͢Δ ͱ͍͏։ൃϑϩʔΛҰ௨Γମײ͢Δ͜ͱ͕ग़དྷͨ 6TFDBTF

Slide 10

Slide 10 text

w 5ZQF4DSJQUΛϝΠϯͰ࢖͍ͨ͘ͳͬͨ w .JEEMFNBOͷΤίγεςϜ಺Ͱ͸54ΛίϯύΠϧग़དྷͳ͍ w (SVOU্Ͱ54ίϯύΠϧ.JEEMFNBO࣮ߦ͢Δ؀ڥΛߏங w ྑ͘΋ѱ͘΋ग़དྷΔ͜ͱ͕ܾ·͍ͬͯΔͨΊɺ͔ͦ͜Β͸Έग़͠ ͨ͜ͱΛ͠Α͏ͱ͢Δͱ్୺ʹϋοΫ·͕͍ͷ͜ͱΛ͢Δඞཁ͕ ͋Δ ଔۀͷ͖͔͚ͬ

Slide 11

Slide 11 text

OPX

Slide 12

Slide 12 text

The JavaScript Task Runner - 2014.early ~ 2015.early - Grunt

Slide 13

Slide 13 text

Grunt +BWB4DSJQU੡ͷλεΫϥϯφʔ /PEFKT্Ͱಈ͘ XFCϑϩϯτΤϯυք۾ͰλεΫϥϯφʔ͕ຊ֨తʹ࢖ΘΕ͸͡ΊΔ͖͔͚ͬͱͳͬͨ

Slide 14

Slide 14 text

w ϓϥάΠϯ /PEFϞδϡʔϧ ͕๛෋ w ͦΕΒΛ૊Έ߹Θͤͯཁ݅ʹదͨ͠Ϗϧυ؀ڥΛߏங w ֤छϝλݴޠ 5ZQF4DSJQU4$44+BEFʜ ͷίϯύΠϧ w ϩʔΧϧαʔόͷىಈ w -JWF3FMPBE w +4 $44ͷ݁߹ϛχϑΝΠԽ w FUDʜ w gruntfile.jsʹϋογϡܗࣜͰλεΫΛఆٛ w ˞$P⒎FF4DSJQUͰ΋هड़Մೳ

Slide 15

Slide 15 text

w খن໛ͳαʔόʔϨεΞϓϦέʔγϣϯͷ։ൃ؀ڥ w 8PSE1SFTTͷςʔϚ։ൃ w +BWB4DSJQU͸5ZQF4DSJQU $44͸4$44Ͱهड़ͨ͠ͷΛϏϧυ 6TFDBTF

Slide 16

Slide 16 text

w λεΫͷॻ͖΍͢͞Մಡੑ͕ΠϚΠν w άάͬͯݟ͚ͭͨίʔυΛίϐϖ͚ͨͩ͠Ͱಈ͍ͨ͜ͱ͕Ұ౓΋ ͳ͘ɺԿ͔͠Βͷख௚͕͠ඞཁͩͬͨ w ಉ͡໨తͰ΋ఆٛͷهड़͕݁ߏόϥ͍͍ͭͯΔ w ࢖͍͜ͳ͢લʹ(VMQʹڵຯ͕Ҡͬͨ ଔۀͷ͖͔͚ͬ

Slide 17

Slide 17 text

OPX

Slide 18

Slide 18 text

Automate and enhance your workflow - 2015.early ~ 2016.mid - Gulp

Slide 19

Slide 19 text

Gulp /PEFKTͷ4USFBN"1* ΠϕϯτετϦʔϜ Λ޼Έʹར༻ͨ͠λεΫϥϯφʔ ΤϯδχΞք۾͚ͩͰͳ͘ɺσβΠφʔք۾Ͱ΋࢖ΘΕΔ͘Β͍ʹ·Ͱීٴ͍ͯ͠Δ

Slide 20

Slide 20 text

w νΣʔϯϝιου෩ʹλεΫΛఆٛ w <ίϯύΠϧ><݁߹><ϛχϑΝΠ>ͷΑ͏ͳಉظతॲཧΛՄಡ ੑߴ͘ఆٛͰ͖Δ w ॲཧͷྲྀΕ͕௥͍΍͍͢ w (SVOUΑΓ΋هड़ʹ౷Ұײ͕͋Δ w ฒྻॲཧ͕ݪଇ w λεΫͷ࣮ߦ଎౓͕଎͍ w ˞(SVOU͸Ұͭͣͭॱ൪ʹॲཧ͢Δ

Slide 21

Slide 21 text

w େن໛41"։ൃҊ݅ͷϑϩϯτΤϯυ։ൃج൫ w 5ZQF4DSJQU4$44+BEF 1VH ͷίϯύΠϧ w ϓϩμΫγϣϯίʔυͱґଘϥΠϒϥϦͱͷ݁߹ w ϩʔΧϧαʔόͷىಈͱXBUDI -JWF3FMPBE w Ϗϧυ؀ڥͷຊ֨తͳߏஙϊ΢ϋ΢ͷଟ͘Λ͜ͷஈ֊ Ͱशಘ w /PEFKTͷ֓ཁ΋͜ͷࠒʹֶΜͩ ˞ͦ͜·Ͱਂ͘͸ཧղͯ͠ͳ͍ 6TFDBTF

Slide 22

Slide 22 text

Browserify lets you require ( ‘modules’ ) in the browser by bundling up all of your dependencies - 2016.mid ~ 2016.later - Use Browserify

Slide 23

Slide 23 text

w +BWB4DSJQUϑϨʔϜϫʔΫΛ࡮৽ w "OHVMBS΍$ZDMFKTͱ͍ͬͨΑΓϞμϯͳ'8Λݕূ w ˞࠷ऴతʹ$ZDMFKTΛ࠾༻ w CSPXTFSJGZΛಋೖ w +4ͷϞδϡʔϧؒͷґଘղܾ΍ϑΝΠϧ݁߹ͷͨΊʹඞཁ w Ϗϧυ࣌ؒ୹ॖͷͨΊʹXBUDIJGZ΋ซͤͯಋೖ ࠩ෼ίϯύΠϧ

Slide 24

Slide 24 text

w CSPXTFSJGZΛ(VMQͷ4USFBN"1*Ͱ࢖͏ϝϦοτ͕ খ͍͞ͱ൑அ w WJOZMTPVSDFTUSFBNͰϥοϓͯ͠ແཧ΍Γ4USFBN"1*্ʹ৐ͤ ͯ͋͛Δඞཁ͕͋Δ w ϏϧυͷͨΊʹґଘ͢Δ/PEFϞδϡʔϧΛݮΒ͍ͨ͠ w (VMQ্Ͱಈ͔͢Ҏ্ɺ֤छίϯύΠϥͷ(VMQϥούʔ͕ඞཁ w όʔδϣϯ61ͨ͠Βಈ͔ͳ͘ͳͬͨͱ͍͏ϦεΫ͕૿͑Δ w ˞࣮ࡍʹԿ౓͔ಈ͔ͳ͘ͳΔ͜ͱ͕͋ͬͨ ଔۀͷ͖͔͚ͬ

Slide 25

Slide 25 text

OPX

Slide 26

Slide 26 text

npm scripts the “scripts” property of the package.json script, for following scripts - 2017.early ~ Now - npm-scripts

Slide 27

Slide 27 text

npm-scripts λεΫϥϯφʔͱ͍͏ΑΓ͸TIFMMTDSJQUͷΤΠϦΞείϚϯυ iTerm my-project > npm run build > my-project@1.0.0 watch /path/to/your/project/my-project > node ./bin/build.js ⋮

Slide 28

Slide 28 text

iTerm my-project > npm run build > my-project@1.0.0 watch /path/to/your/project/my-project > node ./bin/build.js ⋮ w λεΫࣗମ͸TIϑΝΠϧ΍KTϑΝΠϧʹఆٛ w OQNTDSJQUT͸ͦΕΒΛ࣮ߦ͢Δ͚ͩ w .shͳΒbash task.sh w jsͳΒnode task.js w $JSDMF$*ͷcircle.ymlΈ͍ͨͳΠϝʔδ w (VMQ΄ͲෳࡶͳλεΫͷఆٛʹ͸޲͔ͳ͍͕ɺ͋Δ ఔ౓͸͜Ε͚ͩͰॆ෼ΧόʔՄೳ

Slide 29

Slide 29 text

iTerm my-project > npm run build > my-project@1.0.0 watch /path/to/your/project/my-project > node ./bin/build.js ⋮ w /PEFϞδϡʔϧؒͷґଘ͕ܹݮ w (VMQ༻ͷϥούʔϞδϡʔϧ͕ෆཁ w ΞοϓσʔτʹΑΔյ໓ͱ͍͏ϦεΫ͕ܹݮ w ࣮ߦ଎౓͕ܶతʹ޲্

Slide 30

Slide 30 text

my-project > npm run build > my-project@1.0.0 watch /path/to/your/project/my-project > node ./bin/build.js ⋮ iTerm w ݱߦͷ41"։ൃͷͨΊͷج൫ w 5ZQF4DSJQU4UZMVT1VHͷίϯύΠϧ w CSPXTFSJGZͰ+4Ϟδϡʔϧͷґଘؔ܎ΛղܾϑΝΠϧ݁߹ w ϑϩϯτΤϯυɾΤίγεςϜͷਐԽʹ൐ͬͯλεΫ ఆ͕ٛ؆ུԽ w +4ϑϨʔϜϫʔΫ͕ద੾ʹϞδϡʔϧԽ͞Ε͍ͯΔ w #PXFSΛ࢖Θͣͱ΋ຆͲͷ+4ϥΠϒϥϦ͕OQNܦ༝ͰΠϯε τʔϧͰ͖ΔΑ͏ʹͳͬͨ 6TFDBTF

Slide 31

Slide 31 text

{ "name": “my-project", "version": "1.0.0", "main": "index.js", "scripts": { "build": “node ./bin/build.js” }, "dependencies": { "@cycle/dom": "^17.3.0", "@cycle/run": "^3.1.0", "@cycle/rxjs-run": “^7.0.0", "ramda": "^0.24.1", "rxjs": "^5.4.0", "xstream": "^10.8.0" }, "devDependencies": { "browser-sync": "^2.18.11", "browserify": "^14.3.0", "connect-modrewrite": "^0.10.1", "pug": "^2.0.0-rc.1", "pug-cli": "^1.0.0-alpha6", "stylus": "^0.54.5", "tsify": "^3.0.1", "typescript": "^2.3.2", "watchify": "^3.9.0" } } package.json

Slide 32

Slide 32 text

{ "name": “my-project", "version": "1.0.0", "main": "index.js", "scripts": { "build": “node ./bin/build.js” }, "dependencies": { "@cycle/dom": "^17.3.0", "@cycle/run": "^3.1.0", "@cycle/rxjs-run": “^7.0.0", "ramda": "^0.24.1", "rxjs": "^5.4.0", "xstream": "^10.8.0" }, "devDependencies": { "browser-sync": "^2.18.11", "browserify": "^14.3.0", "connect-modrewrite": "^0.10.1", "pug": "^2.0.0-rc.1", "pug-cli": "^1.0.0-alpha6", "stylus": "^0.54.5", "tsify": "^3.0.1", "typescript": "^2.3.2", "watchify": "^3.9.0" } } package.json // Compile Pug sources execSync(`pug src/templates -o public -w`); // Compile Stylus sources execSync(`stylus src/styles/style.styl -o public/assets/style.css`); // Compile TypeScript sources let b = browserify({ entries: ['./src/scripts/main.ts'], cache: {}, packageCache: {}, plugin: [watchify], debug: true }) .plugin(tsify); b.on('update', bundle) bundle(); function bundle() { b.bundle().on('error', (err) => { console.log(err.message); }).pipe(fs.createWriteStream('./public/assets/main.js')); } // Run Server browserSync.create().init({ files: ['public'], server: { baseDir: ['public'] }, startPath: '/', reloadDebounce: 500 }); build.js

Slide 33

Slide 33 text

{ "name": “my-project", "version": "1.0.0", "main": "index.js", "scripts": { "build": “node ./bin/build.sh” }, "dependencies": { "@cycle/dom": "^17.3.0", "@cycle/run": "^3.1.0", "@cycle/rxjs-run": “^7.0.0", "ramda": "^0.24.1", "rxjs": "^5.4.0", "xstream": "^10.8.0" }, "devDependencies": { "browser-sync": "^2.18.11", "browserify": "^14.3.0", "connect-modrewrite": "^0.10.1", "pug": "^2.0.0-rc.1", "pug-cli": "^1.0.0-alpha6", "stylus": "^0.54.5", "tsify": "^3.0.1", "typescript": "^2.3.2", "watchify": "^3.9.0" } } package.json #!/usr/bin/env bash # Compile Pug sources nohup pug src/templates -o public -w & pug_pid=$! trap "kill -15 $pug_pid &>/dev/null" 2 15 # Compile Stylus sources nohup stylus src/styles/app.styl -o public/assets -m -w & stylus_pid=$! trap "kill -15 $stylus_pid &>/dev/null" 2 15 # Compile TypeScript sources nohup watchify -d src/scripts/main.ts -p [ tsify ] -o public/assets/ app.js & watchify_pid=$! trap "kill -15 $watchify_pid $>/dev/null" 2 15 # Run Server nohup browser-sync start --config bs-config.js & browserSync_pid=$! trap "kill -15 $browserSync_pid &>/dev/null" 2 15 tail -f nohup.out build.sh

Slide 34

Slide 34 text

OPX w 1SFQBDL w $44.0%6-&4 w FUDʜ ࠓޙ࢖ͬͯΈ͍ͨ΋ͷ

Slide 35

Slide 35 text

*OUSPEVDFNZTFMG Զͷ໊લΛݴͬͯΈΖ ࣗݾ঺հ

Slide 36

Slide 36 text

גࣜձࣾϦΫϧʔτϚʔέςΟϯάύʔτφʔζ XFCϑϩϯτΤϯυΤϯδχΞ ࢁా ௚थ /BPLJ:"."%" *OUSPEVDFNZTFMG !XBLBNTIB

Slide 37

Slide 37 text

https://tech.recruit-mp.co.jp NET BIZ DIV. TECH BLOG

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

https://tech.recruit-mp.co.jp 3.1 ϒϩά

Slide 40

Slide 40 text

5IBOLZPV