10/2016 / Milan "perún" Herda / @moriquend / prezentacie.perunhq.org
unit/unitFactory.js
a unit/ranged.js
var unitFactory = function () {
var name,
speed,
strength,
health,
obj = {};
obj.setName = function (newName) {
name = newName;
return obj;
};
obj.getName = function () {
return name;
};
obj.setSpeed = function (newSpeed) {
speed = newSpeed;
return obj;
};
obj.getSpeed = function () {
return speed;
};
obj.setStrength = function (newStrength) {
strength = newStrength;
return obj;
};
obj.getStrength = function () {
return strength;
};
obj.setHealth = function (newHealth) {
health = newHealth;
return obj;
};
obj.getHealth = function () {
return health;
};
return obj;
};
module.exports = unitFactory;
var extendByRange = function (unit) {
var range;
unit.setRange = function (newRange) {
range = newRange;
return unit;
};
unit.getRange = function () {
return range;
};
return unit;
};
module.exports = extendByRange;
var unitFactory = require('./unit/unitFactory'),
extendByRange = require('./unit/ranged');
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
require
a module.exports
Všetko vo vnútri modulu je lokálne iba pre modul a von sa dostane iba to, čo uvedieme v module.exports
CommonJS bol projekt, ktorý začal vznikať v roku 2009 v Mozille ako ekosystém pre server-side JavaScript.
V roku 2013 ho začal Node.js opúšťať, ale formát pre moduly ostal.
Takto sa teda pracovalo s modulmi na serverovej strane pred ES2015 (resp. Babelom).
Poďme na web!
www/index.html
a adresár www/js
unit/unitFactory.js
a unit/ranged.js
do vnútra www/js
module.exports
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS module example</title>
<script src="js/unit/unitFactory.js"></script>
<script src="js/unit/ranged.js"></script>
<script>
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
console.log(archer);
</script>
</head>
<body>
</body>
</html>
webpack je "module bundler" pre web, ktorý vie pracovať aj s CommonJS formátom
Mohli by sme skúsiť aj browserify, ale webpack je viac cool :)
npm init
npm install webpack -g
Nové adresáre, pretože toto je už seriózna práca a chceme mať pekne oddelené zdrojáky od vygenerovaných vecí
app.js
potrebujeme ako nový vstupný bod, pretože nechceme exportovať premenné do globálneho priestoru
module.exports = {
entry: {
app: './assets/src/js/app.js'
},
output: {
path: './www/assets/js',
filename: '[name].js'
}
};
Na koniec súborov pridáme
// assets/src/js/unit/unitFactory.js
module.exports = unitFactory;
// assets/src/js/unit/ranged.js
module.exports = extendByRange;
var unitFactory = require('./unit/unitFactory'),
extendByRange = require('./unit/ranged');
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
console.log(archer);
webpack
K premenným v moduloch nemáme prístup zo script tagov v html
Ako nastavíme hodnoty pre jednotky podľa údajov z databázy?
Moduly majú prístup k html a ku globálnym premenným
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS module example</title>
<script src="js/unit/unitFactory.js"></script>
<script src="js/unit/ranged.js"></script>
<script>
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
console.log(archer);
</script>
</head>
<body>
</body>
</html>
require
slúži na načítanie modulov
require(['module1', 'module2'], function (module1, module2) {
// tento kód sa spustí po načítaní oboch modulov
});
define
slúži na definíciu modulov
define('názovModulu', ['module1', 'module2'], function (module1, module2) {
// tento kód sa spustí po načítaní oboch modulov
return moduleDefinition;
});
Názov modulu je nepovinný, pokiaľ je modul v samostatnom súbore.
Závislosti sú nepovinné a nemusí sa uviesť ani prázdne pole
Najpopulárnejšia implementácia AMD
npm init
npm install requirejs --save
npm install gulp del run-requence --save-dev
sudo npm install -g gulp
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS module example</title>
<script src="assets/vendor/require.js"></script>
<script>
requirejs.config({
baseUrl: 'assets/js'
});
require(['unit/unitFactory', 'unit/ranged'], function (unitFactory, extendByRange) {
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
console.log(archer);
});
</script>
</head>
<body>
</body>
</html>
// súbor assets/src/js/unit/unitFactory.js
define(function () {
unitFactory = function () {
var name,
speed,
strength,
health,
obj = {};
obj.setName = function (newName) {
name = newName;
return obj;
};
obj.getName = function () {
return name;
};
obj.setSpeed = function (newSpeed) {
speed = newSpeed;
return obj;
};
obj.getSpeed = function () {
return speed;
};
obj.setStrength = function (newStrength) {
strength = newStrength;
return obj;
};
obj.getStrength = function () {
return strength;
};
obj.setHealth = function (newHealth) {
health = newHealth;
return obj;
};
obj.getHealth = function () {
return health;
};
return obj;
};
return unitFactory;
});
// súbor assets/src/js/unit/ranged.js
define(function () {
var extendByRange = function (unit) {
var range;
unit.setRange = function (newRange) {
range = newRange;
return unit;
};
unit.getRange = function () {
return range;
};
return unit;
};
return extendByRange;
});
// obsah súboru gulpfile.js
var gulp = require('gulp'),
del = require('del'),
runSequence = require('run-sequence');
gulp.task('clean', function () {
return del('www/assets/**/*');
});
gulp.task('copy:require', function () {
return gulp.src(['node_modules/requirejs/*.js'])
.pipe(gulp.dest('www/assets/vendor'));
});
gulp.task('copy:assets', function () {
return gulp.src(['assets/src/js/**/*'])
.pipe(gulp.dest('www/assets/js'));
});
gulp.task('copy', function (done) {
runSequence('copy:require', 'copy:assets', done);
});
gulp.task('default', function (done) {
runSequence('clean', 'copy', done);
});
Každý samostatný modul je samostatný súbor.
Každý súbor je request na server
Nástroj pre requirejs, ktorý umožňuje spájať moduly do jedného súboru
Nainštaloval sa spolu s requirejs, ale potrebujeme modul do gulpu
npm install gulp-requirejs --save-dev
// súbor assets/src/js/app.js
define(['unit/unitFactory', 'unit/ranged'], function (unitFactory, extendByRange) {
return function () {
var pikeman = unitFactory(),
horseman = unitFactory(),
archer = extendByRange(unitFactory());
archer.setName('Robin Hood')
.setSpeed(1)
.setStrength(5)
.setHealth(10)
.setRange(5);
console.log(archer);
};
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS module example</title>
<script src="assets/vendor/require.js"></script>
<script>
requirejs.config({
baseUrl: 'assets/js'
});
require(['app'], function (app) {
app();
});
</script>
</head>
<body>
</body>
</html>
var gulp = require('gulp'),
del = require('del'),
runSequence = require('run-sequence'),
rjs = require('gulp-requirejs');
gulp.task('clean', function () {
return del('www/assets/**/*');
});
gulp.task('copy:require', function () {
return gulp.src(['node_modules/requirejs/*.js'])
.pipe(gulp.dest('www/assets/vendor'));
});
gulp.task('copy', function (done) {
runSequence('copy:require', done);
});
gulp.task('rjs', function () {
rjs({
name: 'app',
baseUrl: 'assets/src/js',
out: 'app.js',
}).pipe(gulp.dest('www/assets/js'));
});
gulp.task('default', function (done) {
runSequence('clean', 'copy', 'rjs', done);
});
Ja som používal AMD, ktoré sa mi pre web zdalo vhodnejšie
S nástupom ES2015, babel a webpack prechádzam na natívne ES2015 moduly