UNPKG

yui-pathogen-encoder

Version:

Enables pathogen encoding in YUI Loader

79 lines (78 loc) 14.4 kB
{ "name": "express-yui", "description": "Express extension for YUI Applications", "version": "0.6.2", "homepage": "https://github.com/yahoo/express-yui", "author": { "name": "Caridy Patino", "email": "caridy@yahoo-inc.com", "url": "http://github.com/caridy" }, "contributors": [ { "name": "alberto chan", "email": "albertoc@yahoo-inc.com" } ], "engines": { "node": ">=0.8.x", "npm": ">=1.2.10" }, "dependencies": { "express-combo": "0.1.x", "express-state": "~1.0.0", "mkdirp": "*", "shifter": "*", "win-spawn": "*", "debug": "*" }, "peerDependencies": { "express": "3.x", "yui": "3.x" }, "devDependencies": { "express": "3.x", "express3-handlebars": "*", "jshint": "~1.1.0", "locator": "~0.3.0", "locator-handlebars": "*", "locator-micro": "*", "mockery": "1.4.x", "tmp": "*", "ytestrunner": "0.3.x", "yui": "3.x", "yui-lint": "~0.1.3", "yuitest": "0.7.x", "yuidocjs": "0.3.x" }, "main": "index", "keywords": [ "framework", "yui", "mojito", "modown", "javascript", "express" ], "directories": { "lib": "./lib", "example": "./examples" }, "repository": { "type": "git", "url": "https://github.com/yahoo/express-yui.git" }, "bugs": { "url": "https://github.com/yahoo/express-yui/issues" }, "scripts": { "test": "node ./node_modules/ytestrunner/lib/cli.js -c --include tests/units/**/*.js", "unit": "node ./node_modules/ytestrunner/lib/cli.js --include tests/units/**/*.js", "lint": "node ./node_modules/.bin/jshint --config ./node_modules/yui-lint/jshint.json ./lib/*.js", "docs": "node ./node_modules/.bin/yuidoc --config ./conf/yuidoc.json ./lib" }, "readme": "Express YUI\n===========\n\n[Express][] extension for YUI Applications.\n\n[![Build Status](https://travis-ci.org/yahoo/express-yui.png?branch=master)][Build Status]\n\n\n[Express]: https://github.com/visionmedia/express\n[Build Status]: https://travis-ci.org/yahoo/express-yui\n\n\nGoals & Design\n--------------\n\nThis compontent extends express by adding a new member `app.yui` to the\nexpress application. It is responsible for controlling and exposing the yui\nconfiguration and the app state into the client side as well has controlling\nthe yui instance on the server.\n\n\nInstallation\n------------\n\nInstall using npm:\n\n```shell\n$ npm install express-yui\n```\n\n\nFeatures\n--------\n\n### Features\n\n * expose yui config and seed files per request\n * provide basic configurations for cdn, debug, and other common conditions in yui\n * provide middleware to serve `static` assets from origin server, including\ncombo capabilities built-in.\n * provide middleware to `expose` the app state and the yui config into the\n view engine to be used in the templates to boot YUI and the app in the client side.\n\n\n### Other features\n\n * built-in integration with [locator][] component to analyze and build applications and dependencies using [shifter][].\n * provide basic express view engine to rely on views registered at the server side thru the `app.yui.use()` as compiled templates.\n\n[locator]: https://github.com/yahoo/locator\n[shifter]: https://github.com/yui/shifter\n\n\nUsage\n-----\n\n### Extending express functionalities\n\n`express-yui` is a conventional `express` extension, which means it will extend\nthe functionalities provided on `express` by augmenting the express app instance\nwith a new member called `yui`. At the same time, `express-yui` provides a set of\nstatic methods that you can call directly off the `express-yui` module, those\nmethods are utility methods and express middleware.\n\nHere is an example of how to extend an `express` app with `express-yui`:\n\n```\nvar express = require('express'),\n expyui = require('express-yui'),\n app = express();\n\n// calling a static method to extend the `express` app instance\nexpyui.extend(app);\n// using the new `yui` member off the app instance\napp.yui.applyConfig({ fetchCSS: false });\n```\n\nAs you can see in the example above, the `yui` member is available off the app instance after extending the `express` app.\n\n\n### Exposing app state into client\n\nTo expose the state of the app, which includes the yui configuration computed based\non the configuration defined thru the express app instance, you can call the `expose`\nmiddleware for any particular route:\n\n```\nvar expyui = require('express-yui'),\n express = require('express'),\n app = express();\n\nexpyui.extend(app);\napp.get('/foo', expyui.expose(), function (req, res, next) {\n res.render('foo');\n});\n```\n\nBy doing `expyui.expose()`, `express-yui` will provision a property call `state` that\ncan be use in your templates as a `javascript` blob that sets up the page to run\nYUI with some very specific settings coming from the server. If you use `handlebars`\nyou will do this:\n\n```\n<script>{{{state}}}</script>\n<script>\napp.yui.use('node', function (Y) {\n Y.one('body').setContent('<p>Ready!</p>');\n});\n</script>\n```\n\nAnd this is really the only thing you should do in your templates to get YUI ready to roll!\n\n\n### Using the locator plugin to build the app\n\n`express-yui` provides many features, but the real power of this package can be seen when\nusing it in conjunction with [locator][] component.\n\n```\nvar express = require('express'),\n expyui = require('express-yui'),\n app = express();\n\nexpyui.extend(app);\n\n// serving static yui modules built by locator\napp.use(expyui.static());\n\napp.get('/foo', expyui.expose(), function (req, res, next) {\n res.render('foo');\n});\n\n// using locator to analyze the app and its dependencies\nnew (require('locator'))({\n buildDirectory: 'build'\n}).plug(app.yui.plugin({\n // provision any yui module to be available on the client side\n registerGroup: true,\n // only needed if you want yui modules available on the server runtime as well\n registerServerModules: true\n})).parseBundle(__dirname, {});\n\napp.listen(8080);\n```\n\nAs a result, any yui module under `__dirname` folder or any npm dependency marked as\na locator bundle will be built by the `express-yui`'s locator plugin, and automatically\nbecome available on the client, and potentially on the server as well. This means you\nno longer need to manually define loader metadata or any kind of yui config to load those\nmodules, and `express-yui` will be capable to handle almost everthing for you.\n\n\n### Using yui modules on the server side\n\nUsing modules on the server is exactly the same that using them on the client thru\n`app.yui.use()` statement. Here is an example of the use of yql module to load the\nweather forecast and passing the result into the template:\n\n```\napp.get('/forecast', expyui.expose(), function (req, res, next) {\n req.app.yui.use('yql', function (Y) {\n Y.YQL('select * from weather.forecast where location=90210', function(r) {\n // r contains the result of the YQL Query\n res.render('forecast', {\n result: r\n });\n });\n });\n});\n```\n\n_note: remember that `req.app` holds a reference to the `app` object for convenience._\n\n\n### Using Y.Template on the server side\n\n`express-yui` ships with a custom `express` view class implementation which allows to control `res.render()` calls. Normally, `express` along with some specific view engine can do the work of compiling and rendering templates on the server side, but `express-yui` is striking for bringing parity between server and client, and for that, it supports the use of compiled-to-javascript templates that can be used on the server and client alike.\n\nFor that, you just need to hook `app.yui.view()` into express, by doing this:\n\n```\napp.set('view', app.yui.view());\n```\n\nWith the code above, there is not need to define anything else in express in terms of engine, or path to views, or anything else, all that is irrelevant since `express-yui` will completely take over the `express`'s template resolution process, and will drive it thru `Y.Template`, which means you can call `res.render('foo')` in your middleware, and `express-yui` will resolve `foo` template. `express-yui` will try to find `foo` template within the `Y.Template` internal cache, and call for render if the exists.\n\n#### Layout\n\nYou can also define a default layout:\n\n```\napp.set('view', app.yui.view({\n defaultLayout: 'bar'\n}));\n```\n\nIf you use `defaultLayout` as above, or just by providing the `layout` value when calling `res.render('foo', { layout: 'bar' })`, `express-yui` will resolve the `view`, render it, and the result of that operation will be passed into the layout render thru a context variable called `outlet`, this is similar to `emberjs`. In a handlebars template, you will define the `outlet` like this:\n\n```\n<div>{{{outlet}}}</div>\n```\n\n#### Bundle (optional)\n\nIf your templates are part of a NPM dependency, you have to tell `express-yui` and the `view` how to resolve those templates from a different package, for that, you can define `defaultBundle`:\n\n```\napp.set('view', app.yui.view({\n defaultBundle: 'name-of-package-with-templates'\n}));\n```\n\nIf you use `defaultBundle` as above, or just by providing the `bundle` value when calling `res.render('foo', { bundle: 'name-of-package-with-templates' })`, `express-yui` will lookup for the template under the specified bundle. Internally, all templates will be prefixed with the package name of their corresponding NPM package, and the `bundle` will be used to specify what prefix to use.\n\n### Using [Locator] plugins\n\nIf you use `locator` component plus other plugins like `locator-handlebars` to precompile templates into YUI Modules, then when calling `res.render('foo')`, `express-yui` can resolve `foo` automatically based on the compiled version. Check this example to see `app.yui.view()` in action:\n\n * https://github.com/yahoo/express-yui/tree/master/examples/locator-express\n\nMore information about this new feature in express here:\n\n * http://caridy.name/blog/2013/05/bending-express-to-support-synthetic-views/\n\n\n### Registering yui groups manually\n\n\nIf you are not using [locator][] component for whatever reason, you will be responsible\nfor building yui modules, grouping them into yui groups and registering them thru\n`app.yui.registerGroup` method. Here is how you register a folder that has the build\nresult with all yui modules compiled thru [shifter][]:\n\n```\napp.yui.registerGroup('foo', 'path/to/foo-1.2.3');\n```\n\nAgain, this is absolutely not needed if you use [locator][].\n\n### Serving static assets from app origin\n\nIdeally, you will use a CDN to serve all static assets for your application, but your\nexpress app is perfectly capable to do so, and even serve as origin server for your CDN.\n\n```\napp.yui.setCoreFromAppOrigin();\napp.use(expyui.static());\n```\n\nWith this configuration, a group called `foo` with version `1.2.3`, and `yui` version `3.11.0`, it will produce urls like these:\n\n * /combo~/yui-3.11.0/yui-base/yui-base-min.js~/foo-1.2.3/bar/bar-min.js~/foo-1.2.3/baz/baz-min.js\n * /yui-3.11.0/yui-base/yui-base-min.js\n * /foo-1.2.3/bar/bar-min.js\n\nAny of those urls will be valid because `express-yui` static middleware will serve them and\ncombo them when needed based on the configuration of yui.\n\n### Serving static assets from CDN\n\nIf you plan to serve the `build` folder, generated by [locator][], from your CDN, then make\nsure you set the proper configuration for all groups so loader can know about them.\nHere is the example:\n\n```\napp.set('yui combo config', {\n comboBase: 'http://mycdn.com/path/to/combo?',\n comboSep: '&',\n maxURLLength: 1024\n});\napp.set('yui default base', 'http://mycdn.com/path/to/static/{{groupDir}}/');\napp.set('yui default root', 'static/{{groupDir}}/');\n```\n\nIn this case you don't need to use `expyui.static` middleware since you are not\nserving local files, unless the app should work as origin server.\n\nWith this configuration, a group called `foo` with version `1.2.3` will produce urls like these:\n\n * http://mycdn.com/path/to/combo?static/foo-1.2.3/bar/bar-min.js&static/foo-1.2.3/baz/baz-min.js\n * http://mycdn.com/path/to/static/foo-1.2.3/bar/bar-min.js\n\n\n### CSS modules and assets\n\nYou can get `express-yui` to compile yui css modules as well, for that, you need to use a json file that describe how to locate and build the css modules. This is the same technique we use in `yui` to build css modules. Here is an example of such as file (build.json):\n\n```\n{\n \"name\": \"styles\",\n \"builds\": {\n \"cssdemo\": {\n \"cssfiles\": [\n \"demo.css\"\n ],\n \"config\": {\n \"type\": \"css\"\n }\n }\n }\n}\n```\n\nAside from that, there are a couple of things you need to keep in mind about yui css modules:\n\n* `cssfiles` from the example above are relative to a `css` folder that is located at the same level than `build.json`.\n* YUI css modules can contain assets (usually located under the `assets` folder at the same level), but if you use a combo, then the path for those assets will not resolve correctly. More info about this problem [here](https://github.com/davglass/cssproc#css-relative-url-processor). To solve this you can enable `cssproc` configuration when you plug the plugin:\n\n```\nlocatorObj.plug(app.yui.plugin({\n cssproc: true\n}));\n```\n\nAPI Docs\n--------\n\nYou can find the [API Docs][] under `apidocs` folder, and you can browse it thru this url:\n\n* http://rawgithub.com/yahoo/express-yui/master/apidocs/index.html\n\n[API Docs]: https://github.com/yahoo/express-yui/tree/master/apidocs\n\n\nLicense\n-------\n\nThis software is free to use under the Yahoo! Inc. BSD license.\nSee the [LICENSE file][] for license text and copyright information.\n\n[LICENSE file]: https://github.com/yahoo/express-yui/blob/master/LICENSE.md\n\n\nContribute\n----------\n\nSee the [CONTRIBUTE file][] for info.\n\n[CONTRIBUTE file]: https://github.com/yahoo/express-yui/blob/master/CONTRIBUTE.md\n", "readmeFilename": "README.md", "_id": "express-yui@0.6.2", "_from": "express-yui@~0.6.0" }