├── .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 | [](https://codeclimate.com/github/NdagiStanley/vue-django)
16 |
17 | [](https://pyup.io/repos/github/NdagiStanley/vue-django/)
18 | [](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 | 
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 | [](https://codeclimate.com/github/NdagiStanley/vue-django)
7 |
8 | [](https://pyup.io/repos/github/NdagiStanley/vue-django/)
9 | [](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 |
8 | Welcome to your Django - Vue.js app! 9 |
10 |