diff --git a/packages/@vue/cli-plugin-typescript/__tests__/tsPluginE2e.spec.js b/packages/@vue/cli-plugin-typescript/__tests__/tsPluginE2e.spec.js
index 75f9bc1ad..6fc1abd0e 100644
--- a/packages/@vue/cli-plugin-typescript/__tests__/tsPluginE2e.spec.js
+++ b/packages/@vue/cli-plugin-typescript/__tests__/tsPluginE2e.spec.js
@@ -13,7 +13,7 @@ test('cypress', async () => {
})
test('cypress with router', async () => {
- const project = await create('ts-e2e-cypress', {
+ const project = await create('ts-e2e-cypress-router', {
router: true,
plugins: {
'@vue/cli-plugin-typescript': {},
diff --git a/packages/@vue/cli-plugin-typescript/generator/template/src/App.vue b/packages/@vue/cli-plugin-typescript/generator/template/src/App.vue
index 12c67eb5b..775a05eab 100644
--- a/packages/@vue/cli-plugin-typescript/generator/template/src/App.vue
+++ b/packages/@vue/cli-plugin-typescript/generator/template/src/App.vue
@@ -1,13 +1,17 @@
-<%_ if (!rootOptions.router) { _%>
-
-
- For guide and recipes on how to configure / customize this project,
- {{ msg }}
-
- check out the
- vue-cli documentation.
- Installed CLI Plugins
-
- <%_ for (plugin of plugins) { _%>
-
- Essential Links
-
-
- Ecosystem
-
-
-
-
@@ -35,11 +35,11 @@ export default {
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
- <%_ if (!options.router) { _%>
+ <%_ if (!rootOptions.router) { _%>
margin-top: 60px;
<%_ } _%>
}
-<%_ if (options.router) { _%>
+<%_ if (rootOptions.router) { _%>
#nav {
padding: 30px;
diff --git a/packages/@vue/cli-service/generator/template/src/main.js b/packages/@vue/cli-service/generator/template/src/main.js
index 90e1fd807..a659a87ff 100644
--- a/packages/@vue/cli-service/generator/template/src/main.js
+++ b/packages/@vue/cli-service/generator/template/src/main.js
@@ -1,19 +1,19 @@
import Vue from 'vue'
import App from './App.vue'
-<%_ if (options.router) { _%>
+<%_ if (rootOptions.router) { _%>
import router from './router'
<%_ } _%>
-<%_ if (options.vuex) { _%>
+<%_ if (rootOptions.vuex) { _%>
import store from './store'
<%_ } _%>
Vue.config.productionTip = false
new Vue({
- <%_ if (options.router) { _%>
+ <%_ if (rootOptions.router) { _%>
router,
<%_ } _%>
- <%_ if (options.vuex) { _%>
+ <%_ if (rootOptions.vuex) { _%>
store,
<%_ } _%>
render: h => h(App)
diff --git a/packages/@vue/cli-service/generator/template/src/router.js b/packages/@vue/cli-service/generator/template/src/router.js
index 11fa13b6b..325a61917 100644
--- a/packages/@vue/cli-service/generator/template/src/router.js
+++ b/packages/@vue/cli-service/generator/template/src/router.js
@@ -1,4 +1,4 @@
-<%_ if (options.router) { _%>
+<%_ if (rootOptions.router) { _%>
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
diff --git a/packages/@vue/cli-service/generator/template/src/store.js b/packages/@vue/cli-service/generator/template/src/store.js
index f0840434f..fd4710d35 100644
--- a/packages/@vue/cli-service/generator/template/src/store.js
+++ b/packages/@vue/cli-service/generator/template/src/store.js
@@ -1,4 +1,4 @@
-<%_ if (options.vuex) { _%>
+<%_ if (rootOptions.vuex) { _%>
import Vue from 'vue'
import Vuex from 'vuex'
diff --git a/packages/@vue/cli-service/generator/template/src/views/About.vue b/packages/@vue/cli-service/generator/template/src/views/About.vue
index a59efa984..72e8abd0d 100644
--- a/packages/@vue/cli-service/generator/template/src/views/About.vue
+++ b/packages/@vue/cli-service/generator/template/src/views/About.vue
@@ -1,4 +1,4 @@
-<%_ if (options.router) { _%>
+<%_ if (rootOptions.router) { _%>
diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js
index a825df262..84a817388 100644
--- a/packages/@vue/cli/lib/GeneratorAPI.js
+++ b/packages/@vue/cli/lib/GeneratorAPI.js
@@ -3,6 +3,7 @@ const ejs = require('ejs')
const path = require('path')
const globby = require('globby')
const isBinary = require('isbinaryfile')
+const yaml = require('yaml-front-matter')
const mergeDeps = require('./util/mergeDeps')
const isString = val => typeof val === 'string'
@@ -207,11 +208,46 @@ function extractCallDir () {
return path.dirname(fileName)
}
+const replaceBlockRE = /<%# REPLACE %>([^]*?)<%# END_REPLACE %>/g
+
function renderFile (name, data, ejsOptions) {
if (isBinary.sync(name)) {
return fs.readFileSync(name) // return buffer
}
- return ejs.render(fs.readFileSync(name, 'utf-8'), data, ejsOptions)
+ const template = fs.readFileSync(name, 'utf-8')
+
+ // custom template inheritance via yaml front matter.
+ // ---
+ // extend: 'source-file'
+ // replace: !!js/regexp /some-regex/
+ // OR
+ // replace:
+ // - !!js/regexp /foo/
+ // - !!js/regexp /bar/
+ // ---
+ const parsed = yaml.loadFront(template)
+ const content = parsed.__content
+ let finalTemplate = content.trim() + `\n`
+ if (parsed.extend) {
+ finalTemplate = fs.readFileSync(require.resolve(parsed.extend), 'utf-8')
+ if (parsed.replace) {
+ if (Array.isArray(parsed.replace)) {
+ const replaceMatch = content.match(replaceBlockRE)
+ if (replaceMatch) {
+ const replaces = replaceMatch.map(m => {
+ return m.replace(replaceBlockRE, '$1').trim()
+ })
+ parsed.replace.forEach((r, i) => {
+ finalTemplate = finalTemplate.replace(r, replaces[i])
+ })
+ }
+ } else {
+ finalTemplate = finalTemplate.replace(parsed.replace, content.trim())
+ }
+ }
+ }
+
+ return ejs.render(finalTemplate, data, ejsOptions)
}
module.exports = GeneratorAPI
diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json
index 4a1c47dc2..6f1cd0cfb 100644
--- a/packages/@vue/cli/package.json
+++ b/packages/@vue/cli/package.json
@@ -49,7 +49,8 @@
"resolve": "^1.5.0",
"rimraf": "^2.6.2",
"semver": "^5.4.1",
- "slash": "^1.0.0"
+ "slash": "^1.0.0",
+ "yaml-front-matter": "^3.4.1"
},
"engines": {
"node": ">=8"
diff --git a/yarn.lock b/yarn.lock
index 5d84bb581..db1205b83 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2067,6 +2067,10 @@ command-join@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf"
+commander@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-1.0.0.tgz#5e6a88e7070ff5908836ead19169548c30f90bcd"
+
commander@2.11.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
@@ -5697,7 +5701,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-js-yaml@^3.10.0, js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@^3.8.1, js-yaml@^3.9.0, js-yaml@^3.9.1:
+js-yaml@^3.10.0, js-yaml@^3.4.3, js-yaml@^3.5.2, js-yaml@^3.7.0, js-yaml@^3.8.1, js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
dependencies:
@@ -10411,6 +10415,13 @@ yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
+yaml-front-matter@^3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/yaml-front-matter/-/yaml-front-matter-3.4.1.tgz#e52e84fea6983b93755e9b1564dba989b006b5a5"
+ dependencies:
+ commander "1.0.0"
+ js-yaml "^3.5.2"
+
yaml-js@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/yaml-js/-/yaml-js-0.0.8.tgz#87cfa5a9613f48e26005420d6a8ee0da6fe8daec"