|
1 | | - |
2 | | - |
3 | 1 | >Apps like django-pipeline and django-compressor have done a great job with static assets. I’ve been a great fan of django-pipeline actually but I hate how they take away all the transparency in order to make things a bit magical. They are limited in what they can do by the staticfiles system. They are opaque and make it harder to debug problems. They also need companion apps for to integrate any new javascript tool like gulp or browserify. Even after having all these wrappers, the experience can be quite rough at times. Documentation and resources available for javascript tools are not directly applicable sometimes when using these wrappers. You’ve an additional layer of software and configuration to worry about or wonder how your python configuration translates to the javascript. Things can be much better. - Owais Lone |
4 | 2 |
|
5 | 3 | ### Rendering |
@@ -124,10 +122,92 @@ npm run build |
124 | 122 | npm run react-service |
125 | 123 | ``` |
126 | 124 |
|
127 | | -### Conclusion |
| 125 | +### Pythonflow |
128 | 126 | - Python HTTP API sends bundle to node server |
129 | 127 | - Node server recieves component |
130 | 128 | - Returns rendered bundle |
131 | 129 | - Import and use in templates |
132 | 130 |
|
| 131 | +## V2 |
| 132 | + |
| 133 | +When researching ways to make JSX deployment easier for designers, I found [react-router](https://github.com/reactjs/react-router), which, in combination with webpack and a node server (probably express.js), was the missing piece in order to really integrate Reactjs as a frontend by replacing urls.py as well. In order for this to work, the Django app must use DRF (or some form of an API), and react-router + webpack + a render service = the full front end suite. Here's a quick example pulled from example code from their repo which shows how powerful the library is at replacing Django's routing service: |
| 134 | + |
| 135 | +```Javascript |
| 136 | +render(( |
| 137 | + <Router history={browserHistory}> |
| 138 | + <Route path="/" component={App}> |
| 139 | + <Route path="about" component={About}/> |
| 140 | + <Route path="users" component={Users}> |
| 141 | + <Route path="/user/:userId" component={User}/> |
| 142 | + </Route> |
| 143 | + <Route path="*" component={NoMatch}/> |
| 144 | + </Route> |
| 145 | + </Router> |
| 146 | +), document.body) |
| 147 | +``` |
| 148 | + |
| 149 | +### Javascriptflow |
| 150 | +With this, the workflow goes along these lines: |
| 151 | + |
| 152 | +- Designer writes .jsx file |
| 153 | +- Adds the file to js/components, and builds the webpack |
| 154 | +- appropriate edits are made to router file, which pulls from the Django API |
| 155 | + |
| 156 | +The .jsx file acts like this: |
| 157 | + |
| 158 | +- Originally written as a component (keeping it DRY) |
| 159 | +- Bundled with webpack |
| 160 | +- Is rendered by node.js server |
| 161 | +- Content is returned to client |
| 162 | +- *content can be cached, allowing quicker page load speeds |
| 163 | + |
| 164 | +Obviously, this is a much larger project, but with is more flexible from a designing perspective, ***WHY*** |
| 165 | + |
| 166 | +With this workflow, the normal webpack template tags would be used to replace the HTML: |
| 167 | + |
| 168 | +```HTML |
| 169 | +{% load render_bundle from webpack_loader %} |
| 170 | +<html> |
| 171 | + <head> |
| 172 | + {% render_bundle 'main' 'css' %} |
| 173 | + </head> |
| 174 | + <body> |
| 175 | + .... |
| 176 | + {% render_bundle 'main' 'js' %} |
| 177 | + </body> |
| 178 | +</head> |
| 179 | +``` |
| 180 | + |
| 181 | +In order to pass props through the components (since you would no longer declare them in views.py, you'd implement this: |
| 182 | + |
| 183 | +```Javascript |
| 184 | +var Dashboard = require('./Dashboard'); |
| 185 | +var Comments = require('./Comments'); |
| 186 | +var RouteHandler = require('react-router/modules/mixins/RouteHandler'); |
| 187 | + |
| 188 | +var Index = React.createClass({ |
| 189 | + mixins: [RouteHandler], |
| 190 | + render: function () { |
| 191 | + var handler = this.getRouteHandler({ myProp: 'value'}); |
| 192 | + return ( |
| 193 | + <div> |
| 194 | + <header>Some header</header> |
| 195 | + {handler} |
| 196 | + </div> |
| 197 | + ); |
| 198 | + } |
| 199 | +}); |
| 200 | +var routes = ( |
| 201 | + <Route path="/" handler={Index}> |
| 202 | + <Route path="comments" handler={Comments}/> |
| 203 | + <DefaultRoute handler={Dashboard}/> |
| 204 | + </Route> |
| 205 | +); |
| 206 | +ReactRouter.run(routes, function (Handler) { |
| 207 | + React.render(<Handler/>, document.body); |
| 208 | +}); |
| 209 | +``` |
| 210 | + |
| 211 | +### Conclusion |
| 212 | + |
133 | 213 | After much research and toying with different tools, using a node.js service like [react-render](https://github.com/mic159/react-render) along with webpack is the best solution for replacing Django's frontend. Using Django solely as an API once React has been implemented is also best practice (remember, JSX files render both JS and HTML). Webpack rocks, and React is the future of front end. Thanks for reading :) |
0 commit comments