Repository: cookiecutter/cookiecutter-django

Issue:
Add Webpack as an Option
I've been interested in it as a way to maintain resources. And this is an AWESOME approach: https://github.com/hzdg/cookiecutter-webpack

Integrating it into Cookiecutter Django would be easy: https://github.com/hzdg/cookiecutter-webpack#integrating-into-existing-projects



Discussion:
That is very very nice, good find. I would far prefer to use webpack vs grunt (but as mentioned in another issue, tooling probably differs the most from person to person, so if possible an option for use of grunt, webpack, (gulp etc...)   would be best. 

+1 for that :)

I'm trying to understand Webpack but the documentation is pretty bad.

:bell: @jambonrose

I think we have to be careful with how webpack is configured if we do this. I'd prefer if Cookiecutter Django wasn't too specific to single-page apps. I lean on the side of not adding webpack unless it's added as an option and someone can maintain the feature.

I have a webpack config file for a Cookecutter Django project that essentially accomplishes most of grunt is doing for the project and adds transpiling of javascript, so it is easy to plug React in (or es6, coffeescript, etc...). It isn't specific to single-page apps. 

Here is a gist of what I have so far: [Webpack Config for Cookiecutter Django](https://gist.github.com/mjsisley/497ad917cd14ada63111e5d95951b892)

This may serve as a starting point that isn't single page app focused and works fairly similarly to how grunt is working in the project right now. The ExtractTextPlugin still needs to be configured properly to completely replace grunt (pulling css into a separate file). A lot more can be done with webpack than what is in the gist currently (ie, managing resources by chunking, [replace Django staticfile](https://github.com/owais/django-webpack-loader)).

I would like to see webpack in the project as an option (I think it makes working with React and other javascript dialects easier and allows for easier management of resources if needed) and would be happy do my best to help maintain the config file for the project if it was brought in.

If the consensus is to bring webpack in, let me know if I can help.

tldr: I agree with @audreyr 

I get the impression that Webpack is mostly used for bundling JS and assets in single page web apps (even though it could be used for bundling smaller scripts). Including it leads down a bit of a rabbit hole. If Webpack is included, a number of other pipelining decisions will likely need to be made to help/ease deployment of a single page app (such as whether to include the Django Rest Framework if Webpack is included). Ultimately, the Webpack config itself will need options, such as whether to use React, or another library, and whether to assume a particular structure for this projects. Finally, given how problematic Webpack's documentation is, I'd assume you would get quite a few requests for extra options and configurations.

Don't get me wrong: having a Webpack config available would be great. I just think it's going to be a lot of work, and it will position this project in a particular way.

tldr: Are you guys sure? I will submit a PR with a simple config if you guys decide you want it.

As someone who started with a Cookiecutter Django project and brought webpack in so that I could transpile React, es6, etc.., I think having a base webpack config file to start with would have been really helpful.

I worked out the issues I had with the CSS extraction to a separate path, so I could submit a pull request that provides webpack as an option with same functionality as Grunt (plus javascript transpiling). Then it would serve as an option to fulfill that role (and also handle different dialects of javascript) so that #466 could be supported and other features could be added later (but don't necessarily need to).  

As an aside, it seems you are moving towards dropping #466 and #538? Should there be a separate Cookiecutter Django - Single Page App Edition or something, or does something like this exist?

> As someone who started with a Cookiecutter Django project and brought webpack in so that I could transpile React, es6, etc.., I think having a base webpack config file to start with would have been really helpful.

The main problem I see is that someone has to maintain it. There will be new releases, bugs and questions and we have to take that into account, too.

Not that I'm totally against it, we just have to keep that in mind :)

That makes complete sense @jayfk and I understand the thought process. It probably makes sense for a Django cookiecutter project to only support one frontend build tool. 

I just like webpack because of its upside and was convinced it was the best of the alternatives by [instagram's usage](https://www.youtube.com/watch?v=VkTCL6Nqm6Y) awhile ago when I wanted to add React to a Cookiecutter Django project.

I've been using it for a few months, so should have submitted a PR awhile ago. I thought someone more experienced would do it at some point. I was hoping for a more standardized approach to using React and Webpack with Django would emerge through this project.

Let me know if you do end up deciding that you want a PR on this. I would be happy to help maintain future releases, bugs, and questions (though I understand at my experience level, that may not be worth enough). If Gulp is the winner, I'll drop it now :)


Resolving patch:
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -16,6 +16,7 @@
 import os
 import random
 import shutil
+from cookiecutter.main import cookiecutter
 
 # Get the root project directory
 PROJECT_DIRECTORY = os.path.realpath(os.path.curdir)
@@ -161,6 +162,30 @@ def remove_packageJSON_file():
             PROJECT_DIRECTORY, filename
         ))
 
