mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-26 03:24:01 +03:00
Add Webpack support (#3623)
* Add support for Webpack as frontend pipeline * Rename CI jobs * Fix a couple of issues with Webpack + Docker * Don't include Boostrap CSS from CDN with Webpack * Rename variable * Set publicPath in prod webpack config * Fix removal of SASS files in post-gen hooks * Add Webpack to readme usage section * Run Django + Webpack dev server concurrently without Docker * Fix async runserver command with Gulp/Webpack * Upgrade django-webpack-loader to 1.5.0 * Pass variables required by Webpack at build time * Upgrade django-webpack-loader to 1.7.0 * Add missing condition * Add support for Azure Storage + Webpack * Whitespaces * Rename ROOT_DIR -> BASE_DIR * Rename jobs * Bump django-webpack-loader to latest * Document limitation of Docker + Webpack + no Whitenoise * Update section on custom Bootstrap compilation in generated readme
This commit is contained in:
parent
977ffd91a3
commit
cbb0e19de7
22
.github/workflows/ci.yml
vendored
22
.github/workflows/ci.yml
vendored
|
@ -29,7 +29,7 @@ jobs:
|
||||||
- windows-latest
|
- windows-latest
|
||||||
- macOS-latest
|
- macOS-latest
|
||||||
|
|
||||||
name: "Run tests"
|
name: "pytest ${{ matrix.os }}"
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -49,10 +49,14 @@ jobs:
|
||||||
script:
|
script:
|
||||||
- name: Basic
|
- name: Basic
|
||||||
args: ""
|
args: ""
|
||||||
- name: Extended
|
- name: Celery & DRF
|
||||||
args: "use_celery=y use_drf=y frontend_pipeline=Gulp"
|
args: "use_celery=y use_drf=y"
|
||||||
|
- name: Gulp
|
||||||
|
args: "frontend_pipeline=Gulp"
|
||||||
|
- name: Webpack
|
||||||
|
args: "frontend_pipeline=Webpack"
|
||||||
|
|
||||||
name: "${{ matrix.script.name }} Docker"
|
name: "Docker ${{ matrix.script.name }}"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
DOCKER_BUILDKIT: 1
|
DOCKER_BUILDKIT: 1
|
||||||
|
@ -74,12 +78,14 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
script:
|
script:
|
||||||
- name: With Celery
|
- name: Celery
|
||||||
args: "use_celery=y frontend_pipeline='Django Compressor'"
|
args: "use_celery=y frontend_pipeline='Django Compressor'"
|
||||||
- name: With Gulp
|
- name: Gulp
|
||||||
args: "frontend_pipeline='Gulp'"
|
args: "frontend_pipeline=Gulp"
|
||||||
|
- name: Webpack
|
||||||
|
args: "frontend_pipeline=Webpack"
|
||||||
|
|
||||||
name: "${{ matrix.script.name }} Bare metal"
|
name: "Bare metal ${{ matrix.script.name }}"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
|
|
@ -27,7 +27,7 @@ production-ready Django projects quickly.
|
||||||
- Registration via [django-allauth](https://github.com/pennersr/django-allauth)
|
- Registration via [django-allauth](https://github.com/pennersr/django-allauth)
|
||||||
- Comes with custom user model ready to go
|
- Comes with custom user model ready to go
|
||||||
- Optional basic ASGI setup for Websockets
|
- Optional basic ASGI setup for Websockets
|
||||||
- Optional custom static build using Gulp and livereload
|
- Optional custom static build using Gulp or Webpack
|
||||||
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
|
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
|
||||||
- Media storage using Amazon S3, Google Cloud Storage or Azure Storage
|
- Media storage using Amazon S3, Google Cloud Storage or Azure Storage
|
||||||
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
|
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
|
||||||
|
@ -149,6 +149,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
|
||||||
1 - None
|
1 - None
|
||||||
2 - Django Compressor
|
2 - Django Compressor
|
||||||
3 - Gulp
|
3 - Gulp
|
||||||
|
4 - Webpack
|
||||||
Choose from 1, 2, 3, 4 [1]: 1
|
Choose from 1, 2, 3, 4 [1]: 1
|
||||||
use_celery [n]: y
|
use_celery [n]: y
|
||||||
use_mailhog [n]: n
|
use_mailhog [n]: n
|
||||||
|
|
|
@ -46,7 +46,8 @@
|
||||||
"frontend_pipeline": [
|
"frontend_pipeline": [
|
||||||
"None",
|
"None",
|
||||||
"Django Compressor",
|
"Django Compressor",
|
||||||
"Gulp"
|
"Gulp",
|
||||||
|
"Webpack"
|
||||||
],
|
],
|
||||||
"use_celery": "n",
|
"use_celery": "n",
|
||||||
"use_mailhog": "n",
|
"use_mailhog": "n",
|
||||||
|
|
|
@ -109,10 +109,10 @@ Or add the DSN for your account, if you already have one:
|
||||||
.. _Sentry add-on: https://elements.heroku.com/addons/sentry
|
.. _Sentry add-on: https://elements.heroku.com/addons/sentry
|
||||||
|
|
||||||
|
|
||||||
Gulp & Bootstrap compilation
|
Gulp or Webpack
|
||||||
++++++++++++++++++++++++++++
|
+++++++++++++++
|
||||||
|
|
||||||
If you've opted for Gulp, you'll most likely need to setup
|
If you've opted for Gulp or Webpack as frontend pipeline, you'll most likely need to setup
|
||||||
your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
@ -121,7 +121,7 @@ your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
||||||
|
|
||||||
At time of writing, this should do the trick: during deployment,
|
At time of writing, this should do the trick: during deployment,
|
||||||
the Heroku should run ``npm install`` and then ``npm build``,
|
the Heroku should run ``npm install`` and then ``npm build``,
|
||||||
which runs Gulp in cookiecutter-django.
|
which run the SASS compilation & JS bundling.
|
||||||
|
|
||||||
If things don't work, please refer to the Heroku docs.
|
If things don't work, please refer to the Heroku docs.
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,32 @@ You can read more about this feature and how to configure it, at `Automatic HTTP
|
||||||
|
|
||||||
.. _Automatic HTTPS: https://docs.traefik.io/https/acme/
|
.. _Automatic HTTPS: https://docs.traefik.io/https/acme/
|
||||||
|
|
||||||
|
.. _webpack-whitenoise-limitation:
|
||||||
|
|
||||||
|
Webpack without Whitenoise limitation
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
If you opt for Webpack without Whitenoise, Webpack needs to know the static URL at build time, when running ``docker-compose build`` (See ``webpack/prod.config.js``). Depending on your setup, this URL may come from the following environment variables:
|
||||||
|
|
||||||
|
- ``AWS_STORAGE_BUCKET_NAME``
|
||||||
|
- ``DJANGO_AWS_S3_CUSTOM_DOMAIN``
|
||||||
|
- ``DJANGO_GCP_STORAGE_BUCKET_NAME``
|
||||||
|
- ``DJANGO_AZURE_CONTAINER_NAME``
|
||||||
|
|
||||||
|
The Django settings are getting these values at runtime via the ``.envs/.production/.django`` file , but Docker does not read this file at build time, it only look for a ``.env`` in the root of the project. Failing to pass the values correctly will result in a page without CSS styles nor javascript.
|
||||||
|
|
||||||
|
To solve this, you can either:
|
||||||
|
|
||||||
|
1. merge all the env files into ``.env`` by running::
|
||||||
|
|
||||||
|
merge_production_dotenvs_in_dotenv.py
|
||||||
|
|
||||||
|
2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them).
|
||||||
|
3. set these variables when running the build command::
|
||||||
|
|
||||||
|
DJANGO_AWS_S3_CUSTOM_DOMAIN=example.com docker-compose -f production.yml build``.
|
||||||
|
|
||||||
|
None of these options are ideal, we're open to suggestions on how to improve this. If you think you have one, please open an issue or a pull request.
|
||||||
|
|
||||||
(Optional) Postgres Data Volume Modifications
|
(Optional) Postgres Data Volume Modifications
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
|
@ -172,7 +172,7 @@ You can also use Django admin to queue up tasks, thanks to the `django-celerybea
|
||||||
Sass Compilation & Live Reloading
|
Sass Compilation & Live Reloading
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
If you've opted for Gulp as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
|
If you've opted for Gulp or Webpack as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
|
||||||
|
|
||||||
#. Make sure that `Node.js`_ v16 is installed on your machine.
|
#. Make sure that `Node.js`_ v16 is installed on your machine.
|
||||||
#. In the project root, install the JS dependencies with::
|
#. In the project root, install the JS dependencies with::
|
||||||
|
|
|
@ -95,7 +95,10 @@ frontend_pipeline:
|
||||||
|
|
||||||
1. None
|
1. None
|
||||||
2. `Django Compressor`_
|
2. `Django Compressor`_
|
||||||
3. `Gulp`_: support Bootstrap recompilation with real-time variables alteration.
|
3. `Gulp`_
|
||||||
|
4. `Webpack`_
|
||||||
|
|
||||||
|
Both Gulp and Webpack support Bootstrap recompilation with real-time variables alteration.
|
||||||
|
|
||||||
use_celery:
|
use_celery:
|
||||||
Indicates whether the project should be configured to use Celery_.
|
Indicates whether the project should be configured to use Celery_.
|
||||||
|
@ -145,6 +148,7 @@ debug:
|
||||||
.. _PostgreSQL: https://www.postgresql.org/docs/
|
.. _PostgreSQL: https://www.postgresql.org/docs/
|
||||||
|
|
||||||
.. _Gulp: https://github.com/gulpjs/gulp
|
.. _Gulp: https://github.com/gulpjs/gulp
|
||||||
|
.. _Webpack: https://webpack.js.org
|
||||||
|
|
||||||
.. _AWS: https://aws.amazon.com/s3/
|
.. _AWS: https://aws.amazon.com/s3/
|
||||||
.. _GCP: https://cloud.google.com/storage/
|
.. _GCP: https://cloud.google.com/storage/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
=====================================
|
===============
|
||||||
|
|
||||||
This page contains some advice about errors and problems commonly encountered during the development of Cookiecutter Django applications.
|
This page contains some advice about errors and problems commonly encountered during the development of Cookiecutter Django applications.
|
||||||
|
|
||||||
|
@ -38,6 +38,16 @@ To fix this, you can either:
|
||||||
.. _rm: https://docs.docker.com/engine/reference/commandline/volume_rm/
|
.. _rm: https://docs.docker.com/engine/reference/commandline/volume_rm/
|
||||||
.. _prune: https://docs.docker.com/v17.09/engine/reference/commandline/system_prune/
|
.. _prune: https://docs.docker.com/v17.09/engine/reference/commandline/system_prune/
|
||||||
|
|
||||||
|
Variable is not set. Defaulting to a blank string
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
WARN[0000] The "DJANGO_AWS_STORAGE_BUCKET_NAME" variable is not set. Defaulting to a blank string.
|
||||||
|
WARN[0000] The "DJANGO_AWS_S3_CUSTOM_DOMAIN" variable is not set. Defaulting to a blank string.
|
||||||
|
|
||||||
|
You have probably opted for Docker + Webpack without Whitenoise. This is a know limitation of the combination, which needs a little bit of manual intervention. See the :ref:`dedicated section about it <webpack-whitenoise-limitation>`.
|
||||||
|
|
||||||
Others
|
Others
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ TODO: restrict Cookiecutter Django project initialization to
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -87,15 +88,30 @@ def remove_heroku_build_hooks():
|
||||||
shutil.rmtree("bin")
|
shutil.rmtree("bin")
|
||||||
|
|
||||||
|
|
||||||
|
def remove_sass_files():
|
||||||
|
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass"))
|
||||||
|
|
||||||
|
|
||||||
def remove_gulp_files():
|
def remove_gulp_files():
|
||||||
file_names = ["gulpfile.js"]
|
file_names = ["gulpfile.js"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
remove_sass_files()
|
|
||||||
|
|
||||||
|
|
||||||
def remove_sass_files():
|
def remove_webpack_files():
|
||||||
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass"))
|
shutil.rmtree("webpack")
|
||||||
|
remove_vendors_js()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_vendors_js():
|
||||||
|
vendors_js_path = os.path.join(
|
||||||
|
"{{ cookiecutter.project_slug }}",
|
||||||
|
"static",
|
||||||
|
"js",
|
||||||
|
"vendors.js",
|
||||||
|
)
|
||||||
|
if os.path.exists(vendors_js_path):
|
||||||
|
os.remove(vendors_js_path)
|
||||||
|
|
||||||
|
|
||||||
def remove_packagejson_file():
|
def remove_packagejson_file():
|
||||||
|
@ -104,6 +120,83 @@ def remove_packagejson_file():
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
|
||||||
|
|
||||||
|
def update_package_json(remove_dev_deps=None, remove_keys=None, scripts=None):
|
||||||
|
remove_dev_deps = remove_dev_deps or []
|
||||||
|
remove_keys = remove_keys or []
|
||||||
|
scripts = scripts or {}
|
||||||
|
with open("package.json", mode="r") as fd:
|
||||||
|
content = json.load(fd)
|
||||||
|
for package_name in remove_dev_deps:
|
||||||
|
content["devDependencies"].pop(package_name)
|
||||||
|
for key in remove_keys:
|
||||||
|
content.pop(key)
|
||||||
|
content["scripts"].update(scripts)
|
||||||
|
with open("package.json", mode="w") as fd:
|
||||||
|
json.dump(content, fd, ensure_ascii=False, indent=2)
|
||||||
|
fd.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def handle_js_runner(choice, use_docker, use_async):
|
||||||
|
if choice == "Gulp":
|
||||||
|
update_package_json(
|
||||||
|
remove_dev_deps=[
|
||||||
|
"@babel/core",
|
||||||
|
"@babel/preset-env",
|
||||||
|
"babel-loader",
|
||||||
|
"concurrently",
|
||||||
|
"css-loader",
|
||||||
|
"mini-css-extract-plugin",
|
||||||
|
"postcss-loader",
|
||||||
|
"postcss-preset-env",
|
||||||
|
"sass-loader",
|
||||||
|
"webpack",
|
||||||
|
"webpack-bundle-tracker",
|
||||||
|
"webpack-cli",
|
||||||
|
"webpack-dev-server",
|
||||||
|
"webpack-merge",
|
||||||
|
],
|
||||||
|
remove_keys=["babel"],
|
||||||
|
scripts={
|
||||||
|
"dev": "gulp",
|
||||||
|
"build": "gulp generate-assets",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
remove_webpack_files()
|
||||||
|
elif choice == "Webpack":
|
||||||
|
scripts = {
|
||||||
|
"dev": "webpack serve --config webpack/dev.config.js",
|
||||||
|
"build": "webpack --config webpack/prod.config.js",
|
||||||
|
}
|
||||||
|
remove_dev_deps = [
|
||||||
|
"browser-sync",
|
||||||
|
"cssnano",
|
||||||
|
"gulp",
|
||||||
|
"gulp-imagemin",
|
||||||
|
"gulp-plumber",
|
||||||
|
"gulp-postcss",
|
||||||
|
"gulp-rename",
|
||||||
|
"gulp-sass",
|
||||||
|
"gulp-uglify-es",
|
||||||
|
]
|
||||||
|
if not use_docker:
|
||||||
|
dev_django_cmd = (
|
||||||
|
"uvicorn config.asgi:application --reload"
|
||||||
|
if use_async
|
||||||
|
else "python manage.py runserver_plus"
|
||||||
|
)
|
||||||
|
scripts.update(
|
||||||
|
{
|
||||||
|
"dev": "concurrently npm:dev:*",
|
||||||
|
"dev:webpack": "webpack serve --config webpack/dev.config.js",
|
||||||
|
"dev:django": dev_django_cmd,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
remove_dev_deps.append("concurrently")
|
||||||
|
update_package_json(remove_dev_deps=remove_dev_deps, scripts=scripts)
|
||||||
|
remove_gulp_files()
|
||||||
|
|
||||||
|
|
||||||
def remove_celery_files():
|
def remove_celery_files():
|
||||||
file_names = [
|
file_names = [
|
||||||
os.path.join("config", "celery_app.py"),
|
os.path.join("config", "celery_app.py"),
|
||||||
|
@ -384,13 +477,21 @@ def main():
|
||||||
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
||||||
append_to_gitignore_file("!.envs/.local/")
|
append_to_gitignore_file("!.envs/.local/")
|
||||||
|
|
||||||
if "{{ cookiecutter.frontend_pipeline }}" != "Gulp":
|
if "{{ cookiecutter.frontend_pipeline }}" in ["None", "Django Compressor"]:
|
||||||
remove_gulp_files()
|
remove_gulp_files()
|
||||||
|
remove_webpack_files()
|
||||||
|
remove_sass_files()
|
||||||
remove_packagejson_file()
|
remove_packagejson_file()
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
remove_node_dockerfile()
|
remove_node_dockerfile()
|
||||||
|
else:
|
||||||
|
handle_js_runner(
|
||||||
|
"{{ cookiecutter.frontend_pipeline }}",
|
||||||
|
use_docker=("{{ cookiecutter.use_docker }}".lower() == "y"),
|
||||||
|
use_async=("{{ cookiecutter.use_async }}".lower() == "y"),
|
||||||
|
)
|
||||||
|
|
||||||
if "{{ cookiecutter.cloud_provider}}" == "None":
|
if "{{ cookiecutter.cloud_provider }}" == "None":
|
||||||
print(
|
print(
|
||||||
WARNING + "You chose not to use a cloud provider, "
|
WARNING + "You chose not to use a cloud provider, "
|
||||||
"media files won't be served in production." + TERMINATOR
|
"media files won't be served in production." + TERMINATOR
|
||||||
|
|
|
@ -32,13 +32,11 @@ pytest
|
||||||
# Make sure the check doesn't raise any warnings
|
# Make sure the check doesn't raise any warnings
|
||||||
python manage.py check --fail-level WARNING
|
python manage.py check --fail-level WARNING
|
||||||
|
|
||||||
|
# Run npm build script if package.json is present
|
||||||
if [ -f "package.json" ]
|
if [ -f "package.json" ]
|
||||||
then
|
then
|
||||||
npm install
|
npm install
|
||||||
if [ -f "gulpfile.js" ]
|
npm run build
|
||||||
then
|
|
||||||
npm run build
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate the HTML for the documentation
|
# Generate the HTML for the documentation
|
||||||
|
|
|
@ -101,6 +101,7 @@ SUPPORTED_COMBINATIONS = [
|
||||||
{"frontend_pipeline": "None"},
|
{"frontend_pipeline": "None"},
|
||||||
{"frontend_pipeline": "Django Compressor"},
|
{"frontend_pipeline": "Django Compressor"},
|
||||||
{"frontend_pipeline": "Gulp"},
|
{"frontend_pipeline": "Gulp"},
|
||||||
|
{"frontend_pipeline": "Webpack"},
|
||||||
{"use_celery": "y"},
|
{"use_celery": "y"},
|
||||||
{"use_celery": "n"},
|
{"use_celery": "n"},
|
||||||
{"use_mailhog": "y"},
|
{"use_mailhog": "y"},
|
||||||
|
|
|
@ -41,3 +41,9 @@ docker-compose -f local.yml run django python manage.py check --fail-level WARNI
|
||||||
|
|
||||||
# Generate the HTML for the documentation
|
# Generate the HTML for the documentation
|
||||||
docker-compose -f local.yml run docs make html
|
docker-compose -f local.yml run docs make html
|
||||||
|
|
||||||
|
# Run npm build script if package.json is present
|
||||||
|
if [ -f "package.json" ]
|
||||||
|
then
|
||||||
|
docker-compose -f local.yml run node npm run build
|
||||||
|
fi
|
||||||
|
|
4
{{cookiecutter.project_slug}}/.gitignore
vendored
4
{{cookiecutter.project_slug}}/.gitignore
vendored
|
@ -348,3 +348,7 @@ vendors.js
|
||||||
*.min.js
|
*.min.js
|
||||||
*.min.js.map
|
*.min.js.map
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
{{ cookiecutter.project_slug }}/static/webpack_bundles/
|
||||||
|
webpack-stats.json
|
||||||
|
{%- endif %}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<option value="celeryworker"/>
|
<option value="celeryworker"/>
|
||||||
<option value="celerybeat"/>
|
<option value="celerybeat"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
<option value="node"/>
|
<option value="node"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</list>
|
</list>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
{% if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
||||||
</content>
|
</content>
|
||||||
|
|
|
@ -128,13 +128,14 @@ See detailed [cookiecutter-django Heroku documentation](http://cookiecutter-djan
|
||||||
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
|
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
|
|
||||||
### Custom Bootstrap Compilation
|
### Custom Bootstrap Compilation
|
||||||
|
|
||||||
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
|
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
|
||||||
Bootstrap v5 is installed using npm and customised by tweaking your variables in `static/sass/custom_bootstrap_vars`.
|
Bootstrap v5 is installed using npm and customised by tweaking your variables in `static/sass/custom_bootstrap_vars`.
|
||||||
|
|
||||||
You can find a list of available variables [in the bootstrap source](https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/docs/5.1/customize/sass/).
|
You can find a list of available variables [in the bootstrap source](https://github.com/twbs/bootstrap/blob/v5.1.3/scss/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/docs/5.1/customize/sass/).
|
||||||
|
|
||||||
Bootstrap's javascript as well as its dependencies is concatenated into a single file: `static/js/vendors.js`.
|
Bootstrap's javascript as well as its dependencies are concatenated into a single file: `static/js/vendors.js`.
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
ARG PYTHON_VERSION=3.10-slim-bullseye
|
ARG PYTHON_VERSION=3.10-slim-bullseye
|
||||||
|
|
||||||
{% if cookiecutter.frontend_pipeline == 'Gulp' -%}
|
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%}
|
||||||
FROM node:16-bullseye-slim as client-builder
|
FROM node:16-bullseye-slim as client-builder
|
||||||
|
|
||||||
ARG APP_HOME=/app
|
ARG APP_HOME=/app
|
||||||
|
@ -9,6 +9,20 @@ WORKDIR ${APP_HOME}
|
||||||
COPY ./package.json ${APP_HOME}
|
COPY ./package.json ${APP_HOME}
|
||||||
RUN npm install && npm cache clean --force
|
RUN npm install && npm cache clean --force
|
||||||
COPY . ${APP_HOME}
|
COPY . ${APP_HOME}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' and cookiecutter.use_whitenoise == 'n' %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
|
ARG DJANGO_AWS_STORAGE_BUCKET_NAME
|
||||||
|
ENV DJANGO_AWS_STORAGE_BUCKET_NAME=${DJANGO_AWS_STORAGE_BUCKET_NAME}
|
||||||
|
ARG DJANGO_AWS_S3_CUSTOM_DOMAIN
|
||||||
|
ENV DJANGO_AWS_S3_CUSTOM_DOMAIN=${DJANGO_AWS_S3_CUSTOM_DOMAIN}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'GCP' %}
|
||||||
|
ARG DJANGO_GCP_STORAGE_BUCKET_NAME
|
||||||
|
ENV DJANGO_GCP_STORAGE_BUCKET_NAME=${DJANGO_GCP_STORAGE_BUCKET_NAME}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'Azure' %}
|
||||||
|
ARG DJANGO_AZURE_ACCOUNT_NAME
|
||||||
|
ENV DJANGO_AZURE_ACCOUNT_NAME=${DJANGO_AZURE_ACCOUNT_NAME}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
@ -99,7 +113,7 @@ RUN chmod +x /start-flower
|
||||||
|
|
||||||
|
|
||||||
# copy application code to WORKDIR
|
# copy application code to WORKDIR
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME}
|
COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME}
|
||||||
{% else %}
|
{% else %}
|
||||||
COPY --chown=django:django . ${APP_HOME}
|
COPY --chown=django:django . ${APP_HOME}
|
||||||
|
|
|
@ -87,6 +87,9 @@ THIRD_PARTY_APPS = [
|
||||||
"corsheaders",
|
"corsheaders",
|
||||||
"drf_spectacular",
|
"drf_spectacular",
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
"webpack_loader",
|
||||||
|
{%- endif %}
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
|
@ -355,6 +358,19 @@ SPECTACULAR_SETTINGS = {
|
||||||
"VERSION": "1.0.0",
|
"VERSION": "1.0.0",
|
||||||
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
||||||
}
|
}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
# django-webpack-loader
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
WEBPACK_LOADER = {
|
||||||
|
"DEFAULT": {
|
||||||
|
"CACHE": not DEBUG,
|
||||||
|
"STATS_FILE": BASE_DIR / "webpack-stats.json",
|
||||||
|
"POLL_INTERVAL": 0.1,
|
||||||
|
"IGNORE": [r".+\.hot-update.js", r".+\.map"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -69,7 +69,7 @@ if env("USE_DOCKER") == "yes":
|
||||||
|
|
||||||
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
||||||
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
try:
|
try:
|
||||||
_, _, ips = socket.gethostbyname_ex("node")
|
_, _, ips = socket.gethostbyname_ex("node")
|
||||||
INTERNAL_IPS.extend(ips)
|
INTERNAL_IPS.extend(ips)
|
||||||
|
@ -94,6 +94,12 @@ CELERY_TASK_ALWAYS_EAGER = True
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-eager-propagates
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-eager-propagates
|
||||||
CELERY_TASK_EAGER_PROPAGATES = True
|
CELERY_TASK_EAGER_PROPAGATES = True
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
# django-webpack-loader
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG # noqa F405
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -10,6 +10,7 @@ const pjson = require('./package.json')
|
||||||
const autoprefixer = require('autoprefixer')
|
const autoprefixer = require('autoprefixer')
|
||||||
const browserSync = require('browser-sync').create()
|
const browserSync = require('browser-sync').create()
|
||||||
const concat = require('gulp-concat')
|
const concat = require('gulp-concat')
|
||||||
|
const tildeImporter = require('node-sass-tilde-importer');
|
||||||
const cssnano = require ('cssnano')
|
const cssnano = require ('cssnano')
|
||||||
const imagemin = require('gulp-imagemin')
|
const imagemin = require('gulp-imagemin')
|
||||||
const pixrem = require('pixrem')
|
const pixrem = require('pixrem')
|
||||||
|
@ -27,7 +28,6 @@ function pathsConfig(appName) {
|
||||||
const vendorsRoot = 'node_modules'
|
const vendorsRoot = 'node_modules'
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bootstrapSass: `${vendorsRoot}/bootstrap/scss`,
|
|
||||||
vendorsJs: [
|
vendorsJs: [
|
||||||
`${vendorsRoot}/@popperjs/core/dist/umd/popper.js`,
|
`${vendorsRoot}/@popperjs/core/dist/umd/popper.js`,
|
||||||
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
|
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
|
||||||
|
@ -61,8 +61,8 @@ function styles() {
|
||||||
|
|
||||||
return src(`${paths.sass}/project.scss`)
|
return src(`${paths.sass}/project.scss`)
|
||||||
.pipe(sass({
|
.pipe(sass({
|
||||||
|
importer: tildeImporter,
|
||||||
includePaths: [
|
includePaths: [
|
||||||
paths.bootstrapSass,
|
|
||||||
paths.sass
|
paths.sass
|
||||||
]
|
]
|
||||||
}).on('error', sass.logError))
|
}).on('error', sass.logError))
|
||||||
|
|
|
@ -105,7 +105,7 @@ services:
|
||||||
command: /start-flower
|
command: /start-flower
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
|
|
||||||
node:
|
node:
|
||||||
build:
|
build:
|
||||||
|
@ -122,7 +122,9 @@ services:
|
||||||
command: npm run dev
|
command: npm run dev
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
||||||
# Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui
|
# Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui
|
||||||
- "3001:3001"
|
- "3001:3001"
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
{
|
{
|
||||||
"name": "{{cookiecutter.project_slug}}",
|
"name": "{{cookiecutter.project_slug}}",
|
||||||
"version": "{{ cookiecutter.version }}",
|
"version": "{{ cookiecutter.version }}",
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bootstrap": "^5.1.3",
|
"@babel/core": "^7.16.5",
|
||||||
"gulp-concat": "^2.6.1",
|
"@babel/preset-env": "^7.16.5",
|
||||||
"@popperjs/core": "^2.10.2",
|
"@popperjs/core": "^2.10.2",
|
||||||
"autoprefixer": "^10.4.0",
|
"autoprefixer": "^10.4.0",
|
||||||
|
"babel-loader": "^8.2.3",
|
||||||
|
"bootstrap": "^5.1.3",
|
||||||
"browser-sync": "^2.27.7",
|
"browser-sync": "^2.27.7",
|
||||||
|
"css-loader": "^6.5.1",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"concurrently": "^7.0.0",
|
||||||
"cssnano": "^5.0.11",
|
"cssnano": "^5.0.11",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-imagemin": "^7.1.0",
|
"gulp-imagemin": "^7.1.0",
|
||||||
|
@ -16,9 +20,19 @@
|
||||||
"gulp-rename": "^2.0.0",
|
"gulp-rename": "^2.0.0",
|
||||||
"gulp-sass": "^5.0.0",
|
"gulp-sass": "^5.0.0",
|
||||||
"gulp-uglify-es": "^3.0.0",
|
"gulp-uglify-es": "^3.0.0",
|
||||||
|
"mini-css-extract-plugin": "^2.4.5",
|
||||||
|
"node-sass-tilde-importer": "^1.0.2",
|
||||||
"pixrem": "^5.0.0",
|
"pixrem": "^5.0.0",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.3.11",
|
||||||
"sass": "^1.43.4"
|
"postcss-loader": "^6.2.1",
|
||||||
|
"postcss-preset-env": "^7.0.2",
|
||||||
|
"sass": "^1.43.4",
|
||||||
|
"sass-loader": "^12.4.0",
|
||||||
|
"webpack": "^5.65.0",
|
||||||
|
"webpack-bundle-tracker": "^1.4.0",
|
||||||
|
"webpack-cli": "^4.9.1",
|
||||||
|
"webpack-dev-server": "^4.6.0",
|
||||||
|
"webpack-merge": "^5.8.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16"
|
"node": "16"
|
||||||
|
@ -26,8 +40,11 @@
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 2 versions"
|
"last 2 versions"
|
||||||
],
|
],
|
||||||
|
"babel": {
|
||||||
|
"presets": ["@babel/preset-env"]
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "gulp",
|
"dev": "",
|
||||||
"build": "gulp generate-assets"
|
"build": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,19 @@ services:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./compose/production/django/Dockerfile
|
dockerfile: ./compose/production/django/Dockerfile
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' and cookiecutter.use_whitenoise == 'n' %}
|
||||||
|
args:
|
||||||
|
# These variable can be defined in an .env file in the root of the repo
|
||||||
|
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
|
DJANGO_AWS_STORAGE_BUCKET_NAME: ${DJANGO_AWS_STORAGE_BUCKET_NAME}
|
||||||
|
DJANGO_AWS_S3_CUSTOM_DOMAIN: ${DJANGO_AWS_S3_CUSTOM_DOMAIN}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'GCP' %}
|
||||||
|
DJANGO_GCP_STORAGE_BUCKET_NAME: ${DJANGO_GCP_STORAGE_BUCKET_NAME}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'Azure' %}
|
||||||
|
DJANGO_AZURE_ACCOUNT_NAME: ${DJANGO_AZURE_ACCOUNT_NAME}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_django
|
image: {{ cookiecutter.project_slug }}_production_django
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
|
|
|
@ -42,7 +42,10 @@ django-redis==5.2.0 # https://github.com/jazzband/django-redis
|
||||||
{%- if cookiecutter.use_drf == 'y' %}
|
{%- if cookiecutter.use_drf == 'y' %}
|
||||||
# Django REST Framework
|
# Django REST Framework
|
||||||
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
|
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
|
||||||
django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
|
django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
|
||||||
# DRF-spectacular for api documentation
|
# DRF-spectacular for api documentation
|
||||||
drf-spectacular==0.25.1 # https://github.com/tfranzel/drf-spectacular
|
drf-spectacular==0.25.1 # https://github.com/tfranzel/drf-spectacular
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
django-webpack-loader==1.8.0 # https://github.com/django-webpack/django-webpack-loader
|
||||||
|
{%- endif %}
|
||||||
|
|
55
{{cookiecutter.project_slug}}/webpack/common.config.js
Normal file
55
{{cookiecutter.project_slug}}/webpack/common.config.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
const path = require('path');
|
||||||
|
const BundleTracker = require('webpack-bundle-tracker');
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
target: "web",
|
||||||
|
context: path.join(__dirname, '../'),
|
||||||
|
entry: {
|
||||||
|
'project': path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/project'),
|
||||||
|
'vendors': path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/js/vendors'),
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, '../{{cookiecutter.project_slug}}/static/webpack_bundles/'),
|
||||||
|
publicPath: '/static/webpack_bundles/',
|
||||||
|
filename: 'js/[name]-[fullhash].js',
|
||||||
|
chunkFilename: 'js/[name]-[hash].js',
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new BundleTracker({filename: path.resolve(__dirname, '../webpack-stats.json')}),
|
||||||
|
new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash].css' }),
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
// we pass the output from babel loader to react-hot loader
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.s?css$/i,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader,
|
||||||
|
'css-loader',
|
||||||
|
{
|
||||||
|
loader: 'postcss-loader',
|
||||||
|
options: {
|
||||||
|
postcssOptions: {
|
||||||
|
plugins: [
|
||||||
|
'postcss-preset-env',
|
||||||
|
'autoprefixer',
|
||||||
|
'pixrem',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'sass-loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
modules: ['node_modules'],
|
||||||
|
extensions: ['.js', '.jsx'],
|
||||||
|
},
|
||||||
|
};
|
20
{{cookiecutter.project_slug}}/webpack/dev.config.js
Normal file
20
{{cookiecutter.project_slug}}/webpack/dev.config.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
const { merge } = require('webpack-merge');
|
||||||
|
const commonConfig = require('./common.config');
|
||||||
|
|
||||||
|
module.exports = merge(commonConfig, {
|
||||||
|
mode: 'development',
|
||||||
|
devtool: 'inline-source-map',
|
||||||
|
devServer: {
|
||||||
|
port: 3000,
|
||||||
|
proxy: {
|
||||||
|
{%- if cookiecutter.use_docker == 'n' %}
|
||||||
|
'/': 'http://0.0.0.0:8000',
|
||||||
|
{%- else %}
|
||||||
|
'/': 'http://django:8000',
|
||||||
|
{%- endif %}
|
||||||
|
},
|
||||||
|
// We need hot=false (Disable HMR) to set liveReload=true
|
||||||
|
hot: false,
|
||||||
|
liveReload: true,
|
||||||
|
},
|
||||||
|
});
|
28
{{cookiecutter.project_slug}}/webpack/prod.config.js
Normal file
28
{{cookiecutter.project_slug}}/webpack/prod.config.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
const { merge } = require('webpack-merge');
|
||||||
|
const commonConfig = require('./common.config');
|
||||||
|
|
||||||
|
// This variable should mirror the one from config/settings/production.py
|
||||||
|
{%- if cookiecutter.use_whitenoise == 'n' %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
|
const s3BucketName = process.env.DJANGO_AWS_STORAGE_BUCKET_NAME;
|
||||||
|
const awsS3Domain = process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN ?
|
||||||
|
process.env.DJANGO_AWS_S3_CUSTOM_DOMAIN
|
||||||
|
: `${s3BucketName}.s3.amazonaws.com`;
|
||||||
|
const staticUrl = `https://${awsS3Domain}/static/`;
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'GCP' %}
|
||||||
|
const staticUrl = `https://storage.googleapis.com/${process.env.DJANGO_GCP_STORAGE_BUCKET_NAME}/static/`;
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'Azure' %}
|
||||||
|
const staticUrl = `https://${process.env.DJANGO_AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/`;
|
||||||
|
{%- endif %}
|
||||||
|
{%- else %}
|
||||||
|
const staticUrl = '/static/';
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
module.exports = merge(commonConfig, {
|
||||||
|
mode: 'production',
|
||||||
|
devtool: 'source-map',
|
||||||
|
bail: true,
|
||||||
|
output: {
|
||||||
|
publicPath: `${staticUrl}webpack_bundles/`,
|
||||||
|
},
|
||||||
|
});
|
|
@ -1 +1,5 @@
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
import '../sass/project.scss';
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
/* Project specific Javascript goes here. */
|
/* Project specific Javascript goes here. */
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
import '@popperjs/core';
|
||||||
|
import 'bootstrap';
|
|
@ -1,5 +1,5 @@
|
||||||
@import "custom_bootstrap_vars";
|
@import "custom_bootstrap_vars";
|
||||||
@import "bootstrap";
|
@import "~bootstrap/scss/bootstrap";
|
||||||
|
|
||||||
|
|
||||||
// project specific CSS goes here
|
// project specific CSS goes here
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
{% raw %}{% load static i18n {% endraw %}{% if cookiecutter.frontend_pipeline == 'Django Compressor' %}compress{% endif %}{% raw %}%}<!DOCTYPE html>
|
{% raw %}{% load static i18n {% endraw %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}compress
|
||||||
|
{%- endif %}{% raw %}%}{% endraw %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}{% raw %}{% load render_bundle from webpack_loader %}{% endraw %}
|
||||||
|
{%- endif %}{% raw %}<!DOCTYPE html>
|
||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
<html lang="{{ LANGUAGE_CODE }}">
|
<html lang="{{ LANGUAGE_CODE }}">
|
||||||
<head>
|
<head>
|
||||||
|
@ -13,7 +17,7 @@
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
{%- endraw %}
|
{%- endraw %}
|
||||||
{%- if cookiecutter.frontend_pipeline != 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['None', 'Django Compressor'] %}
|
||||||
{%- raw %}
|
{%- raw %}
|
||||||
<!-- Latest compiled and minified Bootstrap CSS -->
|
<!-- Latest compiled and minified Bootstrap CSS -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" integrity="sha512-GQGU0fMMi238uA+a/bdWJfpUGKUkBdgfFdgBm72SUQ6BeyWjoY/ton0tEjH+OSH9iP4Dfh+7HM0I9f5eR0L/4w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" integrity="sha512-GQGU0fMMi238uA+a/bdWJfpUGKUkBdgfFdgBm72SUQ6BeyWjoY/ton0tEjH+OSH9iP4Dfh+7HM0I9f5eR0L/4w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
@ -31,6 +35,8 @@
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
{%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
||||||
<link href="{% static 'css/project.min.css' %}" rel="stylesheet">
|
<link href="{% static 'css/project.min.css' %}" rel="stylesheet">
|
||||||
|
{%- endraw %}{% elif cookiecutter.frontend_pipeline == "Webpack" %}{% raw %}
|
||||||
|
{% render_bundle 'project' 'css' %}
|
||||||
{%- endraw %}{% endif %}{% raw %}
|
{%- endraw %}{% endif %}{% raw %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
<!-- Le javascript
|
<!-- Le javascript
|
||||||
|
@ -38,8 +44,11 @@
|
||||||
{# Placed at the top of the document so pages load faster with defer #}
|
{# Placed at the top of the document so pages load faster with defer #}
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
{%- endraw %}{% if cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
{%- endraw %}{% if cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
||||||
<!-- Vendor dependencies bundled as one file-->
|
<!-- Vendor dependencies bundled as one file -->
|
||||||
<script defer src="{% static 'js/vendors.min.js' %}"></script>
|
<script defer src="{% static 'js/vendors.min.js' %}"></script>
|
||||||
|
{%- endraw %}{% elif cookiecutter.frontend_pipeline == "Webpack" %}{% raw %}
|
||||||
|
<!-- Vendor dependencies bundled as one file -->
|
||||||
|
{% render_bundle 'vendors' 'js' attrs='defer' %}
|
||||||
{%- endraw %}{% else %}{% raw %}
|
{%- endraw %}{% else %}{% raw %}
|
||||||
<!-- Bootstrap JS -->
|
<!-- Bootstrap JS -->
|
||||||
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js" integrity="sha512-OvBgP9A2JBgiRad/mM36mkzXSXaJE9BEIENnVEmeZdITvwT09xnxLtT4twkCa8m/loMbPHsvPl0T8lRGVBwjlQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js" integrity="sha512-OvBgP9A2JBgiRad/mM36mkzXSXaJE9BEIENnVEmeZdITvwT09xnxLtT4twkCa8m/loMbPHsvPl0T8lRGVBwjlQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
@ -55,6 +64,8 @@
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
{%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
|
||||||
<script defer src="{% static 'js/project.min.js' %}"></script>
|
<script defer src="{% static 'js/project.min.js' %}"></script>
|
||||||
|
{%- endraw %}{% elif cookiecutter.frontend_pipeline == "Webpack" %}{% raw %}
|
||||||
|
{% render_bundle 'project' 'js' attrs='defer' %}
|
||||||
{%- endraw %}{% endif %}{% raw %}
|
{%- endraw %}{% endif %}{% raw %}
|
||||||
|
|
||||||
{% endblock javascript %}
|
{% endblock javascript %}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user