PHP & CSS & JavaScript Coding Style Bo-Yi Wu 2016.04.21 1
關於我 http://blog.wu-boy.com/ https://github.com/appleboy https://www.facebook.com/appleboy46 2
為什麼要制定 Coding Style 3
Pull Request Pull Request Pull Request Code Review 4
如果沒有制定程式語言 Style • 一份程式碼看起來就像是好幾個人寫的 • Code Reviewer 非常辛苦 • 程式碼維護困難 • 新人加入團隊,上手時間增加 5
最終目的讓專案程式碼 看起來像是一個人寫的 6
聊聊後端 PHP Coding Style 7
PHP-FIG 8
請詳細閱讀並且遵守 PSR-1: Basic Coding Standard PSR-2: Coding Style Guide 9
PHP 只能使用 <?php 或 <?= 10
檔案格式請務必存成 UTF-8 without BOM Unix Lf (linefeed) 11
檔案內容最後保留留一行空白 12
檔案內容最後不需要有 ?> 13
Class Name 務必宣告為 “StudlyCaps” 14
5.3 之後請使用 Namespace 15
5.2.x 或更早版本請遵守底下命名 16
Constant 變數必須為大寫 + 底線命名 const VERSION = '1.0'; const DATE_APPROVED = '2012-06-01'; 17
Method 必須宣告為 camelCase() public function helloWorld() { } 18
縮排原則 請使用 Space 而不是 tab 請勿 space + tab 混用 19
PHP 保留字請務必使用小寫 像是 true, false, null … 等 http://goo.gl/bJH8H 20
if, elseif, else 21
switch, case 22
23
While, do while 注意括號及 space 位置 24
<?php while ($expr) { // structure body } 25
<?php do { // structure body; } while ($expr); 26
for, foreach, try catch 注意括號及 space 位置 27
<?php for ($i = 0; $i < 10; $i++) { // for body } 28
<?php foreach ($data as $k => $v) { // foreach body } 29
<?php try { // try body } catch (FirstExceptionType $e) { // catch body } catch (OtherExceptionType $e) { // catch body } 30
這麼多 Style Rule 有沒 有工具可以幫忙檢查 ? 31
EditorConfig http://editorconfig.org/ 解決編輯器 config 設定 Tab vs space 32
33
搭配 sublime text editor https://github.com/sindresorhus/editorconfig-sublime 34
PHP Coding Standards Fixer http://cs.sensiolabs.org/ The PSR-1 and PSR-2 Coding Standards fixer for your code 35
安裝方式 • wget http://get.sensiolabs.org/php-cs- fixer.phar -O php-cs-fixer • $ sudo chmod a+x php-cs-fixer • $ sudo mv php-cs-fixer /usr/local/bin/php- cs-fixer 36
Mac 安裝 brew install homebrew/php/php-cs-fixer 37
38
搭配 PHP CodeSniffer 外掛 https://github.com/benmatselby/sublime-phpcs 39
40
Demo sublime text 41
Code Review 無 style 檢 查 style 檢查 style 檢查 有人會忘記裝 tool 來檢查 coding style42
The PHP Coding Style Service Because coding standards matter https://styleci.io 43
44
Code Review 無 style 檢 查 style 檢查 style 檢查 style 檢查錯誤 45
Documenting your Code 務必務必寫註解或文件 http://www.phpdoc.org/docs/latest/index.html 46
47
新成員請先閱讀底下文件 PHP The Right Way http://www.phptherightway.com/ 48
來聊聊前端 JavaScript && CSS Coding Style 49
Sass/Scss/Less CSS 預處理器 50
SASS SCSS LESS Compiler CSS 51
缺陷 • 需要經過 compiler 才能變成 CSS 檔案 • 要學習 sass/scss/less 新語法 • 專案成長後,需要 compiler 時間越久 • 無法支援 css lint 檢查語法 52
postcss a tool for transforming styles with JS plugins. https://github.com/postcss/postcss 53
CSS Parser Plugin 1 Plugin 2 New CSS Postcss 54
我們只需要挑專案 用到的 Plugin 即可 55
Plugin • Use Future CSS, Today – autoprefixer, postcss-cssnext • Better CSS Readability – precss, postcss-sorting • Images and Fonts – postcss-sprites 56
Usage gulp.task('css', () => { let postcss = require('gulp-postcss'); return gulp.src('src/*.css') .pipe( postcss([ plugin1, plugin2 ]) ) .pipe( gulp.desc('build/') ); }); 57
Plugin postcss.plugin('my-plugin', function () { return function (css) { doSomething(css); }; }); 58
Like Sass/Less PostCSS .block { &_title { font-size: 1.2em; } } CSS .block_title { font-size: 1.2em; } 59
Fallbacks PostCSS .foo { opacity: 0.8; } CSS .foo { opacity: 0.8; filter: alpha(opacity=80)9; } 60
Minify PostCSS .foo { border: none; } CSS .foo {border:0} 61
Plugin for CSS lint .foo { margin-top: 10px; margin: 0 auto; } foo.css:3:5: margin overrides margin-top. 62
PostCSS vs Gulp PostCSS • Parse – Transform – Fallbacks – Minify Gulp • Parse – Transform • Parse – Fallbacks • Parse – Minify 63
使用方式 Gulp + Less + PostCSS 64
return gulp.src('src/*.less') .pipe( less() ) .pipe( postcss([]) ) .pipe( gulp.desc('build/') ); 65
postcss([]) 沒任何 plugin input === output 66
postcss([ require('postcss-cssnext'), require('postcss-csssimple'), require('autoprefixer') ]) 67
Stylelint A mighty, modern CSS linter https://github.com/stylelint/stylelint 68
CSS Style Lint gulp.task('lint:css', function () { return gulp.src('src/*.less') .pipe( postcss([ require('stylelint'), require('postcss-reporter'), ], { syntax: require('postcss-less') }) ); }); 69
Less Less Lint cssnext autoprefixer Minify CSS PostCSS Process 70
延伸閱讀 A mostly reasonable approach to CSS and Sass. https://github.com/airbnb/css 71
來看看 JavaScript Style 推薦 airbna/javascript https://github.com/airbnb/javascript 72
你是寫 ES5 https://github.com/airbnb/javascript/tree/master/es5 73
寫 object // bad var item = new Object(); // good var item = {}; 74
寫 Array // bad var item = new Array(); // good var item = []; 75
使用單引號 var foo = ‘bar’ 76
Properties var luke = { jedi: true, age: 28 }; // bad var isJedi = luke['jedi']; // good var isJedi = luke.jedi; 77
動態取 Properties function getProp(prop) { return luke[prop]; } var isJedi = getProp('jedi'); 78
變數請宣告在最前面 不管是 global 或在 function 內 79
Use === and !== over == and != 80
你是寫 ES6 https://github.com/airbnb/javascript 81
建議從現在開始寫 ES6 如果你想踏入 React 世界 https://babeljs.io/ Babel transforms your JavaScript 82
Arrow Functions [1, 2, 3].map(function(n) { return n * 2; }, this); // -> [ 2, 4, 6 ] [1, 2, 3].map(n => n * 2); // -> [ 2, 4, 6 ] 83
不需要再寫 var self = this 84
function Person() { this.age = 0; setInterval(function growUp() { this.age++; }, 1000); } var p = new Person(); 85
function Person() { var self = this; self.age = 0; setInterval(function growUp() { self.age++; }, 1000); } var p = new Person(); 86
function Person(){ this.age = 0; setInterval(() => { this.age++; }, 1000); } var p = new Person(); 87
Block Scoping Functions var a = 5; var b = 10; if (a === 5) { let a = 4; var b = 1; console.log(a); // 4 console.log(b); // 1 } console.log(a); // 5 console.log(b); // 1 var a = 5; var b = 10; if (a === 5) { (function () { var a = 4; b = 1; console.log(a); // 4 console.log(b); // 1 })(); } console.log(a); // 5 console.log(b); // 1 88
Template var user = { name: 'Caitlin Potter' }; console.log('Thanks for V8, ' + user.name + '.'); var user = {name: 'Caitlin Potter'}; console.log(`Thanks for V8, ${user.name}.`); 89
Computed Property Names var prefix = 'foo'; var test= { [prefix + 'bar']: 'hello', [prefix + 'baz']: 'world' }; console.log(test['foobar']); // -> hello console.log(test['foobaz']); // -> world var prefix = 'foo'; var test= {}; test[prefix + 'bar'] = 'hello'; test[prefix + 'baz'] = 'world'; console.log(test['foobar']); // -> hello console.log(test['foobaz']); // -> world 90
Destructuring Assignment function f(x, y) { if (y === undefined) { y = 12; } return x + y; } f(3) === 15; function f(x, y = 12) { return x + y; } f(3) === 15; 91
Classes function Hello(name) { this.name = name; } Hello.prototype.hello = function hello() { return 'Hello ' + this.name; }; Hello.sayHelloAll = function () { return 'Hello everyone!'; }; class Hello { constructor(name) { this.name = name; } hello() { return 'Hello ' + this.name; } static sayHelloAll() { return 'Hello everyone!'; } } 92
Module var math = require('lib/math'); console.log('2π = ' + math.sum(math.pi, math.pi)); import math from 'lib/math'; console.log('2π = ' + math.sum(math.pi, math.pi)); 93
Property Method Assignment var object = { value: 42, toString: function toString() { return this.value; } }; var test= { value: 42, toString() { return this.value; } }; 94
Rest Parameters function f(x) { var y = []; y.push.apply(y, arguments) && y.shift(); // y is an Array return x * y.length; } function f(x, ...y) { // y is an Array return x * y.length; } console.log(f(3, 'hello', true) === 6); 95
Spread Operator function f(x, y, z) { return x + y + z; } f.apply(null, [1, 2, 3]) === 6; function f(x, y, z) { return x + y + z; } f(...[1,2,3]) === 6; 96
ES6 讓開發者少寫很多程式碼 97
ESLint The pluggable linting utility for JavaScript and JSX http://eslint.org/ 98
{ "extends": "airbnb" } 99
babel-eslint ESLint using Babel as the parser. https://github.com/babel/babel-eslint 100
.eslintrc { "parser": "babel-eslint", "rules": { "strict": 0 } } $ eslint your-files-here 101
Any Question? 102

PHP & JavaScript & CSS Coding style