Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

uRequire@greecejs: An introduction to http://uRequire.org

15,614 views

Published on

uRequire presented at GreeceJs (Greek JavaScript User Group) @ hackerspace.gr on 04-June-2014

Published in: Software, Technology
  • Be the first to comment

uRequire@greecejs: An introduction to http://uRequire.org

  1. 1. The JavaScript Universal Module & Resource Converter “Write modular JavaScript code once, run everywhere” is a reality. uRequire.org
  2. 2. • Why Modularity • JavaScript module systems • uRequire primer • A modules & dependencies builder • Build config usage uRequire.org
  3. 3. 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 uRequire.org
  4. 4. • Why Modularity • JavaScript module systems & woes • uRequire primer • A modules & dependencies builder • Build config usage uRequire.org
  5. 5. 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 value module.exports = {my: "module"} // or set properties on `exports` exports.my = "module" // `exports` is a pre-given {} uRequire.org
  6. 6. AMD (browser) Asynchronous Module Definition define([“../some/path/dep1”, “other/path/dep2”,“localDep”], function(dep1, dep2, localDep) { // do stuff with dep1, dep2, localDep return {my:'module'} } ); uRequire.org
  7. 7. • 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. uRequire.org Why do JavaScript developers hate modules ?
  8. 8. 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'} } ); uRequire.org 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 working
  9. 9. 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 {}; })); uRequire.org Not really a “Universal” one but … … 10s of proposed module templates, for different scenarios.
  10. 10. 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 ? uRequire.org AMD + CommonJS = neighbors from hell var replace = require(“../../../string/replace"); • define(["utils/string/replace"], ...);
  11. 11. • Why Modularity • JavaScript module systems & woes • uRequire primer • A modules & dependencies builder • Build config usage uRequire.org
  12. 12. 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 uRequire.org
  13. 13. • Why Modularity • JavaScript module systems & woes • uRequire primer • A modules & dependencies builder • Build config usage uRequire.org
  14. 14. 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: uRequire.org // 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': '_' }}}
  15. 15. Manipulate module dependencies • Replace deps with mocks or alternative versions: • With a ResourceConverter callback: uRequire.org // underscore is dead, long live _ dependencies: { replace: { lodash: 'underscore'}} function(m){ m.replaceDeps('models/PersonModel','mock/models/PersonModelMock'); }
  16. 16. Manipulate Module Code Inject, 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: uRequire.org function(m){ m.replaceCode('if (debug){}') } function(m){ m.replaceCode('console.log()', function(nodeAST){}) } function(m) { m.beforeBody = 'var VERSION = ‘1.0’;' }
  17. 17. Manipulate Module Code Inject common or merged statements: • beforeBody can be calculated per module • Before main body at each module: • Like above, but merge code on 'combined' template: uRequire.org 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 + "');"; }
  18. 18. • Why Modularity • JavaScript module systems & woes • uRequire primer • A modules & dependencies builder • Build config usage uRequire.org
  19. 19. 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
  20. 20. 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:
  21. 21. 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)
  22. 22. • Why Modularity • JavaScript module systems & woes • uRequire primer • A modules & dependencies builder • Build config usage •Thank you uRequire.org
  23. 23. uRequire.org

×