SlideShare a Scribd company logo
1 of 50
Download to read offline
How to Webpack
your Django!
David Gibbons
PyCon Ireland, October 2019
About Me
Many time PyCon Ireland attendee (many t-shirts! 👕👕), 1st time PyCon
speaker
Working with Python (and JavaScript) for over seven years 🐍
Software engineer at OpenApp, creating bespoke Web applications
Server and client-side Web development
2
@davgibbs
@davgibbs
About OpenApp
Founded in 2002, 45 staff employed
Web applications for industries such as Healthcare and Postal. Patient registries,
health data analytics
Always interested in interesting CVs (Software engineers, Project managers, QA
and test automation, etc). hr@openapp.ie
Recent greenfield project, an address cleaning application
Decided on Vue.js and webpack - origin of this talk
3
About Talk
Django (without webpack)
Webpack introduction
Integration of webpack into Django
Added webpack extras
4
Talk goals
1. Webpack worth learning
The latest JavaScript features can improve your application
2. Straightforward to incorporate into Django
Simple architecture works for local development and production
5
6
7
Django (without webpack)
8
Django
A high-level Python Web framework that encourages rapid development and
clean pragmatic design
MTV separation with models-template-views architecture
● Models define what is created in database
● Templates contain presentation logic
● Views contain business logic
Django static (eg js, css, images) stored in static file directories and referenced
in HTML Template code.
9
Example application
Small example application:
PyCon Ireland 2019 theme: “Environment”.
Django API provides a random “Environment” related quote.
Result: Request and display quote and corresponding author.
10
11
Models and views for Django API.
HTML template references
frontend files
A frontend directory with static (js,
css, images)
Models
Store the quote text and the author
12
from django.db import models
class Quote(models.Model):
text = models.CharField(max_length=1000, help_text="The quote text")
author = models.CharField(max_length=100, help_text="The quote author")
Django fixtures
Fixture file environment.json contains a list of famous environment quotes
13
{
"model": "quotes.Quote",
"pk": 1,
"fields": {
"text": "The Earth is what we all have in common.",
"author": "Wendell Berry"
}
},
Send request to URL “/random-quote” to get a random Environment quote
Views
14
from django.http import JsonResponse
from django.forms.models import model_to_dict
from .models import Quote
def random_quote(request):
quote = Quote.objects.order_by('?').first()
return JsonResponse(model_to_dict(quote))
15
{% load static %}
<html>
<head>
<link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div id="app">
<div><img src="{% static 'img/environment.png' %}" height="200px"></div>
<div><h1>Environment Random Quote</h1></div>
<div class="quote">
<div><p>[[ quoteText ]]</p></div>
<div><p>- <i>[[ quoteAuthor ]]</i></p></div>
</div>
<div><button class="btn btn-clear button" @click="getQuote()">Next</button></div>
</div>
<script src="{% static 'vue/dist/vue.min.js' %}"></script>
<script src="{% static 'js/script.js' %}"></script>
</body>
</html>
16
{% load static %}
<html>
<head>
<link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div id="app">
<div><img src="{% static 'img/environment.png' %}" height="200px"></div>
<div><h1>Environment Random Quote</h1></div>
<div class="quote">
<div><p>[[ quoteText ]]</p></div>
<div><p>- <i>[[ quoteAuthor ]]</i></p></div>
</div>
<div><button class="btn btn-clear button" @click="getQuote()">Next</button></div>
</div>
<script src="{% static 'vue/dist/vue.min.js' %}"></script>
<script src="{% static 'js/script.js' %}"></script>
</body>
</html>
17
{% load static %}
<html>
<head>
<link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
<div id="app">
<div><img src="{% static 'img/environment.png' %}" height="200px"></div>
<div><h1>Environment Random Quote</h1></div>
<div class="quote">
<div><p>[[ quoteText ]]</p></div>
<div><p>- <i>[[ quoteAuthor ]]</i></p></div>
</div>
<div><button class="btn btn-clear button" @click="getQuote()">Next</button></div>
</div>
<script src="{% static 'vue/dist/vue.min.js' %}"></script>
<script src="{% static 'js/script.js' %}"></script>
</body>
</html>
Result
18
Result
19
That is great, my Web application is working.
20
So why do I need this webpack?
Missing frontend requirements
● On production, minified JavaScript code with any comments removed
● Unique hash in file names to let browser cache know file updated
● On development, page refresh on code change while retaining state
● Code splitting so that only minimal code downloaded to browser
21
Webpack Introduction
22
Static module bundler for modern JavaScript
Initial release in 2012. Currently version 4.
Pete Hunt spoke at OSCON 2014 on how Instagram use webpack.
Can add/remove functionality as you need it
Enter webpack
23
“Best asset manager is webpack“
~ PyCon 2019 talk by Django co-creator Jacob Kaplan-Moss
webpack
webpack.config.js contains all config needed.
Configure webpack for your specific needs: React.js, Vue.js, etc.
Contains information on the mode, input and output along with any plugins or
loaders used.
24
npm install webpack webpack-cli
webpack
Webpack bundles modules with dependencies into files for browser.
25
Webpack.config.js - core concepts
1. mode: “development” or “production” enables the built-in optimizations
2. entry: this is the file(s) which is the starting point for webpack
3. output: this configuration is the place where webpack will place the bundles
26
mode: 'production',
entry: { app: './apps/frontend/js/index.js'},
output: { filename: '[name].[hash].bundle.js',
path: __dirname + '/apps/frontend/dist/',
publicPath: '/static/dist/' },
Webpack.config.js - core concepts
4. plugins: are used for wide range of tasks such as asset management
5. loaders: allow processing of other types of files. (css, etc)
27
plugins: [new VueLoaderPlugin()],
module: {rules: [
{ test: /.css$/, use: ['style-loader', 'css-loader']},
{ test: /.vue$/, use: 'vue-loader'},
{ test: /.*.(png|jpe?g)$/, use: 'file-loader'}]}
28
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
mode: 'production',
entry: { app: './apps/frontend/js/index.js'},
output: { filename: '[name].[hash].bundle.js',
path: __dirname + '/apps/frontend/dist/',
publicPath: '/static/dist/' },
plugins: [
new VueLoaderPlugin(),
],
module: {rules: [
{ test: /.css$/, use: ['style-loader', 'css-loader']},
{ test: /.vue$/, use: 'vue-loader'},
{ test: /.*.(png|jpe?g)$/, use: 'file-loader'},],},
};
Additional
requires
Additional
plugins
Additional
loaders
Update Vue.js code
Webpack also enables the use of Single File Components (SFCs) in vue.js
Really useful as the project expands to create reusable and isolated components
Create new file App.vue. html, javascript and css for app in one file. File index.js
is entry point to App.vue.
29
30
NPM scripts: build command
In package.json “scripts” section add a line for “build” command:
scripts: {"build": "webpack"}
Missing frontend requirements
● On production, minified JavaScript code with any comments removed
● Unique hash in file names to let browser cache know file updated
31
Integrate into Django
32
Library to transparently use webpack with django
Metadata file, produced by webpack plugin, tells Django where the generated
files are located.
33
Enter “django-webpack-loader”
“One of the core principles of django-webpack-loader is to not manage webpack
itself in order to give you the flexibility to run webpack the way you want.“
~ django-webpack-loader documentation
34
Update JavaScript side
const BundleTracker = require('webpack-bundle-tracker');]
plugins: [
<other plugins>...
new BundleTracker({filename: './apps/webpack-stats.json'}),
]
1. npm install webpack-bundle-tracker
2. Add BundleTracker to webpack.config.js which will write to file on build
1. pip install django-webpack-loader
2. Update Django’s settings.py
a. Add “webpack_loader” to INSTALLED_APPS
b. Add in a section WEBPACK_LOADER:
3. Use “render_bundle” template tag rather then “static” in templates. This
links to the files generated in dist/ directory
35
Update Django side
WEBPACK_LOADER = {
'DEFAULT': {
'BUNDLE_DIR_NAME': 'dist/',
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')}}
Integrated!
npm run build is run first to create the bundles
● Bundles in “dist” directory. webpack-stats.json contains the filenames
python manager.py runserver follows to run Django
● Django template will include the bundled files from webpack
36
37
Missing frontend requirements
● On production, minified JavaScript code with any comments removed -> Set
the mode to ‘production’
● Unique hash in file names to let browser cache know file updated -> Include
unique hash in each filename
● On development, page refresh on code change while retaining state
● Code splitting so that only minimal code downloaded to browser
38
Added webpack extras
39
Extra webpack configuration
40
The following additional configurations can be added as needed:
Eslint, Babel, clean old bundles plugin, bundle analyzer plugin, …
Chosen extras:
1. Webpack-dev-server: Hot-reload for local development
2. Code splitting: define multiple entry points to avoid downloading the same
code to the browser twice
Webpack-dev-server
On a code change, re-run build and update Browser display for quicker
development.
Webpack-dev-server runs in one terminal tab and Django development server in
another tab.
41
webpack-dev-server
Save to File
system
Watch for
changes
Update
display
Browser
Webpack-dev-server
Hot reload to refresh page the part of the page that has changed.
npm install webpack-dev-server webpack-merge
Add a 2nd entry to the “scripts” section of package.json:
42
scripts: {"build": "webpack"
"start": "webpack-dev-server --config webpack.dev.js"}
Webpack-dev-server
43
Add new config webpack.dev.js for development specific config
const merge = require('webpack-merge');
const common = require('./webpack.config.js');
module.exports = merge(common, {
mode: 'development',
output: {publicPath: 'http://localhost:3000/static/dist/'},
devServer: {
port: 3000,
hot: true,
headers: {'Access-Control-Allow-Origin': '*'}}
});
Code Splitting
Powerful webpack feature to split code into various bundles which can then be
loaded on demand or in parallel to help improve page load time.
44
Code Splitting
Prevent Duplication: Split out “vendor” code so when a new entry point is added,
no need for browser to re-download vendor (Vue.js, bootstrap).
Separate “render_bundle” call in HTML template for “vendor” bundle
45
optimization: {
splitChunks: {
cacheGroups: { commons: {
test: /[/]node_modules[/]/,
chunks: 'initial',
name: 'vendor'}}}},
● On production, minified JavaScript code with any comments removed -> Set
the mode to ‘production’
● Unique hash in file names to let browser cache know file updated -> Include
hash in each filename
● On development, page refresh on code change while retaining state -> add
webpack-dev-server with configuration to watch source files
● Code splitting so that only minimal code downloaded to browser -> make
use of optimisation in webpack to split files
Missing frontend requirements
46
47
Talk Summary
Webpack is a tool for modern JavaScript development, handles different file
types of static files to produce bundles.
Example application which uses webpack to bundle static files and incorporated
into Django with django-webpack-loader.
Once basic webpack configuration is in place, it is easy to add functionality as
needed.
Tried-and-tested way to webpack your Django!
48
Thank you for listening!
49
Any Questions?
Links
Code from this talk: https://github.com/davgibbs/quotes-display
Django static files: https://docs.djangoproject.com/en/2.2/howto/static-files/
Webpack documentation: https://webpack.js.org/concepts/
Homepage for django-webpack-loader:
https://github.com/owais/django-webpack-loader
50

More Related Content

What's hot

Seasar2で作った俺たちのサービスの今
Seasar2で作った俺たちのサービスの今Seasar2で作った俺たちのサービスの今
Seasar2で作った俺たちのサービスの今
Koichi Sakata
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 

What's hot (20)

Xke spring boot
Xke spring bootXke spring boot
Xke spring boot
 
Seasar2で作った俺たちのサービスの今
Seasar2で作った俺たちのサービスの今Seasar2で作った俺たちのサービスの今
Seasar2で作った俺たちのサービスの今
 
Mongoose and MongoDB 101
Mongoose and MongoDB 101Mongoose and MongoDB 101
Mongoose and MongoDB 101
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)Go swagger tutorial how to create golang api documentation using go swagger (1)
Go swagger tutorial how to create golang api documentation using go swagger (1)
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
 
Hybrid Public Key Encryption (HPKE)
Hybrid Public Key Encryption (HPKE)Hybrid Public Key Encryption (HPKE)
Hybrid Public Key Encryption (HPKE)
 
Open Liberty: オープンソースになったWebSphere Liberty
Open Liberty: オープンソースになったWebSphere LibertyOpen Liberty: オープンソースになったWebSphere Liberty
Open Liberty: オープンソースになったWebSphere Liberty
 
Hyper-V を Windows PowerShell から管理する
Hyper-V を Windows PowerShell から管理するHyper-V を Windows PowerShell から管理する
Hyper-V を Windows PowerShell から管理する
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
날로 먹는 Django admin 활용
날로 먹는 Django admin 활용날로 먹는 Django admin 활용
날로 먹는 Django admin 활용
 
Windows PowerShell によるWindows Server 管理の自動化 v4.0 2014.03.13 更新版
Windows PowerShell によるWindows Server 管理の自動化 v4.0 2014.03.13 更新版Windows PowerShell によるWindows Server 管理の自動化 v4.0 2014.03.13 更新版
Windows PowerShell によるWindows Server 管理の自動化 v4.0 2014.03.13 更新版
 
Eloquent ORM
Eloquent ORMEloquent ORM
Eloquent ORM
 
Jenkins with Docker
Jenkins with DockerJenkins with Docker
Jenkins with Docker
 
Vue.js for beginners
Vue.js for beginnersVue.js for beginners
Vue.js for beginners
 
OpenID Connect: An Overview
OpenID Connect: An OverviewOpenID Connect: An Overview
OpenID Connect: An Overview
 
Modern API Security with JSON Web Tokens
Modern API Security with JSON Web TokensModern API Security with JSON Web Tokens
Modern API Security with JSON Web Tokens
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
 
Json Web Token - JWT
Json Web Token - JWTJson Web Token - JWT
Json Web Token - JWT
 

Similar to How to Webpack your Django!

Write your first WordPress plugin
Write your first WordPress pluginWrite your first WordPress plugin
Write your first WordPress plugin
Anthony Montalbano
 

Similar to How to Webpack your Django! (20)

React django
React djangoReact django
React django
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 
بررسی چارچوب جنگو
بررسی چارچوب جنگوبررسی چارچوب جنگو
بررسی چارچوب جنگو
 
Django Architecture Introduction
Django Architecture IntroductionDjango Architecture Introduction
Django Architecture Introduction
 
Mini Curso de Django
Mini Curso de DjangoMini Curso de Django
Mini Curso de Django
 
WEBPACK
WEBPACKWEBPACK
WEBPACK
 
Virtual Environment and Web development using Django
Virtual Environment and Web development using DjangoVirtual Environment and Web development using Django
Virtual Environment and Web development using Django
 
Django
DjangoDjango
Django
 
Nuxtjs cheat-sheet
Nuxtjs cheat-sheetNuxtjs cheat-sheet
Nuxtjs cheat-sheet
 
Mini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico CesMini Curso Django Ii Congresso Academico Ces
Mini Curso Django Ii Congresso Academico Ces
 
SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015SharePoint Saturday Atlanta 2015
SharePoint Saturday Atlanta 2015
 
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
Universal JavaScript Web Applications with React - Luciano Mammino - Codemoti...
 
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
Universal JS Web Applications with React - Luciano Mammino - Codemotion Rome ...
 
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fastHow Bitbucket Pipelines Loads Connect UI Assets Super-fast
How Bitbucket Pipelines Loads Connect UI Assets Super-fast
 
Build and deploy Python Django project
Build and deploy Python Django projectBuild and deploy Python Django project
Build and deploy Python Django project
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
 
Write your first WordPress plugin
Write your first WordPress pluginWrite your first WordPress plugin
Write your first WordPress plugin
 
An introduction to Vue.js
An introduction to Vue.jsAn introduction to Vue.js
An introduction to Vue.js
 
Love at first Vue
Love at first VueLove at first Vue
Love at first Vue
 
Droidcon Paris 2015
Droidcon Paris 2015Droidcon Paris 2015
Droidcon Paris 2015
 

Recently uploaded

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Recently uploaded (20)

A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 

How to Webpack your Django!

  • 1. How to Webpack your Django! David Gibbons PyCon Ireland, October 2019
  • 2. About Me Many time PyCon Ireland attendee (many t-shirts! 👕👕), 1st time PyCon speaker Working with Python (and JavaScript) for over seven years 🐍 Software engineer at OpenApp, creating bespoke Web applications Server and client-side Web development 2 @davgibbs @davgibbs
  • 3. About OpenApp Founded in 2002, 45 staff employed Web applications for industries such as Healthcare and Postal. Patient registries, health data analytics Always interested in interesting CVs (Software engineers, Project managers, QA and test automation, etc). hr@openapp.ie Recent greenfield project, an address cleaning application Decided on Vue.js and webpack - origin of this talk 3
  • 4. About Talk Django (without webpack) Webpack introduction Integration of webpack into Django Added webpack extras 4
  • 5. Talk goals 1. Webpack worth learning The latest JavaScript features can improve your application 2. Straightforward to incorporate into Django Simple architecture works for local development and production 5
  • 6. 6
  • 7. 7
  • 9. Django A high-level Python Web framework that encourages rapid development and clean pragmatic design MTV separation with models-template-views architecture ● Models define what is created in database ● Templates contain presentation logic ● Views contain business logic Django static (eg js, css, images) stored in static file directories and referenced in HTML Template code. 9
  • 10. Example application Small example application: PyCon Ireland 2019 theme: “Environment”. Django API provides a random “Environment” related quote. Result: Request and display quote and corresponding author. 10
  • 11. 11 Models and views for Django API. HTML template references frontend files A frontend directory with static (js, css, images)
  • 12. Models Store the quote text and the author 12 from django.db import models class Quote(models.Model): text = models.CharField(max_length=1000, help_text="The quote text") author = models.CharField(max_length=100, help_text="The quote author")
  • 13. Django fixtures Fixture file environment.json contains a list of famous environment quotes 13 { "model": "quotes.Quote", "pk": 1, "fields": { "text": "The Earth is what we all have in common.", "author": "Wendell Berry" } },
  • 14. Send request to URL “/random-quote” to get a random Environment quote Views 14 from django.http import JsonResponse from django.forms.models import model_to_dict from .models import Quote def random_quote(request): quote = Quote.objects.order_by('?').first() return JsonResponse(model_to_dict(quote))
  • 15. 15 {% load static %} <html> <head> <link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/styles.css' %}"> </head> <body> <div id="app"> <div><img src="{% static 'img/environment.png' %}" height="200px"></div> <div><h1>Environment Random Quote</h1></div> <div class="quote"> <div><p>[[ quoteText ]]</p></div> <div><p>- <i>[[ quoteAuthor ]]</i></p></div> </div> <div><button class="btn btn-clear button" @click="getQuote()">Next</button></div> </div> <script src="{% static 'vue/dist/vue.min.js' %}"></script> <script src="{% static 'js/script.js' %}"></script> </body> </html>
  • 16. 16 {% load static %} <html> <head> <link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/styles.css' %}"> </head> <body> <div id="app"> <div><img src="{% static 'img/environment.png' %}" height="200px"></div> <div><h1>Environment Random Quote</h1></div> <div class="quote"> <div><p>[[ quoteText ]]</p></div> <div><p>- <i>[[ quoteAuthor ]]</i></p></div> </div> <div><button class="btn btn-clear button" @click="getQuote()">Next</button></div> </div> <script src="{% static 'vue/dist/vue.min.js' %}"></script> <script src="{% static 'js/script.js' %}"></script> </body> </html>
  • 17. 17 {% load static %} <html> <head> <link rel="stylesheet" href="{% static 'bootstrap/dist/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'css/styles.css' %}"> </head> <body> <div id="app"> <div><img src="{% static 'img/environment.png' %}" height="200px"></div> <div><h1>Environment Random Quote</h1></div> <div class="quote"> <div><p>[[ quoteText ]]</p></div> <div><p>- <i>[[ quoteAuthor ]]</i></p></div> </div> <div><button class="btn btn-clear button" @click="getQuote()">Next</button></div> </div> <script src="{% static 'vue/dist/vue.min.js' %}"></script> <script src="{% static 'js/script.js' %}"></script> </body> </html>
  • 20. That is great, my Web application is working. 20 So why do I need this webpack?
  • 21. Missing frontend requirements ● On production, minified JavaScript code with any comments removed ● Unique hash in file names to let browser cache know file updated ● On development, page refresh on code change while retaining state ● Code splitting so that only minimal code downloaded to browser 21
  • 23. Static module bundler for modern JavaScript Initial release in 2012. Currently version 4. Pete Hunt spoke at OSCON 2014 on how Instagram use webpack. Can add/remove functionality as you need it Enter webpack 23 “Best asset manager is webpack“ ~ PyCon 2019 talk by Django co-creator Jacob Kaplan-Moss
  • 24. webpack webpack.config.js contains all config needed. Configure webpack for your specific needs: React.js, Vue.js, etc. Contains information on the mode, input and output along with any plugins or loaders used. 24 npm install webpack webpack-cli
  • 25. webpack Webpack bundles modules with dependencies into files for browser. 25
  • 26. Webpack.config.js - core concepts 1. mode: “development” or “production” enables the built-in optimizations 2. entry: this is the file(s) which is the starting point for webpack 3. output: this configuration is the place where webpack will place the bundles 26 mode: 'production', entry: { app: './apps/frontend/js/index.js'}, output: { filename: '[name].[hash].bundle.js', path: __dirname + '/apps/frontend/dist/', publicPath: '/static/dist/' },
  • 27. Webpack.config.js - core concepts 4. plugins: are used for wide range of tasks such as asset management 5. loaders: allow processing of other types of files. (css, etc) 27 plugins: [new VueLoaderPlugin()], module: {rules: [ { test: /.css$/, use: ['style-loader', 'css-loader']}, { test: /.vue$/, use: 'vue-loader'}, { test: /.*.(png|jpe?g)$/, use: 'file-loader'}]}
  • 28. 28 const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { mode: 'production', entry: { app: './apps/frontend/js/index.js'}, output: { filename: '[name].[hash].bundle.js', path: __dirname + '/apps/frontend/dist/', publicPath: '/static/dist/' }, plugins: [ new VueLoaderPlugin(), ], module: {rules: [ { test: /.css$/, use: ['style-loader', 'css-loader']}, { test: /.vue$/, use: 'vue-loader'}, { test: /.*.(png|jpe?g)$/, use: 'file-loader'},],}, }; Additional requires Additional plugins Additional loaders
  • 29. Update Vue.js code Webpack also enables the use of Single File Components (SFCs) in vue.js Really useful as the project expands to create reusable and isolated components Create new file App.vue. html, javascript and css for app in one file. File index.js is entry point to App.vue. 29
  • 30. 30 NPM scripts: build command In package.json “scripts” section add a line for “build” command: scripts: {"build": "webpack"}
  • 31. Missing frontend requirements ● On production, minified JavaScript code with any comments removed ● Unique hash in file names to let browser cache know file updated 31
  • 33. Library to transparently use webpack with django Metadata file, produced by webpack plugin, tells Django where the generated files are located. 33 Enter “django-webpack-loader” “One of the core principles of django-webpack-loader is to not manage webpack itself in order to give you the flexibility to run webpack the way you want.“ ~ django-webpack-loader documentation
  • 34. 34 Update JavaScript side const BundleTracker = require('webpack-bundle-tracker');] plugins: [ <other plugins>... new BundleTracker({filename: './apps/webpack-stats.json'}), ] 1. npm install webpack-bundle-tracker 2. Add BundleTracker to webpack.config.js which will write to file on build
  • 35. 1. pip install django-webpack-loader 2. Update Django’s settings.py a. Add “webpack_loader” to INSTALLED_APPS b. Add in a section WEBPACK_LOADER: 3. Use “render_bundle” template tag rather then “static” in templates. This links to the files generated in dist/ directory 35 Update Django side WEBPACK_LOADER = { 'DEFAULT': { 'BUNDLE_DIR_NAME': 'dist/', 'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')}}
  • 36. Integrated! npm run build is run first to create the bundles ● Bundles in “dist” directory. webpack-stats.json contains the filenames python manager.py runserver follows to run Django ● Django template will include the bundled files from webpack 36
  • 37. 37
  • 38. Missing frontend requirements ● On production, minified JavaScript code with any comments removed -> Set the mode to ‘production’ ● Unique hash in file names to let browser cache know file updated -> Include unique hash in each filename ● On development, page refresh on code change while retaining state ● Code splitting so that only minimal code downloaded to browser 38
  • 40. Extra webpack configuration 40 The following additional configurations can be added as needed: Eslint, Babel, clean old bundles plugin, bundle analyzer plugin, … Chosen extras: 1. Webpack-dev-server: Hot-reload for local development 2. Code splitting: define multiple entry points to avoid downloading the same code to the browser twice
  • 41. Webpack-dev-server On a code change, re-run build and update Browser display for quicker development. Webpack-dev-server runs in one terminal tab and Django development server in another tab. 41 webpack-dev-server Save to File system Watch for changes Update display Browser
  • 42. Webpack-dev-server Hot reload to refresh page the part of the page that has changed. npm install webpack-dev-server webpack-merge Add a 2nd entry to the “scripts” section of package.json: 42 scripts: {"build": "webpack" "start": "webpack-dev-server --config webpack.dev.js"}
  • 43. Webpack-dev-server 43 Add new config webpack.dev.js for development specific config const merge = require('webpack-merge'); const common = require('./webpack.config.js'); module.exports = merge(common, { mode: 'development', output: {publicPath: 'http://localhost:3000/static/dist/'}, devServer: { port: 3000, hot: true, headers: {'Access-Control-Allow-Origin': '*'}} });
  • 44. Code Splitting Powerful webpack feature to split code into various bundles which can then be loaded on demand or in parallel to help improve page load time. 44
  • 45. Code Splitting Prevent Duplication: Split out “vendor” code so when a new entry point is added, no need for browser to re-download vendor (Vue.js, bootstrap). Separate “render_bundle” call in HTML template for “vendor” bundle 45 optimization: { splitChunks: { cacheGroups: { commons: { test: /[/]node_modules[/]/, chunks: 'initial', name: 'vendor'}}}},
  • 46. ● On production, minified JavaScript code with any comments removed -> Set the mode to ‘production’ ● Unique hash in file names to let browser cache know file updated -> Include hash in each filename ● On development, page refresh on code change while retaining state -> add webpack-dev-server with configuration to watch source files ● Code splitting so that only minimal code downloaded to browser -> make use of optimisation in webpack to split files Missing frontend requirements 46
  • 47. 47
  • 48. Talk Summary Webpack is a tool for modern JavaScript development, handles different file types of static files to produce bundles. Example application which uses webpack to bundle static files and incorporated into Django with django-webpack-loader. Once basic webpack configuration is in place, it is easy to add functionality as needed. Tried-and-tested way to webpack your Django! 48
  • 49. Thank you for listening! 49 Any Questions?
  • 50. Links Code from this talk: https://github.com/davgibbs/quotes-display Django static files: https://docs.djangoproject.com/en/2.2/howto/static-files/ Webpack documentation: https://webpack.js.org/concepts/ Homepage for django-webpack-loader: https://github.com/owais/django-webpack-loader 50