JavaScript/CSS 2015 Autumn Koji Ishimoto @IWATE HTML5 COMMUNITY #3 on October 14 © 2015 Kaizen Platform, Inc.
JavaScript/CSS 2015 AutumnKoji Ishimoto @IWATE HTML5 COMMUNITY #3 on October 14
© 2015 Kaizen Platform, Inc.
StyleStatsCSSを解析するWebサービス
http://www.stylestats.org/
Creative NetworkUX optimize Platform
Search
Social
Site Content
Content
Creative
Conversations
+
Display
About KAIZEN PLATFORM
継続的改善のためのワークフローの管理から実際のテストやナレッジ蓄積まで
2000名を超える専門特化された UIデザイナーやコピーライターのネットワーク
Agenda
Agenda
•フロントエンド開発の現状
• JavaScript 2015
• CSS 2015
• Build Toolsとか
•まとめ
Front-end Development
JavaScript Frameworks
JavaScriptフレームワークの寿命 | POSTD半年ごとに”今一番ホットな”フレームワークが新たに登場しては、私たちは興奮に沸き返ります
http://postd.cc/longevity-or-lack-thereof-in-javascript-frameworks/
Angular 1 と Angular 2 の連携シームレスなアップグレードの方法について
http://googledevjp.blogspot.jp/2015/10/angular-1-angular-2.html
次に『何』が来るかなんて誰にもわかりません。あきらめてください!
Languages that compiles to Javascript
CSS Preprocessors
JS Build Tools
なんでこんなにあるんや…安心してください!僕もそう思います!
第4章:フロントエンド技術──Web標準を振り返り新技術の潮流に活かす - 石本光司
このさき生き残る技術とは?
•それは標準技術なのか?
•それはシンプルに問題を解決するのか?
DOM Selectorの移り変わり
// けっこー前 - DOM Level 2 Core var anchors = document.getElementById(‘js-node') .getElementsByTagName('a');
// jQueryさまさま~ var anchors = $('#js-node > a');
// わりと最近 - Selectors API Level 1 var anchors = document.querySelectorAll(‘#js-node > a');
過去を振り返ってみると…
シンプル複雑
標準
独自
シンプル複雑
標準
独自
DOM Level 2 Core
シンプル複雑
標準
独自
DOM Level 2 Core
シンプル複雑
標準
独自
DOM Level 2 CoreSelectors API
Level 1
シンプル複雑
標準
独自
DOM Level 2 CoreSelectors API
Level 1
イケてる新しい標準技術取り込めばいいじゃん!
JavaScript 2015
Ecma InternationalTechnical Committee 39 - ECMAScript
https://github.com/tc39
ECAMAScript Versions
ECAMAScript Versions
ES3
1999
ECAMAScript Versions
ES3
1999
ES4 (Abandoned)
2008
ECAMAScript Versions
ES3
1999
ES4 (Abandoned)
2008
ES5
2009
ECAMAScript Versions
ES3
1999
ES4 (Abandoned)
2008
ES5
2009
ES6
2015
ECMAScript 6 compatibility tableブラウザ別のES 5/6/7の対応状況を確認可能
https://kangax.github.io/compat-table/es6
使えないじゃん!>m<
安心してください!バべりますよ!
Babel The compiler for writing next generation JavaScript
次世代JavaScriptを今使えるようにするトランスパイラ
https://babeljs.io/
Babel transpile ES6 to ES5
ES6 ES5 ES3
昔、Babelは6to5という名前だったが、ES7、JSX等もトランスパイルできるため現在の名前に落ち着いた
.js .js
Languages that compiles to Javascript
ES6
You might not need Babel
Chrome Extensions
v0.12+
.js
Future Browsers
??
アロー関数 Arrows and Lexical This
var add = (x, y) => x + y;
オススメ
var add = function add(x, y) { return x + y; };
ES6
アロー関数 Arrows and Lexical This
var obj = { name: 't32k', sayHello: function (friends) { friends.forEach( friend => { console.log(this.name + ' says hello to ' + friend) }); } };
var obj = { name: 't32k', sayHello: function sayHello(friends) { var _this = this; friends.forEach(function (friend) { console.log(_this.name + ' says hello to ' + friend); }); } };
ES6
オススメ
オブジェクトリテラル拡張 Enhanced Object Literals
var obj = { somethingMethod, hello(message) { console.log(message); }, [ 'a' + 'b' ]: 'c' };
function _defineProperty(obj, key, value){ …(中略)… } var obj = _defineProperty({ somethingMethod: somethingMethod, hello: function hello(message) { console.log(message); } }, 'a' + 'b', 'c');
ES6
オススメ
ブロックスコープ Let + Const
var x = 'var x'; var y = 'var y'; { let x = 'let x'; const y = 'const x'; }
var x = 'var x'; var y = 'var y'; { var _x = 'let x'; var _y = 'const x'; }
ES6
引数と演算子 Default + Rest + Spread
function add(x, y=2) { return x + y; } add(3) == 5
function add(x) { var y = arguments.length <= 1 || arguments[1] === undefined ? 2 : arguments[1]; return x + y; }
ES6
オススメ
引数と演算子 Default + Rest + Spread
function subtract(x, ...y) { return x - y.length; } subtract(10, 't', '3', '2', 'k') == 7
function subtract(x) { for (var _len = arguments.length, y = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { y[_key - 1] = arguments[_key]; } return x - y.length; }
ES6
オススメ
引数と演算子 Default + Rest + Spread
function multiple(x, y, z) { return x * y * z; } multiple(...[1,2,3]) == 6
function multiple(x, y, z) { return x * y * z; } multiple.apply(undefined, [1, 2, 3]) == 6;
ES6
オススメ
分割代入 Destructuring Assignment
var [a, , b] = [1,2,3];
var {name: c, age: d} = {name: 't32k', age: 32};
var _ref = [1, 2, 3]; var a = _ref[0]; var b = _ref[2];
var _name$age = { name: 't32k', age: 32 }; var c = _name$age.name; var d = _name$age.age;
ES6
テンプレート Template Strings
var name = 't32k', age = 'today'; `Hello ${name}. You are ${time} years old.`
var name = 't32k', age = 'today'; "Hello " + name + ".\n You are " + time + " years old.";
ES6
オススメ
クラス Classes
class Rectangle { constructor(height, width) { this.height = height; this.width = width; } getArea() { return this.calcArea() } calcArea() { return this.height * this.width; } }
ES6
function Rectangle (height, width) { this.height = height; this.width = width; }
Rectangle.prototype.getArea = function () { return this.calcArea(); };
Rectangle.prototype.calcArea = function () { return this.height * this.width; };
ES5
クラス Classes
クラス Classes
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Rectangle = (function () { function Rectangle(height, width) { _classCallCheck(this, Rectangle); this.height = height; this.width = width; } _createClass(Rectangle, [{ key: "calcArea", value: function calcArea() { return this.height * this.width; } }, { key: "area", get: function get() { return this.calcArea(); } }]); return Rectangle; })();
プロミス Promises
function asyncTaskN() { return new Promise(); }
asyncTask1().then(result => { return asyncTask2(); }).then(result => { return asyncTask3(); }).catch(error => { });
asyncTask1(function(error, result) { asyncTask2(function(error, result) { asyncTask3(function(error, result) { }); }); });
ES6
ES5
オススメ要: Polyfill
You must include the Babel polyfill
http://babeljs.io/docs/usage/polyfill/
いくつかの機能を利用するには事前にpolyfillをインストールする必要がある
JavaScript Promiseの本Promiseについて学ぶことを目的とした書籍
http://azu.github.io/promises-book/
Map + Set + WeakMap + WeakSet
// Sets var s = new Set(); s.add("hello").add("goodbye").add("hello"); s.size === 2; s.has("hello") === true;
// Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34;
// Weak Maps var wm = new WeakMap(); wm.set(s, { extra: 42 }); wm.size === undefined
// Weak Sets var ws = new WeakSet(); ws.add({ data: 42 });
要: Polyfill
ES6
モジュール Modules
// lib/math.js export function sum(x, y) { return x + y; } export var pi = 3.14;
// app.js import * as math from "lib/math"; alert(math.sum(math.pi, math.pi));
ES6
ES6
モジュール Modules
// lib/math.js Object.defineProperty(exports, "__esModule", { value: true }); exports.sum = sum; function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }
// app.js var _libMath = require("lib/math"); var math = _interopRequireWildcard(_libMath); function sum(x, y) { return x + y; } var pi = 3.14;exports.pi = pi; alert(math.sum(math.pi, math.pi));
babelifyBrowserify transform for Babel
https://github.com/babel/babelify
Babelで始める!モダンJavaScript開発
https://html5experts.jp/kyo_ago/16979/
• Stage 0 - Strawman • es7.comprehensions • es7.classProperties • es7.doExpressions • es7.functionBind
• Stage 1 - Proposal • es7.decorators • es7.exportExtensions • es7.trailingFunctionCommas
• Stage 2 - Draft (Default Stage) • Stage 3 - Candidate • Stage 4 - Finished
The TC39 categorises proposals into 4 stages:
ES 2016, 2017…
2016年以降は、年次で小さな変更をこまめにリリース
ESLint Pluggable JavaScript linter
自分好みのLint設定が可能
http://eslint.org/
•シンプルな文法•バッドパーツの回避
CSS 2015
CSSの世界にもBabelみたいのないの?
安心してください!cssnext がありますよ!
嘘!ごめん!ES6のように固まっていない
CSS Levels
CSS Levels
CSS1
1996
CSS Levels
CSS1
1996
CSS2
1998
CSS Levels
CSS1
1996
CSS2
1998
CSS2.1
2011
CSS Levels
CSS1
1996
CSS3
20xx?
CSS2
1998
CSS2.1
2011
Taking a Modular Approach
CSS2.1以降はモジュール方式のため、モノリシックなCSSとしてのv3は存在しない
CSS Snapshot 20152015年現在、仕様的に安定しているものをまとめたもの
http://momdo.github.io/css-2015/
CSS current work各モジュールの現在のステータスが確認できる
http://www.w3.org/Style/CSS/current-work
•勧告(Recommendation: REC)
•勧告案(Proposed Recommendation: PR)
•勧告候補(Candidate Recommendation: CR)
•最終草案(Last Call Working Draft: LCWD)
•草案(Working Draft: WD)
•編集者草案(Editor’s Draft: ED)
cssnext Use tomorrow's CSS syntax, today. by MoOx
Future Syntaxが使えるPostCSSのプラグインパッケージ
http://cssnext.io/
PostCSS??
PostCSSとcssnextで最新CSS仕様を先取り!
https://html5experts.jp/t32k/17235/
PostCSSとは何か by @jimbo
https://speakerdeck.com/jmblog/postcss-tohahe-ka
PostCSS自体はCSSパーサーで、それによって生成されるAST(抽象構文木)を扱うAPIを提供するのみ。それを利用した数多くのプラグインによってCSSスタイル変更等がされる。
Sassに頼りすぎてないですか?
それcssnextでもできますよ!(たぶん…だいたい...)
cssnext で使える Future Syntax 一覧
custom properties & var()
:root { --brandColor: green; }
strong { color: var(--brandColor); }
LCWD
Spec: Plugin:
See also:
CSS Custom Properties for Cascading Variables Module Level 1postcss/postcss-custom-properties
postcss/postcss-simple-vars
reduced calc()
:root { --fontSize: 1rem; }
h1 { font-size: calc(var(--fontSize) * 2); }
CR
Spec: Plugin:
CSS Values and Units Module Level 3postcss/postcss-calc
See also: MoOx/reduce-css-calc
custom media queries
@custom-media --small-vieport (max-width: 30em); /* media queriesの範囲を分かりやすく指定 */
@media (--small-viewport) { /* small viewport用のスタイルを記述 */ }
FPWD
Spec: Plugin:
Media Queries Level 4postcss/postcss-custom-media
custom selectors
@custom-selector :--button button, .button; @custom-selector :--enter :hover, :focus;
:--button { /* ボタン用のスタイルを記述 */ } :--button:--enter { /* hover/focus状態のボタン用のスタイルを記述 */ }
ED
Spec: Plugin:
CSS Extensionspostcss/postcss-custom-selectors
color
a { color: color(red alpha(-10%)); }
a:hover { color: color(red blackness(80%)); }
ED
• [red( | green( | blue( | alpha( | a(] ['+' | '-']? [<number> | <percentage>] ) • [red( | green( | blue( | alpha( | a(] '*' <percentage> ) • [hue( | h(] ['+' | '-' | '*']? <angle> ) • [saturation( | s(] ['+' | '-' | '*']? <percentage> ) • [lightness( | l(] ['+' | '-' | '*']? <percentage> ) • [whiteness( | w(] ['+' | '-' | '*']? <percentage> )
• [blackness( | b(] ['+' | '-' | '*']? <percentage> ) • tint( <percentage> ) • shade( <percentage> ) • blend( <color> <percentage> [rgb | hsl | hwb]? ) • contrast( <percentage>? )
List of color-adjuster
Spec: Plugin:
CSS Color Module Level 4 - The color() functionpostcss-color-fucntion
hwb()
body { color: hwb(90, 0%, 0%, 0.5); } /* 変換後のCSS */ body { color: rgba(128, 255, 0, 0.5); }
ED
Spec: Plugin:
CSS Color Module Level 4 - HWB Colors: hwb() functionpostcss/postcss-color-hwb
gray()
body { color: gray(255, 50%); } /* 変換後のCSS */ body { color: rgba(255, 255, 255, 0.5); }
ED
Spec: Plugin:
CSS Color Module Level 4 - The gray() functional notationpostcss/postcss-color-gray
#rrggbbaa
body { background: #99DD99CC } /* 変換後のCSS */ body { background: rgba(153, 221, 153, 0.8) }
ED
Spec: Plugin:
CSS Color Module Level 4 - The RGB hexadecimal notationspostcss/postcss-color-hex-alpha
rebeccapurple
body { background: rebeccapurple } /* 変換後のCSS */ body { background: rgb(102, 51, 153) }
ED
Why this plugin?
If you did some CSS, I'm sure you know who Eric Meyer is, & what he did for this language. In memory of Eric Meyer’s daughter, W3C added new color rebeccapurple to CSS 4 Color Module.
Spec: Plugin:
CSS Color Module Level 4 - Named Colorspostcss/postcss-color-rebeccapurple
font-variant
h2 { font-variant-caps: small-caps; } /* 変換後のCSS */ h2 { font-feature-settings: "c2sc"; font-variant-caps: small-caps; }
Spec: Plugin:
CSS Fonts Module Level 3postcss/postcss-font-variant
CR
filter
.blur { filter: blur(4px); } /* 変換後のCSS */ .blur { filter: url(‘data:image/svg+xml;utf8,<svg xmlns=“...ation=“4” /></filter></svg>#filter’); filter: blur(4px); }
WD
Spec: Plugin:
Filter Effects Module Level 1iamvdo/pleeease-filters
rem units
.section { margin: 2.5rem 2px 3em 100%; } /* 変換後のCSS */ .section { margin: 80px 2px 3em 100%; }
Spec: Plugin:
CSS Values and Units Module Level 3robwierzbowski/node-pixrem
CR
:any-link pseudo-class
nav :any-link > span { background-color: yellow; } /* 変換後のCSS */ nav :link > span, nav :visited > span { background-color: yellow; }
ED
Spec: Plugin:
Selectors Level 4 - The Hyperlink Pseudo-class: :any-linkjonathantneal/postcss-pseudo-class-any-link
:matches pseudo-class
p:matches(:first-child, .special) { color: red; } /* 変換後のCSS */ p:first-child, p.special { color: red; }
ED
Spec: Plugin:
Selectors Level 4 - The Matches-any Pseudo-class: :matches()postcss/postcss-selector-matches
:not pseudo-class
p:not(:first-child, .special) { color: red; } /* 変換後のCSS */ p:not(:first-child), p:not(.special) { color: red; }
ED
Spec: Plugin:
Selectors Level 4 - The Negation Pseudo-class: :not()postcss/postcss-selector-not
pseudo-elements
a::before { color: red; } /* 変換後のCSS */ a:before { color: red; }
REC
Spec: Plugin:
Selectors Level 3axa-ch/postcss-pseudoelements
Alpha colors
body { color: rgba(153, 211, 153, 0.8); } /* 変換後のCSS */ body { color: #99DD99; color: rgba(153, 211, 153, 0.8); }
REC
Spec: Plugin:
CSS Color Module Level 3postcss/postcss-color-rgba-fallback
cssnextで利用するのではなく
その中から個別にプラグインを選択
stylelint Modern CSS linter.
自分好みのCSS Lint設定が可能
http://stylelint.io/
• Sassばかり書いていて標準仕様のこと忘れていた
• 仕様が固まっていないので追随コストがかかる
• MoOx氏が頑張りすぎなので個人的に心配
Build Tools 2015
JS Build Tools
Grunt/Gulpで憔悴したおっさんの話npm run-scriptでまとめようぜって話
http://t32k.me/mol/log/npm-run-script/
このプロジェクト…Gruntだっけ?Gulpだっけ?
えーいままよ!grunt build!いっけー…!
> Fatal error: Unable to find local grunt.
m9(^Д^)プギャー
npm run-scripts
package.json{ "name": "Maple", "version": "0.3.0", "repository": { "type": "git", "url": "git://github.com/t32k/maple.git" }, "scripts": { "start": "gulp serve", "build": "gulp build" }, "engines": { "node": ">=4.0" }, "devDependencies": {
package.json
$ npm run build
GulpだろうがGruntだろうが、package.jsonに記述し、npm runコマンドさえ覚えとけば大丈夫!ひとつ抽象化することで、Buildツールの流行り廃りに対応
kss-nodenode.js製のKSS(スタイルガイドジェネレーター)
https://github.com/kss-node/kss-node
grunt-kss by t32k!kss-nodeのGruntプラグイン
https://github.com/t32k/grunt-kss
更新止まってる…
m9(^Д^)プギャー
すみませんすみませんすみません
gulp-ksskss-nodeのGulpプラグイン
https://github.com/philj/gulp-kss
更新止まってる…
package.json
{ "scripts": { "start": "gulp serve", "publish": "kss-node path/to/stylesheets" }
プラグインを介さず直接コマンドを実行
まとめ
•ツールはプラグイン提供で細分化
•ある程度の選択眼が必要になってくる
•手あたり次第、触るしかない
•時間ない人は最新仕様でトレンドを掴む
t32k/maple今回紹介したBabel/cssnextのサンプルプロジェクト
https://github.com/t32k/maple
Let’s enjoy Front-end Dev!
Work with us!KAIZEN
https://www.wantedly.com/companies/kaizenplatform
Be a Growth Hacker!
https://kaizenplatform.com/ja/about_growth_hacker.html
Thanks!http://t32k.me