Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Enforcing coding standards in a JS project
Search
Sebastiano Armeli
May 14, 2015
Programming
0
560
Enforcing coding standards in a JS project
Talk given at JSConf Budapest (Budapest, Hungary) - May 2015
Sebastiano Armeli
May 14, 2015
Tweet
Share
More Decks by Sebastiano Armeli
See All by Sebastiano Armeli
Cultivate Excellence In Engineering Teams through Continuous Software Engineering
sebarmeli
1
95
From Strategy Definition to Execution with OKRs and Roadmap
sebarmeli
0
95
From Mission to Strategy: going over OKRs and Roadmap
sebarmeli
0
240
Managing a software engineering team
sebarmeli
1
520
Enforcing Coding Standards
sebarmeli
1
110
ES6: The future is now
sebarmeli
2
470
EcmaScript 6 - the future is here
sebarmeli
5
7.1k
Dependency management and Package management in JavaScript
sebarmeli
0
680
Karma - JS Test Runner
sebarmeli
1
800
Other Decks in Programming
See All in Programming
Better Code Design in PHP
afilina
PRO
0
130
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
as(型アサーション)を書く前にできること
marokanatani
10
2.7k
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
Flutterを言い訳にしない!アプリの使い心地改善テクニック5選🔥
kno3a87
1
180
初めてDefinitelyTypedにPRを出した話
syumai
0
410
CSC509 Lecture 13
javiergs
PRO
0
110
AWS IaCの注目アップデート 2024年10月版
konokenj
3
3.3k
最新TCAキャッチアップ
0si43
0
140
TypeScript Graph でコードレビューの心理的障壁を乗り越える
ysk8hori
2
1.1k
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
Featured
See All Featured
For a Future-Friendly Web
brad_frost
175
9.4k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
25
1.8k
How STYLIGHT went responsive
nonsquared
95
5.2k
Done Done
chrislema
181
16k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
890
Git: the NoSQL Database
bkeepers
PRO
427
64k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Transcript
ENFORCING CODING STANDARDS in a JS PROJECT
Sebastiano Armeli @sebarmeli 14/05/2015 - JSConf BD
to enforce verb (used with object), enforced, enforcing. to put
or keep in force; to compel obedience to: “to enforce a rule; Traffic laws will be strictly enforced.”
None
None
standard noun a rule or principle that is used as
a basis for judgment: “They tried to establish standards for a new approach.”
None
commit 111111 Author: Sebastiano Armeli Date: Sun Dec 21 22:08:00
2014 -0500 adding something commit 2222222 Author: Sebastiano Armeli Date: Thu Dec 18 15:35:39 2014 -0500 it will work, trust me
myProject | |— module1.js |— module2.js |— module_3.js |— module_4.js
|— module5.js |— package.json
None
defined by your team Automate
http://facilitationjapan.com/wp-content/uploads/2013/09/consensus_building.jpg
AD LIBRARY
None
None
! IDE (Editorconfig) ! Quality & Style tools (JSHint, JSCS,
ESLint) ! Git commits standards ! Build tools (Grunt, Gulp) ! Language - Transpiler (ES6 - Babel) ! Complexity tool (Plato) Summary 1/2
! Testing (Mocha, Karma) ! Automated Release Flow (Jenkins, NPM)
! Setup script ! Documentation Summary 2/2
None
root = true [*] indent_style = space indent_size = 2
end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true .editorconfig
Coding Style & Quality Tools
Prevent bugs Improve code maintainability & readability Easy to
use
function increment(a) { return a + 1; } increment(1); //
undefined BUG!!
var x = y = z = "example"; Leaking Variables!!
None
{ "curly": true, "eqeqeq": false, "latedef": true, "newcap": true, "noarg":
true, "sub": true, "boss": true, "indent": 2, "noempty": true, "expr": true, "eqnull": true, "esnext": true, "browser": true, "white": true, "undef": true, "predef": [ “require”, "module", “exports", "CustomEvent"] } .jshintrc
{ "curly": true, "eqeqeq": false, "latedef": true, "newcap": true, "noarg":
true, "sub": true, "boss": true, "indent": 2, "noempty": true, "expr": true, "eqnull": true, "esnext": true, "browser": true, "white": true, "undef": true, "predef": [ “require”, "module", “exports", "CustomEvent"] } .jshintrc
{ "curly": true, "eqeqeq": false, "latedef": true, "newcap": true, "noarg":
true, "sub": true, "boss": true, "indent": 2, "noempty": true, "expr": true, "eqnull": true, "esnext": true, "browser": true, "white": true, "undef": true, "predef": [ “require”, "module", “exports", "CustomEvent"] } .jshintrc
JSCS
{ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try"],
"disallowImplicitTypeConversion": ["string"], "disallowMultipleLineBreaks": true, "disallowMixedSpacesAndTabs": true, "disallowKeywords": ["with"], "disallowMultipleVarDecl": true, "disallowTrailingComma": true, "disallowTrailingWhitespace": true, "maximumLineLength": 80, "esnext": true } .jscsrc
{ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try"],
"disallowImplicitTypeConversion": ["string"], "disallowMultipleLineBreaks": true, "disallowMixedSpacesAndTabs": true, "disallowKeywords": ["with"], "disallowMultipleVarDecl": true, "disallowTrailingComma": true, "disallowTrailingWhitespace": true, "maximumLineLength": 80, "esnext": true } .jscsrc
{ "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try"],
"disallowImplicitTypeConversion": ["string"], "disallowMultipleLineBreaks": true, "disallowMixedSpacesAndTabs": true, "disallowKeywords": ["with"], "disallowMultipleVarDecl": true, "disallowTrailingComma": true, "disallowTrailingWhitespace": true, "maximumLineLength": 80, "esnext": true } .jscsrc
None
--- parser: babel-eslint env: browser: true node: true mocha: true
es6: true .eslintrc
rules: space-before-blocks: 2 eqeqeq: [2, 'smart'] curly: [2, 'multi-line'] quotes:
[2, 'single'] space-after-keywords: 2 no-unused-vars: [2, args: none] no-comma-dangle: 2 no-unused-expressions: 0 no-multi-spaces: 2 …
rules: space-before-blocks: 2 eqeqeq: [2, 'smart'] curly: [2, 'multi-line'] quotes:
[2, 'single'] space-after-keywords: 2 no-unused-vars: [2, args: none] no-comma-dangle: 2 no-unused-expressions: 0 no-multi-spaces: 2 …
no-unused-vars: [2, args: none] function test1(a, b) { var c,
d = 2; return a + d; } test1(1, 2); Error!! function test2(a, b, c) { return a + b; } test2(1, 2); Ok
no-trailing-spaces: 2 no-mixed-spaces-and-tabs: 2 quotes: [2, ‘single’] indent: [2, 2]
"use strict”; module.exports = function(context) { return { "NewExpression": function(node)
{ if (node.callee.name === "Object") { context.report(node, “Error …”); } } }; }; no-new-object.js let obj = new Object(); let obj = {};
"use strict”; module.exports = function(context) { return { "NewExpression": function(node)
{ if (node.callee.name === "Object") { context.report(node, “Error …”); } } }; }; no-new-object.js let obj = {};
None
Git Commits (feat | fix | docs | style |
refactor | test | chore)(<scope>): <description> E.g. doc(readme): update with additional links.
Changelog conventional-changelog Changelog.md commit 7aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Author: Sebastiano Armeli <
[email protected]
> Date:
Tue Jan 6 11:48:59 2015 -0500 refactor(BaseAd): Removed addToStreamTime method from BaseAd commit 7bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb Author: Sebastiano Armeli <
[email protected]
> Date: Tue Jan 6 00:04:49 2015 -0500 style(gpt): rearrange for better readability
CHANGELOG.md
Build tool gulp test / gulp dev
var gulp = require('gulp'); var plugins = require(‘gulp-load-plugins')(); … gulp.task('eslint',
function() { return gulp.src(['src/**/*.js']) .pipe(plugins.eslint()) .pipe(plugins.eslint.format()) .pipe(plugins.eslint.failOnError()); }); … gulpfile.js
None
gulp es6 /src /dist ES6 ES5
Plato gulp plato
Testing
describe('#_onContainerResume', function() { it('should call play when container resumes', function()
{ videoAd.views.set(mockedVideoAdMetadata.id, { play: function() {}, hasBeenPlayed: true }); sinon.stub(videoAd.views.get(mockedVideoAdMetadata.id), 'play'); videoAd._onContainerResume(); expect(videoAd.views.get(mockedVideoAdMetadata.id).play).to.have .been.called; }); });
module.exports = function(config) { config.set({ basePath: '../', frameworks: ['mocha', 'fixture'],
files: [ …. ], browsers: ‘Chrome’, singleRun: false, preprocessors: { '**/*.html': ['html2js'], '**/*.json': ['html2js'] }, sauceLabs: { … } }); }; karma.conf.js
module.exports = function(config) { config.set({ basePath: '../', frameworks: ['mocha', 'fixture'],
files: [ …. ], browsers: ‘Chrome’, singleRun: false, preprocessors: { '**/*.html': ['html2js'], '**/*.json': ['html2js'] }, sauceLabs: { … } }); }; karma.conf.js
module.exports = function(config) { config.set({ basePath: '../', frameworks: ['mocha', 'fixture'],
files: [ …. ], browsers: ‘Chrome’, singleRun: false, preprocessors: { '**/*.html': ['html2js'], '**/*.json': ['html2js'] }, sauceLabs: { … } }); }; karma.conf.js
Automated Release flow gulp test:ci gulp bump:path gulp bump:minor gulp
bump:major Changelog.md
./setup.sh pre-commit hook + npm i && gulp test
Documentation README.md CONTRIBUTING.md
Documentation README.md CONTRIBUTING.md
/doc
Sebastiano Armeli <…@spotify.com> Brice Lin <
[email protected]
> <…@gmail.com> Jason Palmer <
[email protected]
>
<
[email protected]
> Joseph Werle <
[email protected]
> <…@gmail.com> Olof Kihlberg <…@spotify.com> Sigfrido Chirinos <…@spotify.com> .mailmap
None
Sebastiano Armeli @sebarmeli