├── .codeclimate.yml ├── .gitignore ├── .pyup.yml ├── CONTRIBUTING.md ├── README.md ├── deploy-docs.sh ├── docs ├── README.md ├── SUMMARY.md ├── backend.md ├── commands.md ├── e2e.md ├── linter.md ├── prerender.md ├── proxy.md ├── static.md ├── structure.md └── unit.md ├── meta.json ├── package.json └── template ├── .babelrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── Dockerfile ├── README.md ├── app ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── tests.py └── views.py ├── build ├── build.js ├── css-loaders.js ├── dev-client.js ├── dev-server.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js ├── config.js ├── confirm.txt ├── db.sqlite3 ├── deploy.sh ├── format_index_html.py ├── index.html ├── manage.py ├── package.json ├── requirements.txt ├── src ├── App.vue ├── assets │ ├── Screenshot.png │ ├── dj.png │ └── vue.png ├── components │ └── Hello.vue └── main.js ├── static └── .gitkeep ├── test ├── e2e │ ├── custom-assertions │ │ └── elementCount.js │ ├── nightwatch.conf.js │ ├── runner.js │ └── specs │ │ └── test.js └── unit │ ├── .eslintrc │ ├── index.js │ ├── karma.conf.js │ └── specs │ └── Hello.spec.js └── vuedj ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | eslint: 3 | enabled: true 4 | pep8: 5 | enabled: true 6 | 7 | ratings: 8 | paths: 9 | - "**.js" 10 | - "**.py" 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | docs/_book 4 | .vscode 5 | -------------------------------------------------------------------------------- /.pyup.yml: -------------------------------------------------------------------------------- 1 | # autogenerated pyup.io config file 2 | # see https://pyup.io/docs/configuration/ for all available options 3 | 4 | schedule: every day 5 | requirements: 6 | - template/requirements.txt 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you would like to contribute to this repository, please first fork the repo, update and create a Pull Request. 4 | 5 | To ensure you'll be working on the right feature in the right way, 6 | 7 | - Understand how we project manage by reading the [README](https://github.com/NdagiStanley/vue-django) 8 | 9 | ### Branch Naming 10 | 11 | The default branches provided by git flow are: 12 | * `master` 13 | * `dist` 14 | * `develop` 15 | 16 | Always work off of `develop` and NOT `master`. 17 | 18 | We use either `dist` or `master` to create the template from vue-cli. The versioning section in the README [here](https://github.com/NdagiStanley/vue-django/blob/master/README.md#version-notice) explains more. 19 | 20 | ## Pull Request Process 21 | 22 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build. Add relevant files/ folders to the .gitingore. 23 | 2. Update the README.md with details of changes to the interface/ process, this includes new environment variables, exposed ports, useful file locations and container parameters. 24 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 25 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 26 | 4. We may merge the Pull Request in once we have the sign-off of two other developers or [the repo owner](https://github.com/NdagiStanley). 27 | 28 | 29 | ## Ideas/ Requests/ Suggestions 30 | 31 | Add them as issues in the original CLI [repo](https://github.com/vuejs-templates/webpack/issues) and tag them as `ideas` or `suggestions`. 32 | 33 | We'll try to keep up with the original and we welcome contributions to help bring the awesomeness of VueJS into Django. :heart: 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-django-webpack-boilerplate 2 | 3 | 4 | > A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction integrated into a django application 5 | 6 | ## Vue CLI Version Notice 7 | 8 | If you are using `vue-cli@1.x`, it will be pulling the `master` branch of this template by default. If you are using `vue-cli@2.x`, it will be pulling the `dist` branch instead, which provides more configurable options thanks to new features in `vue-cli@2.x`. It is recommended to upgrade `vue-cli` as soon as you can. 9 | 10 | ## VueJS Templates Documentation 11 | 12 | Common topics are discussed in the [docs](http://vuejs-templates.github.io/webpack). Make sure to read it! 13 | 14 | # Vue Django 15 | [![Code Climate](https://codeclimate.com/github/NdagiStanley/vue-django/badges/gpa.svg)](https://codeclimate.com/github/NdagiStanley/vue-django) 16 | 17 | [![Updates](https://pyup.io/repos/github/NdagiStanley/vue-django/shield.svg)](https://pyup.io/repos/github/NdagiStanley/vue-django/) 18 | [![Python 3](https://pyup.io/repos/github/NdagiStanley/vue-django/python-3-shield.svg)](https://pyup.io/repos/github/NdagiStanley/vue-django/) 19 | 20 | [https://vuedjango.herokuapp.com/](https://vuedjango.herokuapp.com/) is a deployed instance of this boilerplate. 21 | 22 | ## Usage of VueDjango 23 | 24 | This is a project template that includes `VueJS` and `Django` based on the [vue-cli](https://github.com/vuejs/vue-cli) templates. **It is recommended to use npm 3+ for a more efficient dependency tree.** 25 | 26 | ``` bash 27 | $ npm install -g vue-cli 28 | ``` 29 | You might want to use ```sudo``` if you encounter permissions error 30 | ```bash 31 | $ vue init NdagiStanley/vue-django my-project 32 | $ cd my-project 33 | $ npm install 34 | ``` 35 | 36 | Secondly, have *Python* installed and preferably create a virtual environment for the project. 37 | 38 | To develop 39 | 40 | ```bash 41 | $ npm run dev 42 | ``` 43 | 44 | ## Deploy 45 | To deploy your django project 46 | 47 | `$ .deploy.sh` 48 | 49 | Then get to [localhost:8000](http://localhost:8000/). You should have a page exactly like the image below or as the deployed instance mentioned earlier: [https://vuedjango.herokuapp.com/](https://vuedjango.herokuapp.com/) 50 | 51 | ![](http://i.imgur.com/sY3IpBE.png?1) 52 | 53 | > Docker 54 | 55 | ##### Ensure that **docker** is running. 56 | 57 | If you use `docker` in your workflow, there is a `Dockerfile` in the root directory for you. Simply run 58 | ``` 59 | docker build -t [image-name] . 60 | ``` 61 | Use your preferred _image name_ in place of the `image-name` in the command. Remember to enter the trailing period before running it. 62 | 63 | There is a docker container for vue-django that you can run. Simply run the following command. 64 | ```bash 65 | docker run -p 8000:8000 stanmd/vue-django python manage.py runserver 0.0.0.0:8000 66 | ``` 67 | 68 | Then get to [localhost:8000](http://localhost:8000/). You should have a page exactly like the image above 69 | 70 | ## What's Included 71 | 72 | - `npm run dev`: first-in-class development experience. 73 | - Webpack + `vue-loader` for single file Vue components. 74 | - State preserving hot-reload 75 | - State preserving compilation error overlay 76 | - Lint-on-save with ESLint 77 | - Source maps 78 | 79 | - `npm run build`: Production ready build. 80 | - JavaScript minified with [UglifyJS](https://github.com/mishoo/UglifyJS2). 81 | - HTML minified with [html-minifier](https://github.com/kangax/html-minifier). 82 | - CSS across all components extracted into a single file and minified with [cssnano](https://github.com/ben-eb/cssnano). 83 | - All static assets compiled with version hashes for efficient long-term caching, and a production `index.html` is auto-generated with proper URLs to these generated assets. 84 | 85 | - `npm run unit`: Unit tests run in PhantomJS with [Karma](http://karma-runner.github.io/0.13/index.html) + [Mocha](http://mochajs.org/) + [karma-webpack](https://github.com/webpack/karma-webpack). 86 | - Supports ES2015 in test files. 87 | - Supports all webpack loaders. 88 | - Easy mock injection. 89 | 90 | - `npm run e2e`: End-to-end tests with [Nightwatch](http://nightwatchjs.org/). 91 | - Run tests in multiple browsers in parallel. 92 | - Works with one command out of the box: 93 | - Selenium and chromedriver dependencies automatically handled. 94 | - Automatically spawns the Selenium server. 95 | 96 | ### Contributions 97 | 98 | **NB**: This repo has been forked from vue-webpack-boilerplate to help you start a Django application utilizing the awesomeness of `Vue JS` and `vue-cli` 99 | 100 | Feel free to contribute to this repo. 101 | 102 | To create your own boilerplate, fork this repo or [vue-webpack-boilerplate](https://github.com/vuejs-templates/webpack) and use it with `vue-cli`: 103 | 104 | ``` bash 105 | vue init username/repo my-project 106 | ``` 107 | -------------------------------------------------------------------------------- /deploy-docs.sh: -------------------------------------------------------------------------------- 1 | cd docs 2 | rm -rf _book 3 | gitbook build 4 | cd _book 5 | git init 6 | git add -A 7 | git commit -m 'update book' 8 | git push -f git@github.com:vuejs-templates/webpack.git master:gh-pages 9 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | > A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction integrated into a django application 4 | 5 | # Vue Django 6 | [![Code Climate](https://codeclimate.com/github/NdagiStanley/vue-django/badges/gpa.svg)](https://codeclimate.com/github/NdagiStanley/vue-django) 7 | 8 | [![Updates](https://pyup.io/repos/github/NdagiStanley/vue-django/shield.svg)](https://pyup.io/repos/github/NdagiStanley/vue-django/) 9 | [![Python 3](https://pyup.io/repos/github/NdagiStanley/vue-django/python-3-shield.svg)](https://pyup.io/repos/github/NdagiStanley/vue-django/) 10 | 11 | [https://vuedjango.herokuapp.com/](https://vuedjango.herokuapp.com/) is a deployed instance of this boilerplate. 12 | 13 | ## Usage of VueDjango 14 | 15 | This is a project template that includes `VueJS` and `Django` based on the [vue-cli](https://github.com/vuejs/vue-cli) templates. **It is recommended to use npm 3+ for a more efficient dependency tree.** 16 | 17 | ## Quickstart 18 | 19 | To use this template, scaffold a project with [vue-cli](https://github.com/vuejs/vue-cli). **It is recommended to use npm 3+ for a more efficient dependency tree.** 20 | 21 | ``` bash 22 | $ npm install -g vue-cli 23 | $ vue init webpack my-project 24 | $ cd my-project 25 | $ npm install 26 | $ npm run dev 27 | ``` 28 | 29 | ### Deploy with Django 30 | 31 | Ensure python and pip is installed. 32 | 33 | ```bash 34 | $ npm run build 35 | $ pip install -r requirements.txt 36 | $ python format_index_html.py 37 | $ python manage.py collectstatic --noinput 38 | $ python manage.py runserver 39 | ``` 40 | 41 | Open the app [here](localhost:8000) 42 | 43 | ### Deploy with Docker 44 | 45 | Ensure that docker is running. 46 | 47 | If you use docker in your workflow, there is a Dockerfile in the root directory for you. Simply run: 48 | 49 | ```bash 50 | $ docker build -t [image-name] . 51 | $ docker run [image-name] 52 | ``` 53 | 54 | Open the app [here](localhost:8000) 55 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Project Structure](structure.md) 4 | - [Build Commands](commands.md) 5 | - [Linter Configuration](linter.md) 6 | - [Handling Static Assets](static.md) 7 | - [Integrate with Backend Framework](backend.md) 8 | - [API Proxying During Development](proxy.md) 9 | - [Unit Testing](unit.md) 10 | - [End-to-end Testing](e2e.md) 11 | - [Prerendering for SEO](prerender.md) 12 | -------------------------------------------------------------------------------- /docs/backend.md: -------------------------------------------------------------------------------- 1 | # Integrating with Backend Framework 2 | 3 | If you are building a purely-static app (one that is deployed separately from the backend API), then you probably don't even need to edit `config.js`. However, if you want to integrate this template with an existing backend framework, e.g. Rails/Django/Laravel, which comes with their own project structures, you can edit `config.js` to directly generate front-end assets into your backend project. 4 | 5 | Let's take a look at the default `config.js`: 6 | 7 | ``` js 8 | var path = require('path') 9 | 10 | module.exports = { 11 | build: { 12 | index: path.resolve(__dirname, 'dist/index.html'), 13 | assetsRoot: path.resolve(__dirname, 'dist'), 14 | assetsSubDirectory: 'static', 15 | assetsPublicPath: '/', 16 | productionSourceMap: true 17 | }, 18 | dev: { 19 | port: 8080, 20 | proxyTable: {} 21 | } 22 | } 23 | ``` 24 | 25 | Inside the `build` section, we have the following options: 26 | 27 | ### `build.index` 28 | 29 | > Must be an absolute path on your local file system. 30 | 31 | This is where the `index.html` (with injected asset URLs) will be generated. 32 | 33 | If you are using this template with a backend-framework, you can edit `index.html` accordingly and point this path to a view file rendered by your backend app, e.g. `app/views/layouts/application.html.erb` for a Rails app, or `resources/views/index.blade.php` for a Laravel app. 34 | 35 | ### `build.assetsRoot` 36 | 37 | > Must be an absolute path on your local file system. 38 | 39 | This should point to the root directory that contains all the static assets for your app. For example, `public/` for both Rails/Laravel. 40 | 41 | ### `build.assetsSubDirectory` 42 | 43 | Nest webpack-generated assets under this directory in `build.assetsRoot`, so that they are not mixed with other files you may have in `build.assetsRoot`. For example, if `build.assetsRoot` is `/path/to/dist`, and `build.assetsSubDirectory` is `static`, then all Webpack assets will be generated in `path/to/dist/static`. 44 | 45 | This directory will be cleaned before each build, so it should only contain assets generated by the build. 46 | 47 | Files inside `static/` will be copied into this directory as-is during build. This means if you change this prefix, all your absolute URLs referencing files in `static/` will also need to be changed. See [Handling Static Assets](static.md) for more details. 48 | 49 | ### `build.assetsPublicPath` 50 | 51 | This should be the URL path where your `build.assetsRoot` will be served from over HTTP. In most cases, this will be root (`/`). Only change this if your backend framework serves static assets with a path prefix. Internally, this is passed to Webpack as `output.publicPath`. 52 | 53 | ### `build.productionSourceMap` 54 | 55 | Whether to generate source maps for production build. 56 | 57 | ### `dev.port` 58 | 59 | Specify the port for the dev server to listen to. 60 | 61 | ### `dev.proxyTable` 62 | 63 | Define proxy rules for the dev server. See [API Proxying During Development](proxy.md) for more details. 64 | -------------------------------------------------------------------------------- /docs/commands.md: -------------------------------------------------------------------------------- 1 | # Build Commands 2 | 3 | All build commands are executed via [NPM Scripts](https://docs.npmjs.com/misc/scripts). 4 | 5 | ### `npm run dev` 6 | 7 | > Starts a Node.js local development server. See [API Proxying During Development](proxy.md) for more details. 8 | 9 | - Webpack + `vue-loader` for single file Vue components. 10 | - State preserving hot-reload 11 | - State preserving compilation error overlay 12 | - Lint-on-save with ESLint 13 | - Source maps 14 | 15 | ### `npm run build` 16 | 17 | > Build assets for production. See [Integrating with Backend Framework](backend.md) for more details. 18 | 19 | - JavaScript minified with [UglifyJS](https://github.com/mishoo/UglifyJS2). 20 | - HTML minified with [html-minifier](https://github.com/kangax/html-minifier). 21 | - CSS across all components extracted into a single file and minified with [cssnano](https://github.com/ben-eb/cssnano). 22 | - All static assets compiled with version hashes for efficient long-term caching, and a production `index.html` is auto-generated with proper URLs to these generated assets. 23 | - Also see [deployment notes](#how-do-i-deploy-built-assets-with-my-backend-framework). 24 | 25 | ### `npm run unit` 26 | 27 | > Run unit tests in PhantomJS with [Karma](http://karma-runner.github.io/0.13/index.html). See [Unit Testing](unit.md) for more details. 28 | 29 | - Supports ES2015 in test files. 30 | - Supports all webpack loaders. 31 | - Easy [mock injection](http://vuejs.github.io/vue-loader/workflow/testing-with-mocks.html). 32 | 33 | ### `npm run e2e` 34 | 35 | > Run end-to-end tests with [Nightwatch](http://nightwatchjs.org/). See [End-to-end Testing](e2e.md) for more details. 36 | 37 | - Run tests in multiple browsers in parallel. 38 | - Works with one command out of the box: 39 | - Selenium and chromedriver dependencies automatically handled. 40 | - Automatically spawns the Selenium server. 41 | -------------------------------------------------------------------------------- /docs/e2e.md: -------------------------------------------------------------------------------- 1 | # End-to-end Testing 2 | 3 | This boilerplate uses [Nightwatch.js](http://nightwatchjs.org) for e2e tests. Nightwatch.js is a highly integrated e2e test runner built on top of Selenium. This boilerplate comes with Selenium server and chromedriver binaries pre-configured for you, so you don't have to mess with these yourself. 4 | 5 | Let's take a look at the files in the `test/e2e` directory: 6 | 7 | - `runner.js` 8 | 9 | A Node.js script that starts the dev server, and then launches Nightwatch to run tests against it. This is the script that will run when you run `npm run e2e`. 10 | 11 | - `nightwatch.conf.js` 12 | 13 | Nightwatch configuration file. See [Nightwatch's docs on configuration](http://nightwatchjs.org/guide#settings-file) for more details. 14 | 15 | - `custom-assertions/` 16 | 17 | Custom assertions that can be used in Nightwatch tests. See [Nightwatch's docs on writing custom assertions](http://nightwatchjs.org/guide#writing-custom-assertions) for more details. 18 | 19 | - `specs/` 20 | 21 | You actual tests! See [Nightwatch's docs on writing tests](http://nightwatchjs.org/guide#writing-tests) and [API reference](http://nightwatchjs.org/api) for more details. 22 | 23 | ### Running Tests in More Browsers 24 | 25 | To configure which browsers to run the tests in, add an entry under "test_settings" in [`test/e2e/nightwatch.conf.js`](https://github.com/vuejs-templates/webpack/blob/master/template/test/e2e/nightwatch.conf.js#L17-L39) , and also the `--env` flag in [`test/e2e/runner.js`](https://github.com/vuejs-templates/webpack/blob/master/template/test/e2e/runner.js#L15). If you wish to configure remote testing on services like SauceLabs, you can either make the Nightwatch config conditional based on environment variables, or use a separate config file altogether. Consult [Nightwatch's docs on Selenium](http://nightwatchjs.org/guide#selenium-settings) for more details. 26 | -------------------------------------------------------------------------------- /docs/linter.md: -------------------------------------------------------------------------------- 1 | # Linter Configuration 2 | 3 | This boilerplate uses [ESLint](http://eslint.org/) as the linter, and uses the [Standard](https://github.com/feross/standard/blob/master/RULES.md) preset with some small customizations. 4 | 5 | If you are not happy with the default linting rules, you have several options: 6 | 7 | 1. Overwrite individual rules in `.eslintrc.js`. For example, you can add the following rule to enforce semicolons instead of omitting them: 8 | 9 | ``` js 10 | "semi": [2, "always"] 11 | ``` 12 | 13 | 2. Remove the `extends: 'standard'` line in `.eslintrc.js` and use a completely custom eslint config. See [ESLint documentation](http://eslint.org/docs/user-guide/configuring) for more details. 14 | 15 | 3. Use a different ESLint preset, for example [eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb). 16 | 17 | 4. Disable linting altogether: comment out the `module.preLoaders` block in `build/webpack.base.conf.js`. 18 | 19 | You will also need to disable linting if you are using a compile-to-JavaScript language, e.g. CoffeeScript. 20 | -------------------------------------------------------------------------------- /docs/prerender.md: -------------------------------------------------------------------------------- 1 | # Prerendering for SEO 2 | 3 | If you want to prerender routes that will not significantly change once pushed to production, use this Webpack plugin: [prerender-spa-plugin](https://www.npmjs.com/package/prerender-spa-plugin), which has been tested for use with Vue. For pages that _do_ frequently change, [Prerender.io](https://prerender.io/) and [Netlify](https://www.netlify.com/pricing) both offer plans for regularly re-prerendering your content for search engines. 4 | -------------------------------------------------------------------------------- /docs/proxy.md: -------------------------------------------------------------------------------- 1 | # API Proxying During Development 2 | 3 | When integrating this boilerplate with an existing backend, a common need is to access the backend API when using the dev server. To achieve that, we can run the dev server and the API backend side-by-side (or remotely), and let the dev server proxy all API requests to the actual backend. 4 | 5 | To configure the proxy rules, edit `dev.proxyTable` option in `config.js`. The dev server is using [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) for proxying, so you should refer to its docs for detailed usage. But here's a simple example: 6 | 7 | ``` js 8 | // config.js 9 | module.exports = { 10 | // ... 11 | dev: { 12 | proxyTable: { 13 | // proxy all requests starting with /api to jsonplaceholder 14 | '/api': { 15 | target: 'http://jsonplaceholder.typicode.com', 16 | changeOrigin: true, 17 | pathRewrite: { 18 | '^/api': '' 19 | } 20 | } 21 | } 22 | } 23 | } 24 | ``` 25 | 26 | The above example will proxy the request `/api/posts/1` to `http://jsonplaceholder.typicode.com/posts/1`. 27 | -------------------------------------------------------------------------------- /docs/static.md: -------------------------------------------------------------------------------- 1 | # Handing Static Assets 2 | 3 | You will notice in the project structure we have two directories for static assets: `src/assets` and `static/`. What is the difference between them? 4 | 5 | ### Webpacked Assets 6 | 7 | To answer this question, we first need to understand how Webpack deals with static assets. In `*.vue` components, all your templates and CSS are parsed by `vue-html-loader` and `css-loader` to look for asset URLs. For example, in `` and `background: url(./logo.png)`, `"./logo.png"` is a relative asset path and will be **resolved by Webpack as a module dependency**. 8 | 9 | Because `logo.png` is not JavaScript, when treated as a module dependency, we need to use `url-loader` and `file-loader` to process it. This boilerplate has already configured these loaders for you, so you basically get features such as filename fingerprinting and conditional base64 inlining for free, while being able to use relative/module paths without worrying about deployment. 10 | 11 | Since these assets may be inlined/copied/renamed during build, they are essentially part of your source code. This is why it is recommended to place Webpack-processed static assets inside `/src`, along side other source files. In fact, you don't even have to put them all in `/src/assets`: you can organize them based on the module/component using them. For example, you can put each component in its own directory, with its static assets right next to it. 12 | 13 | ### Asset Resolving Rules 14 | 15 | - **Relative URLs**, e.g. `./assets/logo.png` will be interpreted as a module dependency. They will be replaced with a auto-generated URL based on your Webpack output configuration. 16 | 17 | - **Non-prefixed URLs**, e.g. `assets/logo.png` will be treated the same as the relative URLs and translated into `./assets/logo.png`. 18 | 19 | - **URLs prefixed with `~`** are treated as a module request, similar to `require('some-module/image.png')`. You need to use this prefix if you want to leverage Webpack's module resolving configurations. For example if you have a resolve alias for `assets`, you need to use `` to ensure that alias is respected. 20 | 21 | - **Root-relative URLs**, e.g. `/assets/logo.png` are not processed at all. 22 | 23 | ### "Real" Static Assets 24 | 25 | In comparison, files in `static/` are not processed by Webpack at all: they are directly copied to their final destination as-is, with the same filename. You must reference these files using absolute paths, which is determined by joining `build.assetsPublicPath` and `build.assetsSubDirectory` in `config.js`. 26 | 27 | As an example, with the following default values: 28 | 29 | ``` js 30 | // config.js 31 | module.exports = { 32 | // ... 33 | build: { 34 | assetsPublicPath: '/', 35 | assetsSubDirectory: 'static' 36 | } 37 | } 38 | ``` 39 | 40 | Any file placed in `static/` should be referenced using the absolute URL `/static/[filename]`. If you change `assetSubDirectory` to `assets`, then these URLs will need to be changed to `/assets/[filename]`. 41 | 42 | We will learn more about the config file in the [next section](backend.md). 43 | -------------------------------------------------------------------------------- /docs/structure.md: -------------------------------------------------------------------------------- 1 | # Project Structure 2 | 3 | ``` bash 4 | . 5 | ├── config.js # main project config 6 | ├── build/ # webpack config files 7 | │ └── ... 8 | ├── src/ 9 | │   ├── main.js # app entry file 10 | │   ├── App.vue # main app component 11 | │   ├── components/ # ui components 12 | │   │   └── ... 13 | │   └── assets/ # module assets (processed by webpack) 14 | │      └── ... 15 | ├── static/ # pure static assets (directly copied) 16 | ├── test/ 17 | │ └── unit/ # unit tests 18 | │ │   ├── specs/ # test spec files 19 | │ │   ├── index.js # test build entry file 20 | │ │   └── karma.conf.js # test runner config file 21 | │ └── e2e/ # e2e tests 22 | │ │   ├── specs/ # test spec files 23 | │ │   ├── custom-assertions/ # custom assertions for e2e tests 24 | │ │   ├── runner.js # test runner script 25 | │ │   └── nightwatch.conf.js # test runner config file 26 | ├── .babelrc # babel config 27 | ├── .eslintrc.js # eslint config 28 | ├── index.html # index.html template 29 | └── package.json # build scripts and dependencies 30 | ``` 31 | 32 | ### `config.js` 33 | 34 | This is the main configuration file that exposes some of the most common configuration options for the build setup. See [API Proxying During Development](proxy.md) and [Integrating with Backend Framework](backend.md) for more details. 35 | 36 | ### `build/` 37 | 38 | This directory holds the actual configurations for both the development server and the production webpack build. Normally you don't need to touch these files unless you want to customize Webpack loaders, in which case you should probably look at `build/webpack.base.conf.js`. 39 | 40 | ### `src/` 41 | 42 | This is where most of your application code will live in. How to structure everything inside this directory is largely up to you; if you are using Vuex, you can consult the [recommendations for Vuex applications](http://vuex.vuejs.org/en/structure.html). 43 | 44 | ### `static/` 45 | 46 | This directory is an escape hatch for static assets that you do not want to process with Webpack. They will be directly copied into the same directory where webpack-built assets are generated. 47 | 48 | See [Handling Static Assets](static.md) for more details. 49 | 50 | ### `test/unit` 51 | 52 | Contains unit test related files. See [Unit Testing](unit.md) for more details. 53 | 54 | ### `test/e2e` 55 | 56 | Contains e2e test related files. See [End-to-end Testing](e2e.md) for more details. 57 | 58 | ### `index.html` 59 | 60 | This is the **template** `index.html` for our single page application. During development and builds, Webpack will generate assets, and the URLs for those generated assets will automatically injected into this template to render the final HTML. 61 | 62 | ### `package.json` 63 | 64 | The NPM package meta file that contains all the build dependencies and [build commands](commands.md). 65 | -------------------------------------------------------------------------------- /docs/unit.md: -------------------------------------------------------------------------------- 1 | # Unit Testing 2 | 3 | An overview of the tools used by this boilerplate for unit testing: 4 | 5 | - [Karma](http://karma-runner.github.io/0.13/index.html): the test runner that launches browsers, runs the tests and reports the results to us. 6 | - [karma-webpack](https://github.com/webpack/karma-webpack): the plugin for Karma that bundles our tests using Webpack. 7 | - [Mocha](https://mochajs.org/): the test framework that we write test specs with. 8 | - [Chai](http://chaijs.com/): test assertion library that provides better assertion syntax. 9 | - [Sinon](http://sinonjs.org/): test utility library that provides spies, stubs and mocks. 10 | 11 | Chai and Sinon are integrated using [karma-sinon-chai](https://github.com/kmees/karma-sinon-chai), so all Chai interfaces (`should`, `expect`, `assert`) and `sinon` are globally available in test files. 12 | 13 | And the files: 14 | 15 | - `index.js` 16 | 17 | This the entry file used by `karma-webpack` to bundle all the test code and source code (for coverage purposes). You can ignore it for the most part. 18 | 19 | - `specs/` 20 | 21 | This directory is where you write your actual tests. You can use full ES2015 and all supported Webpack loaders in your tests. 22 | 23 | - `karma.conf.js` 24 | 25 | This is the Karma configuration file. See [Karma docs](http://karma-runner.github.io/0.13/index.html) for more details. 26 | 27 | ## Running Tests in More Browsers 28 | 29 | You can run the tests in multiple real browsers by installing more [karma launchers](http://karma-runner.github.io/0.13/config/browsers.html) and adjusting the `browsers` field in `test/unit/karma.conf.js`. 30 | 31 | ## Mocking Dependencies 32 | 33 | This boilerplate comes with [inject-laoder](https://github.com/plasticine/inject-loader) installed by default. For usage with `*.vue` components, see [vue-loader docs on testing with mocks](http://vuejs.github.io/vue-loader/workflow/testing-with-mocks.html). 34 | -------------------------------------------------------------------------------- /meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": { 3 | "name": { 4 | "type": "string", 5 | "required": true, 6 | "label": "Project name" 7 | }, 8 | "version": { 9 | "type": "string", 10 | "required": true, 11 | "label": "Project version", 12 | "default": "0.1.0" 13 | }, 14 | "description": { 15 | "type": "string", 16 | "required": false, 17 | "label": "Project description", 18 | "default": "A Django - Vue.js project" 19 | }, 20 | "author": { 21 | "type": "string", 22 | "label": "Author" 23 | }, 24 | "private": { 25 | "type": "boolean", 26 | "default": true 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli-template-webpack", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "description": "A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction.", 6 | "scripts": { 7 | "docs": "cd docs && gitbook serve", 8 | "deploy-docs": "bash ./deploy-docs.sh" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /template/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"], 3 | "plugins": ["transform-runtime"], 4 | "comments": false 5 | } 6 | -------------------------------------------------------------------------------- /template/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /template/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 4 | extends: 'standard', 5 | // required to lint *.vue files 6 | plugins: [ 7 | 'html' 8 | ], 9 | // add your custom rules here 10 | 'rules': { 11 | // allow paren-less arrow functions 12 | 'arrow-parens': 0, 13 | // allow debugger during development 14 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log 5 | selenium-debug.log 6 | test/unit/coverage 7 | test/e2e/reports 8 | -------------------------------------------------------------------------------- /template/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node 2 | RUN apt-get update 3 | RUN apt-get install -y python 4 | RUN curl https://bootstrap.pypa.io/get-pip.py | python 5 | WORKDIR /usr/bin/app 6 | COPY requirements.txt . 7 | RUN pip install -r requirements.txt 8 | COPY . . 9 | RUN npm run build 10 | RUN python format_index_html.py 11 | RUN python manage.py collectstatic --noinput 12 | EXPOSE 8000 13 | CMD python manage.py runserver 0.0.0.0:8000 14 | -------------------------------------------------------------------------------- /template/README.md: -------------------------------------------------------------------------------- 1 | # {{ name }} 2 | 3 | > {{ description }} 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # run unit tests 18 | npm run unit 19 | 20 | # run e2e tests 21 | npm run e2e 22 | 23 | # run all tests 24 | npm test 25 | 26 | # deploy 27 | .deploy.sh 28 | ``` 29 | 30 | For detailed explanation on how things work, checkout the [guide](https://github.com/vuejs-templates/webpack#vue-webpack-boilerplate) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 31 | -------------------------------------------------------------------------------- /template/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/app/__init__.py -------------------------------------------------------------------------------- /template/app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /template/app/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class AppConfig(AppConfig): 7 | name = 'app' 8 | -------------------------------------------------------------------------------- /template/app/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | 5 | # Create your models here. 6 | -------------------------------------------------------------------------------- /template/app/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | from views import index 4 | 5 | 6 | # Create your tests here. 7 | class TestView(TestCase): 8 | """Test the views of the application""" 9 | 10 | def setUp(self): 11 | pass 12 | 13 | def tearDown(self): 14 | pass 15 | 16 | def test_index_view(self): 17 | response = self.client.get('/') 18 | self.assertEqual(response.status_code, 200) 19 | -------------------------------------------------------------------------------- /template/app/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | 4 | # Create your views here. 5 | def index(request): 6 | return render(request, 'index.html') 7 | -------------------------------------------------------------------------------- /template/build/build.js: -------------------------------------------------------------------------------- 1 | /* eslint-env shelljs */ 2 | 3 | // https://github.com/shelljs/shelljs 4 | require('shelljs/global') 5 | env.NODE_ENV = 'production' 6 | 7 | var path = require('path') 8 | var config = require('../config') 9 | var ora = require('ora') 10 | var webpack = require('webpack') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | console.log( 14 | ' Tip:\n' + 15 | ' Built files are meant to be served over an HTTP server.\n' + 16 | ' Opening index.html over file:// won\'t work.\n' 17 | ) 18 | 19 | var spinner = ora('building for production...') 20 | spinner.start() 21 | 22 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory) 23 | rm('-rf', assetsPath) 24 | mkdir('-p', assetsPath) 25 | cp('-R', 'static/', assetsPath) 26 | 27 | webpack(webpackConfig, function (err, stats) { 28 | spinner.stop() 29 | if (err) throw err 30 | process.stdout.write(stats.toString({ 31 | colors: true, 32 | modules: false, 33 | children: false, 34 | chunks: false, 35 | chunkModules: false 36 | }) + '\n') 37 | }) 38 | -------------------------------------------------------------------------------- /template/build/css-loaders.js: -------------------------------------------------------------------------------- 1 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 2 | 3 | module.exports = function (options) { 4 | options = options || {} 5 | // generate loader string to be used with extract text plugin 6 | function generateLoaders (loaders) { 7 | var sourceLoader = loaders.map(function (loader) { 8 | var extraParamChar 9 | if (/\?/.test(loader)) { 10 | loader = loader.replace(/\?/, '-loader?') 11 | extraParamChar = '&' 12 | } else { 13 | loader = loader + '-loader' 14 | extraParamChar = '?' 15 | } 16 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') 17 | }).join('!') 18 | 19 | if (options.extract) { 20 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader) 21 | } else { 22 | return ['vue-style-loader', sourceLoader].join('!') 23 | } 24 | } 25 | 26 | // http://vuejs.github.io/vue-loader/configurations/extract-css.html 27 | return { 28 | css: generateLoaders(['css']), 29 | postcss: generateLoaders(['css']), 30 | less: generateLoaders(['css', 'less']), 31 | sass: generateLoaders(['css', 'sass?indentedSyntax']), 32 | scss: generateLoaders(['css', 'sass']), 33 | stylus: generateLoaders(['css', 'stylus']), 34 | styl: generateLoaders(['css', 'stylus']) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /template/build/dev-client.js: -------------------------------------------------------------------------------- 1 | require('eventsource-polyfill') 2 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 3 | 4 | hotClient.subscribe(function (event) { 5 | if (event.action === 'reload') { 6 | window.location.reload() 7 | } 8 | }) 9 | -------------------------------------------------------------------------------- /template/build/dev-server.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var express = require('express') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var proxyMiddleware = require('http-proxy-middleware') 6 | var webpackConfig = process.env.NODE_ENV === 'testing' 7 | ? require('./webpack.prod.conf') 8 | : require('./webpack.dev.conf') 9 | 10 | // default port where dev server listens for incoming traffic 11 | var port = process.env.PORT || config.dev.port 12 | // Define HTTP proxies to your custom API backend 13 | // https://github.com/chimurai/http-proxy-middleware 14 | var proxyTable = config.dev.proxyTable 15 | 16 | var app = express() 17 | var compiler = webpack(webpackConfig) 18 | 19 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 20 | publicPath: webpackConfig.output.publicPath, 21 | stats: { 22 | colors: true, 23 | chunks: false 24 | } 25 | }) 26 | 27 | var hotMiddleware = require('webpack-hot-middleware')(compiler) 28 | // force page reload when html-webpack-plugin template changes 29 | compiler.plugin('compilation', function (compilation) { 30 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 31 | hotMiddleware.publish({ action: 'reload' }) 32 | cb() 33 | }) 34 | }) 35 | 36 | // proxy api requests 37 | Object.keys(proxyTable).forEach(function (context) { 38 | var options = proxyTable[context] 39 | if (typeof options === 'string') { 40 | options = { target: options } 41 | } 42 | app.use(proxyMiddleware(context, options)) 43 | }) 44 | 45 | // handle fallback for HTML5 history API 46 | app.use(require('connect-history-api-fallback')()) 47 | 48 | // serve webpack bundle output 49 | app.use(devMiddleware) 50 | 51 | // enable hot-reload and state-preserving 52 | // compilation error display 53 | app.use(hotMiddleware) 54 | 55 | // serve pure static assets 56 | var staticPath = path.posix.join(config.build.assetsPublicPath, config.build.assetsSubDirectory) 57 | app.use(staticPath, express.static('./static')) 58 | 59 | module.exports = app.listen(port, function (err) { 60 | if (err) { 61 | console.log(err) 62 | return 63 | } 64 | console.log('Listening at http://localhost:' + port + '\n') 65 | }) 66 | -------------------------------------------------------------------------------- /template/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var cssLoaders = require('./css-loaders') 4 | var projectRoot = path.resolve(__dirname, '../') 5 | 6 | module.exports = { 7 | entry: { 8 | app: './src/main.js' 9 | }, 10 | output: { 11 | path: config.build.assetsRoot, 12 | publicPath: config.build.assetsPublicPath, 13 | filename: '[name].js' 14 | }, 15 | resolve: { 16 | extensions: ['', '.js', '.vue'], 17 | fallback: [path.join(__dirname, '../node_modules')], 18 | alias: { 19 | 'src': path.resolve(__dirname, '../src'), 20 | 'assets': path.resolve(__dirname, '../src/assets'), 21 | 'components': path.resolve(__dirname, '../src/components') 22 | } 23 | }, 24 | resolveLoader: { 25 | fallback: [path.join(__dirname, '../node_modules')] 26 | }, 27 | module: { 28 | preLoaders: [ 29 | { 30 | test: /\.vue$/, 31 | loader: 'eslint', 32 | include: projectRoot, 33 | exclude: /node_modules/ 34 | }, 35 | { 36 | test: /\.js$/, 37 | loader: 'eslint', 38 | include: projectRoot, 39 | exclude: /node_modules/ 40 | } 41 | ], 42 | loaders: [ 43 | { 44 | test: /\.vue$/, 45 | loader: 'vue' 46 | }, 47 | { 48 | test: /\.js$/, 49 | loader: 'babel', 50 | include: projectRoot, 51 | exclude: /node_modules/ 52 | }, 53 | { 54 | test: /\.json$/, 55 | loader: 'json' 56 | }, 57 | { 58 | test: /\.html$/, 59 | loader: 'vue-html' 60 | }, 61 | { 62 | test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)(\?.*)?$/, 63 | loader: 'url', 64 | query: { 65 | limit: 10000, 66 | name: path.join(config.build.assetsSubDirectory, '[name].[hash:7].[ext]') 67 | } 68 | } 69 | ] 70 | }, 71 | vue: { 72 | loaders: cssLoaders() 73 | }, 74 | eslint: { 75 | formatter: require('eslint-friendly-formatter') 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /template/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack') 2 | var merge = require('webpack-merge') 3 | var baseWebpackConfig = require('./webpack.base.conf') 4 | var HtmlWebpackPlugin = require('html-webpack-plugin') 5 | 6 | // add hot-reload related code to entry chunks 7 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 8 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 9 | }) 10 | 11 | module.exports = merge(baseWebpackConfig, { 12 | // eval-source-map is faster for development 13 | devtool: '#eval-source-map', 14 | plugins: [ 15 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 16 | new webpack.optimize.OccurenceOrderPlugin(), 17 | new webpack.HotModuleReplacementPlugin(), 18 | new webpack.NoErrorsPlugin(), 19 | // https://github.com/ampedandwired/html-webpack-plugin 20 | new HtmlWebpackPlugin({ 21 | filename: 'index.html', 22 | template: 'index.html', 23 | inject: true 24 | }) 25 | ] 26 | }) 27 | -------------------------------------------------------------------------------- /template/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var webpack = require('webpack') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var cssLoaders = require('./css-loaders') 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | 10 | module.exports = merge(baseWebpackConfig, { 11 | devtool: config.build.productionSourceMap ? '#source-map' : false, 12 | output: { 13 | path: config.build.assetsRoot, 14 | filename: path.join(config.build.assetsSubDirectory, '[name].[chunkhash].js'), 15 | chunkFilename: path.join(config.build.assetsSubDirectory, '[id].[chunkhash].js') 16 | }, 17 | vue: { 18 | loaders: cssLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true 21 | }) 22 | }, 23 | plugins: [ 24 | // http://vuejs.github.io/vue-loader/workflow/production.html 25 | new webpack.DefinePlugin({ 26 | 'process.env': { 27 | NODE_ENV: '"production"' 28 | } 29 | }), 30 | new webpack.optimize.UglifyJsPlugin({ 31 | compress: { 32 | warnings: false 33 | } 34 | }), 35 | new webpack.optimize.OccurenceOrderPlugin(), 36 | // extract css into its own file 37 | new ExtractTextPlugin(path.join(config.build.assetsSubDirectory, '[name].[contenthash].css')), 38 | // generate dist index.html with correct asset hash for caching. 39 | // you can customize output by editing /index.html 40 | // see https://github.com/ampedandwired/html-webpack-plugin 41 | new HtmlWebpackPlugin({ 42 | filename: process.env.NODE_ENV === 'testing' 43 | ? 'index.html' 44 | : config.build.index, 45 | template: 'index.html', 46 | inject: true, 47 | minify: { 48 | removeComments: true, 49 | collapseWhitespace: true, 50 | removeAttributeQuotes: true 51 | // more options: 52 | // https://github.com/kangax/html-minifier#options-quick-reference 53 | } 54 | }) 55 | ] 56 | }) 57 | -------------------------------------------------------------------------------- /template/config.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | index: path.resolve(__dirname, 'templates/index.html'), 7 | assetsRoot: path.resolve(__dirname, 'static'), 8 | assetsSubDirectory: '/', 9 | assetsPublicPath: '/', 10 | productionSourceMap: true 11 | }, 12 | dev: { 13 | port: 8080, 14 | proxyTable: {} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /template/confirm.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/confirm.txt -------------------------------------------------------------------------------- /template/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/db.sqlite3 -------------------------------------------------------------------------------- /template/deploy.sh: -------------------------------------------------------------------------------- 1 | echo 'Running npm build' 2 | npm run build 3 | echo 'Done...' 4 | 5 | echo 'Format index.html as Jinja template' 6 | python format_index_html.py 7 | echo 'Done...' 8 | 9 | echo 'Install python modules' 10 | pip install -r requirements.txt 11 | echo 'Done...' 12 | 13 | echo 'Collect static' 14 | python manage.py collectstatic --noinput 15 | echo 'Done...' 16 | 17 | export PORT=8000 18 | echo 'Server runnning on port ' $PORT 19 | python manage.py runserver 20 | -------------------------------------------------------------------------------- /template/format_index_html.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import fileinput 3 | 4 | file = 'templates/index.html' 5 | 6 | with open(file, "r+") as f: 7 | s = f.read() 8 | f.seek(0) 9 | f.write("{% load staticfiles %}\n" + s) 10 | 11 | for i, line in enumerate(fileinput.input(file, inplace=1)): 12 | sys.stdout.write(line.replace('href=//', "href={% static '")) 13 | for i, line in enumerate(fileinput.input(file, inplace=1)): 14 | sys.stdout.write(line.replace('css', "css' %}")) 15 | for i, line in enumerate(fileinput.input(file, inplace=1)): 16 | sys.stdout.write(line.replace('src=//', "src={% static '")) 17 | for i, line in enumerate(fileinput.input(file, inplace=1)): 18 | sys.stdout.write(line.replace('js', "js' %}")) 19 | -------------------------------------------------------------------------------- /template/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ name }} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /template/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "vuedj.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ name }}", 3 | "version": "{{ version }}", 4 | "description": "{{ description }}", 5 | "author": "{{ author }}", 6 | {{#private}} 7 | "private": true, 8 | {{/private}} 9 | "scripts": { 10 | "dev": "node build/dev-server.js", 11 | "build": "node build/build.js", 12 | "unit": "karma start test/unit/karma.conf.js --single-run", 13 | "e2e": "node test/e2e/runner.js", 14 | "test": "npm run unit && npm run e2e" 15 | }, 16 | "dependencies": { 17 | "vue": "^1.0.21", 18 | "babel-runtime": "^6.0.0" 19 | }, 20 | "devDependencies": { 21 | "babel-core": "^6.0.0", 22 | "babel-loader": "^6.0.0", 23 | "babel-plugin-transform-runtime": "^6.0.0", 24 | "babel-preset-es2015": "^6.0.0", 25 | "babel-preset-stage-2": "^6.0.0", 26 | "chai": "^3.5.0", 27 | "chromedriver": "^2.21.2", 28 | "connect-history-api-fallback": "^1.1.0", 29 | "cross-spawn": "^2.1.5", 30 | "css-loader": "^0.23.0", 31 | "eslint": "^2.0.0", 32 | "eslint-config-standard": "^5.1.0", 33 | "eslint-friendly-formatter": "^1.2.2", 34 | "eslint-loader": "^1.3.0", 35 | "eslint-plugin-html": "^1.3.0", 36 | "eslint-plugin-promise": "^1.0.8", 37 | "eslint-plugin-standard": "^1.3.2", 38 | "eventsource-polyfill": "^0.9.6", 39 | "express": "^4.13.3", 40 | "extract-text-webpack-plugin": "^1.0.1", 41 | "file-loader": "^0.8.4", 42 | "html-webpack-plugin": "^2.8.1", 43 | "http-proxy-middleware": "^0.12.0", 44 | "inject-loader": "^2.0.1", 45 | "isparta-loader": "^2.0.0", 46 | "json-loader": "^0.5.4", 47 | "karma": "^0.13.15", 48 | "karma-coverage": "^0.5.5", 49 | "karma-mocha": "^0.2.2", 50 | "karma-phantomjs-launcher": "^1.0.0", 51 | "karma-sinon-chai": "^1.2.0", 52 | "karma-sourcemap-loader": "^0.3.7", 53 | "karma-spec-reporter": "0.0.24", 54 | "karma-webpack": "^1.7.0", 55 | "lolex": "^1.4.0", 56 | "mocha": "^2.4.5", 57 | "nightwatch": "^0.8.18", 58 | "ora": "^0.2.0", 59 | "phantomjs-prebuilt": "^2.1.3", 60 | "selenium-server": "2.53.0", 61 | "shelljs": "^0.6.0", 62 | "sinon": "^1.17.3", 63 | "sinon-chai": "^2.8.0", 64 | "url-loader": "^0.5.7", 65 | "vue-hot-reload-api": "^1.2.0", 66 | "vue-html-loader": "^1.0.0", 67 | "vue-loader": "^8.3.0", 68 | "vue-style-loader": "^1.0.0", 69 | "webpack": "^1.12.2", 70 | "webpack-dev-middleware": "^1.4.0", 71 | "webpack-hot-middleware": "^2.6.0", 72 | "webpack-merge": "^0.8.3" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /template/requirements.txt: -------------------------------------------------------------------------------- 1 | coverage==4.4.1 2 | coveralls==1.2.0 3 | Django==1.11.4 4 | django-nose==1.4.5 -------------------------------------------------------------------------------- /template/src/App.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 22 | 23 | 53 | -------------------------------------------------------------------------------- /template/src/assets/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/src/assets/Screenshot.png -------------------------------------------------------------------------------- /template/src/assets/dj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/src/assets/dj.png -------------------------------------------------------------------------------- /template/src/assets/vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/src/assets/vue.png -------------------------------------------------------------------------------- /template/src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /template/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | 4 | /* eslint-disable no-new */ 5 | new Vue({ 6 | el: 'body', 7 | components: { App } 8 | }) 9 | -------------------------------------------------------------------------------- /template/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/static/.gitkeep -------------------------------------------------------------------------------- /template/test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count 11 | this.expected = count 12 | this.pass = function (val) { 13 | return val === this.expected 14 | } 15 | this.value = function (res) { 16 | return res.value 17 | } 18 | this.command = function (cb) { 19 | var self = this 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length 22 | }, [selector], function (res) { 23 | cb.call(self, res) 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /template/test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | // http://nightwatchjs.org/guide#settings-file 2 | module.exports = { 3 | 'src_folders': ['test/e2e/specs'], 4 | 'output_folder': 'test/e2e/reports', 5 | 'custom_assertions_path': ['test/e2e/custom-assertions'], 6 | 7 | 'selenium': { 8 | 'start_process': true, 9 | 'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.0.jar', 10 | 'host': '127.0.0.1', 11 | 'port': 4444, 12 | 'cli_args': { 13 | 'webdriver.chrome.driver': require('chromedriver').path 14 | } 15 | }, 16 | 17 | 'test_settings': { 18 | 'default': { 19 | 'selenium_port': 4444, 20 | 'selenium_host': 'localhost', 21 | 'silent': true 22 | }, 23 | 24 | 'chrome': { 25 | 'desiredCapabilities': { 26 | 'browserName': 'chrome', 27 | 'javascriptEnabled': true, 28 | 'acceptSslCerts': true 29 | } 30 | }, 31 | 32 | 'firefox': { 33 | 'desiredCapabilities': { 34 | 'browserName': 'firefox', 35 | 'javascriptEnabled': true, 36 | 'acceptSslCerts': true 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /template/test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing' 3 | var server = require('../../build/dev-server.js') 4 | 5 | // 2. run the nightwatch test suite against it 6 | // to run in additional browsers: 7 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 8 | // 2. add it to the --env flag below 9 | // For more information on Nightwatch's config file, see 10 | // http://nightwatchjs.org/guide#settings-file 11 | var spawn = require('cross-spawn') 12 | var runner = spawn( 13 | './node_modules/.bin/nightwatch', 14 | [ 15 | '--config', 'test/e2e/nightwatch.conf.js', 16 | '--env', 'chrome,firefox' 17 | ], 18 | { 19 | stdio: 'inherit' 20 | } 21 | ) 22 | 23 | runner.on('exit', function (code) { 24 | server.close() 25 | process.exit(code) 26 | }) 27 | 28 | runner.on('error', function (err) { 29 | server.close() 30 | throw err 31 | }) 32 | -------------------------------------------------------------------------------- /template/test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function (browser) { 6 | browser 7 | .url('http://localhost:8080') 8 | .waitForElementVisible('#app', 5000) 9 | .assert.elementPresent('.logo') 10 | .assert.containsText('h1', 'Hello World!') 11 | .assert.elementCount('p', 2) 12 | .end() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /template/test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /template/test/unit/index.js: -------------------------------------------------------------------------------- 1 | // require all test files (files that ends with .spec.js) 2 | var testsContext = require.context('./specs', true, /\.spec$/) 3 | testsContext.keys().forEach(testsContext) 4 | 5 | // require all src files except main.js for coverage. 6 | // you can also change this to match only the subset of files that 7 | // you want coverage for. 8 | var srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/) 9 | srcContext.keys().forEach(srcContext) 10 | -------------------------------------------------------------------------------- /template/test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var path = require('path') 7 | var merge = require('webpack-merge') 8 | var baseConfig = require('../../build/webpack.base.conf') 9 | var projectRoot = path.resolve(__dirname, '../../') 10 | 11 | var webpackConfig = merge(baseConfig, { 12 | // use inline sourcemap for karma-sourcemap-loader 13 | devtool: '#inline-source-map', 14 | vue: { 15 | loaders: { 16 | js: 'isparta' 17 | } 18 | } 19 | }) 20 | 21 | // no need for app entry during tests 22 | delete webpackConfig.entry 23 | 24 | // make sure isparta loader is applied before eslint 25 | webpackConfig.module.preLoaders = webpackConfig.module.preLoaders || [] 26 | webpackConfig.module.preLoaders.unshift({ 27 | test: /\.js$/, 28 | loader: 'isparta', 29 | include: projectRoot, 30 | exclude: /test\/unit|node_modules/ 31 | }) 32 | 33 | // only apply babel for test files when using isparta 34 | webpackConfig.module.loaders.some(function (loader, i) { 35 | if (loader.loader === 'babel') { 36 | loader.include = /test\/unit/ 37 | return true 38 | } 39 | }) 40 | 41 | module.exports = function (config) { 42 | config.set({ 43 | // to run in additional browsers: 44 | // 1. install corresponding karma launcher 45 | // http://karma-runner.github.io/0.13/config/browsers.html 46 | // 2. add it to the `browsers` array below. 47 | browsers: ['PhantomJS'], 48 | frameworks: ['mocha', 'sinon-chai'], 49 | reporters: ['spec', 'coverage'], 50 | files: ['./index.js'], 51 | preprocessors: { 52 | './index.js': ['webpack', 'sourcemap'] 53 | }, 54 | webpack: webpackConfig, 55 | webpackMiddleware: { 56 | noInfo: true 57 | }, 58 | coverageReporter: { 59 | dir: './coverage', 60 | reporters: [ 61 | { type: 'lcov', subdir: '.' }, 62 | { type: 'text-summary' } 63 | ] 64 | } 65 | }) 66 | } 67 | -------------------------------------------------------------------------------- /template/test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from 'src/components/Hello' 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const vm = new Vue({ 7 | template: '
', 8 | components: { Hello } 9 | }).$mount() 10 | expect(vm.$el.querySelector('.hello h1').textContent).to.contain('Hello World!') 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /template/vuedj/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NdagiStanley/vue-django-fork/668b74ff797090ecab78312f12de14bd770dbc2a/template/vuedj/__init__.py -------------------------------------------------------------------------------- /template/vuedj/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for vuedj project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.9.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.9/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | # Project path to allow relative paths for my path variables 19 | PROJECT_PATH = os.path.realpath(os.path.dirname(__file__)) 20 | 21 | 22 | # Quick-start development settings - unsuitable for production 23 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 24 | 25 | # SECURITY WARNING: keep the secret key used in production secret! 26 | SECRET_KEY = 'n3@wsgyxr)65$+s%z=b7#@8460%t_t0&s*elevyu%h5w_0i9@@' 27 | 28 | # SECURITY WARNING: don't run with debug turned on in production! 29 | DEBUG = True 30 | 31 | ALLOWED_HOSTS = [] 32 | 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = [ 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'app', 44 | 'django_nose', 45 | ] 46 | 47 | MIDDLEWARE_CLASSES = [ 48 | 'django.middleware.security.SecurityMiddleware', 49 | 'django.contrib.sessions.middleware.SessionMiddleware', 50 | 'django.middleware.common.CommonMiddleware', 51 | 'django.middleware.csrf.CsrfViewMiddleware', 52 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 53 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 54 | 'django.contrib.messages.middleware.MessageMiddleware', 55 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 56 | ] 57 | 58 | ROOT_URLCONF = 'vuedj.urls' 59 | 60 | TEMPLATES = [ 61 | { 62 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 63 | 'DIRS': ['templates/'], 64 | 'APP_DIRS': True, 65 | 'OPTIONS': { 66 | 'context_processors': [ 67 | 'django.template.context_processors.debug', 68 | 'django.template.context_processors.request', 69 | 'django.contrib.auth.context_processors.auth', 70 | 'django.contrib.messages.context_processors.messages', 71 | ], 72 | }, 73 | }, 74 | ] 75 | 76 | WSGI_APPLICATION = 'vuedj.wsgi.application' 77 | 78 | 79 | # Database 80 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 81 | 82 | DATABASES = { 83 | 'default': { 84 | 'ENGINE': 'django.db.backends.sqlite3', 85 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 86 | } 87 | } 88 | 89 | 90 | # Password validation 91 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 92 | 93 | AUTH_PASSWORD_VALIDATORS = [ 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 102 | }, 103 | { 104 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 105 | }, 106 | ] 107 | 108 | 109 | # Internationalization 110 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 111 | 112 | LANGUAGE_CODE = 'en-us' 113 | 114 | TIME_ZONE = 'UTC' 115 | 116 | USE_I18N = True 117 | 118 | USE_L10N = True 119 | 120 | USE_TZ = True 121 | 122 | 123 | # Static files (CSS, JavaScript, Images) 124 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 125 | 126 | STATICFILES_DIRS = ( 127 | os.path.join(BASE_DIR, 'static'), 128 | ) 129 | 130 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 131 | 132 | STATIC_URL = '/staticfiles/' 133 | 134 | # Use nose to run all tests 135 | TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' 136 | 137 | # Tell nose to measure coverage on the 'foo' and 'bar' apps 138 | NOSE_ARGS = [ 139 | '--with-coverage', 140 | '--cover-package=foo,bar', 141 | ] 142 | -------------------------------------------------------------------------------- /template/vuedj/urls.py: -------------------------------------------------------------------------------- 1 | """vuedj URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | from app.views import index 19 | 20 | 21 | urlpatterns = [ 22 | url(r'^admin/', admin.site.urls), 23 | url(r'^$', index, name='home'), 24 | ] 25 | -------------------------------------------------------------------------------- /template/vuedj/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for vuedj project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "vuedj.settings") 15 | 16 | application = get_wsgi_application() 17 | --------------------------------------------------------------------------------