Javascript 实现 (ES6+ 编写)的 Rails Routing 风格的路由系统。
通过它可以生成 routes mapper,借助 routes mapper 可以进行 DIY ,方便、简化路由入口与其他模块的整合开发。
基本上实现算法都是参照 actionpack/lib/action_dispatch/routing 及好文 Rails 路由系统源码探索。
使用 Javascript ES6+ 进行编写开发(跟上时代步伐……)。
rails new blog
生成路由模板)let routeMapper = new RouteMapper(); routeMapper.draw((m) => { // You can have the root of your site routed with "root" m.root('welcome#index'); // /products/233 cOntroller= catalog, action = view m.get('products/:id', { to: 'catalog#view' }); // Example named route that can be invoked with purchase_path(id: product.id) // /products/233/purchase === purchase_path(233) m.get('products/:id/purchase', { to: 'catalog#purchase', as: 'purchase' }); // Example resource route (maps HTTP verbs to controller actions automatically): m.resources('products'); // Example resource route with options: m.resources('products', () => { m.member(() => { m.get('short'); m.post('toggle'); }); m.collection(() => { m.get('sold'); }); }); // Example resource route with sub-resources: m.resources('products', () => { m.resources('comments', 'sales'); m.resource('seller'); }); // Example resource route with more complex sub-resources: m.resources('products', () => { m.resources('comments') m.resources('sales', () => { m.get('recent', { on: 'collection' }); }); }); // Example resource route with concerns: m.concern('toggleable', () => { m.post('toggle'); }); m.resources('posts', { concerns: 'toggleable' }); m.resources('photos', { concerns: 'toggleable' }); // Example resource route within a namespace: m.namespace('admin', () => { // Directs /admin/products/* m.resources('products'); }); });
import express from 'express'; import RouteMapper from '../..'; let app = express(); let routeMapper = new RouteMapper(); routeMapper.draw((m) => { m.root('welcome#index'); m.resources('photos'); m.constraints({ subdomain: 'api' }, () => { m.namespace('api', { defaults: { format: 'json' }, path: '/' }, () => { m.scope({ module: 'v1' }, () => { m.resources('users'); }); } ); }); }); app.use(function (req, res, next) { res.locals.urlHelpers = routeMapper.urlHelpers; next(); }); routeMapper.routes.forEach((r) => { r.via.forEach((m) => { let controller = r.controller; let action = r.action; let c = require(__dirname + '/controllers/' + controller + '.js'); let a; if (c && (a = c[action])) { if (!Array.isArray(a)) { a = [a]; } app[m](r.path, ...a); }; }); }); app.listen(3300);
import koa from 'koa'; import router from 'koa-router'; import RouteMapper from '../..'; let app = koa(); let routeMapper = new RouteMapper(); routeMapper.draw((m) => { m.root('welcome#index'); m.get('about', { to: 'welcome#about' }); m.resources('posts', () => { m.resources('comments'); }); m.scope({ path: '~:username?', module: 'users', as: 'user'}, () => { m.root('welcome#index'); }); }); app.use(function *(next) { this.urlHelpers = routeMapper.urlHelpers; yield next; }); app.use(router(app)); routeMapper.routes.forEach((r) => { r.via.forEach((m) => { let controller = r.controller; let action = r.action; let c = require(__dirname + '/controllers/' + controller + '.js'); let a; if (c && (a = c[action])) { if (!Array.isArray(a)) { a = [a]; } app[m](r.path, ...a); }; }); }); app.listen(3300);
Rails 在这些地方的设计确实很棒,Express.js,Koa.js 等 Node.js Web 框虽然 DIY 等能力很强,但总感觉过于松散,每次下手都得对目录结构想一番。
该模块还在不懂的完善中。:)
![]() | 1 GPU 2015-01-19 23:45:10 +08:00 via iPhone 轮子哦,赞赞 |
![]() | 2 Temo 2015-01-23 14:09:15 +08:00 via iPhone 赞一个! |