mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-01-25 00:29:06 -06:00
chore: merge dev
This commit is contained in:
41
CHANGELOG.md
41
CHANGELOG.md
@@ -1,3 +1,42 @@
|
||||
<a name="3.0.0-beta.11"></a>
|
||||
# [3.0.0-beta.11](https://github.com/vuejs/vue-cli/compare/v3.0.0-beta.10...v3.0.0-beta.11) (2018-05-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* css sourceMap in production ([#1270](https://github.com/vuejs/vue-cli/issues/1270)) ([2d09a4c](https://github.com/vuejs/vue-cli/commit/2d09a4c))
|
||||
* **css:** css-loader importLoaders should account for vue-loader's injected ([853662c](https://github.com/vuejs/vue-cli/commit/853662c)), closes [#1267](https://github.com/vuejs/vue-cli/issues/1267)
|
||||
* fix babel.config.js compat in vue-jest ([48d7e00](https://github.com/vuejs/vue-cli/commit/48d7e00))
|
||||
* fix transpileDependencies by always using babel.config.js ([1279b3e](https://github.com/vuejs/vue-cli/commit/1279b3e))
|
||||
* **eslint:** ensure all config values are contained in config file ([83f5f4f](https://github.com/vuejs/vue-cli/commit/83f5f4f)), closes [#1006](https://github.com/vuejs/vue-cli/issues/1006) [#1313](https://github.com/vuejs/vue-cli/issues/1313)
|
||||
* fix ts/tsx rule separation ([41a56f1](https://github.com/vuejs/vue-cli/commit/41a56f1)), closes [#1315](https://github.com/vuejs/vue-cli/issues/1315)
|
||||
* handle failed git commit ([a1ccde8](https://github.com/vuejs/vue-cli/commit/a1ccde8)), closes [#1306](https://github.com/vuejs/vue-cli/issues/1306)
|
||||
* rename test-utils `shallow` to `shallowMount` ([#1269](https://github.com/vuejs/vue-cli/issues/1269)) ([5c54df7](https://github.com/vuejs/vue-cli/commit/5c54df7))
|
||||
* stringifyJS should be used in all call sites ([07ac887](https://github.com/vuejs/vue-cli/commit/07ac887))
|
||||
* typo in vue-loader compilerOptions ([#1263](https://github.com/vuejs/vue-cli/issues/1263)) ([b2b277a](https://github.com/vuejs/vue-cli/commit/b2b277a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **build:** add 'watch' option ([#1332](https://github.com/vuejs/vue-cli/issues/1332)) ([6ea17c9](https://github.com/vuejs/vue-cli/commit/6ea17c9))
|
||||
* **cli-service:** add assetsDir option to specify assets root directory ([#1322](https://github.com/vuejs/vue-cli/issues/1322)) ([9638d90](https://github.com/vuejs/vue-cli/commit/9638d90)), closes [#1311](https://github.com/vuejs/vue-cli/issues/1311)
|
||||
* **eslint:** add --max-warnings and --max-errors for cli-plugin-eslint ([#1289](https://github.com/vuejs/vue-cli/issues/1289)) ([ab877a2](https://github.com/vuejs/vue-cli/commit/ab877a2)), closes [#1268](https://github.com/vuejs/vue-cli/issues/1268)
|
||||
* **eslint:** enable caching ([ff0f97b](https://github.com/vuejs/vue-cli/commit/ff0f97b))
|
||||
* **eslint:** pass cli arguments to linter ([#1258](https://github.com/vuejs/vue-cli/issues/1258)) ([9ac2642](https://github.com/vuejs/vue-cli/commit/9ac2642)), closes [#1255](https://github.com/vuejs/vue-cli/issues/1255)
|
||||
* **inspect:** add --rule and --plugin options for inspect command ([82349ba](https://github.com/vuejs/vue-cli/commit/82349ba))
|
||||
* **inspect:** add --rules and --plugins options for inspect command ([fd1c0d5](https://github.com/vuejs/vue-cli/commit/fd1c0d5))
|
||||
* support `<style lang="postcss">` ([#1259](https://github.com/vuejs/vue-cli/issues/1259)) ([1037b9c](https://github.com/vuejs/vue-cli/commit/1037b9c))
|
||||
* **inspect:** improve `vue inspect` output with webpack-chain hints ([f6bfb63](https://github.com/vuejs/vue-cli/commit/f6bfb63)), closes [#881](https://github.com/vuejs/vue-cli/issues/881)
|
||||
* allow disabling serve progress via devServer.progress ([da38747](https://github.com/vuejs/vue-cli/commit/da38747)), closes [#1284](https://github.com/vuejs/vue-cli/issues/1284)
|
||||
* allow router/vuex to be late added via `vue add` ([2a195f0](https://github.com/vuejs/vue-cli/commit/2a195f0)), closes [#1202](https://github.com/vuejs/vue-cli/issues/1202) [#1204](https://github.com/vuejs/vue-cli/issues/1204)
|
||||
* ask for whether to use taobao registry when getting versions ([#1273](https://github.com/vuejs/vue-cli/issues/1273)) ([8fbbd35](https://github.com/vuejs/vue-cli/commit/8fbbd35))
|
||||
* GeneratorAPI: addImports & addRootOptions ([8b32f4a](https://github.com/vuejs/vue-cli/commit/8b32f4a))
|
||||
* make it possible to opt-out of Babel ([d75ea99](https://github.com/vuejs/vue-cli/commit/d75ea99)), closes [#1199](https://github.com/vuejs/vue-cli/issues/1199)
|
||||
* support webp ([763cf7a](https://github.com/vuejs/vue-cli/commit/763cf7a)), closes [#1321](https://github.com/vuejs/vue-cli/issues/1321)
|
||||
* temporarily fix source map by patching babel ([453597a](https://github.com/vuejs/vue-cli/commit/453597a))
|
||||
|
||||
|
||||
|
||||
<a name="3.0.0-beta.10"></a>
|
||||
# [3.0.0-beta.10](https://github.com/vuejs/vue-cli/compare/v3.0.0-beta.9...v3.0.0-beta.10) (2018-05-11)
|
||||
|
||||
@@ -54,7 +93,7 @@ modifications must be webpcak 4 compatible. Drop support
|
||||
for webpack plugins that do not work with v4 or above.
|
||||
* dll option has been removed.
|
||||
* the "vueLoader" option has been removed. To modify vue-loader
|
||||
options, use chainWebpack then `config.module.rule('vue').use('vue-loader').tap()`.
|
||||
options, use chainWebpack then `config.module.rule(vue).use(vue-loader).tap()`.
|
||||
vue-loader has been upgraded to v15 and expects different options from v14.
|
||||
* To include a dependency for Babel transpilation, tapping
|
||||
babel-loader and adding .include() will no longer work. Use the new
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
"lerna": "2.5.1",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "3.0.0-beta.10"
|
||||
"version": "3.0.0-beta.11"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/babel-preset-app",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "babel-preset-app for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-init",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "init addon for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-overlay",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "error overlay & dev server middleware for vue-cli",
|
||||
"main": "dist/client.js",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-babel",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "babel plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -20,7 +20,7 @@
|
||||
"homepage": "https://github.com/vuejs/vue-cli/packages/@vue/cli-plugin-babel#readme",
|
||||
"dependencies": {
|
||||
"@babel/core": "7.0.0-beta.47",
|
||||
"@vue/babel-preset-app": "^3.0.0-beta.10",
|
||||
"@vue/babel-preset-app": "^3.0.0-beta.11",
|
||||
"babel-loader": "^8.0.0-0"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-e2e-cypress",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "e2e-cypress plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-e2e-nightwatch",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "e2e-nightwatch plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -16,17 +16,17 @@ module.exports = (api, { config, lintOn = [] }) => {
|
||||
if (config === 'airbnb') {
|
||||
eslintConfig.extends.push('@vue/airbnb')
|
||||
Object.assign(pkg.devDependencies, {
|
||||
'@vue/eslint-config-airbnb': '^3.0.0-beta.10'
|
||||
'@vue/eslint-config-airbnb': '^3.0.0-beta.11'
|
||||
})
|
||||
} else if (config === 'standard') {
|
||||
eslintConfig.extends.push('@vue/standard')
|
||||
Object.assign(pkg.devDependencies, {
|
||||
'@vue/eslint-config-standard': '^3.0.0-beta.10'
|
||||
'@vue/eslint-config-standard': '^3.0.0-beta.11'
|
||||
})
|
||||
} else if (config === 'prettier') {
|
||||
eslintConfig.extends.push('@vue/prettier')
|
||||
Object.assign(pkg.devDependencies, {
|
||||
'@vue/eslint-config-prettier': '^3.0.0-beta.10'
|
||||
'@vue/eslint-config-prettier': '^3.0.0-beta.11'
|
||||
})
|
||||
} else {
|
||||
// default
|
||||
@@ -37,7 +37,7 @@ module.exports = (api, { config, lintOn = [] }) => {
|
||||
if (api.hasPlugin('typescript')) {
|
||||
eslintConfig.extends.push('@vue/typescript')
|
||||
Object.assign(pkg.devDependencies, {
|
||||
'@vue/eslint-config-typescript': '^3.0.0-beta.10'
|
||||
'@vue/eslint-config-typescript': '^3.0.0-beta.11'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-eslint",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "eslint plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin')
|
||||
|
||||
test('inject import statement for service worker', async () => {
|
||||
const mockMain = (
|
||||
`import Vue from 'vue'\n` +
|
||||
`import Bar from './Bar.vue'`
|
||||
)
|
||||
const { files } = await generateWithPlugin([
|
||||
{
|
||||
id: 'files',
|
||||
apply: api => {
|
||||
api.render(files => {
|
||||
files['src/main.js'] = mockMain
|
||||
})
|
||||
},
|
||||
id: 'core',
|
||||
apply: require('@vue/cli-service/generator'),
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
@@ -22,5 +14,27 @@ test('inject import statement for service worker', async () => {
|
||||
}
|
||||
])
|
||||
|
||||
expect(files['src/main.js']).toMatch(`${mockMain}\nimport './registerServiceWorker'`)
|
||||
expect(files['src/main.js']).toMatch(`import './registerServiceWorker'`)
|
||||
})
|
||||
|
||||
test('inject import statement for service worker (with TS)', async () => {
|
||||
const { files } = await generateWithPlugin([
|
||||
{
|
||||
id: 'core',
|
||||
apply: require('@vue/cli-service/generator'),
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
id: 'typescript',
|
||||
apply: require('@vue/cli-plugin-typescript/generator'),
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
id: 'pwa',
|
||||
apply: require('../generator'),
|
||||
options: {}
|
||||
}
|
||||
])
|
||||
|
||||
expect(files['src/main.ts']).toMatch(`import './registerServiceWorker'`)
|
||||
})
|
||||
|
||||
@@ -4,21 +4,6 @@ module.exports = api => {
|
||||
'register-service-worker': '^1.0.0'
|
||||
}
|
||||
})
|
||||
|
||||
api.injectImports(`src/main.js`, `import './registerServiceWorker'`)
|
||||
api.render('./template')
|
||||
|
||||
api.postProcessFiles(files => {
|
||||
const isTS = 'src/main.ts' in files
|
||||
const file = isTS
|
||||
? 'src/main.ts'
|
||||
: 'src/main.js'
|
||||
const main = files[file]
|
||||
if (main) {
|
||||
// inject import for registerServiceWorker script into main.js
|
||||
const lines = main.split(/\r?\n/g).reverse()
|
||||
const lastImportIndex = lines.findIndex(line => line.match(/^import/))
|
||||
lines[lastImportIndex] += `\nimport './registerServiceWorker'`
|
||||
files[file] = lines.reverse().join('\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-pwa",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "pwa plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
extend: '@vue/cli-service/generator/template/src/views/Home.vue'
|
||||
extend: '@vue/cli-service/generator/router/template/src/views/Home.vue'
|
||||
replace:
|
||||
- !!js/regexp /Welcome to Your Vue\.js App/
|
||||
- !!js/regexp /<script>[^]*?<\/script>/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-typescript",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "typescript plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-unit-jest",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "unit-jest plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-plugin-unit-mocha",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "mocha unit testing plugin for vue-cli",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-service-global",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "vue-cli-service global addon for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
@@ -21,10 +21,10 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/packages/@vue/cli-build#readme",
|
||||
"dependencies": {
|
||||
"@vue/babel-preset-app": "^3.0.0-beta.10",
|
||||
"@vue/cli-plugin-babel": "^3.0.0-beta.10",
|
||||
"@vue/cli-plugin-eslint": "^3.0.0-beta.10",
|
||||
"@vue/cli-service": "^3.0.0-beta.10",
|
||||
"@vue/babel-preset-app": "^3.0.0-beta.11",
|
||||
"@vue/cli-plugin-babel": "^3.0.0-beta.11",
|
||||
"@vue/cli-plugin-eslint": "^3.0.0-beta.11",
|
||||
"@vue/cli-service": "^3.0.0-beta.11",
|
||||
"chalk": "^2.4.1",
|
||||
"eslint-plugin-vue": "^4.5.0",
|
||||
"resolve": "^1.7.1",
|
||||
|
||||
@@ -38,7 +38,7 @@ test('loading plugins from package.json', () => {
|
||||
mockPkg({
|
||||
devDependencies: {
|
||||
'bar': '^1.0.0',
|
||||
'@vue/cli-plugin-babel': '^3.0.0-beta.10',
|
||||
'@vue/cli-plugin-babel': '^3.0.0-beta.11',
|
||||
'vue-cli-plugin-foo': '^1.0.0'
|
||||
}
|
||||
})
|
||||
|
||||
@@ -25,19 +25,11 @@ module.exports = (api, options) => {
|
||||
})
|
||||
|
||||
if (options.router) {
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'vue-router': '^3.0.1'
|
||||
}
|
||||
})
|
||||
require('./router')(api, options)
|
||||
}
|
||||
|
||||
if (options.vuex) {
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
vuex: '^3.0.1'
|
||||
}
|
||||
})
|
||||
require('./vuex')(api, options)
|
||||
}
|
||||
|
||||
if (options.cssPreprocessor) {
|
||||
|
||||
30
packages/@vue/cli-service/generator/router/index.js
Normal file
30
packages/@vue/cli-service/generator/router/index.js
Normal file
@@ -0,0 +1,30 @@
|
||||
module.exports = (api, options) => {
|
||||
api.injectImports(`src/main.js`, `import router from './router'`)
|
||||
api.injectRootOptions(`src/main.js`, `router`)
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
'vue-router': '^3.0.1'
|
||||
}
|
||||
})
|
||||
api.render('./template')
|
||||
|
||||
if (options.invoking) {
|
||||
api.postProcessFiles(files => {
|
||||
const appFile = files[`src/App.vue`]
|
||||
if (appFile) {
|
||||
files[`src/App.vue`] = appFile.replace(/^<template>[^]+<\/script>/, `
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</div>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
`.trim())
|
||||
console.log(files[`src/App.vue`])
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Home from './views/Home.vue'
|
||||
@@ -20,4 +19,3 @@ export default new Router({
|
||||
}
|
||||
]
|
||||
})
|
||||
<%_ } _%>
|
||||
@@ -1,7 +1,5 @@
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>This is an about page</h1>
|
||||
</div>
|
||||
</template>
|
||||
<%_ } _%>
|
||||
@@ -1,4 +1,3 @@
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
<template>
|
||||
<div class="home">
|
||||
<img src="../assets/logo.png">
|
||||
@@ -17,4 +16,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%_ } _%>
|
||||
@@ -1,20 +1,8 @@
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
import router from './router'
|
||||
<%_ } _%>
|
||||
<%_ if (rootOptions.vuex) { _%>
|
||||
import store from './store'
|
||||
<%_ } _%>
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
<%_ if (rootOptions.router) { _%>
|
||||
router,
|
||||
<%_ } _%>
|
||||
<%_ if (rootOptions.vuex) { _%>
|
||||
store,
|
||||
<%_ } _%>
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
|
||||
10
packages/@vue/cli-service/generator/vuex/index.js
Normal file
10
packages/@vue/cli-service/generator/vuex/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = (api, options) => {
|
||||
api.injectImports(`src/main.js`, `import store from './store'`)
|
||||
api.injectRootOptions(`src/main.js`, `store`)
|
||||
api.extendPackage({
|
||||
dependencies: {
|
||||
vuex: '^3.0.1'
|
||||
}
|
||||
})
|
||||
api.render('./template')
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
<%_ if (rootOptions.vuex) { _%>
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
@@ -15,4 +14,3 @@ export default new Vuex.Store({
|
||||
|
||||
}
|
||||
})
|
||||
<%_ } _%>
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-service",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "local service for vue-cli projects",
|
||||
"main": "lib/Service.js",
|
||||
"bin": {
|
||||
@@ -21,8 +21,8 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue-cli/packages/@vue/cli-service#readme",
|
||||
"dependencies": {
|
||||
"@vue/cli-overlay": "^3.0.0-beta.10",
|
||||
"@vue/cli-shared-utils": "^3.0.0-beta.10",
|
||||
"@vue/cli-overlay": "^3.0.0-beta.11",
|
||||
"@vue/cli-shared-utils": "^3.0.0-beta.11",
|
||||
"@vue/web-component-wrapper": "^1.2.0",
|
||||
"acorn": "^5.5.3",
|
||||
"address": "^1.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-shared-utils",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "shared utilities for vue-cli packages",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli-test-utils",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "test utilities for vue-cli packages",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -12,6 +12,13 @@ fs.ensureDirSync(templateDir)
|
||||
fs.writeFileSync(path.resolve(templateDir, 'foo.js'), 'foo(<%- options.n %>)')
|
||||
fs.ensureDirSync(path.resolve(templateDir, 'bar'))
|
||||
fs.writeFileSync(path.resolve(templateDir, 'bar/bar.js'), 'bar(<%- m %>)')
|
||||
fs.writeFileSync(path.resolve(templateDir, 'entry.js'), `
|
||||
import foo from 'foo'
|
||||
|
||||
new Vue({
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
`.trim())
|
||||
|
||||
fs.writeFileSync(path.resolve(templateDir, 'replace.js'), `
|
||||
---
|
||||
@@ -431,6 +438,31 @@ test('api: resolve', () => {
|
||||
] })
|
||||
})
|
||||
|
||||
test('api: addEntryImport & addEntryInjection', async () => {
|
||||
const generator = new Generator('/', { plugins: [
|
||||
{
|
||||
id: 'test',
|
||||
apply: api => {
|
||||
api.injectImports('main.js', `import bar from 'bar'`)
|
||||
api.injectRootOptions('main.js', ['foo', 'bar'])
|
||||
api.render({
|
||||
'main.js': path.join(templateDir, 'entry.js')
|
||||
})
|
||||
}
|
||||
}
|
||||
] })
|
||||
|
||||
await generator.generate()
|
||||
expect(fs.readFileSync('/main.js', 'utf-8')).toMatch(`import foo from 'foo'\nimport bar from 'bar'`)
|
||||
expect(fs.readFileSync('/main.js', 'utf-8')).toMatch(
|
||||
`new Vue({
|
||||
foo,
|
||||
bar,
|
||||
render: h => h(App)
|
||||
})`
|
||||
)
|
||||
})
|
||||
|
||||
test('extract config files', async () => {
|
||||
const configs = {
|
||||
vue: {
|
||||
|
||||
@@ -5,6 +5,7 @@ const GeneratorAPI = require('./GeneratorAPI')
|
||||
const sortObject = require('./util/sortObject')
|
||||
const writeFileTree = require('./util/writeFileTree')
|
||||
const configTransforms = require('./util/configTransforms')
|
||||
const injectImportsAndOptions = require('./util/injectImportsAndOptions')
|
||||
const { toShortPluginId, matchesPluginId } = require('@vue/cli-shared-utils')
|
||||
|
||||
const logger = require('@vue/cli-shared-utils/lib/logger')
|
||||
@@ -27,6 +28,8 @@ module.exports = class Generator {
|
||||
this.plugins = plugins
|
||||
this.originalPkg = pkg
|
||||
this.pkg = Object.assign({}, pkg)
|
||||
this.imports = {}
|
||||
this.rootOptions = {}
|
||||
this.completeCbs = completeCbs
|
||||
|
||||
// for conflict resolution
|
||||
@@ -136,13 +139,19 @@ module.exports = class Generator {
|
||||
for (const middleware of this.fileMiddlewares) {
|
||||
await middleware(files, ejs.render)
|
||||
}
|
||||
// normalize paths
|
||||
Object.keys(files).forEach(file => {
|
||||
// normalize paths
|
||||
const normalized = slash(file)
|
||||
if (file !== normalized) {
|
||||
files[normalized] = files[file]
|
||||
delete files[file]
|
||||
}
|
||||
// handle imports and root option injections
|
||||
files[normalized] = injectImportsAndOptions(
|
||||
files[normalized],
|
||||
this.imports[normalized],
|
||||
this.rootOptions[normalized]
|
||||
)
|
||||
})
|
||||
for (const postProcess of this.postProcessFilesCbs) {
|
||||
await postProcess(files)
|
||||
|
||||
@@ -199,6 +199,32 @@ class GeneratorAPI {
|
||||
genJSConfig (value) {
|
||||
return `module.exports = ${stringifyJS(value, null, 2)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Add import statements to a file.
|
||||
*/
|
||||
injectImports (file, imports) {
|
||||
const _imports = (
|
||||
this.generator.imports[file] ||
|
||||
(this.generator.imports[file] = new Set())
|
||||
)
|
||||
;(Array.isArray(imports) ? imports : [imports]).forEach(imp => {
|
||||
_imports.add(imp)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Add options to the root Vue instance (detected by `new Vue`).
|
||||
*/
|
||||
injectRootOptions (file, options) {
|
||||
const _options = (
|
||||
this.generator.rootOptions[file] ||
|
||||
(this.generator.rootOptions[file] = new Set())
|
||||
)
|
||||
;(Array.isArray(options) ? options : [options]).forEach(opt => {
|
||||
_options.add(opt)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function extractCallDir () {
|
||||
|
||||
@@ -12,6 +12,14 @@ const {
|
||||
} = require('@vue/cli-shared-utils')
|
||||
|
||||
async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
// special internal "plugins"
|
||||
if (/^(@vue\/)?router$/.test(pluginName)) {
|
||||
return addRouter(context)
|
||||
}
|
||||
if (/^(@vue\/)?vuex$/.test(pluginName)) {
|
||||
return addVuex(context)
|
||||
}
|
||||
|
||||
const packageName = resolvePluginId(pluginName)
|
||||
|
||||
log()
|
||||
@@ -35,6 +43,22 @@ async function add (pluginName, options = {}, context = process.cwd()) {
|
||||
}
|
||||
}
|
||||
|
||||
async function addRouter (context) {
|
||||
invoke.runGenerator(context, {
|
||||
id: 'core:router',
|
||||
apply: require('@vue/cli-service/generator/router'),
|
||||
options: { invoking: true }
|
||||
})
|
||||
}
|
||||
|
||||
async function addVuex (context) {
|
||||
invoke.runGenerator(context, {
|
||||
id: 'core:vuex',
|
||||
apply: require('@vue/cli-service/generator/vuex'),
|
||||
options: { invoking: true }
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = (...args) => {
|
||||
return add(...args).catch(err => {
|
||||
error(err)
|
||||
|
||||
@@ -36,16 +36,17 @@ async function readFiles (context) {
|
||||
return res
|
||||
}
|
||||
|
||||
async function invoke (pluginName, options = {}, context = process.cwd()) {
|
||||
delete options._
|
||||
function getPkg (context) {
|
||||
const pkgPath = path.resolve(context, 'package.json')
|
||||
const isTestOrDebug = process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG
|
||||
|
||||
if (!fs.existsSync(pkgPath)) {
|
||||
throw new Error(`package.json not found in ${chalk.yellow(context)}`)
|
||||
}
|
||||
return require(pkgPath)
|
||||
}
|
||||
|
||||
const pkg = require(pkgPath)
|
||||
async function invoke (pluginName, options = {}, context = process.cwd()) {
|
||||
delete options._
|
||||
const pkg = getPkg(context)
|
||||
|
||||
// attempt to locate the plugin in package.json
|
||||
const findPlugin = deps => {
|
||||
@@ -89,6 +90,11 @@ async function invoke (pluginName, options = {}, context = process.cwd()) {
|
||||
options
|
||||
}
|
||||
|
||||
await runGenerator(context, plugin, pkg)
|
||||
}
|
||||
|
||||
async function runGenerator (context, plugin, pkg = getPkg(context)) {
|
||||
const isTestOrDebug = process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG
|
||||
const createCompleteCbs = []
|
||||
const generator = new Generator(context, {
|
||||
pkg,
|
||||
@@ -98,7 +104,7 @@ async function invoke (pluginName, options = {}, context = process.cwd()) {
|
||||
})
|
||||
|
||||
log()
|
||||
logWithSpinner('🚀', `Invoking generator for ${id}...`)
|
||||
logWithSpinner('🚀', `Invoking generator for ${plugin.id}...`)
|
||||
await generator.generate({
|
||||
extractConfigFiles: true,
|
||||
checkExisting: true
|
||||
@@ -127,7 +133,7 @@ async function invoke (pluginName, options = {}, context = process.cwd()) {
|
||||
stopSpinner()
|
||||
|
||||
log()
|
||||
log(` Successfully invoked generator for plugin: ${chalk.cyan(id)}`)
|
||||
log(` Successfully invoked generator for plugin: ${chalk.cyan(plugin.id)}`)
|
||||
if (!process.env.VUE_CLI_TEST && hasGit()) {
|
||||
const { stdout } = await execa('git', [
|
||||
'ls-files',
|
||||
@@ -168,3 +174,5 @@ module.exports = (...args) => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports.runGenerator = runGenerator
|
||||
|
||||
@@ -58,7 +58,8 @@ module.exports = cli => {
|
||||
choices: [
|
||||
{
|
||||
name: 'Lint on save',
|
||||
value: 'save'
|
||||
value: 'save',
|
||||
checked: true
|
||||
},
|
||||
{
|
||||
name: 'Lint and fix on commit' + (hasGit() ? '' : chalk.red(' (requires Git)')),
|
||||
|
||||
55
packages/@vue/cli/lib/util/injectImportsAndOptions.js
Normal file
55
packages/@vue/cli/lib/util/injectImportsAndOptions.js
Normal file
@@ -0,0 +1,55 @@
|
||||
module.exports = function injectImportsAndOptions (source, imports, injections) {
|
||||
imports = imports instanceof Set ? Array.from(imports) : imports
|
||||
injections = injections instanceof Set ? Array.from(injections) : injections
|
||||
|
||||
const hasImports = imports && imports.length > 0
|
||||
const hasInjections = injections && injections.length > 0
|
||||
|
||||
if (!hasImports && !hasInjections) {
|
||||
return source
|
||||
}
|
||||
|
||||
const recast = require('recast')
|
||||
const ast = recast.parse(source)
|
||||
|
||||
if (hasImports) {
|
||||
const toImport = i => recast.parse(`${i}\n`).program.body[0]
|
||||
let lastImportIndex = -1
|
||||
recast.types.visit(ast, {
|
||||
visitImportDeclaration ({ node }) {
|
||||
lastImportIndex = ast.program.body.findIndex(n => n === node)
|
||||
return false
|
||||
}
|
||||
})
|
||||
// avoid blank line after the previous import
|
||||
delete ast.program.body[lastImportIndex].loc
|
||||
|
||||
const newImports = imports.map(toImport)
|
||||
ast.program.body.splice(lastImportIndex + 1, 0, ...newImports)
|
||||
}
|
||||
|
||||
if (hasInjections) {
|
||||
const toProperty = i => {
|
||||
return recast.parse(`({${i}})`).program.body[0].expression.properties
|
||||
}
|
||||
recast.types.visit(ast, {
|
||||
visitNewExpression ({ node }) {
|
||||
if (node.callee.name === 'Vue') {
|
||||
const options = node.arguments[0]
|
||||
if (options && options.type === 'ObjectExpression') {
|
||||
const props = options.properties
|
||||
// inject at index length - 1 as it's usually the render fn
|
||||
options.properties = [
|
||||
...props.slice(0, props.length - 1),
|
||||
...([].concat(...injections.map(toProperty))),
|
||||
...props.slice(props.length - 1)
|
||||
]
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return recast.print(ast).code
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/cli",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "Command line interface for rapid Vue.js development",
|
||||
"bin": {
|
||||
"vue": "bin/vue.js"
|
||||
@@ -27,7 +27,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/cli-shared-utils": "^3.0.0-beta.10",
|
||||
"@vue/cli-shared-utils": "^3.0.0-beta.11",
|
||||
"@vue/cli-ui": "^3.0.0-beta.10",
|
||||
"@vue/cli-ui-addon-webpack": "^3.0.0-beta.10",
|
||||
"chalk": "^2.3.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/eslint-config-airbnb",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "eslint-config-airbnb for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/eslint-config-prettier",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "eslint-config-prettier for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/eslint-config-standard",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "eslint-config-standard for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue/eslint-config-typescript",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "eslint-config-typescript for vue-cli",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-cli-version-marker",
|
||||
"version": "3.0.0-beta.10",
|
||||
"version": "3.0.0-beta.11",
|
||||
"description": "version marker for @vue/cli",
|
||||
"author": "Evan You",
|
||||
"license": "MIT"
|
||||
|
||||
Reference in New Issue
Block a user