React Native and the future of web technology (Mark Wilcox) - GreeceJS #15
uRequire@greecejs: An introduction to
-
Upload
agelos-pikoulas -
Category
Software
-
view
8.729 -
download
1
description
Transcript of uRequire@greecejs: An introduction to
![Page 1: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/1.jpg)
uRequire.org
The JavaScript Universal Module & Resource Converter
“Write modular JavaScript code once, run everywhere” is a reality.
![Page 2: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/2.jpg)
uRequire.org
• Why Modularity• JavaScript module systems• uRequire primer• A modules & dependencies builder• Build config usage
![Page 3: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/3.jpg)
uRequire.org
Why modularity• Maintainable & reusable code– Organize code in logical parts– Clearly stated dependencies– Reusability, Replace-ability, Testability etc
• Employ standards and trusted tools– Unit Testing, Versioning, Regression Testing
• Have a dynamic code loading mechanism.• End the damnation of – Authoring “OneHuge.js” file – .js file concatenation
![Page 4: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/4.jpg)
uRequire.org
• Why Modularity• JavaScript module systems & woes• uRequire primer• A modules & dependencies builder• Build config usage
![Page 5: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/5.jpg)
uRequire.org
CommonJS (nodejs)var dep1 = require("../some/path/dep1"),
dep2 = require("../other/path/dep2"), localDep = require("localDep");// ‘localDep’ in
node_modules
// do stuff with dep1, dep2 & localDep
// `return` module valuemodule.exports = {my: "module"}
// or set properties on `exports` exports.my = "module" // `exports` is a pre-given {}
![Page 6: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/6.jpg)
uRequire.org
AMD (browser)Asynchronous Module Definition
define([“../some/path/dep1”, “other/path/dep2”,“localDep”], function(dep1, dep2, localDep) {
// do stuff with dep1, dep2, localDepreturn {my:'module'}
});
![Page 7: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/7.jpg)
uRequire.org
• Many woes on Module formats & incompatibilities
• Verbose syntax, boilerplate ceremony & intricacies (especially AMD)
• execution environment (AMD only for Web, CommonJs only for nodejs)
• capabilities, dependency/path resolutions, plugins, semantics etc are a mess
• UMD is a semi-standard boilerplate, far from usable.
• U need a bridge to enjoy the richness of modules.
Why do JavaScript developers hate modules ?
![Page 8: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/8.jpg)
uRequire.org
Mixing AMD & CommonJs ? define(['main/dep1', 'main/helpers/dep2'],
function(dep1, dep2) {
var dep3 = require('moredeps/dep3');
if (dep3(dep1) === 'wow'){
require(['./dep4'], function(dep4) {
// asynchronously do things with dep4
});
}
// do stuff with dep1, dep2, dep3
return {my:'module'}
}
);
Too many woes
AMD: “require” needs to be in [] dependencies 1st (& fn
params)
AMD: “moredeps/dep3” not listed as [] dependency,
halts
nodejs: ‘define’ is unknown (use amdefine ?)
nodejs: async ‘require’ not
working
nodejs: bundleRelative paths
not workingUnleash m
odule hell!
![Page 9: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/9.jpg)
uRequire.org
UMD: Universal Module Definition
// https://github.com/umdjs/umd/blob/master/returnExports.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['b'], factory);
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports, like Node.
module.exports = factory(require('b'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.b);
}
}(this, function (b) {
// use b in some fashion.
// Just return a value to define the module export.
// This example returns {}, but can return a function as the exported value.
return {};
}));
Not really a “Universal” one but … … 10s of proposed module templates, for different scenarios.
‘Unive
rsal’
mes
s!
![Page 10: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/10.jpg)
uRequire.org
Dependency path resolution: • nodejs: relative to requiring file (fileRelative) only:
• AMD: relative to bundle (bundleRelative) also:
• Both are useful (at times). Can we use both ?
AMD + CommonJS = neighbors from hell
var replace = require(“../../../string/replace");
• define(["utils/string/replace"], ...);
![Page 11: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/11.jpg)
uRequire.org
• Why Modularity• JavaScript module systems & woes• uRequire primer• A modules & dependencies builder• Build config usage
![Page 12: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/12.jpg)
uRequire.org
uRequire primer• Convert from any format to any other:– from AMD and CommonJS (.js, .coffee, .iced, .coco, .ls)– to AMD, CommonJS, UMD, Combined for nodejs-Web/AMD-
Web/Script– Control conversion features (runtimeInfo, globalWindow etc)
• Forget the woes or Module formats incompatibilities– Resolve paths, fill missing deps from [], inject ‘require’ etc
• Eliminate boilerplate & write modular Javascript code once, run everywhere : Web/Script, Web/AMD, nodejs
• A Universal Module Format with the power, goodies & standards from all.
• Convert to a single combined.js, that runs everywhere & is super optimized
![Page 13: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/13.jpg)
uRequire.org
• Why Modularity• JavaScript module systems & woes• uRequire primer• A modules & dependencies builder• Build config usage
![Page 14: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/14.jpg)
uRequire.org
A Modules & Dependencies aware builder.
• Exporting modules to global (like window.$) with no boilerplate.
• Want noConflict(), baked in? Its a simple declaration away.
• The same in a config:
• Export to bundle:
// file `uberscore.js` - export it to root (`window`) as `_B`
({ urequire: { rootExports: '_B', noConflict: true }});
module.exports = {...}
dependencies: { exports: { root: { 'uberscore': '_B' }}}
dependencies: { exports: { bundle: { ‘lodash': '_' }}}
![Page 15: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/15.jpg)
uRequire.org
Manipulate module dependencies
• Replace deps with mocks or alternative versions:
• With a ResourceConverter callback:
// underscore is dead, long live _
dependencies: { replace: { lodash: 'underscore'}}
function(m){ m.replaceDeps('models/PersonModel','mock/models/PersonModelMock'); }
![Page 16: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/16.jpg)
uRequire.org
Manipulate Module CodeInject, replace or delete code fragments or AST nodes:• Delete matching code of code skeleton
• Traverse matching nodes, replace or delete them
• Inject code before (or after) each module's body:
function(m){ m.replaceCode('if (debug){}') }
function(m){ m.replaceCode('console.log()', function(nodeAST){}) }
function(m) { m.beforeBody = 'var VERSION = ‘1.0’;' }
![Page 17: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/17.jpg)
uRequire.org
Manipulate Module CodeInject common or merged statements:• beforeBody can be calculated per module
• Before main body at each module:
• Like above, but merge code on 'combined' template:bundle: commonCode: 'var expect = chai.expect;'
function(m) { m.mergedCode = '"var p1 = myModule.p1, p2 = myModule.p2;"'}
function(m) { m.beforeBody = "var l = new _B.Logger('" + m.dstFilename + "');"; }
![Page 18: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/18.jpg)
uRequire.org
• Why Modularity• JavaScript module systems & woes• uRequire primer• A modules & dependencies builder• Build config usage
![Page 19: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/19.jpg)
uRequire config
uRequire.org
uberscore:
path: 'source'
dstPath: 'build'
filez: ['**/*', (f)-> f isnt 'badfile']
copy: [/./]
runtimeInfo: ['!**/*', 'Logger']
dependencies: exports:
bundle: 'lodash': '_'
root: 'uberscore': '_B'
resources: [
['+inject:VERSION', ['uberscore.js'],
(m)-> m.beforeBody = "var VERSION ='0.0.15';"]
]
template: banner: "// uBerscore v0.0.15"
read files from ‘source’
save to ‘build’
filter some filez
copy all other files
affect template selectively
inject ‘lodash’ in each module
export ‘uberscore’ as `window._B` with noConflict()
inject ‘VERSION = ..’ before body
banner after template/optimize
Can be gruntjs, .coffee / .js nodejs module, .json, .yml & more
![Page 20: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/20.jpg)
Deriving a config
uRequire.org
min:
derive: ['uberscore']
filez: ['!', /RegExpSpecs/]
template: 'combined'
dstPath: 'build/uberscore-min.js'
optimize: true
inherit deeply & modify
filter more filez
change template
optimize through Uglify2. Can also pass an options {}
• Deeply inherit / extend all properties
change destination
filez: ['**/*', (f)-> f isnt 'badfile', '!', /RegExpSpecs/]
• Either overwriting or appending props:
![Page 21: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/21.jpg)
Declarative template options
uRequire.org
globalWindow: false
runtimeInfo: ['Logger']
useStrict: true
injectExportsModule:
['circular/Dependency']
bare: true
allNodeRequires: ['/data/preCached']
noRootExports: true
scanAllow: false
window === global always
__isWeb, __isNode & __isAMD
inject 'use strict;‘
inject ‘exports’ & ‘module’
no enclosing function
& more…
• per module (minimatch of module path)• whole bundle (true)
![Page 22: uRequire@greecejs: An introduction to](https://reader033.fdocuments.net/reader033/viewer/2022052822/554f9283b4c905435d8b515e/html5/thumbnails/22.jpg)
uRequire.org
• Why Modularity• JavaScript module systems & woes• uRequire primer• A modules & dependencies builder• Build config usage
• Thank you