├── .gitignore ├── README.md ├── circle.yml ├── deploy-docs.sh ├── docs ├── README.md ├── SUMMARY.md ├── backend.md ├── commands.md ├── e2e.md ├── env.md ├── linter.md ├── pre-processors.md ├── prerender.md ├── proxy.md ├── static.md ├── structure.md └── unit.md ├── meta.js ├── package.json ├── template ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build │ ├── build-lib.js │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ ├── webpack.lib.conf.js │ ├── webpack.prod.conf.js │ └── webpack.test.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── index-template.html ├── index.html ├── package.json ├── src │ ├── app.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── hello.vue │ ├── docs.js │ ├── lib.js │ ├── router │ │ └── index.js │ └── styles │ │ ├── app.scss │ │ ├── app.styl │ │ ├── lib.scss │ │ └── lib.styl ├── 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 └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | docs/_book 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-library-template 2 | 3 | > A [Vue-cli](https://github.com/vuejs/vue-cli) template based on the [Vuejs full-featured Webpack setup](http://vuejs-templates.github.io/webpack) with hot-reload, lint-on-save, unit testing & css extraction. 4 | > Adjusted for library development (ie. creating components to be imported into other projects via npm). 5 | > Includes docs site so you can release documentation online for your library. 6 | > This template is Vue 2.x compatible. 7 | 8 | Features: 9 | 10 | 1. Easily build your component and publish it for other people to include in their projects. 11 | 2. Optionally include: 12 | - Sass/SCSS 13 | - Stylus 14 | - Pug (Jade) 15 | - Buefy/Bulma 16 | 3. Easily build SPA for a docs/demo site to show off your library. (Works great for GitHub Pages) 17 | 4. Simultaneous package development: Build and write changes to disk when running dev-server. Useful for when you are developing packages simultaneously where one package depends on the other (using [npm link](https://docs.npmjs.com/cli/link)). 18 | 19 | ## Usage 20 | 21 | 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.** 22 | 23 | #### Run the Cli, Install Node_modules, and Start the Dev Server 24 | 25 | ``` bash 26 | $ npm install -g vue-cli 27 | $ vue init prograhammer/vue-library-template my-project 28 | $ cd my-project 29 | $ npm install 30 | $ npm run dev 31 | ``` 32 | 33 | If port 8080 is already in use on your machine you must change the port number in `/config/index.js`. Otherwise `npm run dev` will fail. 34 | 35 | #### Update Library Entry 36 | 37 | Let's suppose you created a component called **Hello** that you want other folks to use in their projects. Export your library using the entry point like this: 38 | 39 | */src/lib.js* 40 | ```javascript 41 | import Hello from './components/Hello' 42 | 43 | export default Hello // <-- you could also export more modules than just the default 44 | ``` 45 | 46 | #### Update Docs Site Entry 47 | 48 | This is your SPA entry point for your Docs website. Create some documentation pages for your library and make any changes you need here. 49 | 50 | */src/docs.js* 51 | ```javascript 52 | import Vue from 'vue' 53 | import App from './App' 54 | import router from './router' 55 | 56 | Vue.config.productionTip = false 57 | 58 | /* eslint-disable no-new */ 59 | new Vue({ 60 | el: '#app', 61 | router, 62 | render: h => h(App) 63 | }) 64 | ``` 65 | 66 | #### Update index-template.html 67 | 68 | This is your template for index.html. Add anything you need here that you want to show up in your built index.html. 69 | 70 | Note: The reason I've updated the configuration to use *index-template.html* instead of *index.html* is because 71 | GitHub Pages will look for the built index.html in your repo's root when you upload it. See the section 72 | [Don't Forget to Put your Docs Site Online](#dont-forget-to-put-your-docs-site-online) further down. 73 | 74 | #### Add externals 75 | 76 | If you are using certain dependencies (ie. Lodash, jQuery, etc.) that you think clients would more likely provide 77 | in their own project or in their site directly as a script globally (such as from a CDN) then you can use 78 | Webpack's externals configuration for this. You can [read more here](https://webpack.js.org/guides/author-libraries/#add-externals). 79 | 80 | #### Let's Build 81 | 82 | ``` bash 83 | $ npm build # This builds both your library and your docs/demo SPA. 84 | $ npm build:lib # This builds just your library. 85 | $ npm build:docs # This builds just your docs/demo SPA. 86 | ``` 87 | 88 | Check your */dist* folder and you'll see some output like this: 89 | 90 | ``` 91 | /dist 92 | /docs 93 | /css 94 | /js 95 | /lib 96 | hello.min.css 97 | hello.min.js 98 | ... 99 | ``` 100 | 101 | And in your *package.json* you'll notice: 102 | 103 | *package.json* 104 | 105 | ```json 106 | "main": "dist/lib/hello.min.js", 107 | ``` 108 | 109 | #### Publish! 110 | 111 | 1. If this is your first time publishing an npm package, you need to register a username/password with `npm adduser`. 112 | 2. Make sure the version number set in *package.json* is correct, as you won't be allowed to publish to a version number more than once. 113 | 3. Check https://www.npmjs.com/package/your-package-name-here where `your-package-name-here` is the the name you want to see is available. You'll get a nice 404 if the package name is not being used. 114 | 115 | Now just publish: 116 | 117 | ``` bash 118 | $ npm publish # Note: This will run npm build before publishing. See package.json prepublish (hook). 119 | ``` 120 | 121 | Your package is now both on NPM and the Unpkg CDN (https://unpkg.com/your-package-name-here). 122 | 123 | #### Import it to another Project 124 | 125 | If you've made your package public (via package.json `private:false`) then other developers can install it: 126 | 127 | ``` bash 128 | $ npm install hello --save-dev 129 | ``` 130 | 131 | Then just import anywhere, for example a Vue file: 132 | 133 | ```javascript 134 | import Hello from 'hello' // <-- hello is the name you gave to your project when you ran the CLI. 135 | import '~hello/dist/lib/hello.css' // <-- If your library has styles, you can import those too. 136 | 137 | export default { 138 | components: { Hello }, 139 | // ... 140 | 141 | ``` 142 | 143 | #### Don't Forget to Put your Docs Site Online 144 | 145 | The */dist/docs* folder contains your docs site. Don't forget to copy these files to your server or GitHub Pages where you can demo your library and show documentation for other's to see. For Github pages, go to your repo > Settings > GitHub Pages > Source > master branch (note: You should already have setup your own GitHub Pages github.io repo). This will look for `index.html` in your repo's root folder and configure it automatically so that `my-username.github.io/my-project/` will load your repo's docs site. 146 | 147 | #### You Can Work on Your Library at the Same Time You Work on Your Project 148 | 149 | See the *Simultaneous Package Development* section further down. 150 | 151 | Enjoy! 152 | 153 | ## What's Included 154 | 155 | - `prepublishOnly`: Npm prepublish hook so you can run `npm publish` and both your library and docs are built first. 156 | 157 | - `npm run dev`: Shortcut to run both dev:lib and dev:docs in parallel using [npm-run-all](https://github.com/mysticatea/npm-run-all). 158 | 159 | - `npm run dev:lib`: Runs webpack watch mode on your library so file changes are built and re-written to disk automatically (useful for [npm link](https://docs.npmjs.com/cli/link) situations). 160 | 161 | - `npm run dev:docs`: Runs both the development server for your docs/demo site. 162 | 163 | - `npm run build`: Shortcut to run both build:lib and build:docs. 164 | 165 | - `npm run build:lib`: Production ready build of your library as an ES6 module (via UMD), ready to import into another project via npm. 166 | 167 | - `npm run build:docs`: Production ready build of your docs site for your library. Put this build online so you can demo your library to the world and provide documentation. 168 | 169 | ## What's So Different from the Vue-cli Webpack Template 170 | 171 | #### package.json 172 | 173 | A few changes oriented more towards OSS library development: 174 | 175 | ```json 176 | "version": "0.0.1", 177 | "private": false, 178 | "license": "MIT", 179 | ``` 180 | 181 | #### webpack.lib.conf.js 182 | 183 | Configuration to build a library from your library entry: 184 | 185 | ```javascript 186 | baseWebpackConfig.entry = { 187 | '{{ name }}': './src/lib.js' 188 | } 189 | 190 | var webpackConfig = merge(baseWebpackConfig, { 191 | output: { 192 | path: config.build.assetsRoot, 193 | filename: utils.assetsLibPath('[name].min.js'), 194 | library: '[name]', 195 | libraryTarget: 'umd' 196 | }, 197 | 198 | //... 199 | ``` 200 | 201 | #### Add Vue Recommendations to the Default Linter Standard 202 | 203 | The [Vue Eslint Plugin](https://github.com/vuejs/eslint-plugin-vue) now comes with the recommended rules configuration included that you can add to whatever rules you are using (ie. Standard). Since this seems to be the most typical way to develop in Vue, I've added this plugin along with the Standard linter option (default). 204 | 205 | **Update:** The plugin [does not yet work with templates other than HTML](https://github.com/vuejs/eslint-plugin-vue/issues/165). So for now, I've reverted it back 206 | to the setup used in Vue's official Webpack template (which this template is forked from). 207 | 208 | #### Stylus, Pug, Bulma 209 | 210 | In the Cli, you can choose to also include Stylus, Pug (formally Jade), and Buefy (A light Vue UI components framework that uses the popular Bulma CSS/SASS-only UI framework) which is helpful for building your demo/docs site). 211 | 212 | #### docs.js 213 | 214 | The entry point has been changed from */src/main.js* to */src/docs.js* because the SPA you are releasing is your docs site. 215 | 216 | Note: Your library and vendors are chunked out from your docs into separate files and included in the *index.html* file automatically. This should give a little more flexibility to improve caching on your docs/demo website. 217 | 218 | #### Vue build default 219 | 220 | In the Cli, switches the default to be the smaller Runtime build since most people don't reference templates outside of .vue files. (So you can just press 'Enter' key for 'yes') 221 | 222 | #### Simultaneous Package Development 223 | 224 | In many instances you are working on a library and are likely to be writing it for a bigger parent project you are simultaneously working on. Using webpack's watch mode, we can write/build files to disk while running the dev server. First connect your packages using [npm link](https://docs.npmjs.com/cli/link) then do `npm run dev`. Notice each time you make a change to your library, the */dist/lib* folder get's updated with the new build. If you are simultaneously running the dev server in your parent project (don't forget, check *config/index.js* to ensure projects are on different ports!) then you'll notice the changes take effect immediately across packages. 225 | 226 | Here's where watch is activated: 227 | 228 | *package.json* 229 | 230 | "scripts": { 231 | // ... 232 | 233 | "dev": "npm-run-all --parallel dev:lib dev:docs", 234 | "dev:lib": "webpack --config build/webpack.lib.conf.js --watch --progress --hide-modules", // <-- watch flag added 235 | "dev:docs": "node build/dev-server.js", 236 | 237 | You'll notice we are using [npm-run-all](https://github.com/mysticatea/npm-run-all) to run the dev-server and webpack watch npm scripts in parallel 238 | (and it's cross-platform). You could also look into Webpack's multi-compiler mode example: 239 | https://github.com/webpack/webpack/tree/master/examples/multi-compiler. 240 | 241 | #### index-template.html instead of index.html 242 | 243 | Since GitHub wants the built index.html to reside in the repo's root, we'll need to using another file for the template. Use the file 244 | *index-template.html* instead. (We updated the *HtmlWebpackPlugin* configuration in *webpack.dev.conf.js* and *webpack.prod.conf.js* to look 245 | for the template file named *index-template.html*) 246 | 247 | #### Some Additional Meta Tags 248 | 249 | These additional meta tags are included in your *index-template.html*: 250 | 251 | 252 | 253 | 254 | #### Removed */dist* from .gitignore 255 | 256 | The `dist` folder is removed from .gitignore so that it's available on npm (unless you create a separate .npmignore) and user's who want the minified built distribution of your library can grab it (located in `/lib` subfolder). Also your docs site built distribution is made available in the same folder (located in `/docs` subfolder). 257 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 6 4 | 5 | test: 6 | override: 7 | - bash test.sh 8 | -------------------------------------------------------------------------------- /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 | This boilerplate is targeted towards large, serious projects and assumes you are somewhat familiar with Webpack and `vue-loader`. Make sure to also read [`vue-loader`'s documentation](http://vuejs.github.io/vue-loader/index.html) for common workflow recipes. 4 | 5 | If you just want to try out `vue-loader` or whip out a quick prototype, use the [webpack-simple](https://github.com/vuejs-templates/webpack-simple) template instead. 6 | 7 | ## Quickstart 8 | 9 | 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.** 10 | 11 | ``` bash 12 | $ npm install -g vue-cli 13 | $ vue init webpack my-project 14 | $ cd my-project 15 | $ npm install 16 | $ npm run dev 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [Project Structure](structure.md) 4 | - [Build Commands](commands.md) 5 | - [Linter Configuration](linter.md) 6 | - [Pre-Processors](pre-processors.md) 7 | - [Handling Static Assets](static.md) 8 | - [Environment Variables](env.md) 9 | - [Integrate with Backend Framework](backend.md) 10 | - [API Proxying During Development](proxy.md) 11 | - [Unit Testing](unit.md) 12 | - [End-to-end Testing](e2e.md) 13 | - [Prerendering for SEO](prerender.md) 14 | -------------------------------------------------------------------------------- /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/index.js` to directly generate front-end assets into your backend project. 4 | 5 | Let's take a look at the default `config/index.js`: 6 | 7 | ``` js 8 | // config/index.js 9 | var path = require('path') 10 | 11 | module.exports = { 12 | build: { 13 | index: path.resolve(__dirname, 'dist/index.html'), 14 | assetsRoot: path.resolve(__dirname, 'dist'), 15 | assetsSubDirectory: 'static', 16 | assetsPublicPath: '/', 17 | productionSourceMap: true 18 | }, 19 | dev: { 20 | port: 8080, 21 | proxyTable: {} 22 | } 23 | } 24 | ``` 25 | 26 | Inside the `build` section, we have the following options: 27 | 28 | ### `build.index` 29 | 30 | > Must be an absolute path on your local file system. 31 | 32 | This is where the `index.html` (with injected asset URLs) will be generated. 33 | 34 | 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. 35 | 36 | ### `build.assetsRoot` 37 | 38 | > Must be an absolute path on your local file system. 39 | 40 | This should point to the root directory that contains all the static assets for your app. For example, `public/` for both Rails/Laravel. 41 | 42 | ### `build.assetsSubDirectory` 43 | 44 | 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`. 45 | 46 | This directory will be cleaned before each build, so it should only contain assets generated by the build. 47 | 48 | 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. 49 | 50 | ### `build.assetsPublicPath` 51 | 52 | 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`. 53 | 54 | ### `build.productionSourceMap` 55 | 56 | Whether to generate source maps for production build. 57 | 58 | ### `dev.port` 59 | 60 | Specify the port for the dev server to listen to. 61 | 62 | ### `dev.proxyTable` 63 | 64 | Define proxy rules for the dev server. See [API Proxying During Development](proxy.md) for more details. 65 | -------------------------------------------------------------------------------- /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 | 24 | ### `npm run unit` 25 | 26 | > Run unit tests in PhantomJS with [Karma](https://karma-runner.github.io/). See [Unit Testing](unit.md) for more details. 27 | 28 | - Supports ES2015+ in test files. 29 | - Supports all webpack loaders. 30 | - Easy [mock injection](http://vuejs.github.io/vue-loader/en/workflow/testing-with-mocks.html). 31 | 32 | ### `npm run e2e` 33 | 34 | > Run end-to-end tests with [Nightwatch](http://nightwatchjs.org/). See [End-to-end Testing](e2e.md) for more details. 35 | 36 | - Run tests in multiple browsers in parallel. 37 | - Works with one command out of the box: 38 | - Selenium and chromedriver dependencies automatically handled. 39 | - Automatically spawns the Selenium server. 40 | -------------------------------------------------------------------------------- /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 | Your 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/env.md: -------------------------------------------------------------------------------- 1 | # Environment Variables 2 | 3 | Sometimes it is practical to have different config values according to the environment that the application is running in. 4 | 5 | As an example: 6 | 7 | ```js 8 | // config/prod.env.js 9 | module.exports = { 10 | NODE_ENV: '"production"', 11 | DEBUG_MODE: false, 12 | API_KEY: '"..."' // this is shared between all environments 13 | } 14 | 15 | // config/dev.env.js 16 | module.exports = merge(prodEnv, { 17 | NODE_ENV: '"development"', 18 | DEBUG_MODE: true // this overrides the DEBUG_MODE value of prod.env 19 | }) 20 | 21 | // config/test.env.js 22 | module.exports = merge(devEnv, { 23 | NODE_ENV: '"testing"' 24 | }) 25 | ``` 26 | 27 | > **Note:** string variables need to be wrapped into single and double quotes `'"..."'` 28 | 29 | So, the environment variables are: 30 | - Production 31 | - NODE_ENV = 'production', 32 | - DEBUG_MODE = false, 33 | - API_KEY = '...' 34 | - Development 35 | - NODE_ENV = 'development', 36 | - DEBUG_MODE = true, 37 | - API_KEY = '...' 38 | - Testing 39 | - NODE_ENV = 'testing', 40 | - DEBUG_MODE = true, 41 | - API_KEY = '...' 42 | 43 | As we can see, `test.env` inherits the `dev.env` and the `dev.env` inherits the `prod.env`. 44 | 45 | ### Usage 46 | 47 | It is simple to use the environment variables in your code. For example: 48 | 49 | ```js 50 | Vue.config.debug = process.env.DEBUG_MODE 51 | ``` -------------------------------------------------------------------------------- /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 and the [Vue](https://github.com/vuejs/eslint-plugin-vue) plugin/preset. 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 | // .eslintrc.js 11 | "semi": [2, "always"] 12 | ``` 13 | 14 | 2. Pick a different ESLint preset when generating the project, for example [eslint-config-airbnb](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb). 15 | 16 | 3. Pick "none" for ESLint preset when generating the project and define your own rules. See [ESLint documentation](http://eslint.org/docs/rules/) for more details. -------------------------------------------------------------------------------- /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/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 | 5 | ## Using `prerender-spa-plugin` 6 | 7 | 1. Install it as a dev dependency: 8 | 9 | ```bash 10 | npm install --save-dev prerender-spa-plugin 11 | ``` 12 | 13 | 2. Require it in **build/webpack.prod.conf.js**: 14 | 15 | ```js 16 | // This line should go at the top of the file where other 'imports' live in 17 | var PrerenderSpaPlugin = require('prerender-spa-plugin') 18 | ``` 19 | 20 | 3. Configure it in the `plugins` array (also in **build/webpack.prod.conf.js**): 21 | 22 | ```js 23 | new PrerenderSpaPlugin( 24 | // Path to compiled app 25 | path.join(__dirname, '../dist'), 26 | // List of endpoints you wish to prerender 27 | [ '/' ] 28 | ) 29 | ``` 30 | 31 | If you also wanted to prerender `/about` and `/contact`, then that array would be `[ '/', '/about', '/contact' ]`. 32 | 33 | 4. Enable history mode for `vue-router`: 34 | ```js 35 | const router = new VueRouter({ 36 | mode: 'history', 37 | routes: [...] 38 | }) 39 | ``` 40 | -------------------------------------------------------------------------------- /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/index.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/index.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 | 28 | ## URL Matching 29 | 30 | In addition to static urls you can also use glob patterns to match URLs, e.g. `/api/**`. See [Context Matching](https://github.com/chimurai/http-proxy-middleware#context-matching) for more details. In addition, you can provide a `filter` option that can be a custom function to determine whether a request should be proxied: 31 | 32 | ``` js 33 | proxyTable: { 34 | '**': { 35 | target: 'http://jsonplaceholder.typicode.com', 36 | filter: function (pathname, req) { 37 | return pathname.match('^/api') && req.method === 'GET' 38 | } 39 | } 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /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 | │ └── ... 7 | ├── config/ 8 | │   ├── index.js # main project config 9 | │ └── ... 10 | ├── src/ 11 | │   ├── main.js # app entry file 12 | │   ├── App.vue # main app component 13 | │   ├── components/ # ui components 14 | │   │   └── ... 15 | │   └── assets/ # module assets (processed by webpack) 16 | │      └── ... 17 | ├── static/ # pure static assets (directly copied) 18 | ├── test/ 19 | │ └── unit/ # unit tests 20 | │ │   ├── specs/ # test spec files 21 | │ │   ├── index.js # test build entry file 22 | │ │   └── karma.conf.js # test runner config file 23 | │ └── e2e/ # e2e tests 24 | │ │   ├── specs/ # test spec files 25 | │ │   ├── custom-assertions/ # custom assertions for e2e tests 26 | │ │   ├── runner.js # test runner script 27 | │ │   └── nightwatch.conf.js # test runner config file 28 | ├── .babelrc # babel config 29 | ├── .postcssrc.js # postcss config 30 | ├── .eslintrc.js # eslint config 31 | ├── .editorconfig # editor config 32 | ├── index.html # index.html template 33 | └── package.json # build scripts and dependencies 34 | ``` 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 | ### `config/index.js` 41 | 42 | 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. 43 | 44 | ### `src/` 45 | 46 | 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). 47 | 48 | ### `static/` 49 | 50 | 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. 51 | 52 | See [Handling Static Assets](static.md) for more details. 53 | 54 | ### `test/unit` 55 | 56 | Contains unit test related files. See [Unit Testing](unit.md) for more details. 57 | 58 | ### `test/e2e` 59 | 60 | Contains e2e test related files. See [End-to-end Testing](e2e.md) for more details. 61 | 62 | ### `index.html` 63 | 64 | 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. 65 | 66 | ### `package.json` 67 | 68 | The NPM package meta file that contains all the build dependencies and [build commands](commands.md). 69 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | "camelcase": str => { 11 | const capitalize = str => str.charAt(0).toUpperCase() + str.toLowerCase().slice(1) 12 | let string = str.toLowerCase().replace(/[^A-Za-z0-9]/g, ' ').split(' ') 13 | .reduce((result, word) => result + capitalize(word.toLowerCase())) 14 | return string.charAt(0).toLowerCase() + string.slice(1) 15 | } 16 | }, 17 | "prompts": { 18 | "name": { 19 | "type": "string", 20 | "required": true, 21 | "message": "Project name" 22 | }, 23 | "description": { 24 | "type": "string", 25 | "required": false, 26 | "message": "Project description", 27 | "default": "A Vue.js project" 28 | }, 29 | "author": { 30 | "type": "string", 31 | "message": "Author" 32 | }, 33 | "build": { 34 | "type": "list", 35 | "message": "Vue build", 36 | "choices": [ 37 | { 38 | "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", 39 | "value": "runtime", 40 | "short": "runtime" 41 | }, 42 | { 43 | "name": "Runtime + Compiler: recommended for most users", 44 | "value": "standalone", 45 | "short": "standalone" 46 | } 47 | ] 48 | }, 49 | "router": { 50 | "type": "confirm", 51 | "message": "Install vue-router?" 52 | }, 53 | "lint": { 54 | "type": "confirm", 55 | "message": "Use ESLint to lint your code?" 56 | }, 57 | "lintConfig": { 58 | "when": "lint", 59 | "type": "list", 60 | "message": "Pick an ESLint preset", 61 | "choices": [ 62 | { 63 | "name": "Standard with Vue Recommendations (https://github.com/feross/standard)", 64 | "value": "standard", 65 | "short": "Standard" 66 | }, 67 | { 68 | "name": "Airbnb (https://github.com/airbnb/javascript)", 69 | "value": "airbnb", 70 | "short": "Airbnb" 71 | }, 72 | { 73 | "name": "none (configure it yourself)", 74 | "value": "none", 75 | "short": "none" 76 | } 77 | ] 78 | }, 79 | "buefy": { 80 | "type": "confirm", 81 | "message": "Install Buefy, a lightweight Vue UI framework with Bulma, useful for your demo/docs pages (will also add a material design icons cdn link to your index.html)?" 82 | }, 83 | "sass": { 84 | "type": "confirm", 85 | "message": "Install Sass/SCSS (Note: Buefy needs this)?" 86 | }, 87 | "stylus": { 88 | "type": "confirm", 89 | "message": "Install Stylus (Note: You'll need to additionally install it globally for Sublime yourself)?" 90 | }, 91 | "pug": { 92 | "type": "confirm", 93 | "message": "Install Pug (formally Jade) for cleaner templates in your .vue files?" 94 | }, 95 | "unit": { 96 | "type": "confirm", 97 | "message": "Setup unit tests with Karma + Mocha?" 98 | }, 99 | "e2e": { 100 | "type": "confirm", 101 | "message": "Setup e2e tests with Nightwatch?" 102 | } 103 | }, 104 | "filters": { 105 | ".eslintrc.js": "lint", 106 | ".eslintignore": "lint", 107 | "config/test.env.js": "unit || e2e", 108 | "test/unit/**/*": "unit", 109 | "build/webpack.test.conf.js": "unit", 110 | "test/e2e/**/*": "e2e", 111 | "src/router/**/*": "router", 112 | "src/styles/app.scss": "sass", 113 | "src/styles/app.styl": "stylus" 114 | }, 115 | "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" 116 | }; 117 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-library-template", 3 | "version": "2.0.0", 4 | "license": "MIT", 5 | "description": "A fork of the Vue-cli webpack template, but adjusted for library (with docs site) development.", 6 | "scripts": { 7 | "docs": "cd docs && gitbook serve", 8 | "docs:deploy": "bash ./deploy-docs.sh" 9 | }, 10 | "devDependencies": { 11 | "vue-cli": "^2.8.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /template/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /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/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /template/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | {{#if_eq lintConfig "standard"}} 13 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 14 | extends: 'standard', 15 | {{/if_eq}} 16 | {{#if_eq lintConfig "airbnb"}} 17 | extends: 'airbnb-base', 18 | {{/if_eq}} 19 | // required to lint *.vue files 20 | plugins: [ 21 | 'html' 22 | ], 23 | {{#if_eq lintConfig "airbnb"}} 24 | // check if imports actually resolve 25 | 'settings': { 26 | 'import/resolver': { 27 | 'webpack': { 28 | 'config': 'build/webpack.base.conf.js' 29 | } 30 | } 31 | }, 32 | {{/if_eq}} 33 | // add your custom rules here 34 | 'rules': { 35 | {{#if_eq lintConfig "standard"}} 36 | // allow paren-less arrow functions 37 | 'arrow-parens': 0, 38 | // allow async-await 39 | 'generator-star-spacing': 0, 40 | {{/if_eq}} 41 | {{#if_eq lintConfig "airbnb"}} 42 | // don't require .vue extension when importing 43 | 'import/extensions': ['error', 'always', { 44 | 'js': 'never', 45 | 'vue': 'never' 46 | }], 47 | // allow optionalDependencies 48 | 'import/no-extraneous-dependencies': ['error', { 49 | 'optionalDependencies': ['test/unit/index.js'] 50 | }], 51 | {{/if_eq}} 52 | // allow debugger during development 53 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 54 | } 55 | } -------------------------------------------------------------------------------- /template/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | {{#unit}} 7 | test/unit/coverage 8 | {{/unit}} 9 | {{#e2e}} 10 | test/e2e/reports 11 | selenium-debug.log 12 | {{/e2e}} 13 | 14 | # Editor directories and files 15 | .idea 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | -------------------------------------------------------------------------------- /template/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /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 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | {{#unit}} 20 | 21 | # run unit tests 22 | npm run unit 23 | {{/unit}} 24 | {{#e2e}} 25 | 26 | # run e2e tests 27 | npm run e2e 28 | {{/e2e}} 29 | {{#if_or unit e2e}} 30 | 31 | # run all tests 32 | npm test 33 | {{/if_or}} 34 | ``` 35 | 36 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 37 | -------------------------------------------------------------------------------- /template/build/build-lib.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.lib.conf') 12 | 13 | var spinner = ora('building for library...') 14 | spinner.start() 15 | 16 | rm(path.join(config.lib.assetsRoot, config.lib.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: Now you are ready to publish your library to npm.\n' + 32 | ' Then users can import it as an es6 module: import {{camelcase name}} from \'{{ name }}\'\n' 33 | )) 34 | }) 35 | }) -------------------------------------------------------------------------------- /template/build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /template/build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /template/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /template/build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = {{#if_or unit e2e}}process.env.NODE_ENV === 'testing' 14 | ? require('./webpack.prod.conf') 15 | : {{/if_or}}require('./webpack.dev.conf') 16 | 17 | // default port where dev server listens for incoming traffic 18 | var port = process.env.PORT || config.dev.port 19 | // automatically open browser, if not set will be false 20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 21 | // Define HTTP proxies to your custom API backend 22 | // https://github.com/chimurai/http-proxy-middleware 23 | var proxyTable = config.dev.proxyTable 24 | 25 | var app = express() 26 | var compiler = webpack(webpackConfig) 27 | 28 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 29 | publicPath: webpackConfig.output.publicPath, 30 | quiet: true 31 | }) 32 | 33 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 34 | log: () => {}, 35 | heartbeat: 2000 36 | }) 37 | // force page reload when html-webpack-plugin template changes 38 | compiler.plugin('compilation', function (compilation) { 39 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 40 | hotMiddleware.publish({ action: 'reload' }) 41 | cb() 42 | }) 43 | }) 44 | 45 | // proxy api requests 46 | Object.keys(proxyTable).forEach(function (context) { 47 | var options = proxyTable[context] 48 | if (typeof options === 'string') { 49 | options = { target: options } 50 | } 51 | app.use(proxyMiddleware(options.filter || context, options)) 52 | }) 53 | 54 | // handle fallback for HTML5 history API 55 | app.use(require('connect-history-api-fallback')()) 56 | 57 | // serve webpack bundle output 58 | app.use(devMiddleware) 59 | 60 | // enable hot-reload and state-preserving 61 | // compilation error display 62 | app.use(hotMiddleware) 63 | 64 | // serve pure static assets 65 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 66 | app.use(staticPath, express.static('./static')) 67 | 68 | var uri = 'http://localhost:' + port 69 | 70 | var _resolve 71 | var readyPromise = new Promise(resolve => { 72 | _resolve = resolve 73 | }) 74 | 75 | console.log('> Starting dev server...') 76 | devMiddleware.waitUntilValid(() => { 77 | console.log('> Listening at ' + uri + '\n') 78 | // when env is testing, don't need open it 79 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 80 | opn(uri) 81 | } 82 | _resolve() 83 | }) 84 | 85 | var server = app.listen(port) 86 | 87 | module.exports = { 88 | ready: readyPromise, 89 | close: () => { 90 | server.close() 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /template/build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.assetsLibPath = function (_path) { 13 | return path.posix.join(config.lib.assetsSubDirectory, _path) 14 | } 15 | 16 | exports.cssLoaders = function (options) { 17 | options = options || {} 18 | 19 | var cssLoader = { 20 | loader: 'css-loader', 21 | options: { 22 | minimize: process.env.NODE_ENV === 'production', 23 | sourceMap: options.sourceMap 24 | } 25 | } 26 | 27 | // generate loader string to be used with extract text plugin 28 | function generateLoaders (loader, loaderOptions) { 29 | var loaders = [cssLoader] 30 | if (loader) { 31 | loaders.push({ 32 | loader: loader + '-loader', 33 | options: Object.assign({}, loaderOptions, { 34 | sourceMap: options.sourceMap 35 | }) 36 | }) 37 | } 38 | 39 | // Extract CSS when that option is specified 40 | // (which is the case during production build) 41 | if (options.extract) { 42 | return ExtractTextPlugin.extract({ 43 | use: loaders, 44 | fallback: 'vue-style-loader' 45 | }) 46 | } else { 47 | return ['vue-style-loader'].concat(loaders) 48 | } 49 | } 50 | 51 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 52 | return { 53 | css: generateLoaders(), 54 | postcss: generateLoaders(), 55 | less: generateLoaders('less'), 56 | sass: generateLoaders('sass', { indentedSyntax: true }), 57 | scss: generateLoaders('sass'), 58 | stylus: generateLoaders('stylus'), 59 | styl: generateLoaders('stylus') 60 | } 61 | } 62 | 63 | // Generate loaders for standalone style files (outside of .vue) 64 | exports.styleLoaders = function (options) { 65 | var output = [] 66 | var loaders = exports.cssLoaders(options) 67 | for (var extension in loaders) { 68 | var loader = loaders[extension] 69 | output.push({ 70 | test: new RegExp('\\.' + extension + '$'), 71 | use: loader 72 | }) 73 | } 74 | return output 75 | } 76 | -------------------------------------------------------------------------------- /template/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }), 12 | transformToRequire: { 13 | video: 'src', 14 | source: 'src', 15 | img: 'src', 16 | image: 'xlink:href' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /template/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | docs: './src/docs.js', 13 | ['{{ name }}']: './src/lib.js' 14 | }, 15 | output: { 16 | path: config.build.assetsRoot, 17 | filename: '[name].js', 18 | publicPath: process.env.NODE_ENV === 'production' 19 | ? config.build.assetsPublicPath 20 | : config.dev.assetsPublicPath 21 | }, 22 | resolve: { 23 | extensions: ['.js', '.vue', '.json'], 24 | alias: { 25 | {{#if_eq build "standalone"}} 26 | 'vue$': 'vue/dist/vue.esm.js', 27 | {{/if_eq}} 28 | '@': resolve('src') 29 | } 30 | }, 31 | module: { 32 | rules: [ 33 | {{#lint}} 34 | { 35 | test: /\.(js|vue)$/, 36 | loader: 'eslint-loader', 37 | enforce: 'pre', 38 | include: [resolve('src'), resolve('test')], 39 | options: { 40 | formatter: require('eslint-friendly-formatter') 41 | } 42 | }, 43 | {{/lint}} 44 | { 45 | test: /\.vue$/, 46 | loader: 'vue-loader', 47 | options: vueLoaderConfig 48 | }, 49 | { 50 | test: /\.js$/, 51 | loader: 'babel-loader', 52 | include: [resolve('src'), resolve('test')] 53 | }, 54 | { 55 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 56 | loader: 'url-loader', 57 | options: { 58 | limit: 10000, 59 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 60 | } 61 | }, 62 | { 63 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 64 | loader: 'url-loader', 65 | options: { 66 | limit: 10000, 67 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 68 | } 69 | }, 70 | { 71 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 72 | loader: 'url-loader', 73 | options: { 74 | limit: 10000, 75 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 76 | } 77 | } 78 | ] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /template/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index-template.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /template/build/webpack.lib.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 8 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 9 | 10 | var env = {{#if_or unit e2e}}process.env.NODE_ENV === 'testing' 11 | ? require('../config/test.env') 12 | : {{/if_or}}config.lib.env 13 | 14 | baseWebpackConfig.entry = { 15 | '{{ name }}': './src/lib.js' 16 | } 17 | 18 | var webpackConfig = merge(baseWebpackConfig, { 19 | module: { 20 | rules: utils.styleLoaders({ 21 | sourceMap: config.lib.productionSourceMap, 22 | extract: true 23 | }) 24 | }, 25 | devtool: config.lib.productionSourceMap ? '#source-map' : false, 26 | output: { 27 | path: config.lib.assetsRoot, 28 | filename: utils.assetsLibPath('[name].min.js'), 29 | library: '[name]', 30 | libraryTarget: 'umd' 31 | }, 32 | plugins: [ 33 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 34 | new webpack.DefinePlugin({ 35 | 'process.env': env 36 | }), 37 | new webpack.optimize.UglifyJsPlugin({ 38 | compress: { 39 | warnings: false 40 | }, 41 | sourceMap: true 42 | }), 43 | // extract css into its own file 44 | new ExtractTextPlugin({ 45 | filename: utils.assetsLibPath('[name].min.css') 46 | }), 47 | // Compress extracted CSS. We are using this plugin so that possible 48 | // duplicated CSS from different components can be deduped. 49 | new OptimizeCSSPlugin({ 50 | cssProcessorOptions: { 51 | safe: true 52 | } 53 | }) 54 | ] 55 | }) 56 | 57 | if (config.lib.productionGzip) { 58 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 59 | 60 | webpackConfig.plugins.push( 61 | new CompressionWebpackPlugin({ 62 | asset: '[path].gz[query]', 63 | algorithm: 'gzip', 64 | test: new RegExp( 65 | '\\.(' + 66 | config.lib.productionGzipExtensions.join('|') + 67 | ')$' 68 | ), 69 | threshold: 10240, 70 | minRatio: 0.8 71 | }) 72 | ) 73 | } 74 | 75 | if (config.lib.bundleAnalyzerReport) { 76 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 77 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 78 | } 79 | 80 | module.exports = webpackConfig 81 | -------------------------------------------------------------------------------- /template/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var CopyWebpackPlugin = require('copy-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 11 | 12 | var env = {{#if_or unit e2e}}process.env.NODE_ENV === 'testing' 13 | ? require('../config/test.env') 14 | : {{/if_or}}config.build.env 15 | 16 | var webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true 21 | }) 22 | }, 23 | devtool: config.build.productionSourceMap ? '#source-map' : false, 24 | output: { 25 | path: config.build.assetsRoot, 26 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | }, 38 | sourceMap: true 39 | }), 40 | // extract css into its own file 41 | new ExtractTextPlugin({ 42 | filename: utils.assetsPath('css/[name].[contenthash].css') 43 | }), 44 | // Compress extracted CSS. We are using this plugin so that possible 45 | // duplicated CSS from different components can be deduped. 46 | new OptimizeCSSPlugin({ 47 | cssProcessorOptions: { 48 | safe: true 49 | } 50 | }), 51 | // generate dist index.html with correct asset hash for caching. 52 | // you can customize output by editing /index.html 53 | // see https://github.com/ampedandwired/html-webpack-plugin 54 | new HtmlWebpackPlugin({ 55 | filename: {{#if_or unit e2e}}process.env.NODE_ENV === 'testing' 56 | ? 'index.html' 57 | : {{/if_or}}config.build.index, 58 | template: 'index-template.html', 59 | inject: true, 60 | minify: { 61 | removeComments: true, 62 | collapseWhitespace: true, 63 | removeAttributeQuotes: true 64 | // more options: 65 | // https://github.com/kangax/html-minifier#options-quick-reference 66 | }, 67 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 68 | chunksSortMode: 'dependency' 69 | }), 70 | // split your library css/js into separate files 71 | new webpack.optimize.CommonsChunkPlugin({ 72 | name: '{{ name }}' 73 | }), 74 | // split vendor js into its own file 75 | new webpack.optimize.CommonsChunkPlugin({ 76 | name: 'vendor', 77 | minChunks: function (module, count) { 78 | // any required modules inside node_modules are extracted to vendor 79 | return ( 80 | module.resource && 81 | /\.js$/.test(module.resource) && 82 | module.resource.indexOf( 83 | path.join(__dirname, '../node_modules') 84 | ) === 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.build.assetsSubDirectory, 99 | ignore: ['.*'] 100 | } 101 | ]) 102 | ] 103 | }) 104 | 105 | if (config.build.productionGzip) { 106 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 107 | 108 | webpackConfig.plugins.push( 109 | new CompressionWebpackPlugin({ 110 | asset: '[path].gz[query]', 111 | algorithm: 'gzip', 112 | test: new RegExp( 113 | '\\.(' + 114 | config.build.productionGzipExtensions.join('|') + 115 | ')$' 116 | ), 117 | threshold: 10240, 118 | minRatio: 0.8 119 | }) 120 | ) 121 | } 122 | 123 | if (config.build.bundleAnalyzerReport) { 124 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 125 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 126 | } 127 | 128 | module.exports = webpackConfig 129 | -------------------------------------------------------------------------------- /template/build/webpack.test.conf.js: -------------------------------------------------------------------------------- 1 | // This is the webpack config used for unit tests. 2 | 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseConfig = require('./webpack.base.conf') 7 | 8 | var webpackConfig = merge(baseConfig, { 9 | // use inline sourcemap for karma-sourcemap-loader 10 | module: { 11 | rules: utils.styleLoaders() 12 | }, 13 | devtool: '#inline-source-map', 14 | resolveLoader: { 15 | alias: { 16 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option 17 | // see discussion at https://github.com/vuejs/vue-loader/issues/724 18 | 'scss-loader': 'sass-loader' 19 | } 20 | }, 21 | plugins: [ 22 | new webpack.DefinePlugin({ 23 | 'process.env': require('../config/test.env') 24 | }) 25 | ] 26 | }) 27 | 28 | // no need for app entry during tests 29 | delete webpackConfig.entry 30 | 31 | module.exports = webpackConfig 32 | -------------------------------------------------------------------------------- /template/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /template/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'docs', 10 | assetsPublicPath: '/{{ name }}/dist', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | lib: { 25 | env: require('./prod.env'), 26 | assetsRoot: path.resolve(__dirname, '../dist'), 27 | assetsSubDirectory: 'lib', 28 | assetsPublicPath: '/', 29 | productionSourceMap: true, 30 | productionGzip: false, 31 | productionGzipExtensions: ['js', 'css'], 32 | bundleAnalyzerReport: process.env.npm_config_report 33 | }, 34 | dev: { 35 | env: require('./dev.env'), 36 | port: 8080, 37 | autoOpenBrowser: true, 38 | assetsSubDirectory: 'docs', 39 | assetsPublicPath: '/', 40 | proxyTable: {}, 41 | // CSS Sourcemaps off by default because relative paths are "buggy" 42 | // with this option, according to the CSS-Loader README 43 | // (https://github.com/webpack/css-loader#sourcemaps) 44 | // In our experience, they generally work as expected, 45 | // just be aware of this issue when enabling this option. 46 | cssSourceMap: false 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /template/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /template/config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /template/index-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#buefy}} 8 | 9 | {{/buefy}} 10 | {{ name }} 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /template/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{ name }}", 3 | "version": "0.0.1", 4 | "description": "{{ description }}", 5 | "author": "{{ author }}", 6 | "main": "dist/lib/{{ name }}.min.js", 7 | "private": false, 8 | "license": "MIT", 9 | "scripts": { 10 | "prepublishOnly": "npm run build", 11 | "dev": "npm-run-all --parallel dev:lib dev:docs", 12 | "dev:lib": "webpack --config build/webpack.lib.conf.js --watch --progress --hide-modules", 13 | "dev:docs": "node build/dev-server.js", 14 | "build": "npm run build:lib && npm run build:docs", 15 | "build:lib": "node build/build-lib.js", 16 | "build:docs": "node build/build.js"{{#unit}}, 17 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run"{{/unit}}{{#e2e}}, 18 | "e2e": "node test/e2e/runner.js"{{/e2e}}{{#if_or unit e2e}}, 19 | "test": "{{#unit}}npm run unit{{/unit}}{{#unit}}{{#e2e}} && {{/e2e}}{{/unit}}{{#e2e}}npm run e2e{{/e2e}}"{{/if_or}}{{#lint}}, 20 | "lint": "eslint --ext .js,.vue src{{#unit}} test/unit/specs{{/unit}}{{#e2e}} test/e2e/specs{{/e2e}}"{{/lint}} 21 | }, 22 | "dependencies": { 23 | "vue": "^2.3.3"{{#router}}, 24 | "vue-router": "^2.6.0"{{/router}} 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^7.1.2", 28 | "babel-core": "^6.22.1", 29 | {{#lint}} 30 | "babel-eslint": "^7.1.1", 31 | {{/lint}} 32 | "babel-loader": "^7.1.1", 33 | "babel-plugin-transform-runtime": "^6.22.0", 34 | "babel-preset-env": "^1.3.2", 35 | "babel-preset-stage-2": "^6.22.0", 36 | "babel-register": "^6.22.0", 37 | {{#buefy}} 38 | "buefy": "^0.4.6", 39 | {{/buefy}} 40 | "chalk": "^2.0.1", 41 | "connect-history-api-fallback": "^1.3.0", 42 | "copy-webpack-plugin": "^4.0.1", 43 | "css-loader": "^0.28.0", 44 | "cssnano": "^3.10.0", 45 | {{#lint}} 46 | "eslint": "^3.19.0", 47 | "eslint-friendly-formatter": "^3.0.0", 48 | "eslint-loader": "^1.7.1", 49 | "eslint-plugin-html": "^3.0.0", 50 | {{#if_eq lintConfig "standard"}} 51 | "eslint-config-standard": "^6.2.1", 52 | "eslint-plugin-promise": "^3.4.0", 53 | "eslint-plugin-standard": "^2.0.1", 54 | {{/if_eq}} 55 | {{#if_eq lintConfig "airbnb"}} 56 | "eslint-config-airbnb-base": "^11.1.3", 57 | "eslint-import-resolver-webpack": "^0.8.1", 58 | "eslint-plugin-import": "^2.2.0", 59 | {{/if_eq}} 60 | {{/lint}} 61 | "eventsource-polyfill": "^0.9.6", 62 | "express": "^4.14.1", 63 | "extract-text-webpack-plugin": "^2.0.0", 64 | "file-loader": "^0.11.1", 65 | "friendly-errors-webpack-plugin": "^1.1.3", 66 | "html-webpack-plugin": "^2.28.0", 67 | "http-proxy-middleware": "^0.17.3", 68 | "npm-run-all": "^4.0.2", 69 | "webpack-bundle-analyzer": "^2.2.1", 70 | {{#unit}} 71 | "cross-env": "^5.0.1", 72 | "karma": "^1.4.1", 73 | "karma-coverage": "^1.1.1", 74 | "karma-mocha": "^1.3.0", 75 | "karma-phantomjs-launcher": "^1.0.2", 76 | "karma-phantomjs-shim": "^1.4.0", 77 | "karma-sinon-chai": "^1.3.1", 78 | "karma-sourcemap-loader": "^0.3.7", 79 | "karma-spec-reporter": "0.0.31", 80 | "karma-webpack": "^2.0.2", 81 | "lolex": "^1.5.2", 82 | "mocha": "^3.2.0", 83 | "chai": "^3.5.0", 84 | "sinon": "^2.1.0", 85 | "sinon-chai": "^2.8.0", 86 | "inject-loader": "^3.0.0", 87 | "babel-plugin-istanbul": "^4.1.1", 88 | "phantomjs-prebuilt": "^2.1.14", 89 | {{/unit}} 90 | {{#e2e}} 91 | "chromedriver": "^2.27.2", 92 | "cross-spawn": "^5.0.1", 93 | "nightwatch": "^0.9.12", 94 | "selenium-server": "^3.0.1", 95 | {{/e2e}} 96 | "semver": "^5.3.0", 97 | "shelljs": "^0.7.6", 98 | {{#stylus}} 99 | "stylus": "^0.54.5", 100 | "stylus-loader": "^3.0.1", 101 | {{/stylus}} 102 | "opn": "^5.1.0", 103 | "optimize-css-assets-webpack-plugin": "^2.0.0", 104 | "ora": "^1.2.0", 105 | {{#pug}} 106 | "pug": "^2.0.0-rc.1", 107 | {{/pug}} 108 | "rimraf": "^2.6.0", 109 | {{#sass}} 110 | "sass-loader": "^6.0.5", 111 | "node-sass": "^4.5.2", 112 | {{/sass}} 113 | "url-loader": "^0.5.8", 114 | "vue-loader": "^12.1.0", 115 | "vue-style-loader": "^3.0.1", 116 | "vue-template-compiler": "^2.3.3", 117 | "webpack": "^2.6.1", 118 | "webpack-dev-middleware": "^1.10.0", 119 | "webpack-hot-middleware": "^2.18.0", 120 | "webpack-merge": "^4.1.0" 121 | }, 122 | "engines": { 123 | "node": ">= 4.0.0", 124 | "npm": ">= 3.0.0" 125 | }, 126 | "browserslist": [ 127 | "> 1%", 128 | "last 2 versions", 129 | "not ie <= 8" 130 | ] 131 | } 132 | -------------------------------------------------------------------------------- /template/src/app.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 24 | 25 | 35 | -------------------------------------------------------------------------------- /template/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prograhammer/vue-library-template/788eea64000fc15482d29f22978023937b0275cf/template/src/assets/logo.png -------------------------------------------------------------------------------- /template/src/components/hello.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /template/src/docs.js: -------------------------------------------------------------------------------- 1 | {{#if_eq build "standalone"}} 2 | // The Vue build version to load with the `import` command 3 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 4 | {{/if_eq}} 5 | import Vue from 'vue'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 6 | {{#buefy}} 7 | import Buefy from 'buefy' 8 | Vue.use(Buefy) 9 | {{/buefy}} 10 | import App from './app'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 11 | {{#router}} 12 | import router from './router'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 13 | {{/router}} 14 | 15 | {{#sass}} 16 | import './styles/app.scss'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 17 | {{/sass}} 18 | {{#stylus}} 19 | import './styles/app.styl'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 20 | {{/stylus}} 21 | 22 | Vue.config.productionTip = false{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 23 | 24 | /* eslint-disable no-new */ 25 | new Vue({ 26 | el: '#app', 27 | {{#router}} 28 | router, 29 | {{/router}} 30 | {{#if_eq build "runtime"}} 31 | render: h => h(App){{#if_eq lintConfig "airbnb"}},{{/if_eq}} 32 | {{/if_eq}} 33 | {{#if_eq build "standalone"}} 34 | template: '', 35 | components: { App }{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 36 | {{/if_eq}} 37 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 38 | -------------------------------------------------------------------------------- /template/src/lib.js: -------------------------------------------------------------------------------- 1 | import {{camelcase name}} from './components/hello'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 2 | {{#sass}} 3 | import './styles/lib.scss'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 4 | {{/sass}} 5 | {{#stylus}} 6 | import './styles/lib.styl'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 7 | {{/stylus}} 8 | 9 | export default {{camelcase name}}{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 10 | -------------------------------------------------------------------------------- /template/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 2 | import Router from 'vue-router'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 3 | import Hello from '@/components/hello'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 4 | 5 | Vue.use(Router){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 6 | 7 | export default new Router({ 8 | routes: [ 9 | { 10 | path: '/', 11 | name: 'Hello', 12 | component: Hello{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 13 | }{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 14 | ]{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 15 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 16 | -------------------------------------------------------------------------------- /template/src/styles/app.scss: -------------------------------------------------------------------------------- 1 | {{#buefy}} 2 | // See Buefy customization docs for more: https://buefy.github.io/#/documentation/customization 3 | 4 | // Import Bulma's core 5 | @import "~bulma/sass/utilities/_all"; 6 | 7 | // Set your colors 8 | $primary: #8c67ef; 9 | $primary-invert: findColorInvert($primary); 10 | $twitter: #4099FF; 11 | $twitter-invert: findColorInvert($twitter); 12 | 13 | // Setup $colors to use as bulma classes (e.g. 'is-twitter') 14 | $colors: ( 15 | "white": ($white, $black), 16 | "black": ($black, $white), 17 | "light": ($light, $light-invert), 18 | "dark": ($dark, $dark-invert), 19 | "primary": ($primary, $primary-invert), 20 | "info": ($info, $info-invert), 21 | "success": ($success, $success-invert), 22 | "warning": ($warning, $warning-invert), 23 | "danger": ($danger, $danger-invert), 24 | "twitter": ($twitter, $twitter-invert) 25 | ); 26 | 27 | // Links 28 | $link: $primary; 29 | $link-invert: $primary-invert; 30 | $link-focus-border: $primary; 31 | 32 | // Import Bulma and Buefy styles 33 | @import "~bulma"; 34 | @import "~buefy/src/scss/buefy"; 35 | {{/buefy}} 36 | 37 | // Import your library's styles 38 | @import 'lib' -------------------------------------------------------------------------------- /template/src/styles/app.styl: -------------------------------------------------------------------------------- 1 | // Import your library's styles 2 | @import 'lib' -------------------------------------------------------------------------------- /template/src/styles/lib.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prograhammer/vue-library-template/788eea64000fc15482d29f22978023937b0275cf/template/src/styles/lib.scss -------------------------------------------------------------------------------- /template/src/styles/lib.styl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prograhammer/vue-library-template/788eea64000fc15482d29f22978023937b0275cf/template/src/styles/lib.styl -------------------------------------------------------------------------------- /template/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prograhammer/vue-library-template/788eea64000fc15482d29f22978023937b0275cf/template/static/.gitkeep -------------------------------------------------------------------------------- /template/test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 11 | this.expected = count{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 12 | this.pass = function (val) { 13 | return val === this.expected{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 14 | } 15 | this.value = function (res) { 16 | return res.value{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 17 | } 18 | this.command = function (cb) { 19 | var self = this{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 22 | }, [selector], function (res) { 23 | cb.call(self, res){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 24 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /template/test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/gettingstarted#settings-file 5 | module.exports = { 6 | src_folders: ['test/e2e/specs'], 7 | output_folder: 'test/e2e/reports', 8 | custom_assertions_path: ['test/e2e/custom-assertions'], 9 | 10 | selenium: { 11 | start_process: true, 12 | server_path: require('selenium-server').path, 13 | host: '127.0.0.1', 14 | port: 4444, 15 | cli_args: { 16 | 'webdriver.chrome.driver': require('chromedriver').path 17 | } 18 | }, 19 | 20 | test_settings: { 21 | default: { 22 | selenium_port: 4444, 23 | selenium_host: 'localhost', 24 | silent: true, 25 | globals: { 26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | chrome: { 31 | desiredCapabilities: { 32 | browserName: 'chrome', 33 | javascriptEnabled: true, 34 | acceptSslCerts: true 35 | } 36 | }, 37 | 38 | firefox: { 39 | desiredCapabilities: { 40 | browserName: 'firefox', 41 | javascriptEnabled: true, 42 | acceptSslCerts: true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /template/test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 3 | var server = require('../../build/dev-server.js'){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 4 | 5 | server.ready.then(() => { 6 | // 2. run the nightwatch test suite against it 7 | // to run in additional browsers: 8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 9 | // 2. add it to the --env flag below 10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 11 | // For more information on Nightwatch's config file, see 12 | // http://nightwatchjs.org/guide#settings-file 13 | var opts = process.argv.slice(2){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 14 | if (opts.indexOf('--config') === -1) { 15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 16 | } 17 | if (opts.indexOf('--env') === -1) { 18 | opts = opts.concat(['--env', 'chrome']){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 19 | } 20 | 21 | var spawn = require('cross-spawn'){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 23 | 24 | runner.on('exit', function (code) { 25 | server.close(){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 26 | process.exit(code){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 27 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 28 | 29 | runner.on('error', function (err) { 30 | server.close(){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 31 | throw err{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 32 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 33 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 34 | -------------------------------------------------------------------------------- /template/test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function {{#if_eq lintConfig "airbnb"}}test{{/if_eq}}(browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end(){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 18 | }{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 19 | }{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 20 | -------------------------------------------------------------------------------- /template/test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /template/test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 2 | 3 | Vue.config.productionTip = false{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 7 | testsContext.keys().forEach(testsContext){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 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 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 13 | srcContext.keys().forEach(srcContext){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 14 | -------------------------------------------------------------------------------- /template/test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var webpackConfig = require('../../build/webpack.test.conf'){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 7 | 8 | module.exports = function (config) { 9 | config.set({ 10 | // to run in additional browsers: 11 | // 1. install corresponding karma launcher 12 | // http://karma-runner.github.io/0.13/config/browsers.html 13 | // 2. add it to the `browsers` array below. 14 | browsers: ['PhantomJS'], 15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], 16 | reporters: ['spec', 'coverage'], 17 | files: ['./index.js'], 18 | preprocessors: { 19 | './index.js': ['webpack', 'sourcemap'] 20 | }, 21 | webpack: webpackConfig, 22 | webpackMiddleware: { 23 | noInfo: true{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 24 | }, 25 | coverageReporter: { 26 | dir: './coverage', 27 | reporters: [ 28 | { type: 'lcov', subdir: '.' }, 29 | { type: 'text-summary' }{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 30 | ] 31 | }{{#if_eq lintConfig "airbnb"}},{{/if_eq}} 32 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 33 | }{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 34 | -------------------------------------------------------------------------------- /template/test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 2 | import Hello from '@/components/Hello'{{#if_eq lintConfig "airbnb"}};{{/if_eq}} 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(Hello){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 7 | const vm = new Constructor().$mount(){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .to.equal('Welcome to Your Vue.js App'){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 10 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 11 | }){{#if_eq lintConfig "airbnb"}};{{/if_eq}} 12 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | yes "" | ./node_modules/.bin/vue init . test 4 | 5 | cd test 6 | npm install 7 | npm run lint 8 | npm test 9 | npm run build 10 | --------------------------------------------------------------------------------