mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-07-16 11:02:22 +03:00
Node.JS + docker-compose = ♥ (#1128)
* Introduce static asset build infrastructure * Enhance gulpfile.js * Introduce node service * BrowserSync debug-only support * Remove newline before BrowserSync debug-only support section * FIx node Dockerfile package.json COPY * Try fiixing node Dockerfile package.json COPY ones again * Switch to `node:7-slim` * Try switching to node:6 To account for possible node:7 docker-compose incompatibiltiy * Revert "Try switching to node:6" This reverts commit62cc02df1a
. * Try switcging workdir to /app * Try utilizing relative package.json path * Resetting to the last version working locally with docker-compose 1.11.x * Build upon the latest node:7.9-slim * Stop dockerignoring package.json * Fix typo * Try a different package.json path * Revert "Try a different package.json path" This reverts commitf29f8500b8
. * Revert "Fix typo" This reverts commit02033729b5
. * Revert "Stop dockerignoring package.json" This reverts commit63c5491546
. * Upgrade docker-engine and docker-compose used by Travis CI * Fix .travis.yml comments * Inline docker-engine and docker-compose versions * DEBUG: pwd * Revert "DEBUG: pwd " This reverts commit6c2ed4321a
. * Try copying package.json to the same dir as node Dockerfile's * Revert "Try copying package.json to the same dir as node Dockerfile's" This reverts commit24340a0783
. * Try out node:7.9 * Revert "Try out node:7.9" This reverts commit32286d33c2
. * Revert "Upgrade docker-engine and docker-compose used by Travis CI" * Get rid of npm-check-updates Reason: Reserved for the upcoming PR * Get rid of npm-check Reason: Reserved for the upcoming PR * Get rid of 'standard' npm package Reason: Reserved for the upcoming PR * Clean up package.json * Preserve package.json uncoditionally Since we now have *unconditional* node.js integration, `package.json` must be out there whenever `node` service gets built * Upgrade node service image to 7.10 * Document Node.js-Docker integration * Fix gulpfile.js images region name * Get rid of Gulp migrate task * Document Gulp-Docker integration * Introduce static asset build infrastructure * Enhance gulpfile.js * Introduce node service * BrowserSync debug-only support * Remove newline before BrowserSync debug-only support section * FIx node Dockerfile package.json COPY * Try fiixing node Dockerfile package.json COPY ones again * Switch to `node:7-slim` * Try switching to node:6 To account for possible node:7 docker-compose incompatibiltiy * Revert "Try switching to node:6" This reverts commit62cc02df1a
. * Try switcging workdir to /app * Try utilizing relative package.json path * Resetting to the last version working locally with docker-compose 1.11.x * Build upon the latest node:7.9-slim * Stop dockerignoring package.json * Revert "Stop dockerignoring package.json" This reverts commit63c5491546
. * Fix typo * Revert "Fix typo" This reverts commit02033729b5
. * Try a different package.json path * Revert "Try a different package.json path" This reverts commitf29f8500b8
. * Upgrade docker-engine and docker-compose used by Travis CI * Fix .travis.yml comments * Inline docker-engine and docker-compose versions * DEBUG: pwd * Revert "DEBUG: pwd " This reverts commit6c2ed4321a
. * Try copying package.json to the same dir as node Dockerfile's * Revert "Try copying package.json to the same dir as node Dockerfile's" This reverts commit24340a0783
. * Try out node:7.9 * Revert "Try out node:7.9" This reverts commit32286d33c2
. * Revert "Upgrade docker-engine and docker-compose used by Travis CI" * Get rid of npm-check-updates Reason: Reserved for the upcoming PR * Get rid of npm-check Reason: Reserved for the upcoming PR * Get rid of 'standard' npm package Reason: Reserved for the upcoming PR * Clean up package.json * Preserve package.json uncoditionally Since we now have *unconditional* node.js integration, `package.json` must be out there whenever `node` service gets built * Upgrade node service image to 7.10 * Document Node.js-Docker integration * Fix gulpfile.js images region name * Get rid of Gulp migrate task * Document Gulp-Docker integration * Remove Gulp-Docker integraton not supported initialization message
This commit is contained in:
parent
ec62188fae
commit
4b06fe3958
|
@ -6,6 +6,8 @@ Getting Up and Running Locally With Docker
|
||||||
The steps below will get you up and running with a local development environment.
|
The steps below will get you up and running with a local development environment.
|
||||||
All of these commands assume you are in the root of your generated project.
|
All of these commands assume you are in the root of your generated project.
|
||||||
|
|
||||||
|
.. _devlocdocker-prereq:
|
||||||
|
|
||||||
Prerequisites
|
Prerequisites
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -30,6 +32,9 @@ Currently PostgreSQL (``psycopg2`` python package) is not installed inside Docke
|
||||||
|
|
||||||
Doing this will prevent the project from being installed in an Windows-only environment (thus without usage of Docker). If you want to use this project without Docker, make sure to remove ``psycopg2`` from the requirements again.
|
Doing this will prevent the project from being installed in an Windows-only environment (thus without usage of Docker). If you want to use this project without Docker, make sure to remove ``psycopg2`` from the requirements again.
|
||||||
|
|
||||||
|
|
||||||
|
.. _devlocdocker-build-the-stack:
|
||||||
|
|
||||||
Build the Stack
|
Build the Stack
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -40,6 +45,9 @@ on your development system::
|
||||||
|
|
||||||
If you want to build the production environment you don't have to pass an argument -f, it will automatically use docker-compose.yml.
|
If you want to build the production environment you don't have to pass an argument -f, it will automatically use docker-compose.yml.
|
||||||
|
|
||||||
|
|
||||||
|
.. _devlocdocker-boot-the-system:
|
||||||
|
|
||||||
Boot the System
|
Boot the System
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
76
docs/gulp-with-docker.rst
Normal file
76
docs/gulp-with-docker.rst
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
Gulp with Docker
|
||||||
|
================
|
||||||
|
|
||||||
|
.. index:: gulp, gulpjs, gulpfile, gulpfilejs, docker, docker-compose
|
||||||
|
|
||||||
|
`Gulp`_ support is provided out-of-the-box, ready for use as-is, or with any kind of customizations suiting the specific needs of the project.
|
||||||
|
|
||||||
|
.. _`Gulp`: http://gulpjs.com/
|
||||||
|
|
||||||
|
*All paths are relative to the generated project's root.*
|
||||||
|
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- These :ref:`nodewithdocker-prereq` are satisfied.
|
||||||
|
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
:ref:`nodewithdocker-overview` Node.js integration details first to get the whole picture.
|
||||||
|
|
||||||
|
Essential aspects of Gulp integration are
|
||||||
|
|
||||||
|
- :code:`./gulpfile.js` with Gulp tasks defined;
|
||||||
|
- :code:`./{{ cookiecutter.project_slug }}/static/build/` (build directory) with static assets built via Gulp.
|
||||||
|
|
||||||
|
Let us take a closer look at :code:`./gulpfile.js`:
|
||||||
|
|
||||||
|
- paths to static assets are provided by :code:`pathsConfig()`;
|
||||||
|
- for clarity, related tasks are grouped by :code:`region`:
|
||||||
|
- :code:`images`:
|
||||||
|
- :code:`images`: run image-related tasks in parallel, namely:
|
||||||
|
- :code:`favicons-images`: process favicon images only;
|
||||||
|
- :code:`nonfavicons-images`: process all images except for favicons.
|
||||||
|
- :code:`scripts`:
|
||||||
|
- :code:`scripts`: run script-related tasks in sequence, namely:
|
||||||
|
- :code:`js-scripts`: process js scripts.
|
||||||
|
- :code:`styles`:
|
||||||
|
- :code:`styles`: run script-related tasks in sequence, namely:
|
||||||
|
- :code:`sass-styles`: process SCSS styles;
|
||||||
|
- :code:`css-styles`: process CSS styles.
|
||||||
|
- :code:`build`:
|
||||||
|
- :code:`build`: run :code:`images`, :code:`scripts`, and :code:`styles` in parallel;
|
||||||
|
- :code:`clean-build`: clean up build directory:
|
||||||
|
- the :code:`default` task runs the following ones in sequence:
|
||||||
|
- :code:`build`;
|
||||||
|
- :code:`init-browserSync`: initialize `BrowserSync`_;
|
||||||
|
- :code:`watch`: watch static asset files/directories changes, running BrowserSync on any changes.
|
||||||
|
|
||||||
|
.. _`BrowserSync`: https://www.browsersync.io/
|
||||||
|
|
||||||
|
|
||||||
|
Workflow
|
||||||
|
--------
|
||||||
|
|
||||||
|
#. [*skip if done*] :ref:`devlocdocker-build-the-stack`;
|
||||||
|
#. :ref:`devlocdocker-boot-the-system`.
|
||||||
|
|
||||||
|
By default, :code:`gulp` command gets executed immediately after :code:`node`
|
||||||
|
container startup (see :code:`./dev.yml` for details) which in turn invokes
|
||||||
|
the :code:`default` task, so generally one would not need to run any
|
||||||
|
of the aforementioned tasks manually. However, should the need arise,
|
||||||
|
oftentimes just a few of the tasks listed above will be used to, for instance,
|
||||||
|
straightforwardly :code:`build` all assets
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ docker-compose -f dev.yml exec node gulp build
|
||||||
|
|
||||||
|
or build :code:`scripts` selectively
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ docker-compose -f dev.yml exec node gulp scripts
|
|
@ -17,6 +17,8 @@ Contents:
|
||||||
developing-locally-docker
|
developing-locally-docker
|
||||||
settings
|
settings
|
||||||
linters
|
linters
|
||||||
|
nodejs-with-docker
|
||||||
|
gulp-with-docker
|
||||||
live-reloading-and-sass-compilation
|
live-reloading-and-sass-compilation
|
||||||
deployment-on-pythonanywhere
|
deployment-on-pythonanywhere
|
||||||
deployment-on-heroku
|
deployment-on-heroku
|
||||||
|
|
45
docs/nodejs-with-docker.rst
Normal file
45
docs/nodejs-with-docker.rst
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
Node.js with Docker
|
||||||
|
===================
|
||||||
|
|
||||||
|
.. index:: node, nodejs, docker, docker-compose
|
||||||
|
|
||||||
|
`Node.js`_ support is provided out-of-the-box, ready for use as-is, or with any kind of customizations suiting the specific needs of the project.
|
||||||
|
|
||||||
|
.. _`Node.js`: https://nodejs.org/en/
|
||||||
|
|
||||||
|
*All paths are relative to the generated project's root.*
|
||||||
|
|
||||||
|
|
||||||
|
.. _nodewithdocker-prereq:
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- The project was generated with :code:`use_docker` set to :code:`y`.
|
||||||
|
- These :ref:`devlocdocker-prereq` are met as well.
|
||||||
|
|
||||||
|
|
||||||
|
.. _nodewithdocker-overview:
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
Essential aspects of Node.js integration are
|
||||||
|
|
||||||
|
- node docker-compose service (:code:`node`) definition in :code:`./dev.yml`;
|
||||||
|
- :code:`./compose/node/Dockerfile-dev` defining the :code:`node` image;
|
||||||
|
- :code:`./node_modules/` 'overlayed' with :code:`/app/node_modules/`, its counterpart from the running instance of :code:`node`.
|
||||||
|
|
||||||
|
|
||||||
|
Workflow
|
||||||
|
--------
|
||||||
|
|
||||||
|
#. [*skip if done*] :ref:`devlocdocker-build-the-stack`:
|
||||||
|
- when building :code:`node` image from scratch, dependencies from :code:`package.json` are installed.
|
||||||
|
#. :ref:`devlocdocker-boot-the-system`.
|
||||||
|
|
||||||
|
To log the running :code:`node` container's activity,
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ docker-compose -f dev.yml logs node
|
|
@ -256,7 +256,6 @@ elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt':
|
||||||
else:
|
else:
|
||||||
remove_gulp_files()
|
remove_gulp_files()
|
||||||
remove_grunt_files()
|
remove_grunt_files()
|
||||||
remove_packageJSON_file()
|
|
||||||
|
|
||||||
# 7. Removes all certbot/letsencrypt files if it isn't going to be used
|
# 7. Removes all certbot/letsencrypt files if it isn't going to be used
|
||||||
if '{{ cookiecutter.use_lets_encrypt }}'.lower() != 'y':
|
if '{{ cookiecutter.use_lets_encrypt }}'.lower() != 'y':
|
||||||
|
@ -264,11 +263,10 @@ if '{{ cookiecutter.use_lets_encrypt }}'.lower() != 'y':
|
||||||
|
|
||||||
# 8. Display a warning if use_docker and use_grunt are selected. Grunt isn't
|
# 8. Display a warning if use_docker and use_grunt are selected. Grunt isn't
|
||||||
# supported by our docker config atm.
|
# supported by our docker config atm.
|
||||||
if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt'] and '{{ cookiecutter.use_docker }}'.lower() == 'y':
|
||||||
print(
|
print(
|
||||||
"You selected to use docker and a JS task runner. This is NOT supported out of the box for now. You "
|
"You selected to use Docker and Grunt task runner. This is NOT supported out of the box for now. You "
|
||||||
"can continue to use the project like you normally would, but you will need to add a "
|
"can continue to use the project like you normally would, but you will need to setup Grunt manually."
|
||||||
"js task runner service to your docker configuration manually."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 9. Removes the certbot/letsencrypt files and display a warning if use_lets_encrypt is selected and use_docker isn't.
|
# 9. Removes the certbot/letsencrypt files and display a warning if use_lets_encrypt is selected and use_docker isn't.
|
||||||
|
|
1
{{cookiecutter.project_slug}}/.gitignore
vendored
1
{{cookiecutter.project_slug}}/.gitignore
vendored
|
@ -79,3 +79,4 @@ staticfiles/
|
||||||
|
|
||||||
.cache/
|
.cache/
|
||||||
|
|
||||||
|
{{ cookiecutter.project_slug }}/static/build/
|
||||||
|
|
11
{{cookiecutter.project_slug}}/compose/node/Dockerfile-dev
Normal file
11
{{cookiecutter.project_slug}}/compose/node/Dockerfile-dev
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
FROM node:7.10-slim
|
||||||
|
|
||||||
|
RUN mkdir -p /app
|
||||||
|
|
||||||
|
COPY ./package.json /app
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN npm install && npm cache clean
|
||||||
|
|
||||||
|
ENV PATH ./node_modules/.bin/:$PATH
|
|
@ -184,9 +184,10 @@ STATIC_ROOT = str(ROOT_DIR('staticfiles'))
|
||||||
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
|
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
_STATIC_BUILD_ROOT_DIR_NAME = 'build'
|
||||||
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
|
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
str(APPS_DIR.path('static')),
|
(_STATIC_BUILD_ROOT_DIR_NAME, str(APPS_DIR.path('static').path(_STATIC_BUILD_ROOT_DIR_NAME))),
|
||||||
]
|
]
|
||||||
|
|
||||||
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
|
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
|
||||||
|
|
|
@ -21,6 +21,7 @@ services:
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres{% if cookiecutter.use_mailhog == 'y' %}
|
- postgres{% if cookiecutter.use_mailhog == 'y' %}
|
||||||
- mailhog{% endif %}
|
- mailhog{% endif %}
|
||||||
|
- node
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER={{cookiecutter.project_slug}}
|
- POSTGRES_USER={{cookiecutter.project_slug}}
|
||||||
- USE_DOCKER=yes
|
- USE_DOCKER=yes
|
||||||
|
@ -48,3 +49,19 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- "8025:8025"
|
- "8025:8025"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
node:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./compose/node/Dockerfile-dev
|
||||||
|
volumes:
|
||||||
|
- .:/app
|
||||||
|
# http://jdlm.info/articles/2016/03/06/lessons-building-node-app-docker.html
|
||||||
|
- /app/node_modules
|
||||||
|
command: "gulp"
|
||||||
|
ports:
|
||||||
|
# BrowserSync port.
|
||||||
|
- "3000:3000"
|
||||||
|
# BrowserSync UI port.
|
||||||
|
- "3001:3001"
|
||||||
|
|
||||||
|
|
|
@ -1,105 +1,139 @@
|
||||||
|
const gulp = require('gulp')
|
||||||
|
const pump = require('pump')
|
||||||
|
const sass = require('gulp-sass')
|
||||||
|
const pjson = require('./package.json')
|
||||||
|
const autoprefixer = require('gulp-autoprefixer')
|
||||||
|
const cleanCSS = require('gulp-clean-css')
|
||||||
|
const rename = require('gulp-rename')
|
||||||
|
const pixrem = require('gulp-pixrem')
|
||||||
|
const concat = require('gulp-concat')
|
||||||
|
const uglify = require('gulp-uglify')
|
||||||
|
const imagemin = require('gulp-imagemin')
|
||||||
|
const clean = require('gulp-clean')
|
||||||
|
const spawn = require('child_process').spawn
|
||||||
|
const runSequence = require('run-sequence')
|
||||||
|
const browserSync = require('browser-sync').create()
|
||||||
|
const pathsConfig = function (appName) {
|
||||||
|
this.paths = {}
|
||||||
|
|
||||||
////////////////////////////////
|
this.paths['app'] = './' + (appName || pjson.name)
|
||||||
//Setup//
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
// Plugins
|
this.paths['static'] = this.paths['app'] + '/static'
|
||||||
var gulp = require('gulp'),
|
|
||||||
pjson = require('./package.json'),
|
|
||||||
gutil = require('gulp-util'),
|
|
||||||
sass = require('gulp-sass'),
|
|
||||||
autoprefixer = require('gulp-autoprefixer'),
|
|
||||||
cssnano = require('gulp-cssnano'),
|
|
||||||
rename = require('gulp-rename'),
|
|
||||||
del = require('del'),
|
|
||||||
plumber = require('gulp-plumber'),
|
|
||||||
pixrem = require('gulp-pixrem'),
|
|
||||||
uglify = require('gulp-uglify'),
|
|
||||||
imagemin = require('gulp-imagemin'),
|
|
||||||
spawn = require('child_process').spawn,
|
|
||||||
runSequence = require('run-sequence'),
|
|
||||||
browserSync = require('browser-sync').create(),
|
|
||||||
reload = browserSync.reload;
|
|
||||||
|
|
||||||
|
this.paths['build'] = this.paths['static'] + '/build'
|
||||||
|
|
||||||
// Relative paths function
|
this.paths['buildImages'] = this.paths['build'] + '/images'
|
||||||
var pathsConfig = function (appName) {
|
this.paths['images'] = this.paths['static'] + '/images'
|
||||||
this.app = "./" + (appName || pjson.name);
|
this.paths['images_files'] = this.paths['images'] + '/*'
|
||||||
|
this.paths['buildImagesFavicons'] = this.paths['buildImages'] + '/favicons'
|
||||||
|
this.paths['imagesFavicons'] = this.paths['images'] + '/favicons'
|
||||||
|
this.paths['imagesFavicons_files'] = this.paths['imagesFavicons'] + '/*'
|
||||||
|
|
||||||
return {
|
this.paths['build_scriptsFileName'] = 'scripts.js'
|
||||||
app: this.app,
|
this.paths['scripts'] = this.paths['static'] + '/scripts'
|
||||||
templates: this.app + '/templates',
|
this.paths['scripts_files'] = this.paths['scripts'] + '/**/*'
|
||||||
css: this.app + '/static/css',
|
this.paths['scriptsJs'] = this.paths['scripts'] + '/js'
|
||||||
sass: this.app + '/static/sass',
|
this.paths['scriptsJs_files'] = this.paths['scriptsJs'] + '/*.js'
|
||||||
fonts: this.app + '/static/fonts',
|
|
||||||
images: this.app + '/static/images',
|
this.paths['build_stylesFileName'] = 'styles.css'
|
||||||
js: this.app + '/static/js',
|
this.paths['styles'] = this.paths['static'] + '/styles'
|
||||||
|
this.paths['styles_files'] = this.paths['styles'] + '/**/*'
|
||||||
|
this.paths['stylesSass'] = this.paths['styles'] + '/sass'
|
||||||
|
this.paths['stylesSass_files'] = this.paths['stylesSass'] + '/*.scss'
|
||||||
|
this.paths['stylesCss'] = this.paths['styles'] + '/css'
|
||||||
|
this.paths['stylesCss_files'] = this.paths['stylesCss'] + '/*.css'
|
||||||
|
|
||||||
|
this.paths['templates'] = this.paths['app'] + '/templates'
|
||||||
|
this.paths['templates_files'] = this.paths['templates'] + '/**/*.html'
|
||||||
|
|
||||||
|
return this.paths
|
||||||
}
|
}
|
||||||
};
|
const paths = pathsConfig()
|
||||||
|
|
||||||
var paths = pathsConfig();
|
// region images
|
||||||
|
gulp.task('favicons-images', function (cb) {
|
||||||
|
pump([gulp.src(paths.imagesFavicons_files),
|
||||||
|
gulp.dest(paths.buildImagesFavicons)],
|
||||||
|
cb)
|
||||||
|
})
|
||||||
|
|
||||||
////////////////////////////////
|
gulp.task('nonfavicons-images', function (cb) {
|
||||||
//Tasks//
|
pump([gulp.src(paths.images_files),
|
||||||
////////////////////////////////
|
imagemin(),
|
||||||
|
gulp.dest(paths.buildImages)],
|
||||||
|
cb)
|
||||||
|
})
|
||||||
|
|
||||||
// Styles autoprefixing and minification
|
gulp.task('images', function () {
|
||||||
gulp.task('styles', function() {
|
runSequence(['favicons-images', 'nonfavicons-images'])
|
||||||
return gulp.src(paths.sass + '/project.scss')
|
})
|
||||||
.pipe(sass().on('error', sass.logError))
|
// endregion
|
||||||
.pipe(plumber()) // Checks for errors
|
|
||||||
.pipe(autoprefixer({browsers: ['last 2 versions']})) // Adds vendor prefixes
|
// region scripts
|
||||||
.pipe(pixrem()) // add fallbacks for rem units
|
gulp.task('js-scripts', function (cb) {
|
||||||
.pipe(gulp.dest(paths.css))
|
pump([gulp.src(paths.scriptsJs_files),
|
||||||
.pipe(rename({ suffix: '.min' }))
|
concat(paths.build_scriptsFileName),
|
||||||
.pipe(cssnano()) // Minifies the result
|
uglify(),
|
||||||
.pipe(gulp.dest(paths.css));
|
rename({suffix: '.min'}),
|
||||||
});
|
gulp.dest(paths.build)],
|
||||||
|
cb)
|
||||||
|
})
|
||||||
|
|
||||||
// Javascript minification
|
|
||||||
gulp.task('scripts', function () {
|
gulp.task('scripts', function () {
|
||||||
return gulp.src(paths.js + '/project.js')
|
runSequence('js-scripts')
|
||||||
.pipe(plumber()) // Checks for errors
|
})
|
||||||
.pipe(uglify()) // Minifies the js
|
// endregion
|
||||||
.pipe(rename({ suffix: '.min' }))
|
|
||||||
.pipe(gulp.dest(paths.js));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Image compression
|
// region styles
|
||||||
gulp.task('imgCompression', function(){
|
gulp.task('sass-styles', function (cb) {
|
||||||
return gulp.src(paths.images + '/*')
|
pump([gulp.src(paths.stylesSass_files),
|
||||||
.pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images
|
sass(),
|
||||||
.pipe(gulp.dest(paths.images))
|
gulp.dest(paths.stylesCss)],
|
||||||
});
|
cb
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// Run django server
|
gulp.task('css-styles', function (cb) {
|
||||||
gulp.task('runServer', function(cb) {
|
pump([gulp.src(paths.stylesCss_files),
|
||||||
var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'});
|
concat(paths.build_stylesFileName),
|
||||||
cmd.on('close', function(code) {
|
autoprefixer({browsers: ['last 2 versions']}),
|
||||||
console.log('runServer exited with code ' + code);
|
pixrem(),
|
||||||
cb(code);
|
cleanCSS({rebaseTo: '../../'}),
|
||||||
});
|
rename({suffix: '.min'}),
|
||||||
});
|
gulp.dest(paths.build)],
|
||||||
|
cb)
|
||||||
|
})
|
||||||
|
|
||||||
// Browser sync server for live reload
|
gulp.task('styles', function () {
|
||||||
gulp.task('browserSync', function() {
|
runSequence('sass-styles', 'css-styles')
|
||||||
browserSync.init(
|
})
|
||||||
[paths.css + "/*.css", paths.js + "*.js", paths.templates + '*.html'], {
|
// endregion
|
||||||
proxy: "localhost:8000"
|
|
||||||
});
|
// region build
|
||||||
});
|
gulp.task('build', function () {
|
||||||
|
runSequence(['images', 'scripts', 'styles'])
|
||||||
|
})
|
||||||
|
|
||||||
|
gulp.task('clean-build', function (cb) {
|
||||||
|
pump([gulp.src(paths.build),
|
||||||
|
clean()],
|
||||||
|
cb)
|
||||||
|
})
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
gulp.task('init-browserSync', function () {
|
||||||
|
browserSync.init({
|
||||||
|
host: 'localhost:8000'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// Watch
|
|
||||||
gulp.task('watch', function () {
|
gulp.task('watch', function () {
|
||||||
|
gulp.watch(paths.images_files, ['images']).on('change', browserSync.reload)
|
||||||
|
gulp.watch(paths.scripts_files, ['scripts']).on('change', browserSync.reload)
|
||||||
|
gulp.watch(paths.styles_files, ['styles']).on('change', browserSync.reload)
|
||||||
|
gulp.watch(paths.templates_files).on('change', browserSync.reload)
|
||||||
|
})
|
||||||
|
|
||||||
gulp.watch(paths.sass + '/*.scss', ['styles']);
|
|
||||||
gulp.watch(paths.js + '/*.js', ['scripts']).on("change", reload);
|
|
||||||
gulp.watch(paths.images + '/*', ['imgCompression']);
|
|
||||||
gulp.watch(paths.templates + '/**/*.html').on("change", reload);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Default task
|
|
||||||
gulp.task('default', function () {
|
gulp.task('default', function () {
|
||||||
runSequence(['styles', 'scripts', 'imgCompression'], 'runServer', 'browserSync', 'watch');
|
runSequence('build', 'init-browserSync', 'watch')
|
||||||
});
|
})
|
||||||
|
|
|
@ -16,18 +16,18 @@
|
||||||
"pixrem": "~1.3.1",
|
"pixrem": "~1.3.1",
|
||||||
"time-grunt": "~1.2.1"
|
"time-grunt": "~1.2.1"
|
||||||
{% elif cookiecutter.js_task_runner == 'Gulp' %}
|
{% elif cookiecutter.js_task_runner == 'Gulp' %}
|
||||||
"browser-sync": "^2.14.0",
|
"browser-sync": "^2.18.8",
|
||||||
"del": "^2.2.2",
|
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-autoprefixer": "^3.1.1",
|
"gulp-autoprefixer": "^3.1.1",
|
||||||
"gulp-cssnano": "^2.1.2",
|
"gulp-clean": "^0.3.2",
|
||||||
"gulp-imagemin": "^3.0.3",
|
"gulp-clean-css": "^3.0.4",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"gulp-imagemin": "^3.1.1",
|
||||||
"gulp-pixrem": "^1.0.0",
|
"gulp-pixrem": "^1.0.0",
|
||||||
"gulp-plumber": "^1.1.0",
|
|
||||||
"gulp-rename": "^1.2.2",
|
"gulp-rename": "^1.2.2",
|
||||||
"gulp-sass": "^2.3.2",
|
"gulp-sass": "^3.1.0",
|
||||||
"gulp-uglify": "^2.0.0",
|
"gulp-uglify": "^2.1.2",
|
||||||
"gulp-util": "^3.0.7",
|
"pump": "^1.0.2",
|
||||||
"run-sequence": "^1.2.2"
|
"run-sequence": "^1.2.2"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/* These styles are generated from project.scss. */
|
|
||||||
|
|
||||||
.alert-debug {
|
|
||||||
color: black;
|
|
||||||
background-color: white;
|
|
||||||
border-color: #d6e9c6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-error {
|
|
||||||
color: #b94a48;
|
|
||||||
background-color: #f2dede;
|
|
||||||
border-color: #eed3d7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is a fix for the bootstrap4 alpha release */
|
|
||||||
@media (max-width: 47.9em) {
|
|
||||||
.navbar-nav .nav-item {
|
|
||||||
float: none;
|
|
||||||
width: 100%;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-nav .nav-item + .nav-item {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav.navbar-nav.pull-xs-right {
|
|
||||||
float: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Display django-debug-toolbar.
|
|
||||||
See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
|
||||||
and https://github.com/pydanny/cookiecutter-django/issues/317
|
|
||||||
*/
|
|
||||||
[hidden][style="display: block;"] {
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/* Project specific Javascript goes here. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Formatting hack to get around crispy-forms unfortunate hardcoding
|
|
||||||
in helpers.FormHelper:
|
|
||||||
|
|
||||||
if template_pack == 'bootstrap4':
|
|
||||||
grid_colum_matcher = re.compile('\w*col-(xs|sm|md|lg|xl)-\d+\w*')
|
|
||||||
using_grid_layout = (grid_colum_matcher.match(self.label_class) or
|
|
||||||
grid_colum_matcher.match(self.field_class))
|
|
||||||
if using_grid_layout:
|
|
||||||
items['using_grid_layout'] = True
|
|
||||||
|
|
||||||
Issues with the above approach:
|
|
||||||
|
|
||||||
1. Fragile: Assumes Bootstrap 4's API doesn't change (it does)
|
|
||||||
2. Unforgiving: Doesn't allow for any variation in template design
|
|
||||||
3. Really Unforgiving: No way to override this behavior
|
|
||||||
4. Undocumented: No mention in the documentation, or it's too hard for me to find
|
|
||||||
*/
|
|
||||||
$('.form-group').removeClass('row');
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Project specific Javascript goes here. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Formatting hack to get around crispy-forms unfortunate hardcoding
|
||||||
|
in helpers.FormHelper:
|
||||||
|
|
||||||
|
if template_pack == 'bootstrap4':
|
||||||
|
grid_colum_matcher = re.compile('\w*col-(xs|sm|md|lg|xl)-\d+\w*')
|
||||||
|
using_grid_layout = (grid_colum_matcher.match(self.label_class) or
|
||||||
|
grid_colum_matcher.match(self.field_class))
|
||||||
|
if using_grid_layout:
|
||||||
|
items['using_grid_layout'] = True
|
||||||
|
|
||||||
|
Issues with the above approach:
|
||||||
|
|
||||||
|
1. Fragile: Assumes Bootstrap 4's API doesn't change (it does)
|
||||||
|
2. Unforgiving: Doesn't allow for any variation in template design
|
||||||
|
3. Really Unforgiving: No way to override this behavior
|
||||||
|
4. Undocumented: No mention in the documentation, or it's too hard for me to find
|
||||||
|
*/
|
||||||
|
$('.form-group').removeClass('row')
|
|
@ -0,0 +1,26 @@
|
||||||
|
.alert-debug {
|
||||||
|
background-color: #fff;
|
||||||
|
border-color: #d6e9c6;
|
||||||
|
color: #000; }
|
||||||
|
|
||||||
|
.alert-error {
|
||||||
|
background-color: #f2dede;
|
||||||
|
border-color: #eed3d7;
|
||||||
|
color: #b94a48; }
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
border-radius: 0px; }
|
||||||
|
|
||||||
|
@media (max-width: 47.9em) {
|
||||||
|
.navbar-nav .nav-item {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
width: 100%; }
|
||||||
|
.navbar-nav .nav-item + .nav-item {
|
||||||
|
margin-left: 0; }
|
||||||
|
.nav.navbar-nav.pull-xs-right {
|
||||||
|
float: none !important; } }
|
||||||
|
|
||||||
|
[hidden][style="display: block;"] {
|
||||||
|
display: block !important; }
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
// project specific CSS goes here
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//Variables//
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Alert colors
|
||||||
|
|
||||||
|
$white: #fff;
|
||||||
|
$mint-green: #d6e9c6;
|
||||||
|
$black: #000;
|
||||||
|
$pink: #f2dede;
|
||||||
|
$dark-pink: #eed3d7;
|
||||||
|
$red: #b94a48;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//Alerts//
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// bootstrap alert CSS, translated to the django-standard levels of
|
||||||
|
// debug, info, success, warning, error
|
||||||
|
|
||||||
|
.alert-debug {
|
||||||
|
background-color: $white;
|
||||||
|
border-color: $mint-green;
|
||||||
|
color: $black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-error {
|
||||||
|
background-color: $pink;
|
||||||
|
border-color: $dark-pink;
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//Navbar//
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// This is a fix for the bootstrap4 alpha release
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
border-radius: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 47.9em) {
|
||||||
|
.navbar-nav .nav-item {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav .nav-item + .nav-item {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav.navbar-nav.pull-xs-right {
|
||||||
|
float: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//Django Toolbar//
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Display django-debug-toolbar.
|
||||||
|
// See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742
|
||||||
|
// and https://github.com/pydanny/cookiecutter-django/issues/317
|
||||||
|
|
||||||
|
[hidden][style="display: block;"] {
|
||||||
|
display: block !important;
|
||||||
|
}
|
|
@ -20,7 +20,7 @@
|
||||||
<!-- Your stuff: Third-party CSS libraries go here -->
|
<!-- Your stuff: Third-party CSS libraries go here -->
|
||||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %}
|
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %}
|
||||||
<!-- This file stores project-specific CSS -->
|
<!-- This file stores project-specific CSS -->
|
||||||
<link href="{% static 'css/project.css' %}" rel="stylesheet">
|
<link href="{% static 'build/styles.min.css' %}" rel="stylesheet"/>
|
||||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -88,6 +88,13 @@
|
||||||
================================================== -->
|
================================================== -->
|
||||||
<!-- Placed at the end of the document so the pages load faster -->
|
<!-- Placed at the end of the document so the pages load faster -->
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
|
<!-- BrowserSync debug-only support -->
|
||||||
|
{% if debug %}
|
||||||
|
<script id="__bs_script__">//<![CDATA[
|
||||||
|
document.write('<script async src=\'http://HOST:3000/browser-sync/browser-sync-client.js?v=2.18.8\'><\/script>'.replace('HOST', location.hostname))
|
||||||
|
//]]></script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<!-- Required by Bootstrap v4 Alpha 4 -->
|
<!-- Required by Bootstrap v4 Alpha 4 -->
|
||||||
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
|
||||||
|
@ -97,7 +104,7 @@
|
||||||
|
|
||||||
<!-- place project specific Javascript in this file -->
|
<!-- place project specific Javascript in this file -->
|
||||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
|
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
|
||||||
<script src="{% static 'js/project.js' %}"></script>
|
<script src="{% static 'build/scripts.min.js' %}"></script>
|
||||||
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
|
||||||
|
|
||||||
{% endblock javascript %}
|
{% endblock javascript %}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user