+
+def add_webpack():
+    """
+    Adds webpack configuration using cookiecutter to install hzdg/cookiecutter-webpack
+    """
+    cookiecutter(
+        'git@github.com:hzdg/cookiecutter-webpack.git',
+        replay=False, overwrite_if_exists=True, output_dir='../',
+        checkout='pydanny-django', no_input=True, extra_context={
+            'project_name': '{{ cookiecutter.project_name }}',
+            'repo_name': '{{ cookiecutter.project_slug }}',
+            'repo_owner': '',
+            'project_dir': '{{ cookiecutter.project_slug }}',
+            'static_root': '{{ cookiecutter.project_slug }}/static/{{ cookiecutter.project_slug }}',
+            'production_output_path': '{{ cookiecutter.project_slug }}/static/{{ cookiecutter.project_slug }}/dist/',
+            'author_name': '{{ cookiecutter.author_name }}',
+            'description': '{{ cookiecutter.description }}',
+            'version': '{{ cookiecutter.version }}',
+            'existing_project': 'y',
+            'css_extension': 'sass',
+            'use_ejs': 'n',
+            'open_source_license': '{{ cookiecutter.open_source_license }}'
+        })
+
 def remove_certbot_files():
     """
     Removes files needed for certbot if it isn't going to be used
@@ -212,6 +237,11 @@ def remove_certbot_files():
     remove_grunt_files()
 elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt':
     remove_gulp_files()
+elif '{{ cookiecutter.js_task_runner }}'.lower() == 'webpack':
+    remove_gulp_files()
+    remove_grunt_files()
+    remove_packageJSON_file()
+    add_webpack()
 else:
     remove_gulp_files()
     remove_grunt_files()
diff --git a/{{cookiecutter.project_slug}}/config/settings/common.py b/{{cookiecutter.project_slug}}/config/settings/common.py
--- a/{{cookiecutter.project_slug}}/config/settings/common.py
+++ b/{{cookiecutter.project_slug}}/config/settings/common.py
@@ -243,5 +243,18 @@
 
 # Location of root django.contrib.admin URL, use {% raw %}{% url 'admin:index' %}{% endraw %}
 ADMIN_URL = r'^admin/'
+{% if cookiecutter.js_task_runner == 'Webpack' %}
+# WEBPACK
+# ------------------------------------------------------------------------------
+INSTALLED_APPS += ('webpack_loader',)
+# Webpack Local Stats file
+STATS_FILE = ROOT_DIR('webpack-stats.json')
+# Webpack config
+WEBPACK_LOADER = {
+    'DEFAULT': {
+        'STATS_FILE': STATS_FILE
+    }
+}
+{% endif %}
 
 # Your common stuff: Below this line define 3rd party library settings
diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py
--- a/{{cookiecutter.project_slug}}/config/settings/production.py
+++ b/{{cookiecutter.project_slug}}/config/settings/production.py
@@ -303,5 +303,19 @@
 {% endif %}
 # Custom Admin URL, use {% raw %}{% url 'admin:index' %}{% endraw %}
 ADMIN_URL = env('DJANGO_ADMIN_URL')
+{% if cookiecutter.js_task_runner == 'Webpack' %}
+
+# WEBPACK
+# ------------------------------------------------------------------------------
+# Webpack Production Stats file
+STATS_FILE = ROOT_DIR('webpack-stats-production.json')
+# Webpack config
+WEBPACK_LOADER = {
+    'DEFAULT': {
+        'BUNDLE_DIR_NAME': '{{ cookiecutter.project_slug }}/static/{{ cookiecutter.project_slug }}/dist/',
+        'STATS_FILE': STATS_FILE
+    }
+}
+{% endif %}
 
 # Your production stuff: Below this line define 3rd party library settings


Test patch: