diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index 7dc38823cb..e0bd6ac2fb 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -2,6 +2,7 @@
- [Project Structure](structure.md)
- [Build Commands](commands.md)
+- [Babel Configuration](babel.md)
- [Linter Configuration](linter.md)
- [Pre-Processors](pre-processors.md)
- [Handling Static Assets](static.md)
diff --git a/docs/babel.md b/docs/babel.md
new file mode 100644
index 0000000000..eaa0ca9d83
--- /dev/null
+++ b/docs/babel.md
@@ -0,0 +1,22 @@
+# Babel Configuration
+
+This boilerplate uses [`babel-preset-env`](https://www.npmjs.com/package/babel-preset-env) for configuring babel. You can read more about it here - http://2ality.com/2017/02/babel-preset-env.html.
+
+> A Babel preset that compiles ES2015+ down to ES5 by automatically determining the Babel plugins and polyfills you need based on your targeted browser or runtime environments.
+
+It uses [`browserslist`](https://github.com/ai/browserslist) to parse this information, so we can use any [valid query format supported by `browserslist`](https://github.com/ai/browserslist#queries).
+
+However there is a caveat. `browserslist` recommends defining the target in a common place like `package.json` or in a `.browserslistrc` config file. This allows tools like [`autoprefixer`](https://github.com/postcss/autoprefixer) and [`eslint-plugin-compat`](https://github.com/amilajack/eslint-plugin-compat) to share the config. For this template, `browserslist` is configured in the `package.json`:
+
+```json
+{
+ "...": "...",
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not ie <= 8"
+ ]
+}
+```
+
+But the latest stable release of `babel-preset-env`, `v1.6.1` does not support loading the config from `package.json`. So the target environment is repeated in `.babelrc`. If you wish to change your target environment, please be sure to update both `package.json` and `.babelrc`. Note that this has been fixed in the beta version([`@babel/preset-env@7.0.0-beta.34`](https://github.com/babel/babel/tree/master/packages/babel-preset-env)) and the template will be updated once it is out of beta.
diff --git a/docs/structure.md b/docs/structure.md
index 33bec21d84..75c958a42f 100644
--- a/docs/structure.md
+++ b/docs/structure.md
@@ -31,7 +31,7 @@
├── .babelrc # babel config
├── .editorconfig # indentation, spaces/tabs and similar settings for your editor
├── .eslintrc.js # eslint config
-├── .eslintignore.js # eslint ignore rules
+├── .eslintignore # eslint ignore rules
├── .gitignore # sensible defaults for gitignore
├── .postcssrc.js # postcss config
├── index.html # index.html template
diff --git a/meta.js b/meta.js
index ed7a8b6a2d..1e0b798e20 100644
--- a/meta.js
+++ b/meta.js
@@ -1,18 +1,15 @@
const path = require('path');
const fs = require('fs');
-
-function sortObject(object) {
- // Based on https://github.com/yarnpkg/yarn/blob/v1.3.2/src/config.js#L79-L85
- const sortedObject = {};
- Object.keys(object).sort().forEach(item => {
- sortedObject[item] = object[item];
- });
- return sortedObject;
-}
+const {
+ sortDependencies,
+ installDependencies,
+ runLintFix,
+ printMessage
+} = require('./utils')
module.exports = {
- "helpers": {
- "if_or": function (v1, v2, options) {
+ helpers: {
+ if_or: function (v1, v2, options) {
if (v1 || v2) {
return options.fn(this);
}
@@ -20,127 +17,153 @@ module.exports = {
return options.inverse(this);
}
},
- "prompts": {
- "name": {
- "type": "string",
- "required": true,
- "message": "Project name"
+ prompts: {
+ name: {
+ type: 'string',
+ required: true,
+ message: 'Project name'
},
- "description": {
- "type": "string",
- "required": false,
- "message": "Project description",
- "default": "A Vue.js project"
+ description: {
+ type: 'string',
+ required: false,
+ message: 'Project description',
+ default: 'A Vue.js project'
},
- "author": {
- "type": "string",
- "message": "Author"
+ author: {
+ type: 'string',
+ message: 'Author'
},
- "build": {
- "type": "list",
- "message": "Vue build",
- "choices": [
+ build: {
+ type: 'list',
+ message: 'Vue build',
+ choices: [
{
- "name": "Runtime + Compiler: recommended for most users",
- "value": "standalone",
- "short": "standalone"
+ name: 'Runtime + Compiler: recommended for most users',
+ value: 'standalone',
+ short: 'standalone'
},
{
- "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",
- "value": "runtime",
- "short": "runtime"
+ 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',
+ value: 'runtime',
+ short: 'runtime'
}
]
},
- "router": {
- "type": "confirm",
- "message": "Install vue-router?"
+ router: {
+ type: 'confirm',
+ message: 'Install vue-router?'
},
- "lint": {
- "type": "confirm",
- "message": "Use ESLint to lint your code?"
+ lint: {
+ type: 'confirm',
+ message: 'Use ESLint to lint your code?'
},
- "lintConfig": {
- "when": "lint",
- "type": "list",
- "message": "Pick an ESLint preset",
- "choices": [
+ lintConfig: {
+ when: 'lint',
+ type: 'list',
+ message: 'Pick an ESLint preset',
+ choices: [
{
- "name": "Standard (https://github.com/standard/standard)",
- "value": "standard",
- "short": "Standard"
+ name: 'Standard (https://github.com/standard/standard)',
+ value: 'standard',
+ short: 'Standard'
},
{
- "name": "Airbnb (https://github.com/airbnb/javascript)",
- "value": "airbnb",
- "short": "Airbnb"
+ name: 'Airbnb (https://github.com/airbnb/javascript)',
+ value: 'airbnb',
+ short: 'Airbnb'
},
{
- "name": "none (configure it yourself)",
- "value": "none",
- "short": "none"
+ name: 'none (configure it yourself)',
+ value: 'none',
+ short: 'none'
}
]
},
- "unit": {
- "type": "confirm",
- "message": "Set up unit tests"
+ unit: {
+ type: 'confirm',
+ message: 'Set up unit tests'
},
- "runner": {
- "when": "unit",
- "type": "list",
- "message": "Pick a test runner",
- "choices": [
+ runner: {
+ when: 'unit',
+ type: 'list',
+ message: 'Pick a test runner',
+ choices: [
{
- "name": "Jest",
- "value": "jest",
- "short": "jest"
+ name: 'Jest',
+ value: 'jest',
+ short: 'jest'
},
{
- "name": "Karma and Mocha",
- "value": "karma",
- "short": "karma"
+ name: 'Karma and Mocha',
+ value: 'karma',
+ short: 'karma'
},
{
- "name": "none (configure it yourself)",
- "value": "noTest",
- "short": "noTest"
+ name: 'none (configure it yourself)',
+ value: 'noTest',
+ short: 'noTest'
}
]
},
- "e2e": {
- "type": "confirm",
- "message": "Setup e2e tests with Nightwatch?"
+ e2e: {
+ type: 'confirm',
+ message: 'Setup e2e tests with Nightwatch?'
+ },
+ autoInstall: {
+ type: 'list',
+ message: 'Should we run `npm install` for you after the project has been created? (recommended)',
+ choices: [
+ {
+ name: 'Yes, use NPM',
+ value: 'npm',
+ short: 'npm'
+ },
+ {
+ name: 'Yes, use Yarn',
+ value: 'yarn',
+ short: 'yarn'
+ },
+ {
+ name: 'No, I will handle that myself',
+ value: false,
+ short: 'no'
+ }
+ ]
}
},
- "filters": {
- ".eslintrc.js": "lint",
- ".eslintignore": "lint",
- "config/test.env.js": "unit || e2e",
- "build/webpack.test.conf.js": "e2e || (unit && runner === 'karma')",
- "test/unit/**/*": "unit",
- "test/unit/index.js": "unit && runner === 'karma'",
- "test/unit/jest.conf.js": "unit && runner === 'jest'",
- "test/unit/karma.conf.js": "unit && runner === 'karma'",
- "test/unit/specs/index.js": "unit && runner === 'karma'",
- "test/unit/setup.js": "unit && runner === 'jest'",
- "test/e2e/**/*": "e2e",
- "src/router/**/*": "router"
+ filters: {
+ '.eslintrc.js': 'lint',
+ '.eslintignore': 'lint',
+ 'config/test.env.js': 'unit || e2e',
+ 'build/webpack.test.conf.js': "unit && runner === 'karma'",
+ 'test/unit/**/*': 'unit',
+ 'test/unit/index.js': "unit && runner === 'karma'",
+ 'test/unit/jest.conf.js': "unit && runner === 'jest'",
+ 'test/unit/karma.conf.js': "unit && runner === 'karma'",
+ 'test/unit/specs/index.js': "unit && runner === 'karma'",
+ 'test/unit/setup.js': "unit && runner === 'jest'",
+ 'test/e2e/**/*': 'e2e',
+ 'src/router/**/*': 'router'
},
- "complete": function (data) {
- const packageJsonFile = path.join(
- data.inPlace ? "" : data.destDirName,
- "package.json"
- );
- const packageJson = JSON.parse(fs.readFileSync(packageJsonFile));
- packageJson.devDependencies = sortObject(packageJson.devDependencies);
- packageJson.dependencies = sortObject(packageJson.dependencies);
- fs.writeFileSync(
- packageJsonFile,
- JSON.stringify(packageJson, null, 2) + "\n"
- );
+ 'complete': function (data, { chalk }) {
+
+ const green = chalk.green
- const message = `To get started:\n\n ${data.inPlace ? '' : `cd ${data.destDirName}\n `}npm install\n npm run dev\n\nDocumentation can be found at https://vuejs-templates.github.io/webpack`;
- console.log("\n" + message.split(/\r?\n/g).map(line => " " + line).join("\n"));
+ sortDependencies(data, green)
+
+ const cwd = path.join(process.cwd(), data.inPlace ? '' : data.destDirName)
+
+ if (data.autoInstall) {
+ installDependencies(cwd, data.autoInstall, green)
+ .then(() => {
+ return runLintFix(cwd, data, green)
+ })
+ .then(() => {
+ printMessage(data, green)
+ })
+ } else {
+ printMessage(data, chalk)
+ }
+
}
};
diff --git a/package.json b/package.json
index 09951adace..a00df3c157 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-cli-template-webpack",
- "version": "1.2.5",
+ "version": "1.2.6",
"license": "MIT",
"description": "A full-featured Webpack setup with hot-reload, lint-on-save, unit testing & css extraction.",
"scripts": {
diff --git a/template/.babelrc b/template/.babelrc
index 6e0aaac99c..6646ce7f96 100644
--- a/template/.babelrc
+++ b/template/.babelrc
@@ -1,16 +1,19 @@
{
"presets": [
["env", {
- "modules": false
+ "modules": false,
+ "targets": {
+ "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+ }
}],
"stage-2"
],
- "plugins": ["transform-runtime"]{{#if_or unit e2e}},
+ "plugins": ["transform-vue-jsx", "transform-runtime"]{{#if_or unit e2e}},
"env": {
"test": {
"presets": ["env", "stage-2"]{{#if_eq runner "karma"}},
- "plugins": ["istanbul"]{{/if_eq}}{{#if_eq runner "jest"}},
- "plugins": ["transform-es2015-modules-commonjs", "dynamic-import-node"]{{/if_eq}}
+ "plugins": ["transform-vue-jsx", "istanbul"]{{/if_eq}}{{#if_eq runner "jest"}},
+ "plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"]{{/if_eq}}
}
}{{/if_or}}
}
diff --git a/template/.eslintrc.js b/template/.eslintrc.js
index 8e8be20e8d..8624b369c5 100644
--- a/template/.eslintrc.js
+++ b/template/.eslintrc.js
@@ -42,6 +42,16 @@ module.exports = {
js: 'never',
vue: 'never'
}],
+ // disallow reassignment of function parameters
+ // disallow parameter object manipulation except for specific exclusions
+ 'no-param-reassign': ['error', {
+ props: true,
+ ignorePropertyModificationsFor: [
+ 'state', // for vuex state
+ 'acc', // for reduce accumulators
+ 'e' // for e.returnvalue
+ ]
+ }],
// allow optionalDependencies
'import/no-extraneous-dependencies': ['error', {
optionalDependencies: ['test/unit/index.js']
diff --git a/template/build/webpack.prod.conf.js b/template/build/webpack.prod.conf.js
index d121faed35..bf613e8424 100644
--- a/template/build/webpack.prod.conf.js
+++ b/template/build/webpack.prod.conf.js
@@ -46,10 +46,11 @@ const webpackConfig = merge(baseWebpackConfig, {
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
- // set the following option to `true` if you want to extract CSS from
- // codesplit chunks into this main css file as well.
- // This will result in *all* of your app's CSS being loaded upfront.
- allChunks: false,
+ // Setting the following option to `false` will not extract CSS from codesplit chunks.
+ // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
+ // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
+ // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
+ allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
diff --git a/template/config/index.js b/template/config/index.js
index 0a7cfb43e1..05c69c1620 100644
--- a/template/config/index.js
+++ b/template/config/index.js
@@ -1,5 +1,5 @@
'use strict'
-// Template version: 1.2.5
+// Template version: 1.2.6
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
diff --git a/template/package.json b/template/package.json
index 23ffeb6ccc..e4e637e1d5 100644
--- a/template/package.json
+++ b/template/package.json
@@ -84,8 +84,11 @@
{{/e2e}}
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
+ "babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
+ "babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
+ "babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
diff --git a/template/src/App.vue b/template/src/App.vue
index 2ef72e8cbc..03d5e7247d 100644
--- a/template/src/App.vue
+++ b/template/src/App.vue
@@ -11,15 +11,15 @@