whitenoise collectstatic: ignore map filles

Hi there,

I’m trying to deploy my django website. I’m using a template for the webdesign which includes a lot of js frameworks. When i try to collect static i get errors that references to .map files cannot be found, which is absolutely logical. However I am now unable to create my staticfiles dir.

Is there a way to skip .map files when using whitenoise ?

ChatGPT suggested me to include:

WHITENOISE_STATIC_FILE_EXCLUDE_EXTENSIONS = ['map']

However that does not work. Which is also logical since the documentation or changelog of whitenoise does not even mention this option. The closest thing to this setting is the following.

However changing the code to the following also does not work:

WHITENOISE_SKIP_COMPRESS_EXTENSIONS = ['map']

I’ve found some websites providing a solution to just skip all errors, to make whitenoise more forgiving. I however I would like to avoid using shady libraries.

I think skipping .map files should be something straightforward since i recon this should be a fairly common thing to happen. So is there also a straightforward solution to this ?

This is my error:

docker-compose exec web python manage.py collectstatic

You have requested to collect static files at the destination
location as specified in your settings:

    /websiteV2/staticfiles

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel: yes
Post-processing 'libs/@popperjs/core/dist/umd/popper-base.min.js' failed!

Traceback (most recent call last):
  File "/websiteV2/manage.py", line 22, in <module>
    main()
  File "/websiteV2/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 209, in handle
    collected = self.collect()
  File "/usr/local/lib/python3.10/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 154, in collect
    raise processed
whitenoise.storage.MissingFileError: The file 'libs/@popperjs/core/dist/umd/popper-base.min.js.map' could not be found with <whitenoise.storage.CompressedManifestStaticFilesStorage object at 0x7fc0ae296110>.

The JS file 'libs/@popperjs/core/dist/umd/popper-base.min.js' references a file which could not be found:
  libs/@popperjs/core/dist/umd/popper-base.min.js.map

Please check the URL references in this JS file, particularly any
relative paths which might be pointing to the wrong location.

and this is my settings.py:

"""
Django settings for base project.

Generated by 'django-admin startproject' using Django 4.2.4.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path
#from . import secret_keys
from environs import Env
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

env = Env()
env.read_env()

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
#SECRET_KEY = secret_keys.django_secret_key()
SECRET_KEY=env.str("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = True
DEBUG = env.bool("DEBUG", default=False)

#Cookies
SESSION_COOKIE_SAMESITE = 'Strict'
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_COOKIE_SECURE = True

ALLOWED_HOSTS = ['0.0.0.0','127.0.0.1','localhost']

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    # Third party apps
    "crispy_forms",
    "crispy_bootstrap5",
    'allauth',
    'allauth.account',
    'django_countries',
    'rest_framework',
    'corsheaders',
    # Local apps
    "pages.apps.PagesConfig",
    "subscription.apps.SubscriptionConfig",
    "book.apps.BookConfig",
    "solver.apps.SolverConfig",
    "accounts.apps.AccountsConfig",
    "api.apps.ApiConfig",
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
}

# django-allauth config
LOGIN_REDIRECT_URL = "home"
ACCOUNT_LOGOUT_REDIRECT = "home"
SITE_ID = 1
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
]
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True

MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware', #whitenoise
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware', #corsheaders
]

CORS_ALLOWED_ORIGINS = (
    "http://localhost:3000",
    "http://localhost:8000",
    "https://localhost:3000",
    "https://localhost:8000",
)

CSRF_TRUSTED_ORIGINS = [
    "http://localhost:3000",
    "http://localhost:8000",
    "https://localhost:3000",
    "https://localhost:8000",
]

ROOT_URLCONF = 'base.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / "templates",BASE_DIR / "book" / "templates"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'base.wsgi.application'

# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "postgres",
       "USER": "postgres",
       "PASSWORD": "postgres",
        "HOST": "db", # set in docker-compose.yml
        "PORT": 5432, # default postgres port
    }
}

#DATABASES = {
#    'default': env.dj_db_url('DATABASE_URL')
#}

# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'
#STATICFILES_DIRS = [BASE_DIR / "static"]
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
    os.path.join(BASE_DIR, 'geeks', 'dist', 'assets'),
    os.path.join(BASE_DIR, 'solver'),
    os.path.join(BASE_DIR, 'node_modules'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

# Django Whitenoise Configuration
WHITENOISE_SKIP_COMPRESS_EXTENSIONS = ['.map']

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
#STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"

CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"

CRISPY_TEMPLATE_PACK = "bootstrap5"

#MEDIA
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'


# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

AUTH_USER_MODEL = "accounts.CustomUser"

LOGOUT_REDIRECT_URL = "home"

Found the solution, I should’ve used this instead of the line mentioned above:

STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage