If you're like me, you know that being a great backend developer isn't enough. To make *truly* great applications, we need to spend significant time in an area that's moving at a lightning pace: frontend development.
This talk is for you: the backend developer that wants to hook their API's up to rich, interactive JavaScript frontends. To do that, first, we need to demystify a lot of new terms, like ES6/ES2015, ECMAScript, JSX, Babel and the idea that modern JavaScript (surprise) *requires* a build step.
With this in mind, I'll give you a brief introduction into Webpack & the modular development it finally allows.
But the real star is ReactJS. In the frontend world, you never know what new tech will *win*, but React is a star. I'll give you enough of an intro to get you rolling on your project.
The new frontend dev world is huge! Consider the starting line down an exciting new journey.
2. > Lead of the Symfony documentation team
> KnpLabs US - Symfony consulting, training & kumbaya
> Writer for KnpUniversity.com:
PHP & Symfony screencasts
packed with puns, unrelated
(but entertaining) illustrations
and coding challenges!
> Husband of the much more
talented @leannapelham
knpuniversity.com
twitter.com/weaverryan
¡Hola!
4. , ReactJS, webpack
@weaverryan
All of Modern JavaScript in
45 minutes!
ES6
the 12 new JS things they invent
during this presentation
, ES2015 , ECMAScript
, Babel
, NodeJS
npm , JSX …
… and of course …
7. @weaverryan
You spent 6 months building
your site in <Cool.JS> only
to read on Twitter that:
“no self-respecting dev
uses that crap anymore”
That character you love and
followed for 2 seasons, was
just unceremoniously decapitated
JavaScript
GoT
10. @weaverryan
// yay.js
var message = 'I like Java...Script';
console.log(message);
> node yay.js
I like Java...Script
NodeJS: server-side
JavaScript engine
npm: Composer
for NodeJS
11. @weaverryan
Follow along with the real code:
github.com/weaverryan/symfonycat-js
(hint: look at the history, each
thing we do is its own commit)
12. // web/js/productApp.js
var products = [
'Sheer Shears',
'Wool Hauling Basket',
'After-Shear (Fresh Cut Grass)',
'After-Shear (Morning Dew)'
];
var loopThroughProducts = function(callback) {
for (var i = 0, length = products.length; i < length; i++) {
callback(products[i]);
}
};
loopThroughProducts(function(product) {
console.log('Product: '+product);
});
{# app/Resources/views/default/products.html.twig' #}
<script src="{{ asset('js/productApp.js') }}"></script>
our store for
sheep (baaaa)
13.
14. class ProductCollection
{
constructor(products) {
this.products = products;
}
}
let collection = new ProductCollection([
'Sheer Shears',
'Wool Hauling Basket',
'After-Shear (Fresh Cut Grass)',
'After-Shear (Morning Dew)',
]);
let prods = collection.getProducts();
let loopThroughProducts = function(callback) {
for (let i = 0, length = prods.length; i < length; i++) {
callback(collection.getProduct(i));
}
};
loopThroughProducts(product => console.log('Product: '+product));
what language
is this?
JavaScript
16. class ProductCollection
{
constructor(products) {
this.products = products;
}
}
let collection = new ProductCollection([
'Sheer Shears',
'Wool Hauling Basket',
'After-Shear (Fresh Cut Grass)',
'After-Shear (Morning Dew)',
]);
let prods = collection.getProducts();
let loopThroughProducts = function(callback) {
for (let i = 0, length = prods.length; i < length; i++) {
callback(collection.getProduct(i));
}
};
loopThroughProducts(product => console.log('Product: '+product));
But will it run in a browser???
Maybe!
17. class ProductCollection
{
constructor(products) {
this.products = products;
}
}
let collection = new ProductCollection([
'Sheer Shears',
'Wool Hauling Basket',
'After-Shear (Fresh Cut Grass)',
'After-Shear (Morning Dew)',
]);
let prods = collection.getProducts();
let loopThroughProducts = function(callback) {
for (let i = 0, length = prods.length; i < length; i++) {
callback(collection.getProduct(i));
}
};
loopThroughProducts(product => console.log(product));
Proper class and
inheritance syntax
let: similar to var,
but different
function (product) {
console.log(product);
}
18. Now we just need to
wait 5 years for the
crappiest browsers
to support this
37. Use require instead of import/export *
* I’ll tell you why later
// web/js/ProductCollection.js
class ProductCollection
{
// ...
}
module.exports = ProductCollection;
// web/js/productApp.js
var ProductCollection = require('./ProductCollection');
// ...
38. Go webpack Go!
> ./node_modules/.bin/webpack
web/js/productApp.js
web/builds/productApp.js
The one built file contains
the code from both source files
39. Optional config to make it easier to use:
// webpack.config.js
module.exports = {
entry: {
product: './web/js/productApp.js'
},
output: {
path: './web/builds',
filename: '[name].js',
publicPath: '/builds/'
}
};
builds/product.js
{# app/Resources/views/default/products.html.twig' #}
<script src="{{ asset('builds/product.js') }}"></script>
42. Hey webpack!
Yo! When you load .js files,
can you run them through
Babel for me?
- kthxbai <3 Ryan
webpack loaders allow you to transform files
as they’re loaded
46. Use import/export now if you prefer
// web/js/ProductCollection.js
class ProductCollection
{
// ...
}
export default ProductCollection;
// web/js/productApp.js
import ProductCollection from './ProductCollection';
// ...
51. Wait!
@weaverryan
Don’t I need to update all my script tags?
<script
src="{{ asset('builds/product.js') }}">
<script
src="http://localost:8080/builds/product.js">
57. Could we do this?
// web/js/productApp.js
import ProductCollection from './ProductCollection';
// could this somehow load that CSS for us?
import '../css/productApp.css';
// ...
Loader!
59. 1) Install the css-loader
2) Activate the loader just for this file
> npm install css-loader --save-dev
import 'css!../css/productApp.css';
this transforms the CSS into a JS data-
structure… but does nothing with it
60. 1) Install the style-loader
> npm install style-loader --save-dev
import 'style!css!../css/productApp.css';
inlines the CSS on the page in
a style tag
2) Activate both loaders for this file
61. Yes,
@weaverryan
the one JS file now holds the contents of
two JS files and a CSS file
{# app/Resources/views/default/products.html.twig' #}
<script src="{{ asset('builds/product.js') }}"></script>
66. {
test: /.png/,
loader: "url-loader?limit=10000"
}
For .png files < 10kb
image is turned into a “data url”
and inlined in the CSS
For .png files > 10kb
image is copied to builds/ and the
new URL is written into the CSS
99. @weaverryan
Babel
A tool that can transform JavaScript
to different JavaScript
presets
A) ES6 js to “old” JS
B) JSX to raw JS
100. @weaverryan
Webpack
A tool that follows imports to bundle
JavaScript, CSS, and anything else you
dream up into one JavaScript package
loaders
A) JS through Babel
B) CSS to inlined styles
C) images copied, paths used