senchacon 2016: the modern toolchain - ross gerbasi

27
The Modern Toolchain Ross Gerbasi Senior Software Engineer, Sencha

Upload: sencha

Post on 11-Apr-2017

109 views

Category:

Technology


2 download

TRANSCRIPT

PowerPoint Presentation

The Modern ToolchainRoss GerbasiSenior Software Engineer, Sencha

Hello and welcome. Thanks for coming to my session today. My name is ross gerbasi I am a.How many people are using CMD/build tools1

Where weve been

How many people have been developing for 5 years? 7?

2

Javascript was a browser language7 years ago

The iPhone 3GS was just releasedIt featured a 3 Mega pixel cameraA 480 x 320 screenWas the first iPhone to natively shoot videoiOS 3.0 was releasedIt added MMS supportThe world could also finally Copy and Paste Android released version 2 (Eclair)It added HTML5 support to its browser. (then the app was actually called browser)The Nexus One would be released early 2010Chrome released version 3.0 was outIt added HTML5 video and audio tag supportIE and FireFox rules the browser statistics warIE around 40% (w3c schools)Firefox around 50% (w3c schools)Sencha CMD was still 3 years away from being a thing (2.0 beta release)Sencha Touch was pushing to release version 1.1.0 and bring web dev to the mobile world.The first use of the word NodeJS was bornOh and Flash was a thing.3

Where we are now

DesktopPhonesTabletsRobotics Platform

SmartTVJavascript Now

Where we heading

Where are we heading

The Future of Build Tools

code name

nodeJs with a package manager of NPM or yarnWebpack for bundling and loading of assetsBabel for our transpiling needsSencha build for various ext related build toolsAnd Mondorepo for organization and team collaboration in the node world8

NodeJS is a Javascript runtime builton Chromes V8 JavaScript engine

Foundation of our future build toolsHow many people ate using node now?9

Package Managers: NPM vs YarnPackage Version ManagementNPM uses an optional shrinkwrap for package version guaranteeYarn uses mandatory Yarn.lock file generated during every installationParallel vs Sequential InstallationNPM installs sequentiallyYarn install in ParallelBottom LineYarn is faster & more secure but also new and untestedNPM is slower but has years of usage and testing

Package Managers: NPM vs Yarn

NPMYarn

How many people are using webpack now?12

