Take the goRe out of a DjangoReact stack
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Gaberel, Nathan
Developing, packaging and integrating JS apps with Django. As a Django dev you cannot ignore Javascript frameworks anymore. But integrating React (or any javascript framework) with Django is not seamless: there’s no documented guide to setup a project, getting hot reloading to work is a painful must-have, and then how do you even leverage the power of both frameworks to code faster? Doing this without losing time and productivity is very hard. After 4 years of building a dozen django/react projects at Theodo, I want to share with you the very efficient setup we came up with, both for development and production use. In this session we’ll see how to: setup a JS frontend alongside Django for a smooth development experience (with hot reloading!) package and deploy a js app with a Django project make frontend and backend work together: automatically harvest Django REST framework validation errors inside redux-form and get free validation in React
 Hi. Hello. Okay. So my name is Nathan and I'm going to be talking about building and architecture in Django alongside JavaScript applications. So I'm a full-time developer. I work with Django and React on most of the projects I work on. However, and despite the name of this talk, after a few months, I really start to dislike it. So despite the name, it's not about React. Most of what I'm going to say is it works exactly the same if you're using Angular, Vue, or Ember, any modern framework. If anything, it's maybe a bad webpack, but we'll come back to this. Okay. So just to get started, by show of hand, who here uses a similar stack with a modern JS framework alongside Django? Okay. So quite a few of you. So I don't know about you guys, but I really find this exercise of setting up a JS framework alongside Django to really not being a trivial exercise. I think the main reason is there's no standard documented implementation guidelines or even architecture and guidelines. So I think it's something that we still can improve in the Django community. So it's something I've done quite a few projects, and my goal for this talk is to take you through some of the design decisions that we can make to try and build such an application, how it's going to work in development and production. And in this talk, I'll also try and show you what it ends up looking like in the code. So before I start, a quick catch up on the JS tool chain. I'm not sure everyone knows about this. So very quickly, NPM is the main JavaScript package repository. It's actually both the repository and the client for the repository. So it's equivalent to both PyPI and PIP. Webpack is the main build tool for more than JS applications. So it's what produces the bundle that's the JavaScript source code that ends up being shipped to the browser. There's no direct equivalent for this in Python because we can just run the Python code. And Webpack Dev Server is a wrapper on Webpack that's much like the Django hotel reloader, looks for changes in the source code, recompiles, and sells those files on the server. So in this first part, I want to go through a quick recap of Django's history and the tools we've had to handle JavaScript files. And the goal here is also to set up a common vocabulary so we can all be talking about the same thing. So when Django came out in 2005, the main use for JS back then was to sprinkle on top of HTML pages that were otherwise generated by the backend. And for this, we had tools like Django pipeline and Django compressor who came out in 2008, 2009. And their main goal was to take this JavaScript source code that usually lived in the static folders of Django, minify it, render a script tag in the template, and that was it. And a few less later, Django and Chain came out and that really messed up my chart. So if you were wondering what the spec is, let's check on Chain. But around the same time, you can see the red and the blue lines, it's angular and then a couple years after a react. So the modern frameworks that the most common modern frameworks that are coming out in 2012, 2014, I think. And those frameworks need much more potent build pipelines. They need integration with the JS packages. They need to pull in dependencies from NPM. They need to be able to work with image files, font files, CSS, et cetera. And so that's where Django pipeline and Django compressor weren't enough anymore. And the front end community came up with something called Webpack, which solves all of this problem. So a few less later in 2015, Django Webpack came out and it's the first setup at integrating Webpack and Django together. So the goal here was to really separate the responsibilities of building the JavaScript for the browser and serving it. Before that, Django pipeline, Django compressor and equivalent were doing all of this. From now on, we would leave Webpack in charge of building this bundle and Django in charge of just generating a script tag that links to it. And so it transformed the development environment from a single process where Django is in charge of serving and generating the HTML and the JS to a dual environment where we have both Webpack and Django running. And Django would still be in charge of generating the HTML but then point to Webpack, which would serve the JS. So something else I want to mention in this section is Amrik Augustin's blog article series from last year, because they really helped me out and meet on formulating a lot of what I've been thinking about. So his blog article is about a series of formalization of the requirements for building a Django application. So it's very much linked to what I'm talking about. And the main thing I remember from this is his taxonomy of JS applications. There's basically two kinds of JS applications or two kinds of architecture. The single page applications and in hybrid applications. And I come back to this in the example slides. And in his blogs, he also talks about production and development parity, authentication, cores, CSRF, et cetera. So I really recommend going there if you're working on Django and JavaScript. So in Amrik's taxonomy, a single page application is an application where the HTML is purely static and never changes. So it's not rendered by Django. It can be a static file that's served by Nginx or Apache alongside the JS files. And in this context, Django is purely used as an API. And so typically in a production setting, the browser would end up making requests to two different origins. The front end where it would load all the static files, HTML, CSS, JS images. And the back end where Django runs as the API. And the counterpart is the hybrid application where the HTML is served by Django and potentially as a template rendered by the Django team engine. And so you end up with an application running where the DOM is a mix of the HTML that was generated by Django and whatever JavaScript framework, whatever changes it brought to this DOM. And typically in the hybrid application, the browser ends up only talking to one origin where it would first load the HTML, which would be rendered for it, and then load the JS. And API calls, of course. So both infrastructures have pros and cons. There's no silver bullet, of course. And even once you've been able to pick between single page application and hybrid application, depending on what's right for you, there's still a lot of implementation details that will vary between implementations. Still a lot more of design decisions. So now that's exactly what I want to go through from designing a Django and JavaScript architecture together. So before we go and start making random design decisions, it's probably better that we agree on a set of requirements first on what we want the application to be able to achieve. So of course, those requirements will vary a lot between projects. And the example I have here is something that's very typical for the project I work on. But they are binominal. They might not apply to your use case. For example, I think a typical requirement that I don't have is around having to separate the code base between front end and back end. I think separate also deployment flow between front end and back end. I work in a team where everyone is full stack, so that's fine for me. But I know lots of companies out there have different teams for front end and back end. And I think if that was a requirement for you, you would end up with a very different solution. But hopefully, I think the reasoning here will apply whatever your use case and you should be able to use this on your own projects. So sorry. My requirements are I want underignment independent builds. So I'll come back to what I mean exactly for each of them in a minute. I want hot reloading and development. And I want development and production parity. So for underignment independent builds, first of all, do I mean by build? By build, I mean whatever code artifact you ship to a server when you deploy. It could be a file archive, a Docker image, a binary bit and conventionally Python, but a commit in a Git repository, for example. And why this is important to me is because it allows me to do version promotion. When I've had a version running in one environment for a while and I know it fixes the problem I intended to solve, then I can take this exact build, this exact set of code and then send it to a different environment. This is something that I discovered on Heroku, a while back, and it really stuck with me. So yeah, that brings a lot of trust in what I'm about to deploy and I know I'm going to break the next environment down the line. So how might I achieve this? The first, the view sensor is to not have any environment-specific values encoded in the code. And the main way to do this is to use environment variables. The main, when I'm talking about this section, is very related to the 12-factor app. So if you don't know about this, I really recommend you go and read the 12 pages on 12factor.net. It's very interesting. So environment variables, they're really easy to use in Django. That's not a problem at all. In the back end, we can read them anywhere on the code and read them in the settings and then read the settings. So Django is really easy to write in an environment in a better way as long as you have access to environment variables on your server. But in JavaScript, it's a bit of a different story. The other thing that's a bit harder, typically, the main bit of config you would need in the JavaScript application is the API endpoint. Where am I going to send my request to? For example, in production, I might want to connect to api.example.com over HTTPS, while in development, I'm going to connect to localhost on port 8000 over HTTP. So, of course, JavaScript doesn't have a concept of environment variable. We can't set environment variables in our users' browsers. So as far as I can tell, that leaves us with two options. Either we find a way to load the config when the application starts from somewhere. That probably means an API call. And if I'm making an API call to what endpoint, it's kind of snake-hitting its own tail. That's probably not going to work. The alternative I can see is to inject the configuration inside of the HTML during rendering in Django. So that means that our HTML has to be a Django template. So that means we're using a hybrid application in Augustine's taxonomy. And one way you might, this would translate in the template. If this is the template for your JavaScript application, you might want to write a global config variable in JavaScript with the set of, this is an example, but I'm setting, for example, an API endpoint that's actually just a context variable in Django templates. And also, all the business logic values that are actually coming from the database. Right. Okay. So that was environment independence. Next, hot reloading in development. So hot reloading is this very powerful front-end development feature that's very much like Django, what the Django hot reloader provides. It's based on Webpack Dev server. And as soon as I make a change in my JavaScript source code, in my browser refreshes, and I can see the change immediately in my browser. So it really shortens the feedback look from writing a code and potentially a bug and then detecting it. So this feature relies on Webpack Dev server, as I just said, and there's actually two levels to it. There's live reloading where, as soon as I make a change in my source code, then it gets picked up and my browser refreshes. So that means I do see the change in my browser, but I lose all the variables, values, I lose all of my context where I was in the application, et cetera. So it's a start, but not great. And then hot reloading is the next step. It's where instead of triggering a refresh of the page, Webpack Dev server is going to send the new rebuild chunk of our Websocket to the browser. And the browser is going to replace it in place with that trigger refresh. So I get to keep my variable where I was in the application, et cetera. Right. So let's start with hot reloading, actually, and it's going to be quick. So hot reloading uses Websocket on Webpack Dev server. And as I just described, the way it looks like is in development, you load the HTML from Django, which would then point to the static phase in Webpack Dev server. And then every time I make a change to my JavaScript source code, then Webpack is going to ship those hot updates of our Websocket and my application is going to update itself. So I've got one big problem with hot reloading. And it's because I'm using create react app, which is the main react boilerplate out there, and it's broken. I won't go into why if you're interested, then we can discuss this after the talk when I'm working for feedback from the folks at Facebook. If you are not using create react app and you're using a vanilla or a custom setup of Webpack Dev server, then they might just work. So taking a step back and let's take a step back and just aim for live reloading, for live loading to work. All I need is to make sure that my JavaScript source code is coming from Webpack Dev server. So that leaves us again with two options. Either when the application, when I load the page on my browser, it's able to tell which files I need on Webpack Dev server and dynamically load them in the page. Or Django is able to render all of the scripts in the page for me at random time and serve the HTML to my browser. So it loads the files. And both of them work. Both of them are fine. And to help us decide between those two solutions, one thing we could do is look at the third criteria, development and production parity. So what is this going to look like in production? Well, in production, we won't have Webpack Dev server running, of course. So we will have to use, we will have to be able to render script tags with the right URLs in the HTML. And for the development, production parity requirement to work, then we should probably pick the same thing in development. So now I have to be very honest with you and tell you that I've been doing solution one for a long time for absolutely no good reason. And just for the sake of completeness, I'm going to show you what that looks like. So it's probably not readable from afar. Don't worry. I'll just skim through it. If you've got good eyes, you can see several if debug, if not debug, et cetera. So that's very bad for the development and production parity. And this big chunk in the middle here is actually manually fetching a manifest with the list of all the files in Webpack Dev server and dynamically adding them to the document here. So it's very dirty. And I mentioned Django Webpackloader earlier, and I think that's where Django Webpackloader could help a lot. We could transform this and nice animation. We could replace all of this with just two lines, render bundle for CSS and render bundle for JS. And this would work both in production and in development, removing the need for the if and else's, and also the need for dynamically loading all of this. So as I've said, I haven't tried this method yet. It's on my to-do list for the very short term. So I can't guarantee this is going to work. I think this is the right way to go. And about the development and production parity, it's actually very difficult to achieve 100% parity, especially between development and any other environment. Actually, if you think about it, my requirement around development, sorry, environment-independent builds is kind of a UAT versus production parity or staging versus production parity. Because I want to make sure that they're exactly the same. But in development, it's different because you always end up using different tools, different servers. So it's difficult to reach 100% parity, but it's still something that's definitely worth aiming for. All right. So now that we've gone through those requirements and we've got already a list of design decisions we've made, let's look at what it looks like in the code. So this is our setup, at least in development. And the main piece of integration between Django and JavaScript now resides in the template for the HTML that's rendered by Django. And so here we end up with the main block here, setting the config for the JavaScript application that's actually rendered by Django. We have the two render bundle tags for the CSS in the top and the JS at the bottom. That's coming from our hot reloading requirement and development production parity requirement. And that's it. So this is built for React. So there's a div with ID app. But you could definitely adapt this to whatever framework you're using. And you could actually build many other things prebuilt into the HTML and just load the JS application in the tiny part of the page. That's also an option here. Because we're using every application, it gives us this flexibility around how much content do I want to be generated by Django and how much content do I want to be taken care of by JavaScript. So of course, once we have this template, we need a view to render it. I thought I'd just show this just to show where I set the, where I define the context variable for rendering. In this example, I'm reading both from the settings and from the models in the database. But you can pull in the information to configure your frontend application for whatever that makes sense in your case. And finally, we need to mount this view on a URL, which needs to be generated enough so that we're going to set, serve this HTML for every page of our JavaScript application, every URL that's supported by your JavaScript application. All right. And in the frontend, it's even simpler. In the frontend, there's no need to make any change to our JavaScript at least. The one tiny change that we need to make is to make sure that our webpack configuration is able to output a manifest. So a list of all the files that it just outputted last time it ran so that Django can then read this and so and link to all the files in the HTML. So it's this one line here, the bundle tracker plugin. And finally, I thought I'd show you what my deployment looked like. So I used Docker, but I didn't use Docker. I used Docker. But if you use something similar, you'll see you have the main steps, which are first building the JavaScript application. So you output a set of JavaScript, CSS, images, whatever, and also a manifest file, which contains a list of all of those other files. Then copying this over to a static directory that's controlled by Django, which Django has access to. And then finally running codec static. And from here, you know that the static files are available to be served and Django will know where to get those files from. So you can link to them. And that's it. So it's not, it's by far not a complete example. There's many other things that we probably would need to go through when designing a Django JavaScript application. Things like authentication, cores, CSRF, although I wouldn't say that those last two are interesting topics. But they're in the list anyway. SEO, progressive web app support, etc. And most of these are actually topics that were covered by Augustin in his article series. So if you're interested in this, I again highly recommend reading them. So that's it for me. I think in conclusion, I'd say that we can still improve the state of the documentation of how to integrate JavaScript and Django. I don't think that Django is missing any feature to make this work properly. It's more about building the, documenting the known state of the art for this to work and giving examples for both code and architecture patterns. Right. And I'm also really curious to know how you guys manage your own JavaScript and Django applications. So feel free to comment to me after. Thanks. Thank you, Nathan. And do we have any questions from the audience? As usual, please line up. Anybody? No. All right. Thank you, Nathan. Thank you. Oh, wait, one question. We have questions from the internet. Oh, there we go. Now we've got Mike. No, no, no. Oh, it's that one. Hey, there we go. If you open the floor for questions, there's always a question. In your example code there, where you had the settings being rendered in Django and then the rest being done as hot reloading. Yeah. One of the pieces that's in there is this list of opening hours or something like that. To mean this. Yes, that's the one. You've got your opening hours being rendered as something from template. Yeah. That's not going to play well with the hot reloading, I would assume. Is that it's like an example of something that you maybe want to try and push to an API or is there? I don't see why it wouldn't. So these set of variables are... Do you mean hot reloading or live reloading? Sorry, live reloading. Sorry. So on live reloading, every time the browser is refreshed, then the HTML would be re-compiled and rerun. So those variables would be reset every time. And Django would just be rendered the same exact template every time. So I don't think that would be a problem. Okay. But then so on the JavaScript, on the hot reloading, that once the page renders, once the settings are only ever done on the page reload, but you can modify the JavaScript and then that won't pick up any changes there. So I don't think it creates problems with this because this variable is never reset. It's always defined globally. But it does create problems, especially... I think it's... Hot reloading works very well for React components, for example. Everything visual is perfectly fine. It works less well when you change a bit of logic somewhere. I couldn't explain you why. I'm not an expert by far on hot reloading. It does have limitations. I don't think there was any particular guidelines about what you keep in... What you can put in that kind of... I think this is fairly flexible and I'm pretty confident that this is not going to be reset by either live reloading or hot reloading. You can just see this as the main configuration object for your JavaScript application and put anything you want in there. Sure. Very quick question. First of all, I'm not a full stack, just a backend engineer, but our team had some problems previously about the Django local dot-on server not running over HTTPS. Do you have anything to... With HTTPS? Yes. You don't have any problems in your React app? No, I'm not sure. Could say a lot of things about HTTPS. I'm not sure what exactly was your issue. We couldn't serve the development server over HTTPS and React at some point has some problems, maybe across the side. I don't know. In development, I don't use HTTPS in development and this has never been a problem to me. Webpack Dev Server runs over HTTPS. Once you're in production, the webpack Dev Server doesn't matter anymore because you just have to set up static files that are always going to be served. I personally create a container for them and they are served over HTTPS. Maybe your issues could be around requesting non-HTTP resources from a page that's served over HTTPS. I know there are limitations in browsers around this. Maybe probably. Thank you. Good luck. All right. That was it for the questions. Thank you, Nathan. Thank you.
 Hi. Hello. Okay. So my name is Nathan and I'm going to be talking about building and  architecture in Django alongside JavaScript applications. So I'm a full-time developer.  I work with Django and React on most of the projects I work on. However, and despite the  name of this talk, after a few months, I really start to dislike it. So despite the name, it's  not about React. Most of what I'm going to say is it works exactly the same if you're using  Angular, Vue, or Ember, any modern framework. If anything, it's maybe a bad webpack, but we'll  come back to this. Okay. So just to get started, by show of hand, who here uses a similar stack  with a modern JS framework alongside Django? Okay. So quite a few of you. So I don't know about you  guys, but I really find this exercise of setting up a JS framework alongside Django to really not  being a trivial exercise. I think the main reason is there's no standard documented implementation  guidelines or even architecture and guidelines. So I think it's something that we still can  improve in the Django community. So it's something I've done quite a few projects, and my goal for  this talk is to take you through some of the design decisions that we can make to try and  build such an application, how it's going to work in development and production. And in this talk,  I'll also try and show you what it ends up looking like in the code. So before I start,  a quick catch up on the JS tool chain. I'm not sure everyone knows about this. So very quickly,  NPM is the main JavaScript package repository. It's actually both the repository and the client  for the repository. So it's equivalent to both PyPI and PIP. Webpack is the main build tool for  more than JS applications. So it's what produces the bundle that's the JavaScript source code that  ends up being shipped to the browser. There's no direct equivalent for this in Python because  we can just run the Python code. And Webpack Dev Server is a wrapper on Webpack that's much  like the Django hotel reloader, looks for changes in the source code, recompiles, and sells those  files on the server. So in this first part, I want to go through a quick recap of Django's  history and the tools we've had to handle JavaScript files. And the goal here is also to  set up a common vocabulary so we can all be talking about the same thing. So when Django came out  in 2005, the main use for JS back then was to sprinkle on top of HTML pages that were otherwise  generated by the backend. And for this, we had tools like Django pipeline and Django compressor  who came out in 2008, 2009. And their main goal was to take this JavaScript source code that  usually lived in the static folders of Django, minify it, render a script tag in the template,  and that was it. And a few less later, Django and Chain came out and that really messed up my  chart. So if you were wondering what the spec is, let's check on Chain. But around the same time,  you can see the red and the blue lines, it's angular and then a couple years after a react. So the  modern frameworks that the most common modern frameworks that are coming out in 2012, 2014,  I think. And those frameworks need much more potent build pipelines. They need integration with  the JS packages. They need to pull in dependencies from NPM. They need to be able to work with  image files, font files, CSS, et cetera. And so that's where Django pipeline and Django  compressor weren't enough anymore. And the front end community came up with something called Webpack,  which solves all of this problem. So a few less later in 2015, Django Webpack came out and it's  the first setup at integrating Webpack and Django together. So the goal here was to really  separate the responsibilities of building the JavaScript for the browser and serving it. Before  that, Django pipeline, Django compressor and equivalent were doing all of this. From now on,  we would leave Webpack in charge of building this bundle and Django in charge of just generating a  script tag that links to it. And so it transformed the development environment from a single process  where Django is in charge of serving and generating the HTML and the JS to a dual environment where  we have both Webpack and Django running. And Django would still be in charge of generating  the HTML but then point to Webpack, which would serve the JS. So something else I want to mention  in this section is Amrik Augustin's blog article series from last year, because they really helped  me out and meet on formulating a lot of what I've been thinking about. So his blog article is about  a series of formalization of the requirements for building a Django application. So it's very much  linked to what I'm talking about. And the main thing I remember from this is his taxonomy of  JS applications. There's basically two kinds of JS applications or two kinds of architecture.  The single page applications and in hybrid applications. And I come back to this in the  example slides. And in his blogs, he also talks about production and development parity,  authentication, cores, CSRF, et cetera. So I really recommend going there if you're working on  Django and JavaScript. So in Amrik's taxonomy, a single page application is an application where  the HTML is purely static and never changes. So it's not rendered by Django. It can be a static  file that's served by Nginx or Apache alongside the JS files. And in this context, Django is purely  used as an API. And so typically in a production setting, the browser would end up making requests  to two different origins. The front end where it would load all the static files, HTML, CSS,  JS images. And the back end where Django runs as the API. And the counterpart is the hybrid  application where the HTML is served by Django and potentially as a template rendered by the  Django team engine. And so you end up with an application running where the DOM is a mix of  the HTML that was generated by Django and whatever JavaScript framework, whatever changes it brought  to this DOM. And typically in the hybrid application, the browser ends up only talking to one origin  where it would first load the HTML, which would be rendered for it, and then load the JS. And API  calls, of course. So both infrastructures have pros and cons. There's no silver bullet, of course.  And even once you've been able to pick between single page application and hybrid application,  depending on what's right for you, there's still a lot of implementation details that will vary  between implementations. Still a lot more of design decisions. So now that's exactly what I  want to go through from designing a Django and JavaScript architecture together.  So before we go and start making random design decisions, it's probably better that we agree  on a set of requirements first on what we want the application to be able to achieve.  So of course, those requirements will vary a lot between projects. And the example I have here is  something that's very typical for the project I work on. But they are binominal. They might not  apply to your use case. For example, I think a typical requirement that I don't have is around  having to separate the code base between front end and back end. I think separate also deployment  flow between front end and back end. I work in a team where everyone is full stack, so that's fine  for me. But I know lots of companies out there have different teams for front end and back end.  And I think if that was a requirement for you, you would end up with a very different solution.  But hopefully, I think the reasoning here will apply whatever your use case and  you should be able to use this on your own projects. So sorry.  My requirements are I want underignment independent builds. So I'll come back to what I mean  exactly for each of them in a minute. I want hot reloading and development. And I want  development and production parity. So for underignment independent builds, first of all,  do I mean by build? By build, I mean whatever code artifact you ship to a server when you deploy.  It could be a file archive, a Docker image, a binary bit and conventionally Python,  but a commit in a Git repository, for example. And why this is important to me is because it  allows me to do version promotion. When I've had a version running in one environment for a while  and I know it fixes the problem I intended to solve, then I can take this exact build, this exact set  of code and then send it to a different environment. This is something that I discovered on Heroku,  a while back, and it really stuck with me. So yeah, that brings a lot of trust in what I'm  about to deploy and I know I'm going to break the next environment down the line.  So how might I achieve this? The first, the view sensor is to not have any environment-specific  values encoded in the code. And the main way to do this is to use environment variables.  The main, when I'm talking about this section, is very related to the 12-factor app. So if you  don't know about this, I really recommend you go and read the 12 pages on 12factor.net.  It's very interesting. So environment variables, they're really easy to use in Django. That's not  a problem at all. In the back end, we can read them anywhere on the code and read them in the  settings and then read the settings. So Django is really easy to write in an environment in a  better way as long as you have access to environment variables on your server. But in JavaScript,  it's a bit of a different story. The other thing that's a bit harder, typically, the main bit of  config you would need in the JavaScript application is the API endpoint. Where am I going to send my  request to? For example, in production, I might want to connect to api.example.com over HTTPS,  while in development, I'm going to connect to localhost on port 8000 over HTTP. So, of course,  JavaScript doesn't have a concept of environment variable. We can't set environment variables in  our users' browsers. So as far as I can tell, that leaves us with two options. Either we find a way  to load the config when the application starts from somewhere. That probably means an API call.  And if I'm making an API call to what endpoint, it's kind of snake-hitting its own tail. That's  probably not going to work. The alternative I can see is to inject the configuration inside of the  HTML during rendering in Django. So that means that our HTML has to be a Django template. So that  means we're using a hybrid application in Augustine's taxonomy. And one way you might,  this would translate in the template. If this is the template for your JavaScript application,  you might want to write a global config variable in JavaScript with the set of, this is an example,  but I'm setting, for example, an API endpoint that's actually just a context variable in Django  templates. And also, all the business logic values that are actually coming from the database.  Right. Okay. So that was environment independence. Next, hot reloading in development.  So hot reloading is this very powerful front-end development feature that's very much like  Django, what the Django hot reloader provides. It's based on Webpack Dev server. And as soon as I  make a change in my JavaScript source code, in my browser refreshes, and I can see the  change immediately in my browser. So it really shortens the feedback look from writing a code  and potentially a bug and then detecting it. So this feature relies on Webpack Dev server,  as I just said, and there's actually two levels to it. There's live reloading where,  as soon as I make a change in my source code, then it gets picked up and my browser refreshes. So  that means I do see the change in my browser, but I lose all the variables, values, I lose all of my  context where I was in the application, et cetera. So it's a start, but not great. And then hot  reloading is the next step. It's where instead of triggering a refresh of the page, Webpack Dev  server is going to send the new rebuild chunk of our Websocket to the browser. And the browser is  going to replace it in place with that trigger refresh. So I get to keep my variable where I  was in the application, et cetera. Right. So let's start with hot reloading, actually, and it's  going to be quick. So hot reloading uses Websocket on Webpack Dev server. And as I just described,  the way it looks like is in development, you load the HTML from Django, which would then point to  the static phase in Webpack Dev server. And then every time I make a change to my JavaScript  source code, then Webpack is going to ship those hot updates of our Websocket and my application  is going to update itself. So I've got one big problem with hot reloading. And it's because I'm  using create react app, which is the main react boilerplate out there, and it's broken. I won't  go into why if you're interested, then we can discuss this after the talk when I'm working for  feedback from the folks at Facebook. If you are not using create react app and you're using a  vanilla or a custom setup of Webpack Dev server, then they might just work.  So taking a step back and let's take a step back and just aim for live reloading, for live  loading to work. All I need is to make sure that my JavaScript source code is coming from Webpack  Dev server. So that leaves us again with two options. Either when the application, when I  load the page on my browser, it's able to tell which files I need on Webpack Dev server and  dynamically load them in the page. Or Django is able to render all of the scripts in the page for  me at random time and serve the HTML to my browser. So it loads the files. And both of them work.  Both of them are fine. And to help us decide between those two solutions, one thing we could do is  look at the third criteria, development and production parity. So what is this going to  look like in production? Well, in production, we won't have Webpack Dev server running, of course.  So we will have to use, we will have to be able to render script tags with the right URLs in the  HTML. And for the development, production parity requirement to work, then we should probably  pick the same thing in development. So now I have to be very honest with you and tell you that I've  been doing solution one for a long time for absolutely no good reason. And just for the sake  of completeness, I'm going to show you what that looks like. So it's probably not readable from  afar. Don't worry. I'll just skim through it. If you've got good eyes, you can see several if debug,  if not debug, et cetera. So that's very bad for the development and production parity. And this  big chunk in the middle here is actually manually fetching a manifest with the list of all the files  in Webpack Dev server and dynamically adding them to the document here. So it's very dirty.  And I mentioned Django Webpackloader earlier, and I think that's where Django Webpackloader  could help a lot. We could transform this and nice animation. We could replace all of this with  just two lines, render bundle for CSS and render bundle for JS. And this would work both in production  and in development, removing the need for the if and else's, and also the need for dynamically  loading all of this. So as I've said, I haven't tried this method yet. It's on my to-do list for  the very short term. So I can't guarantee this is going to work. I think this is the right way to go.  And about the development and production parity, it's actually very difficult to achieve 100%  parity, especially between development and any other environment. Actually, if you think about it,  my requirement around development, sorry, environment-independent builds is kind of  a UAT versus production parity or staging versus production parity. Because I want to make sure  that they're exactly the same. But in development, it's different because you always end up using  different tools, different servers. So it's difficult to reach 100% parity, but it's still  something that's definitely worth aiming for. All right. So now that we've  gone through those requirements and we've got already a list of design decisions we've made,  let's look at what it looks like in the code. So this is our setup, at least in development.  And the main piece of integration between Django and JavaScript now resides in the template for  the HTML that's rendered by Django. And so here we end up with the main block here, setting the  config for the JavaScript application that's actually rendered by Django. We have the two  render bundle tags for the CSS in the top and the JS at the bottom. That's coming from our  hot reloading requirement and development production parity requirement. And that's it. So  this is built for React. So there's a div with ID app. But you could definitely adapt this to  whatever framework you're using. And you could actually build many other things prebuilt into  the HTML and just load the JS application in the tiny part of the page. That's also an option here.  Because we're using every application, it gives us this flexibility around  how much content do I want to be generated by Django and how much content do I want to be  taken care of by JavaScript. So of course, once we have this template, we need a view to render it.  I thought I'd just show this just to show where I set the, where I define the context variable for  rendering. In this example, I'm reading both from the settings and from the models in the  database. But you can pull in the information to configure your frontend application for  whatever that makes sense in your case. And finally, we need to mount this view on a URL,  which needs to be generated enough so that we're going to set, serve this HTML for every page of  our JavaScript application, every URL that's supported by your JavaScript application.  All right. And in the frontend, it's even simpler. In the frontend, there's no need to make any  change to our JavaScript at least. The one tiny change that we need to make is to make sure that  our webpack configuration is able to output a manifest. So a list of all the files that  it just outputted last time it ran so that Django can then read this and so and link to all the  files in the HTML. So it's this one line here, the bundle tracker plugin. And finally, I thought I'd  show you what my deployment looked like. So I used Docker, but I didn't use Docker. I used  Docker. But if you use something similar, you'll see you have the main steps, which are first  building the JavaScript application. So you output a set of JavaScript, CSS, images, whatever,  and also a manifest file, which contains a list of all of those other files. Then copying this  over to a static directory that's controlled by Django, which Django has access to. And then  finally running codec static. And from here, you know that the static files are available to be  served and Django will know where to get those files from. So you can link to them.  And that's it. So it's not, it's by far not a complete example. There's many other things  that we probably would need to go through when designing a Django JavaScript application.  Things like authentication, cores, CSRF, although I wouldn't say that those last two are  interesting topics. But they're in the list anyway. SEO, progressive web app support, etc.  And most of these are actually topics that were covered by Augustin in his article series. So  if you're interested in this, I again highly recommend reading them. So that's it for me.  I think in conclusion, I'd say that we can still improve the state of the documentation of how to  integrate JavaScript and Django. I don't think that Django is missing any feature to make this  work properly. It's more about building the, documenting the known state of the art for this  to work and giving examples for both code and architecture patterns. Right. And I'm also really  curious to know how you guys manage your own JavaScript and Django applications. So feel free  to comment to me after. Thanks. Thank you, Nathan. And do we have any questions from the audience?  As usual, please line up. Anybody? No. All right. Thank you, Nathan. Thank you. Oh, wait,  one question. We have questions from the internet.  Oh, there we go. Now we've got Mike. No, no, no. Oh, it's that one. Hey, there we go.  If you open the floor for questions, there's always a question. In your example code there,  where you had the settings being rendered in Django and then the rest being done as hot reloading.  Yeah. One of the pieces that's in there is this list of opening hours or something like that.  To mean this. Yes, that's the one. You've got your opening hours being rendered as something from  template. Yeah. That's not going to play well with the hot reloading, I would assume. Is that  it's like an example of something that you maybe want to try and push to an API or is there?  I don't see why it wouldn't. So these set of variables are... Do you mean hot reloading or  live reloading? Sorry, live reloading. Sorry. So on live reloading, every time the browser is  refreshed, then the HTML would be re-compiled and rerun. So those variables would be reset every  time. And Django would just be rendered the same exact template every time. So I don't think that  would be a problem. Okay. But then so on the JavaScript, on the hot reloading, that once the  page renders, once the settings are only ever done on the page reload, but you can modify the  JavaScript and then that won't pick up any changes there. So I don't think it creates  problems with this because this variable is never reset. It's always defined globally.  But it does create problems, especially... I think it's... Hot reloading works very well for  React components, for example. Everything visual is perfectly fine. It works less well when you  change a bit of logic somewhere. I couldn't explain you why. I'm not an expert by far on hot  reloading. It does have limitations. I don't think there was any particular guidelines about  what you keep in... What you can put in that kind of... I think this is fairly flexible and I'm  pretty confident that this is not going to be reset by either live reloading or hot reloading.  You can just see this as the main configuration object for your JavaScript application and  put anything you want in there. Sure.  Very quick question. First of all, I'm not a full stack, just a backend engineer, but our team had  some problems previously about the Django local dot-on server not running over HTTPS.  Do you have anything to... With HTTPS? Yes.  You don't have any problems in your React app? No, I'm not sure. Could say a lot of  things about HTTPS. I'm not sure what exactly was your issue.  We couldn't serve the development server over HTTPS and React at some point has some problems,  maybe across the side. I don't know. In development, I don't use HTTPS in development and this has  never been a problem to me. Webpack Dev Server runs over HTTPS. Once you're in production,  the webpack Dev Server doesn't matter anymore because you just have to set up static files that  are always going to be served. I personally create a container for them and they are served over HTTPS.  Maybe your issues could be around requesting non-HTTP resources from a page that's served over  HTTPS. I know there are limitations in browsers around this. Maybe probably. Thank you. Good luck.  All right. That was it for the questions. Thank you, Nathan. Thank you.
DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_0_587.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_588_1979.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_1980_2771.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_2772_2891.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_2892_4643.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_4644_7439.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_7440_12803.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_12804_13043.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_13044_19331.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_19332_19967.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_19968_25499.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_25500_25811.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_25812_26519.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_26520_26591.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_26592_28019.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_28020_28115.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_28116_28727.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_28728_28799.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_28800_29063.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_29064_29411.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_29412_29603.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_29604_30767.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_30768_31367.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_31368_31787.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_31788_31859.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_31860_32603.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_32604_32663.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_32664_33671.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_33672_34691.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_34692_34763.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_34764_36107.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_36108_36347.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_36348_36887.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_36888_37223.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_37224_37379.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_37380_37655.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_37656_40463.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_40464_41579.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_41580_42155.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_42156_42707.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_42708_42755.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_42756_42803.png DjangoCon_2019_-_Take_the_goRe_out_of_a_DjangoReact_stack_42804_42901.png