├── static
└── .gitkeep
├── .travis.yml
├── src
├── vuex
│ ├── mutation-types.js
│ ├── actions.js
│ └── store.js
├── assets
│ └── logo.png
├── main.js
├── App.vue
├── router
│ └── index.js
└── components
│ ├── About.vue
│ ├── Hello.vue
│ └── Index.vue
├── test
├── unit
│ ├── .eslintrc
│ ├── specs
│ │ └── Hello.spec.js
│ ├── index.js
│ └── karma.conf.js
└── e2e
│ ├── specs
│ └── test.js
│ ├── runner.js
│ ├── custom-assertions
│ └── elementCount.js
│ └── nightwatch.conf.js
├── .babelrc
├── .gitignore
├── .editorconfig
├── index.html
├── .eslintrc.js
├── README.md
└── package.json
/static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4.2"
4 |
--------------------------------------------------------------------------------
/src/vuex/mutation-types.js:
--------------------------------------------------------------------------------
1 | export const INCREMENT = 'INCREMENT'
2 |
--------------------------------------------------------------------------------
/test/unit/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/funkyLover/vue-boilerplate/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2"],
3 | "plugins": ["transform-runtime"],
4 | "comments": false
5 | }
6 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/vuex/actions.js:
--------------------------------------------------------------------------------
1 | import * as types from './mutation-types'
2 |
3 | export const increment = ({ dispatch }, x) => {
4 | dispatch(types.INCREMENT, x)
5 | }
6 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-boilerplate
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import { sync } from 'vuex-router-sync'
4 | import store from './vuex/store'
5 | import router from './router/index'
6 |
7 | // for debugging
8 | Vue.config.debug = true
9 |
10 | sync(store, router)
11 |
12 | router.start(App, '#app')
13 |
--------------------------------------------------------------------------------
/src/vuex/store.js:
--------------------------------------------------------------------------------
1 | import Vuex from 'vuex'
2 | import Vue from 'vue'
3 | import { INCREMENT } from './mutation-types'
4 |
5 | Vue.use(Vuex)
6 |
7 | export default new Vuex.Store({
8 | state: {
9 | count: 1
10 | },
11 | mutations: {
12 | [INCREMENT] (state, x) {
13 | state.count += x
14 | }
15 | }
16 | })
17 |
--------------------------------------------------------------------------------
/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', 3)
12 | .end()
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import VueRouter from 'vue-router'
2 | import Vue from 'vue'
3 | import Index from '../components/Index'
4 | import About from '../components/About'
5 | import Hello from '../components/Hello'
6 |
7 | Vue.use(VueRouter)
8 |
9 | var router = new VueRouter()
10 |
11 | router.map({
12 | '/index': {
13 | component: Index
14 | },
15 | '/about': {
16 | component: About
17 | },
18 | '/hello': {
19 | component: Hello
20 | }
21 | })
22 |
23 | export default router
24 |
--------------------------------------------------------------------------------
/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).toBe('Hello World!')
11 | })
12 | })
13 |
14 | // also see example testing a component with mocks at
15 | // https://github.com/vuejs/vue-loader-example/blob/master/test/unit/a.spec.js#L24-L49
16 |
--------------------------------------------------------------------------------
/test/unit/index.js:
--------------------------------------------------------------------------------
1 | // Polyfill fn.bind() for PhantomJS
2 | /* eslint-disable no-extend-native */
3 | Function.prototype.bind = require('function-bind')
4 |
5 | // require all test files (files that ends with .spec.js)
6 | var testsContext = require.context('./specs', true, /\.spec$/)
7 | testsContext.keys().forEach(testsContext)
8 |
9 | // require all src files except main.js for coverage.
10 | // you can also change this to match only the subset of files that
11 | // you want coverage for.
12 | var srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
13 | srcContext.keys().forEach(srcContext)
14 |
--------------------------------------------------------------------------------
/src/components/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 |
6 |
7 |
33 |
--------------------------------------------------------------------------------
/src/components/Hello.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 |
6 |
7 |
33 |
--------------------------------------------------------------------------------
/src/components/Index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 |
6 |
7 |
33 |
--------------------------------------------------------------------------------
/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | // 1. start the dev server
2 | var server = require('../../build/dev-server.js')
3 |
4 | // 2. run the nightwatch test suite against it
5 | // to run in additional browsers:
6 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
7 | // 2. add it to the --env flag below
8 | // For more information on Nightwatch's config file, see
9 | // http://nightwatchjs.org/guide#settings-file
10 | var spawn = require('cross-spawn')
11 | var runner = spawn(
12 | './node_modules/.bin/nightwatch',
13 | [
14 | '--config', 'test/e2e/nightwatch.conf.js',
15 | '--env', 'chrome,firefox'
16 | ],
17 | {
18 | stdio: 'inherit'
19 | }
20 | )
21 |
22 | runner.on('exit', function (code) {
23 | server.close()
24 | process.exit(code)
25 | })
26 |
27 | runner.on('error', function (err) {
28 | server.close()
29 | throw err
30 | })
31 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > # outdated! please check [vue-spa](https://github.com/funkyLover/vue-spa) instead
2 |
3 | # vue-boilerplate
4 |
5 | > A boilerplate for building spa with vue, vuex, vue-router
6 |
7 | ## detail
8 |
9 | firstly, get `vue-webpack-boilerplate` by [vue-cli](https://github.com/vuejs/vue-cli). and then add the dependencies(`vuex`, `vue-router`, `vuex-router-sync`) for building spa.
10 |
11 | ## Build Setup
12 |
13 | ``` bash
14 | # install dependencies
15 | npm install
16 |
17 | # serve with hot reload at localhost:8080
18 | npm run dev
19 |
20 | # build for production with minification
21 | npm run build
22 |
23 | # run unit tests
24 | npm run unit
25 |
26 | # run e2e tests
27 | npm run e2e
28 |
29 | # run all tests
30 | npm test
31 | ```
32 |
33 | 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).
34 |
--------------------------------------------------------------------------------
/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.52.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 |
--------------------------------------------------------------------------------
/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.unshift({
26 | test: /\.js$/,
27 | loader: 'isparta',
28 | include: projectRoot,
29 | exclude: /test\/unit|node_modules/
30 | })
31 |
32 | // only apply babel for test files when using isparta
33 | webpackConfig.module.loaders.some(function (loader, i) {
34 | if (loader.loader === 'babel') {
35 | loader.include = /test\/unit/
36 | return true
37 | }
38 | })
39 |
40 | module.exports = function (config) {
41 | config.set({
42 | // to run in additional browsers:
43 | // 1. install corresponding karma launcher
44 | // http://karma-runner.github.io/0.13/config/browsers.html
45 | // 2. add it to the `browsers` array below.
46 | browsers: ['PhantomJS'],
47 | frameworks: ['jasmine'],
48 | reporters: ['spec', 'coverage'],
49 | files: ['./index.js'],
50 | preprocessors: {
51 | './index.js': ['webpack', 'sourcemap']
52 | },
53 | webpack: webpackConfig,
54 | webpackMiddleware: {
55 | noInfo: true
56 | },
57 | coverageReporter: {
58 | dir: './coverage',
59 | reporters: [
60 | { type: 'lcov', subdir: '.' },
61 | { type: 'text-summary' }
62 | ]
63 | }
64 | })
65 | }
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-boilerplate",
3 | "version": "0.1.0",
4 | "description": "A boilerplate for building spa with vue, vuex, vue-router",
5 | "author": "funkyLover ",
6 | "scripts": {
7 | "dev": "node build/dev-server.js",
8 | "build": "rimraf dist && mkdirp dist && ncp static dist/static && cross-env NODE_ENV=production webpack --progress --hide-modules --config build/webpack.prod.conf.js",
9 | "unit": "karma start test/unit/karma.conf.js --single-run",
10 | "e2e": "node test/e2e/runner.js",
11 | "test": "npm run unit && npm run e2e"
12 | },
13 | "dependencies": {
14 | "vue": "^1.0.17",
15 | "vue-router": "^0.7.11",
16 | "vuex": "^0.6.2",
17 | "vuex-router-sync": "^1.0.0"
18 | },
19 | "devDependencies": {
20 | "babel-core": "^6.0.0",
21 | "babel-loader": "^6.0.0",
22 | "babel-plugin-transform-runtime": "^6.0.0",
23 | "babel-preset-es2015": "^6.0.0",
24 | "babel-preset-stage-2": "^6.0.0",
25 | "babel-runtime": "^5.8.0",
26 | "chromedriver": "^2.21.2",
27 | "connect-history-api-fallback": "^1.1.0",
28 | "cross-env": "^1.0.7",
29 | "cross-spawn": "^2.1.5",
30 | "css-loader": "^0.23.1",
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 | "function-bind": "^1.0.2",
43 | "html-webpack-plugin": "^2.8.1",
44 | "http-proxy-middleware": "^0.11.0",
45 | "inject-loader": "^2.0.1",
46 | "isparta-loader": "^2.0.0",
47 | "jasmine-core": "^2.4.1",
48 | "json-loader": "^0.5.4",
49 | "karma": "^0.13.15",
50 | "karma-coverage": "^0.5.5",
51 | "karma-jasmine": "^0.3.6",
52 | "karma-phantomjs-launcher": "^1.0.0",
53 | "karma-sourcemap-loader": "^0.3.7",
54 | "karma-spec-reporter": "0.0.24",
55 | "karma-webpack": "^1.7.0",
56 | "less": "^2.6.1",
57 | "less-loader": "^2.2.2",
58 | "mkdirp": "^0.5.1",
59 | "ncp": "^2.0.0",
60 | "nightwatch": "^0.8.18",
61 | "node-sass": "^3.4.2",
62 | "phantomjs-prebuilt": "^2.1.3",
63 | "rimraf": "^2.5.0",
64 | "sass-loader": "^3.2.0",
65 | "selenium-server": "2.52.0",
66 | "style-loader": "^0.13.1",
67 | "stylus-loader": "^1.5.1",
68 | "url-loader": "^0.5.7",
69 | "vue-hot-reload-api": "^1.2.0",
70 | "vue-html-loader": "^1.0.0",
71 | "vue-loader": "^8.1.3",
72 | "vue-style-loader": "^1.0.0",
73 | "webpack": "^1.12.2",
74 | "webpack-dev-middleware": "^1.4.0",
75 | "webpack-hot-middleware": "^2.6.0",
76 | "webpack-merge": "^0.8.3"
77 | }
78 | }
79 |
--------------------------------------------------------------------------------