module.exports = { entry: './app.js', output: { path: __dirname + '/build', filename: 'bundle.js' }, resolve: { alias: { 'somePackage': '/path/to/my/code } }, module: { loaders: [{ test: /\.js$/, loader: 'babel', query: { plugins: [ 'babel-plugin-transform-es2015-modules-commonjs' ] } }] }};Webpack 2.0 ConfigurationEntry point and output initializationAlias resolution allows code to be located in locations what work for developersModule Loaders allow for code transformation before bundling

Entry & BuildBasic config for entry point and location of build filesentry: './app.js',output: { path: __dirname + '/build', filename: 'bundle.js'},

Resolver & AliasPowerful aliasing features allow you to keep code where you want. resolve: {alias: {'somePackage': '/path/to/my/code}},

LoadersTransformations applied to a file in your application.

This can be used to do anything from transpile to compress imagesloaders: [{ test: /\.js$/, loader: 'babel', query: { plugins: [ 'babel-plugin-transform-es2015-modules-commonjs' ] } }]

// Minified outputfunction (t, n, r) { function e() { return "foo" } n.foo = e }// helpers.js export function foo() { return 'foo'; } export function bar() { return 'bar'; }

// main.jsimport {foo} from './helpers';console.log(foo());Webpack 2.0 Tree ShakingTwo Stage processAny exports that are not imported are not exported anymoreBundle is minified removing dead codeWill not work reliably for CommonJS modules, as they cannot be statically analyzed for unused exports

Code Sample from: http://www.2ality.com/2015/12/webpack-tree-shaking.html// Webpack bundled outputfunction(module, exports, __webpack_require__) { /* harmony export */ exports["foo"] = foo; /* unused harmony export bar */; function foo() { return 'foo'; } function bar() { return 'bar'; }}

Babel: The Javascript TranspilerSupport for ES2015 and beyondPlugin based allows control of what code is transpiledPolyfill for new functionality not supported in your target target browserSource maps for debugging compiled code in the browser Easy to try in the browser at: http://babeljs.io/repl/

Future code makes it faster for devs to work, but transpile back for browser support

Choose what plugin you use to transpile for your target

You dont want to be debugging transpiled code, you want to see the code you wrote15

Webpack & Babel: Code Demo

Package and Repository Organization

Goal was to re-create workspaces in the node world.17

import {magic} from '../../../packages/magic-sauce/magic'NPM Structure

app.js

webpack.config.js

package.json

packages

magic-sauce

magic.js// Main.js

MyApplication

node_modules

package_a

app

view

main

Main.js

1:1 package system of node18

import {magic} from '../../../../magic-sauce/magic'NPM Structure

MyApplication

app.js

webpack.config.js

package.json

node_modules

package_a

app

magic-sauce

magic.js

view

main

Main.js// Main.js

cd magic-saucenpm linkcd ../MyApplicationnpm link magic-sauce

Package Organization with NPMRelative PathsMessy CodeAnnoying to refactor your folder structureNPM LinkGlobally installedHard to share across a team of people

Lerna

import {magic} from 'magic-sauce'// Main.js

app.js

webpack.config.js

package.json

packages

magic-sauce

magic.js

MyApplication

node_modules

package_a

app

view

main

Main.js

magic-sauce

index.js

linked togetherrequire('../../packages/magic-sauce/magic.js')import {test} from 'magic-sauce/magic/some/sub/folder/test.js'One Extra FolderA packages folder is available butyou are not able to add other foldersto your classpathBabel Github Repo

The problem we are looking to solve is you need to work on multiple packaes that depend on eachother1:many21

code name

many:many structure22

Mondorepo Structure

{ "name": "my-mondo-repo", "version": "0.0.1", "mondo": { "repo": true, "packages": packages", "uses": { "magic-sauce": { "repository": "sencha/magic-sauce, "branch: "top-secret-dev" }, "my-utilities": { "repository": "my-user/my-utilities" } } }, "license": "ISC", "dependencies": { }}

app.js

webpack.config.js

package.json

mondo_repos

magic-sauce

MyApplication

node_modules

package_a

my-utilities

addinator

subtractifier

packagesimport {magic} from 'magic-sauceimport {add} from 'addinatorimport {sub} from 'subtractifierimport {trim} from 'addinator/src/utils/trim'

Repo can also be a NPM packageRepo can be a container of packagesconst Repo = require('mondorepo').Repo;const repo = Repo.open();resolve: { alias: repo.allPackageAliases},const Repo = require('mondorepo/src/init);const add = require('addinator');// Node Require shim allows for easy modulemondo run index.js// Mondo CLI will inject initialization automatically!const add = require('addinator');

{'magic-sauce': '/path/to/mondo_repos/magic-sauce,'addinator': '/path/to/mondo_repos/my-utilities/packages/addinator,subtractifier': '/path/to/mondo_repos/my-utilities/packages/subtractifier}

Mondorepo Demo

Show smartgit multiple repos during demo24

Build ToolsScannerIndexerCompressorOptimizerUpgradinator

Upgradinator Sneak Peek

Limit Slide Titles to One Line Whenever PossibleLimit the number of lines of text in bullet lists for legibilityThe default font for a sub-bullet is Source Sans Pro 42 pt.The default for an additional layer of sub-bullet is Source Sans Pro 36 pt.CapitalizationFor slide titles and headlines use title case capitalization: capitalize the first letter of each important wordFor bullet text, use sentence case capitalization: capitalize only the first letter in the sentence, proper nouns, and product namesRemember: less is better28

Slide Titles Can Be Title CaseBut subheaders should be sentence caseParagraphs are also sentence case.Bullets are sentence case too.

class CanvasItem: def __init__(self, canvas, itemType, *args, **kw): self.canvas = canvas self.id = canvas._create(itemType, args, kw) if not hasattr(canvas, 'items'): canvas.items = {} canvas.items[self.id] = self def __str__(self): return str(self.id) def __repr__(self): return '' % (self.__class__.__name__, self.id) def delete(self): del self.canvas.items[self.id] self.canvas.delete(self.id) def __getitem__(self, key): v = self.canvas.tk.split(self.canvas.tk.call( self.canvas._w, 'itemconfigure', self.id, '-' + key)) return v[4] cget = __getitem__ def __setitem__(self, key, value): self.canvas.itemconfig(self.id, {key: value})

Code CommentaryUsed to combine typical slide content and source codeSource code font can be sized up by user to make more legibleIt is not recommended to reduce code text size due to legibility concerns!

Two Column Code Pageclass CanvasItem: def __init__(self, canvas, itemType, *args, **kw): self.canvas = canvas self.id = canvas._create(itemType, args, kw) if not hasattr(canvas, 'items'): canvas.items = {} canvas.items[self.id] = self def __str__(self): return str(self.id) def __repr__(self): return '' % (self.__class__.__name__, self.id) def delete(self): del self.canvas.items[self.id] self.canvas.delete(self.id) def __getitem__(self, key): v = self.canvas.tk.split(self.canvas.tk.call( self.canvas._w, 'itemconfigure', self.id, '-' + key)) return v[4] cget = __getitem__ def __setitem__(self, key, value): self.canvas.itemconfig(self.id, {key: value})

class CanvasItem: def __init__(self, canvas, itemType, *args, **kw): self.canvas = canvas self.id = canvas._create(itemType, args, kw) if not hasattr(canvas, 'items'): canvas.items = {}

Code Page With Calloutclass CanvasItem: def __init__(self, canvas, itemType, *args, **kw): self.canvas = canvas self.id = canvas._create(itemType, args, kw) if not hasattr(canvas, 'items'): canvas.items = {} canvas.items[self.id] = self def __str__(self): return str(self.id) def __repr__(self): return '' % (self.__class__.__name__, self.id) def delete(self): del self.canvas.items[self.id] self.canvas.delete(self.id) def __getitem__(self, key): v = self.canvas.tk.split(self.canvas.tk.call( self.canvas._w, 'itemconfigure', self.id, '-' + key)) return v[4] cget = __getitem__ def __setitem__(self, key, value): self.canvas.itemconfig(self.id, {key: value})

class CanvasItem: def __init__(self, canvas, itemType, *args, **kw): self.canvas = canvas self.id = canvas._create(itemType, args, kw) if not hasattr(canvas, 'items'): canvas.items = {}

Callout Box TitleThis is a callout box! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus molestiae!id(self) self.tag = self.id = tag self.canvas = canvas self.canvas.dtag(self.tag) def str(self): return self.tag __str__ = str

Graphic ContentGraphics should utilize primarily lines rather than solid shapes. Please avoid using free or not-premium clip art and photographs

Icon LibraryCopy and paste these if you need them, their color may be set via the color palate

Brand ColorsThis template carries appropriate brand colors, as seen to the right.Keep color use to a minimum, using it to direct the conversation. Do not use color for embellishment.Other shades of the palate may be used when the primary, secondary, and tertiary colors do not suffice, eg. Infographics.Avoid using unnecessary embellishments such as shadows, bevels, etc.

Text colorHighlightsPrimarySecondary