senchacon 2016: the modern toolchain - ross gerbasi
Post on 11-Apr-2017
109 Views
Preview:
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
top related