21 |
22 |
23 |
33 |
34 |
35 |
54 |
--------------------------------------------------------------------------------
/docs/unit.md:
--------------------------------------------------------------------------------
1 | # Unit Testing
2 |
3 | An overview of the tools used by this boilerplate for unit testing:
4 |
5 | - [Karma](https://karma-runner.github.io/): 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 is 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](https://karma-runner.github.io/) 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](https://karma-runner.github.io/1.0/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-loader](https://github.com/plasticine/inject-loader) installed by default. For usage with `*.vue` components, see [vue-loader docs on testing with mocks](http://vue-loader.vuejs.org/en/workflow/testing-with-mocks.html).
34 |
--------------------------------------------------------------------------------
/docs/pre-processors.md:
--------------------------------------------------------------------------------
1 | # Pre-Processors
2 |
3 | This boilerplate has pre-configured CSS extraction for most popular CSS pre-processors including LESS, SASS, Stylus, and PostCSS. To use a pre-processor, all you need to do is installing the appropriate webpack loader for it. For example, to use SASS:
4 |
5 | ``` bash
6 | npm install sass-loader node-sass --save-dev
7 | ```
8 |
9 | Note you also need to install `node-sass` because `sass-loader` depends on it as a peer dependency.
10 |
11 | ### Using Pre-Processors inside Components
12 |
13 | Once installed, you can use the pre-processors inside your `*.vue` components using the `lang` attribute on `
19 | ```
20 |
21 | ### A note on SASS syntax
22 |
23 | - `lang="scss"` corresponds to the CSS-superset syntax (with curly braces and semicolons).
24 | - `lang="sass"` corresponds to the indentation-based syntax.
25 |
26 | ### PostCSS
27 |
28 | Styles in `*.vue` files are piped through PostCSS by default, so you don't need to use a specific loader for it. You can simply add PostCSS plugins you want to use in `build/webpack.base.conf.js` under the `vue` block:
29 |
30 | ``` js
31 | // build/webpack.base.conf.js
32 | module.exports = {
33 | // ...
34 | vue: {
35 | postcss: [/* your plugins */]
36 | }
37 | }
38 | ```
39 |
40 | See [vue-loader's related documentation](http://vuejs.github.io/vue-loader/en/features/postcss.html) for more details.
41 |
42 | ### Standalone CSS Files
43 |
44 | To ensure consistent extraction and processing, it is recommended to import global, standalone style files from your root `App.vue` component, for example:
45 |
46 | ``` html
47 |
48 |
49 | ```
50 |
51 | Note you should probably only do this for the styles written by yourself for your application. For existing libraries e.g. Bootstrap or Semantic UI, you can place them inside `/static` and reference them directly in `index.html`. This avoids extra build time and also is better for browser caching. (See [Static Asset Handling](static.md))
52 |
--------------------------------------------------------------------------------
/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/index.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.production.js` or `config.development.js` to directly generate front-end assets into your backend project.
4 |
5 |
6 | Inside the `config.production.js` section, we have the following options:
7 |
8 | ### `index`
9 |
10 | > Must be an absolute path on your local file system.
11 |
12 | This is where the `index.html` (with injected asset URLs) will be generated.
13 |
14 | 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.
15 |
16 | ### `assetsRoot`
17 |
18 | > Must be an absolute path on your local file system.
19 |
20 | This should point to the root directory that contains all the static assets for your app. For example, `public/` for both Rails/Laravel.
21 |
22 | ### `assetsSubDirectory`
23 |
24 | 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`.
25 |
26 | This directory will be cleaned before each build, so it should only contain assets generated by the build.
27 |
28 | 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.
29 |
30 | ### `assetsPublicPath`
31 |
32 | 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`.
33 |
--------------------------------------------------------------------------------
/template/build/webpack.base.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const config = require('../config');
3 | const webpack = require('webpack');
4 | {{#lint}}
5 | const ESlintFormatter = require('eslint-friendly-formatter');
6 | {{/lint}}
7 |
8 | const defaults = {
9 | __DEV__: JSON.stringify(config.isDev),
10 | __PROD__: JSON.stringify(config.isProd),
11 | 'process.env.NODE_ENV': `"${config.env}"`,
12 | __APP_MODE__: `"${config.appMode}"`,
13 | };
14 |
15 | const webpackConfig = {
16 | entry: './src/js/main.js',
17 | output: {
18 | path: config.assetsRoot,
19 | publicPath: config.assetsPublicPath,
20 | filename: config.isDev ? './js/[name].js' : './js/[name].[chunkhash].js',
21 | chunkFilename: config.isDev ? './js/[id].js' : './js/chunk.[chunkhash].js',
22 | },
23 | resolve: {
24 | extensions: ['.js', '.vue', '.json'],
25 | alias: {
26 | {{#if_eq build "standalone"}}
27 | vue$: 'vue/dist/vue.esm.js',
28 | {{/if_eq}}
29 | },
30 | },
31 | plugins: [
32 | new webpack.DefinePlugin(defaults),
33 | ],
34 | module: {
35 | rules: [
36 | {{#lint}}
37 | {
38 | test: /\.(js|vue)$/,
39 | loader: 'eslint-loader',
40 | enforce: 'pre',
41 | exclude: /node_modules/,
42 | options: {
43 | formatter: ESlintFormatter,
44 | },
45 | },
46 | {{/lint}}
47 | {
48 | test: /\.js$/,
49 | loader: 'babel-loader',
50 | exclude: /node_modules/,
51 | },
52 | {
53 | test: /\.vue$/,
54 | loader: 'vue-loader',
55 | options: {
56 | extractCSS: config.isProd,
57 | },
58 | },
59 | {
60 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
61 | loader: 'url-loader',
62 | options: {
63 | limit: 100,
64 | name: path.posix.join(config.assetsSubDirectory, './img/[name].[hash:7].[ext]'),
65 | },
66 | },
67 | {
68 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
69 | loader: 'url-loader',
70 | options: {
71 | limit: 10000,
72 | name: path.posix.join(config.assetsSubDirectory, './media/[name].[hash:7].[ext]'),
73 | },
74 | },
75 | {
76 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
77 | loader: 'url-loader',
78 | options: {
79 | limit: 10000,
80 | name: path.posix.join(config.assetsSubDirectory, './fonts/[name].[hash:7].[ext]'),
81 | },
82 | },
83 | ],
84 | },
85 | };
86 |
87 | module.exports = webpackConfig;
88 |
--------------------------------------------------------------------------------
/template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{ name }}",
3 | "description": "{{ description }}",
4 | "version": "1.0.0",
5 | "author": "{{ author }}",
6 | "private": true,
7 | "scripts": {
8 | "dev": "cross-env NODE_ENV=development NODE_APP_MODE=app webpack-dev-server --open --hot",
9 | "build": "cross-env NODE_ENV=production NODE_APP_MODE=app webpack --progress --hide-modules"{{#unit}},
10 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
11 | "test": "npm run unit"{{/unit}}{{#lint}},
12 | "lint": "eslint --ext .js,.vue src test/unit/specs"{{/lint}}
13 | },
14 | "dependencies": {
15 | "vue": "^2.4.2"{{#router}},
16 | "vue-router": "^2.7.0"{{/router}}
17 | },
18 | "devDependencies": {
19 | {{#axios}}
20 | "axios": "^0.16.2",
21 | {{/axios}}
22 | "babel-core": "^6.25.0",
23 | {{#lint}}
24 | "babel-eslint": "^7.2.3",
25 | {{/lint}}
26 | "babel-loader": "^7.1.1",
27 | "babel-preset-env": "^1.6.0",
28 | "compression-webpack-plugin": "^1.0.0",
29 | "copy-webpack-plugin": "^4.0.1",
30 | "cross-env": "^5.0.5",
31 | "css-loader": "^0.28.4",
32 | {{#lint}}
33 | "eslint": "^4.4.1",
34 | "eslint-loader": "^1.9.0",
35 | "eslint-friendly-formatter": "^3.0.0",
36 | "eslint-plugin-html": "^3.2.0",
37 | {{#if_eq lintConfig "airbnb"}}
38 | "eslint-config-airbnb-base": "^11.3.1",
39 | "eslint-import-resolver-webpack": "^0.8.3",
40 | "eslint-plugin-import": "^2.7.0",
41 | {{/if_eq}}
42 | {{/lint}}
43 | "extract-text-webpack-plugin": "^3.0.0",
44 | "file-loader": "^0.11.2",
45 | {{#ui}}
46 | {{#if_eq uiLibrary "foundation"}}
47 | "foundation-sites": "^6.4.2",
48 | {{/if_eq}}
49 | {{#if_eq uiLibrary "element"}}
50 | "element-ui": "^1.4.2",
51 | "babel-plugin-component": "^0.10.0",
52 | {{/if_eq}}
53 | {{/ui}}
54 | "friendly-errors-webpack-plugin": "^1.6.1",
55 | "html-webpack-plugin": "^2.30.1",
56 | {{#unit}}
57 | "karma": "^1.4.1",
58 | "karma-coverage": "^1.1.1",
59 | "karma-mocha": "^1.3.0",
60 | "karma-phantomjs-launcher": "^1.0.2",
61 | "karma-phantomjs-shim": "^1.4.0",
62 | "karma-sinon-chai": "^1.3.1",
63 | "karma-sourcemap-loader": "^0.3.7",
64 | "karma-spec-reporter": "0.0.31",
65 | "karma-webpack": "^2.0.2",
66 | "lolex": "^1.5.2",
67 | "mocha": "^3.2.0",
68 | "chai": "^3.5.0",
69 | "sinon": "^2.1.0",
70 | "sinon-chai": "^2.8.0",
71 | "inject-loader": "^3.0.0",
72 | "babel-plugin-istanbul": "^4.1.1",
73 | "phantomjs-prebuilt": "^2.1.14",
74 | {{/unit}}
75 | {{#lodash}}
76 | "lodash": "^4.17.4",
77 | "babel-plugin-lodash": "^3.2.11",
78 | "lodash-webpack-plugin": "^0.11.4",
79 | {{/lodash}}
80 | "node-sass": "^4.5.3",
81 | "optimize-css-assets-webpack-plugin": "^3.0.0",
82 | "sass-loader": "^6.0.6",
83 | "style-loader": "^0.18.2",
84 | "url-loader": "^0.5.9",
85 | "vue-loader": "^13.0.4",
86 | "vue-template-compiler": "^2.4.2",
87 | "webpack": "^3.5.4",
88 | "webpack-bundle-analyzer": "^2.9.0",
89 | "webpack-dev-server": "^2.7.1",
90 | "webpack-merge": "^4.1.0"
91 | },
92 | "engines": {
93 | "node": ">= 4.0.0",
94 | "npm": ">= 3.0.0"
95 | },
96 | "browserslist": [
97 | "> 1%",
98 | "last 2 versions",
99 | "not ie <= 8"
100 | ]
101 | }
102 |
--------------------------------------------------------------------------------
/meta.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "helpers": {
3 | "if_or": function (v1, v2, options) {
4 | if (v1 || v2) {
5 | return options.fn(this);
6 | }
7 |
8 | return options.inverse(this);
9 | }
10 | },
11 | "prompts": {
12 | "name": {
13 | "type": "string",
14 | "required": true,
15 | "message": "Project name"
16 | },
17 | "description": {
18 | "type": "string",
19 | "required": false,
20 | "message": "Project description",
21 | "default": "A Vue.js project"
22 | },
23 | "author": {
24 | "type": "string",
25 | "message": "Author"
26 | },
27 | "build": {
28 | "type": "list",
29 | "message": "Vue build",
30 | "choices": [
31 | {
32 | "name": "Runtime + Compiler: recommended for most users",
33 | "value": "standalone",
34 | "short": "standalone"
35 | },
36 | {
37 | "name": "Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are ONLY allowed in .vue files - render functions are required elsewhere",
38 | "value": "runtime",
39 | "short": "runtime"
40 | }
41 | ]
42 | },
43 | "router": {
44 | "type": "confirm",
45 | "message": "Install vue-router?"
46 | },
47 | "lint": {
48 | "type": "confirm",
49 | "message": "Use ESLint to lint your code?"
50 | },
51 | "lintConfig": {
52 | "when": "lint",
53 | "type": "list",
54 | "message": "Pick an ESLint preset",
55 | "choices": [
56 | {
57 | "name": "Airbnb (https://github.com/airbnb/javascript)",
58 | "value": "airbnb",
59 | "short": "Airbnb"
60 | },
61 | {
62 | "name": "none (configure it yourself)",
63 | "value": "none",
64 | "short": "none"
65 | }
66 | ]
67 | },
68 | "unit": {
69 | "type": "confirm",
70 | "message": "Setup unit tests with Karma + Mocha?"
71 | },
72 | "lodash": {
73 | "type": "confirm",
74 | "message": "Install lodash into the project?"
75 | },
76 | "axios": {
77 | "type": "confirm",
78 | "message": "Install axios into the project?"
79 | },
80 | "ui": {
81 | "type": "confirm",
82 | "message": "Use a UI library to help with basic styles and components?"
83 | },
84 | "uiLibrary": {
85 | "when": "ui",
86 | "type": "list",
87 | "message": "Pick a UI Library",
88 | "choices": [
89 | {
90 | "name": "Element - A Vue based component library (http://element.eleme.io/#/en-US)",
91 | "value": "element",
92 | "short": "Element"
93 | },
94 | {
95 | "name": "Foundation - Responsive front-end framework (http://foundation.zurb.com/)",
96 | "value": "foundation",
97 | "short": "Foundation"
98 | }
99 | ]
100 |
101 | }
102 | },
103 | "filters": {
104 | ".eslintrc.js": "lint",
105 | ".eslintignore": "lint",
106 | "test/unit/**/*": "unit",
107 | "build/webpack.testing.js": "unit",
108 | "src/router/**/*": "router"
109 | },
110 | "completeMessage": "To get started:\n\n {{^inPlace}}cd {{destDirName}}\n {{/inPlace}}npm install\n npm run dev\n\nDocumentation can be found at https://vuejs-templates.github.io/webpack"
111 | };
112 |
--------------------------------------------------------------------------------
/docs/static.md:
--------------------------------------------------------------------------------
1 | # Handling 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 an 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 | ### Getting Asset Paths in JavaScript
24 |
25 | In order for Webpack to return the correct asset paths, you need to use `require('./relative/path/to/file.jpg')`, which will get processed by `file-loader` and returns the resolved URL. For example:
26 |
27 | ``` js
28 | computed: {
29 | background () {
30 | return require('./bgs/' + this.id + '.jpg')
31 | }
32 | }
33 | ```
34 |
35 | **Note the above example will include every image under `./bgs/` in the final build.** This is because Webpack cannot guess which of them will be used at runtime, so it includes them all.
36 |
37 | ### "Real" Static Assets
38 |
39 | 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`.
40 |
41 | As an example, with the following default values:
42 |
43 | ``` js
44 | // config/index.js
45 | module.exports = {
46 | // ...
47 | build: {
48 | assetsPublicPath: '/',
49 | assetsSubDirectory: 'static'
50 | }
51 | }
52 | ```
53 |
54 | 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]`.
55 |
56 | We will learn more about the config file in the section about [backend integration](backend.md).
57 |
--------------------------------------------------------------------------------
/docs/structure.md:
--------------------------------------------------------------------------------
1 | # Project Structure
2 |
3 | ```bash
4 | .
5 | ├── build # webpack config files
6 | │ ├── webpack.base.js
7 | │ ├── webpack.development.js
8 | │ ├── webpack.production.js
9 | │ └── webpack.testing.js
10 | ├── config # main project config
11 | │ ├── config.app.js # contains app specific values. {app} can be any name eg - scroll, st
12 | │ ├── config.base.js # contains default values
13 | │ ├── config.development.js # contains values used in dev environment
14 | │ ├── config.production.js # conatins values used in prod environment
15 | │ └── index.js
16 | ├── dist
17 | ├── src
18 | │ ├── assets # module assets (processed by webpack)
19 | │ │ └── logo.png
20 | │ ├── js
21 | │ │ ├── components # ui components
22 | │ │ │ └── Hello.vue
23 | │ │ ├── router
24 | │ │ │ └── index.js
25 | │ │ ├── utils
26 | │ │ │ └── .gitkeep
27 | │ │ ├── views
28 | │ │ │ └── .gitkeep
29 | │ │ ├── App.vue # main app component
30 | │ │ └── main.js # app entry file
31 | │ └── scss
32 | │ └── style.scss
33 | ├── static # pure static assets (directly copied)
34 | │ └── .gitkeep
35 | ├── test
36 | │ └── unit # unit tests
37 | │ ├── specs
38 | │ │ └── Hello.spec.js # test spec files
39 | │ ├── .eslintrc
40 | │ ├── index.js # test build entry file
41 | │ └── karma.conf.js # test runner config file
42 | ├── .babelrc # babel config
43 | ├── .editorconfig # editor config
44 | ├── .eslintignore # config for ignored files and dirs for eslint
45 | ├── .eslintrc.js # eslint config
46 | ├── .gitignore
47 | ├── README.md
48 | ├── index.html # index.html template
49 | ├── package.json # build scripts and dependencies
50 | └── webpack.config.js # webpack config entry point
51 | ```
52 |
53 |
54 | ### `build/`
55 |
56 | 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.js`.
57 |
58 | ### `config/index.js`
59 |
60 | This is the main configuration file that exposes some of the most common configuration options for the build setup. It merges three different config files to give a unified configuration management based on the environaments and app modes.
61 |
62 | - baseConfig (`config.base.js`)
63 | - envConfig (`config.${env}.js` based on the environment (dev, prod) the app is running)
64 | - appConfig (`config.${appMode}.js` based on the appMode. This file can be renamed as per your app name like `config.app1.js` or added a new file for `config.app2.js`)
65 |
66 |
67 | ### `src/`
68 |
69 | 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).
70 |
71 | ### `static/`
72 |
73 | 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.
74 |
75 | See [Handling Static Assets](static.md) for more details.
76 |
77 | ### `test/unit`
78 |
79 | Contains unit test related files. See [Unit Testing](unit.md) for more details.
80 |
81 | ### `index.html`
82 |
83 | 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 be automatically injected into this template to render the final HTML.
84 |
85 | ### `package.json`
86 |
87 | The NPM package meta file that contains all the build dependencies and [build commands](commands.md).
88 |
--------------------------------------------------------------------------------
/template/build/webpack.production.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const config = require('../config');
3 | const webpack = require('webpack');
4 |
5 | const CopyWebpackPlugin = require('copy-webpack-plugin');
6 | const HtmlWebpackPlugin = require('html-webpack-plugin');
7 | const ExtractTextPlugin = require('extract-text-webpack-plugin');
8 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
9 | {{#lodash}}
10 | const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
11 | {{/lodash}}
12 |
13 | const webpackConfig = {
14 | devtool: '#source-map',
15 | module: {
16 | rules: [
17 | {
18 | test: /\.scss$/i,
19 | use: ExtractTextPlugin.extract({
20 | fallback: 'style-loader',
21 | // resolve-url-loader may be chained before sass-loader if necessary
22 | use: ['css-loader', 'sass-loader'],
23 | }),
24 | },
25 | {
26 | test: /\.css$/i,
27 | use: ExtractTextPlugin.extract({
28 | fallback: 'style-loader',
29 | use: 'css-loader',
30 | }),
31 | },
32 | ],
33 | },
34 | plugins: [
35 | new webpack.optimize.UglifyJsPlugin({
36 | sourceMap: true,
37 | output: {
38 | comments: false,
39 | },
40 | debug: false,
41 | compress: {
42 | warnings: false,
43 | dead_code: true,
44 | },
45 | }),
46 | {{#lodash}}
47 | new LodashModuleReplacementPlugin(),
48 | {{/lodash}}
49 | // extract css into its own file
50 | new ExtractTextPlugin({
51 | filename: './css/[name].[contenthash].css',
52 | }),
53 | // Compress extracted CSS. We are using this plugin so that possible
54 | // duplicated CSS from different components can be deduped.
55 | new OptimizeCSSPlugin({
56 | cssProcessorOptions: {
57 | safe: true,
58 | },
59 | }),
60 | // generate dist index.html with correct asset hash for caching.
61 | // you can customize output by editing /index.html
62 | // see https://github.com/ampedandwired/html-webpack-plugin
63 | new HtmlWebpackPlugin({
64 | filename: config.index,
65 | template: 'index.html',
66 | inject: true,
67 | minify: {
68 | removeComments: true,
69 | collapseWhitespace: true,
70 | removeAttributeQuotes: true,
71 | // more options:
72 | // https://github.com/kangax/html-minifier#options-quick-reference
73 | },
74 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
75 | chunksSortMode: 'dependency',
76 | }),
77 | // split vendor js into its own file
78 | new webpack.optimize.CommonsChunkPlugin({
79 | name: 'vendor',
80 | minChunks(module) {
81 | // any required modules inside node_modules are extracted to vendor
82 | return (
83 | module.resource && /\.js$/.test(module.resource) &&
84 | module.resource.indexOf(path.join(__dirname, '../node_modules')) === 0
85 | );
86 | },
87 | }),
88 | // extract webpack runtime and module manifest to its own file in order to
89 | // prevent vendor hash from being updated whenever app bundle is updated
90 | new webpack.optimize.CommonsChunkPlugin({
91 | name: 'manifest',
92 | chunks: ['vendor'],
93 | }),
94 | // copy custom static assets
95 | new CopyWebpackPlugin([
96 | {
97 | from: path.resolve(__dirname, '../static'),
98 | to: config.assetsSubDirectory,
99 | ignore: ['.*'],
100 | },
101 | ]),
102 | new webpack.LoaderOptionsPlugin({
103 | minimize: true,
104 | }),
105 | ],
106 | };
107 |
108 |
109 | if (config.productionGzip) {
110 | const CompressionWebpackPlugin = require('compression-webpack-plugin');
111 |
112 | webpackConfig.plugins.push(
113 | new CompressionWebpackPlugin({
114 | asset: '[path].gz[query]',
115 | algorithm: 'gzip',
116 | test: new RegExp(`\\.(${config.productionGzipExtensions.join('|')})$`),
117 | threshold: 10240,
118 | minRatio: 0.8,
119 | }));
120 | }
121 |
122 | if (config.bundleAnalyzerReport) {
123 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
124 | webpackConfig.plugins.push(new BundleAnalyzerPlugin());
125 | }
126 |
127 | module.exports = webpackConfig;
128 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-starter
2 |
3 | > A Vue.js starter kit that lets you focus on more programming and less configuration.
4 |
5 | > A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction.
6 |
7 | > This template is Vue 2.0 compatible.
8 |
9 |
10 | ## Why?
11 |
12 | At [Scroll.in](https://scroll.in), we have chosen Vue.js as our primary JS framework. So, while working on various Vue.js projects we felt like we needed a template for all our projects which can be used for better consistency and coding style across developers.
13 |
14 | We could always use the in built templates that come with vue-cli, but somehow I felt [webpack-simple](https://github.com/vuejs-templates/webpack-simple) was too simple and lacked certain necessary features to be opted as a standard boilerplate for our projects. On the other hand, [webpack](https://github.com/vuejs-templates/webpack-simple) seemed too complex to understand what's going on inside it specially for a junior dev it would be nightmare to make some config changes to it.
15 |
16 | This is why this project came to life. With certain decisions already made to make life easier for programmers and certain feature built in right out of the box.
17 |
18 | This project started as a webpack-simple template with incremental addition of features and configs to suit the needs of a medium to large vue.js project. It is inspired by the webpack template but without all the complexity.
19 |
20 |
21 | ## Documentation
22 |
23 | - [For this template](http://arkpod.in/vue-starter): common questions specific to this template are answered and each part is described in greater detail
24 | - [For Vue 2.0](http://vuejs.org/guide/): general information about how to work with Vue, not specific to this template
25 |
26 | ## Usage
27 |
28 | This is a project template for [vue-cli](https://github.com/vuejs/vue-cli). **It is recommended to use npm 3+ for a more efficient dependency tree.**
29 |
30 | ``` bash
31 | $ npm install -g vue-cli
32 | $ vue init rohitkrai03/vue-starter my-project
33 | $ cd my-project
34 | $ npm install
35 | $ npm run dev
36 | ```
37 |
38 | ## What's Included
39 |
40 | - `npm run dev`: first-in-class development experience.
41 | - Webpack + `vue-loader` for single file Vue components.
42 | - State preserving hot-reload
43 | - State preserving compilation error overlay
44 | - Lint-on-save with ESLint
45 | - Source maps
46 |
47 | - `npm run build`: Production ready build.
48 | - JavaScript minified with [UglifyJS](https://github.com/mishoo/UglifyJS2).
49 | - HTML minified with [html-minifier](https://github.com/kangax/html-minifier).
50 | - CSS across all components extracted into a single file and minified with [cssnano](https://github.com/ben-eb/cssnano).
51 | - 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.
52 | - Use `npm run build --report`to build with bundle size analytics.
53 |
54 | - `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).
55 | - Supports ES2015+ in test files.
56 | - Supports all webpack loaders.
57 | - Easy mock injection.
58 |
59 | - This boilerplate uses [ESLint](http://eslint.org/) as the linter, and uses the [eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb) preset with some small customizations.
60 |
61 | - Option to install and setup [vue-router](https://github.com/vuejs/vue-router)
62 |
63 | - Utilities like `lodash` and `axios` come installed out of the box. You can opt out while installing template from vue-cli as well. Also, webpack will be configured accordingly to make use of only the modules that are used and not the whole library to reduce bundle size.
64 |
65 | - An option to install a UI Library
66 | - [Element](http://element.eleme.io/#/en-US) A Vue 2.0 based component library for developers, designers and product managers. Also, configured to use only the required modules and components in the final bundle.
67 | - [Foundation](http://foundation.zurb.com/) A responsive front-end framework. Imported minified css file in index.html. Js file can be imported as per the need as well.
68 |
69 | - A converge like config management system which merges different config files based on environment and app mode.
70 |
71 | - A well defined folder structure for medium to large Vue.js projects.
72 |
73 |
74 | ### Fork It And Make Your Own
75 |
76 | You can fork this repo to create your own boilerplate, and use it with `vue-cli`:
77 |
78 | ``` bash
79 | vue init username/repo my-project
80 | ```
81 |
--------------------------------------------------------------------------------