. βββ app β βββ app.js # β βββ bower_components # , bower.json β β βββ ... β βββ index.html β βββ scripts β β βββ controllers # Backbone β β β βββ src β β β βββ hello.jsx β β β βββ main.jsx β β β βββ notfound.jsx β β βββ router.js # β β βββ ui-components # React β β βββ src β β βββ panel β β βββ panel.jsx β β βββ panel.less β βββ styles # β βββ src β βββ main.less βββ bower.json # βββ Gruntfile.js βββ install-deps.bat # , βββ install-deps.sh # βββ install-env.bat # βββ install-env.sh # βββ package.json # node.js, (, node.js) βββ server βββ test # βββ test.config.js βββ ui-components βββ src βββ panel.test.jsx
/* * app/app.js * index.html, require * (Backbone). */ 'use strict'; requirejs.config({ baseUrl: './', paths: { app: './scripts', controllers: './scripts/controllers/dest', // dest - "" .jsx .less ui: './scripts/ui-components/dest', // underscore: './bower_components/underscore/underscore', backbone: './bower_components/backbone/backbone', jquery: './bower_components/jquery/dist/jquery.min', react: './bower_components/react/react' } });
/* * app/scripts/router.js */ 'use strict'; define(function(require) { var Backbone = require('backbone'); var AppRouter = Backbone.Router.extend({ routes: { '': 'MainCtrl', 'hello/:name(/)': 'HelloCtrl', '*actions': 'NotFoundCtrl' }, MainCtrl: require('controllers/main'), HelloCtrl: require('controllers/hello'), NotFoundCtrl: require('controllers/notfound') }); return new AppRouter(); });
/* * app/scripts/controllers/src/hello.jsx */ 'use strict'; define(['react', 'ui/panel/panel'], function(React, Panel){ /* */ return function(name){ /* * , , . * (). */ React.render( <Panel title="Hello controller"> <h1>Hello, {name}!</h1> </Panel>, document.body); }; });
. /* * app/scripts/ui-components/src/panel.jsx */ define(['react'], function(React){ 'use strict'; var Panel = React.createClass({ render: function(){ return ( <div className="panel panel-default"> <div className="panel-heading"> <h1>{this.props.title}</h1> </div> <div className="panel-body"> {this.props.children} </div> </div>); } }); return Panel; });
/* * test/ui-components/src/panel.test.jsx */ 'use strict'; define(['react', 'ui/panel/panel'], function(React, Panel) { describe('Panel behaviour tests', function() { var TestUtils = React.addons.TestUtils; var panel; var p; /* * this.setUp() xxxUnit */ beforeEach(function(){ panel = TestUtils.renderIntoDocument(( <Panel title="Test"> <p>Paragraph content</p> </Panel>)); }); /* */ it('Should render itself into DOM', function(){ expect(TestUtils.isCompositeComponent(panel)).toBe(true); }); /* , */ it('Should render title from props', function(){ var h1 = TestUtils.findRenderedDOMComponentWithTag(panel, 'h1'); expect(h1.getDOMNode().innerHTML).toBe('Test'); }); /* */ it('Should render children from props', function(){ var paragraph = TestUtils.findRenderedDOMComponentWithTag(panel, 'p'); /* * Specific react feature, it does not render text node directly, * but renders <span ... >Paragraph content</span> */ expect(paragraph.getDOMNode().innerHTML).toContain('Paragraph content'); }); }); });
<html> <head> <title>React+Backbone</title> <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="styles/dest/styles.css"> </head> <body> <div id="main"></div> <script type="text/javascript" src="bower_components/requirejs/require.js"></script> <script type="text/javascript" src="app.js"></script> <script src="//localhost:35729/livereload.js"></script> </body> </html>
Source: https://habr.com/ru/post/250103/
All Articles