django npm and node packages architecture
Question:
On the project I am joining this is the architecture for the node_packages
:
|- Django project
|-- app1
|-- app2
|-- node_modules
|--- foundation-sites
|--- grunt
|-- static
|--- css
|--- images
|--- js
|--urls.py
|--settings.py
|--package.json
I personally think node_packages
should be in the static under the js
folder as well as the package.json
like so:
|- Django project
|-- app1
|-- app2
|-- static
|--- css
|--- images
|--- js
|---- node_modules
|----- foundation-sites
|----- grunt
|---- packages.json
|--urls.py
|--settings.py
is there a difference? which is best practice? why?
Answers:
I understand your thinking of wanting to keep all the javascript related files in one place, but here are a couple of reasons you might want to keep the node_modules
folder and the package.json
file out of a Django app’s static
directory.
- You’ll likely end up statically serving files that aren’t meant to be. If the
node_modules
folder exists in your production environment, running collectstatic
will have to check that it’s in sync every time, which can be slow due to nodes nested dependency structure. And assuming you have a build step to bundle and transpile your JS, if those source files are within static
, they too will be served as static files, for no reason.
- You might want to use node for more than just your JavaScript build process. I see you’re using Grunt, and you may want to use it to for more than your JavaScript needs, like minifying your
css
, or running a proxy server around your Django dev server that auto-reloads your browser when files change or the Django server restarts. With this in mind, it might make more sense to think of Node.js as a tool in your build process that could touch any part of your project, the bundling/transpiling of JavaScript being only one part of that.
In general the node_modules
should be outside of the Django application. The typical format I use for a Django application is the following:
- AppName
---- appname (This is the Django Project)
---- appname-env (Python virtualenv)
---- bower_components
---- bower.json
---- gulpfile.js
---- node_modules
---- package.json
---- requirements.txt
Then I use gulp to copy the components from either node modules or bower components into my app static/lib
directory.
-
Put node_modules
and package.json
at the top level of your project:
- easily accessible, you install modules and run commands at the top level of your project
- dependencies exposed at the top level, commonly alongside pip requirements
- external libraries/modules separated from your code
- Add
node_modules
to .gitignore
-
Serve only generated files. Keep your source code outside STATICFILES_DIRS
-
(Optional) If you want to serve some npm modules without vendoring (instead of bower) use a tool like django-npm to specify what will be exposed
Example projects:
On the project I am joining this is the architecture for the node_packages
:
|- Django project
|-- app1
|-- app2
|-- node_modules
|--- foundation-sites
|--- grunt
|-- static
|--- css
|--- images
|--- js
|--urls.py
|--settings.py
|--package.json
I personally think node_packages
should be in the static under the js
folder as well as the package.json
like so:
|- Django project
|-- app1
|-- app2
|-- static
|--- css
|--- images
|--- js
|---- node_modules
|----- foundation-sites
|----- grunt
|---- packages.json
|--urls.py
|--settings.py
is there a difference? which is best practice? why?
I understand your thinking of wanting to keep all the javascript related files in one place, but here are a couple of reasons you might want to keep the node_modules
folder and the package.json
file out of a Django app’s static
directory.
- You’ll likely end up statically serving files that aren’t meant to be. If the
node_modules
folder exists in your production environment, runningcollectstatic
will have to check that it’s in sync every time, which can be slow due to nodes nested dependency structure. And assuming you have a build step to bundle and transpile your JS, if those source files are withinstatic
, they too will be served as static files, for no reason. - You might want to use node for more than just your JavaScript build process. I see you’re using Grunt, and you may want to use it to for more than your JavaScript needs, like minifying your
css
, or running a proxy server around your Django dev server that auto-reloads your browser when files change or the Django server restarts. With this in mind, it might make more sense to think of Node.js as a tool in your build process that could touch any part of your project, the bundling/transpiling of JavaScript being only one part of that.
In general the node_modules
should be outside of the Django application. The typical format I use for a Django application is the following:
- AppName
---- appname (This is the Django Project)
---- appname-env (Python virtualenv)
---- bower_components
---- bower.json
---- gulpfile.js
---- node_modules
---- package.json
---- requirements.txt
Then I use gulp to copy the components from either node modules or bower components into my app static/lib
directory.
-
Put
node_modules
andpackage.json
at the top level of your project:- easily accessible, you install modules and run commands at the top level of your project
- dependencies exposed at the top level, commonly alongside pip requirements
- external libraries/modules separated from your code
- Add
node_modules
to.gitignore
-
Serve only generated files. Keep your source code outside
STATICFILES_DIRS
-
(Optional) If you want to serve some npm modules without vendoring (instead of bower) use a tool like django-npm to specify what will be exposed
Example projects: