diff --git a/docs/guide/plugins-and-presets.md b/docs/guide/plugins-and-presets.md index ae0de69711..fb3aa47850 100644 --- a/docs/guide/plugins-and-presets.md +++ b/docs/guide/plugins-and-presets.md @@ -105,7 +105,6 @@ Here's an example preset: ``` json { "useConfigFiles": true, - "vuex": true, "cssPreprocessor": "sass", "plugins": { "@vue/cli-plugin-babel": {}, @@ -113,7 +112,8 @@ Here's an example preset: "config": "airbnb", "lintOn": ["save", "commit"] }, - "@vue/cli-plugin-router": {} + "@vue/cli-plugin-router": {}, + "@vue/cli-plugin-vuex": {} } } ``` diff --git a/docs/ru/guide/plugins-and-presets.md b/docs/ru/guide/plugins-and-presets.md index 7bd8b63618..742e119609 100644 --- a/docs/ru/guide/plugins-and-presets.md +++ b/docs/ru/guide/plugins-and-presets.md @@ -105,7 +105,6 @@ vue add @vue/eslint --config airbnb --lintOn save ``` json { "useConfigFiles": true, - "vuex": true, "cssPreprocessor": "sass", "plugins": { "@vue/cli-plugin-babel": {}, @@ -113,7 +112,8 @@ vue add @vue/eslint --config airbnb --lintOn save "config": "airbnb", "lintOn": ["save", "commit"] }, - "@vue/cli-plugin-router": {} + "@vue/cli-plugin-router": {}, + "@vue/cli-plugin-vuex": {} } } ``` diff --git a/docs/zh/guide/plugins-and-presets.md b/docs/zh/guide/plugins-and-presets.md index db6b8754c5..dc42c1fd10 100644 --- a/docs/zh/guide/plugins-and-presets.md +++ b/docs/zh/guide/plugins-and-presets.md @@ -105,7 +105,6 @@ vue add @vue/eslint --config airbnb --lintOn save ``` json { "useConfigFiles": true, - "vuex": true, "cssPreprocessor": "sass", "plugins": { "@vue/cli-plugin-babel": {}, @@ -113,7 +112,8 @@ vue add @vue/eslint --config airbnb --lintOn save "config": "airbnb", "lintOn": ["save", "commit"] }, - "@vue/cli-plugin-router": {} + "@vue/cli-plugin-router": {}, + "@vue/cli-plugin-vuex": {} } } ``` diff --git a/packages/@vue/cli-plugin-vuex/.npmignore b/packages/@vue/cli-plugin-vuex/.npmignore new file mode 100644 index 0000000000..e0b178a189 --- /dev/null +++ b/packages/@vue/cli-plugin-vuex/.npmignore @@ -0,0 +1,2 @@ +__tests__ +__mocks__ diff --git a/packages/@vue/cli-plugin-vuex/README.md b/packages/@vue/cli-plugin-vuex/README.md new file mode 100644 index 0000000000..5fa9dfdd12 --- /dev/null +++ b/packages/@vue/cli-plugin-vuex/README.md @@ -0,0 +1,9 @@ +# @vue/cli-plugin-vuex + +> vuex plugin for vue-cli + +## Installing in an Already Created Project + +``` sh +vue add @vue/vuex +``` diff --git a/packages/@vue/cli-plugin-vuex/__tests__/vuexGenerator.spec.js b/packages/@vue/cli-plugin-vuex/__tests__/vuexGenerator.spec.js new file mode 100644 index 0000000000..f95317c267 --- /dev/null +++ b/packages/@vue/cli-plugin-vuex/__tests__/vuexGenerator.spec.js @@ -0,0 +1,14 @@ +const generateWithPlugin = require('@vue/cli-test-utils/generateWithPlugin') + +test('base', async () => { + const { files, pkg } = await generateWithPlugin({ + id: 'vuex', + apply: require('../generator'), + options: {} + }) + + expect(files['src/store/index.js']).toBeTruthy() + expect(files['src/store/index.js']).toMatch('import Vuex') + + expect(pkg.dependencies).toHaveProperty('vuex') +}) diff --git a/packages/@vue/cli-service/generator/vuex/index.js b/packages/@vue/cli-plugin-vuex/generator/index.js similarity index 71% rename from packages/@vue/cli-service/generator/vuex/index.js rename to packages/@vue/cli-plugin-vuex/generator/index.js index aded240926..5aa8358cbd 100644 --- a/packages/@vue/cli-service/generator/vuex/index.js +++ b/packages/@vue/cli-plugin-vuex/generator/index.js @@ -1,12 +1,18 @@ -module.exports = (api, options) => { +module.exports = (api, options = {}) => { + api.assertCliVersion('^4.0.0-alpha.3') + api.assertCliServiceVersion('^4.0.0-alpha.3') + api.injectImports(api.entryFile, `import store from './store'`) api.injectRootOptions(api.entryFile, `store`) + api.extendPackage({ dependencies: { vuex: '^3.0.1' } }) - api.render('./template') + + api.render('./template', { + }) if (api.invoking && api.hasPlugin('typescript')) { /* eslint-disable-next-line node/no-extraneous-require */ diff --git a/packages/@vue/cli-service/generator/vuex/template/src/store.js b/packages/@vue/cli-plugin-vuex/generator/template/src/store/index.js similarity index 89% rename from packages/@vue/cli-service/generator/vuex/template/src/store.js rename to packages/@vue/cli-plugin-vuex/generator/template/src/store/index.js index 3c7424edc4..332b916928 100644 --- a/packages/@vue/cli-service/generator/vuex/template/src/store.js +++ b/packages/@vue/cli-plugin-vuex/generator/template/src/store/index.js @@ -5,12 +5,11 @@ Vue.use(Vuex) export default new Vuex.Store({ state: { - }, mutations: { - }, actions: { - + }, + modules: { } }) diff --git a/packages/@vue/cli-plugin-vuex/index.js b/packages/@vue/cli-plugin-vuex/index.js new file mode 100644 index 0000000000..615dfd51d3 --- /dev/null +++ b/packages/@vue/cli-plugin-vuex/index.js @@ -0,0 +1 @@ +module.exports = (api, options = {}) => {} diff --git a/packages/@vue/cli-plugin-vuex/package.json b/packages/@vue/cli-plugin-vuex/package.json new file mode 100644 index 0000000000..892e1c37b8 --- /dev/null +++ b/packages/@vue/cli-plugin-vuex/package.json @@ -0,0 +1,29 @@ +{ + "name": "@vue/cli-plugin-vuex", + "version": "4.0.0-alpha.3", + "description": "Vuex plugin for vue-cli", + "main": "index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/vuejs/vue-cli.git", + "directory": "packages/@vue/cli-plugin-vuex" + }, + "keywords": [ + "vue", + "cli", + "vuex" + ], + "author": "Evan You", + "license": "MIT", + "bugs": { + "url": "https://github.com/vuejs/vue-cli/issues" + }, + "homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/cli-plugin-vuex#readme", + "publishConfig": { + "access": "public" + }, + "dependencies": {}, + "devDependencies": { + "@vue/cli-test-utils": "^4.0.0-alpha.3" + } +} diff --git a/packages/@vue/cli-service/__tests__/serve.spec.js b/packages/@vue/cli-service/__tests__/serve.spec.js index 69dc584836..dd241076b9 100644 --- a/packages/@vue/cli-service/__tests__/serve.spec.js +++ b/packages/@vue/cli-service/__tests__/serve.spec.js @@ -74,6 +74,19 @@ test('serve with legacy router option', async () => { ) }) +test('serve with legacy vuex option', async () => { + const project = await create('e2e-serve-legacy-vuex', Object.assign({}, defaultPreset, { + vuex: true + })) + + await serve( + () => project.run('vue-cli-service serve'), + async ({ page, helpers }) => { + expect(await helpers.getText('h1')).toMatch(`Welcome to Your Vue.js App`) + } + ) +}) + test('serve with inline entry', async () => { const project = await create('e2e-serve-inline-entry', defaultPreset) diff --git a/packages/@vue/cli-service/generator/index.js b/packages/@vue/cli-service/generator/index.js index 4bc3bcf8c1..4b5f4814bb 100644 --- a/packages/@vue/cli-service/generator/index.js +++ b/packages/@vue/cli-service/generator/index.js @@ -25,10 +25,6 @@ module.exports = (api, options) => { ] }) - if (options.vuex) { - require('./vuex')(api, options) - } - if (options.cssPreprocessor) { const deps = { sass: { diff --git a/packages/@vue/cli-service/lib/PluginAPI.js b/packages/@vue/cli-service/lib/PluginAPI.js index 39ebe76c28..66ed0ab0d1 100644 --- a/packages/@vue/cli-service/lib/PluginAPI.js +++ b/packages/@vue/cli-service/lib/PluginAPI.js @@ -64,10 +64,6 @@ class PluginAPI { * @return {boolean} */ hasPlugin (id) { - if (['vuex'].includes(id)) { - const pkg = this.service.pkg - return ((pkg.dependencies && pkg.dependencies[id]) || (pkg.devDependencies && pkg.devDependencies[id])) - } return this.service.plugins.some(p => matchesPluginId(id, p.id)) } diff --git a/packages/@vue/cli-ui/apollo-server/api/PluginApi.js b/packages/@vue/cli-ui/apollo-server/api/PluginApi.js index e5ecbf2044..bb70ad1c45 100644 --- a/packages/@vue/cli-ui/apollo-server/api/PluginApi.js +++ b/packages/@vue/cli-ui/apollo-server/api/PluginApi.js @@ -4,7 +4,6 @@ const logs = require('../connectors/logs') const sharedData = require('../connectors/shared-data') const views = require('../connectors/views') const suggestions = require('../connectors/suggestions') -const folders = require('../connectors/folders') const progress = require('../connectors/progress') const app = require('../connectors/app') // Utils @@ -397,10 +396,6 @@ class PluginApi { * @param {string} id Plugin id or short id */ hasPlugin (id) { - if (['vuex'].includes(id)) { - const pkg = folders.readPackage(this.cwd, this.context, true) - return ((pkg.dependencies && pkg.dependencies[id]) || (pkg.devDependencies && pkg.devDependencies[id])) - } return this.plugins.some(p => matchesPluginId(id, p.id)) } diff --git a/packages/@vue/cli-ui/tests/e2e/specs/g2-plugins.js b/packages/@vue/cli-ui/tests/e2e/specs/g2-plugins.js index 8bd290edcf..6d65c1ce2c 100644 --- a/packages/@vue/cli-ui/tests/e2e/specs/g2-plugins.js +++ b/packages/@vue/cli-ui/tests/e2e/specs/g2-plugins.js @@ -1,7 +1,7 @@ describe('Plugins', () => { it('Should display the plugins', () => { cy.visit('/plugins') - cy.get('.project-plugin-item').should('have.length', 5) + cy.get('.project-plugin-item').should('have.length', 6) }) it('Should add a plugin', () => { @@ -26,6 +26,6 @@ describe('Plugins', () => { .should('be.visible') .should('not.have.class', 'disabled') .click() - cy.get('.project-plugin-item').should('have.length', 5) + cy.get('.project-plugin-item').should('have.length', 6) }) }) diff --git a/packages/@vue/cli-ui/ui-defaults/suggestions.js b/packages/@vue/cli-ui/ui-defaults/suggestions.js index ae27af4081..89bf21b823 100644 --- a/packages/@vue/cli-ui/ui-defaults/suggestions.js +++ b/packages/@vue/cli-ui/ui-defaults/suggestions.js @@ -1,4 +1,3 @@ -const { loadModule } = require('@vue/cli-shared-utils') const invoke = require('@vue/cli/lib/invoke') const ROUTER = 'org.vue.vue-router-add' @@ -78,14 +77,7 @@ async function install (api, id) { let error try { - if (id === 'router') { - await invoke(id, {}, context) - } else { - await invoke.runGenerator(context, { - id: `core:${id}`, - apply: loadModule(`@vue/cli-service/generator/${id}`, context) - }) - } + await invoke(id, {}, context) } catch (e) { error = e } diff --git a/packages/@vue/cli/lib/Creator.js b/packages/@vue/cli/lib/Creator.js index e8db9c0774..b03f37d31a 100644 --- a/packages/@vue/cli/lib/Creator.js +++ b/packages/@vue/cli/lib/Creator.js @@ -106,6 +106,11 @@ module.exports = class Creator extends EventEmitter { } } + // legacy support for vuex + if (preset.vuex) { + preset.plugins['@vue/cli-plugin-vuex'] = {} + } + const packageManager = ( cliOptions.packageManager || loadOptions().packageManager || diff --git a/packages/@vue/cli/lib/Generator.js b/packages/@vue/cli/lib/Generator.js index ecd826a87e..0955b212de 100644 --- a/packages/@vue/cli/lib/Generator.js +++ b/packages/@vue/cli/lib/Generator.js @@ -243,10 +243,6 @@ module.exports = class Generator { } hasPlugin (_id) { - if (['vuex'].includes(_id)) { - const pkg = this.pkg - return ((pkg.dependencies && pkg.dependencies[_id]) || (pkg.devDependencies && pkg.devDependencies[_id])) - } return [ ...this.plugins.map(p => p.id), ...Object.keys(this.pkg.devDependencies || {}), diff --git a/packages/@vue/cli/lib/add.js b/packages/@vue/cli/lib/add.js index 4d8b147921..8f6b989c63 100644 --- a/packages/@vue/cli/lib/add.js +++ b/packages/@vue/cli/lib/add.js @@ -8,16 +8,10 @@ const { hasProjectYarn, hasProjectPnpm, resolvePluginId, - resolveModule, - loadModule + resolveModule } = require('@vue/cli-shared-utils') async function add (pluginName, options = {}, context = process.cwd()) { - // special internal "plugins" - if (/^(@vue\/)?vuex$/.test(pluginName)) { - return addVuex(context) - } - const packageName = resolvePluginId(pluginName) log() @@ -38,13 +32,6 @@ async function add (pluginName, options = {}, context = process.cwd()) { } } -async function addVuex (context) { - invoke.runGenerator(context, { - id: 'core:vuex', - apply: loadModule('@vue/cli-service/generator/vuex', context) - }) -} - module.exports = (...args) => { return add(...args).catch(err => { error(err) diff --git a/packages/@vue/cli/lib/options.js b/packages/@vue/cli/lib/options.js index e2f26e729a..8aad95c6c9 100644 --- a/packages/@vue/cli/lib/options.js +++ b/packages/@vue/cli/lib/options.js @@ -10,7 +10,7 @@ const rcPath = exports.rcPath = getRcPath('.vuerc') const presetSchema = createSchema(joi => joi.object().keys({ bare: joi.boolean(), useConfigFiles: joi.boolean(), - // TODO: Use warn for router once @hapi/joi v16 releases + // TODO: Use warn for router and vuex once @hapi/joi v16 releases router: joi.boolean(), routerHistoryMode: joi.boolean(), vuex: joi.boolean(), @@ -32,7 +32,6 @@ exports.validatePreset = preset => validate(preset, presetSchema, msg => { }) exports.defaultPreset = { - vuex: false, useConfigFiles: false, cssPreprocessor: undefined, plugins: { diff --git a/packages/@vue/cli/lib/promptModules/__tests__/vuex.spec.js b/packages/@vue/cli/lib/promptModules/__tests__/vuex.spec.js index a24227baf1..b6958f7a75 100644 --- a/packages/@vue/cli/lib/promptModules/__tests__/vuex.spec.js +++ b/packages/@vue/cli/lib/promptModules/__tests__/vuex.spec.js @@ -15,8 +15,9 @@ test('vuex', async () => { ] const expectedOptions = { - vuex: true, - plugins: {} + plugins: { + '@vue/cli-plugin-vuex': {} + } } await assertPromptModule( diff --git a/packages/@vue/cli/lib/promptModules/vuex.js b/packages/@vue/cli/lib/promptModules/vuex.js index 0cad42ed55..59b77412dc 100644 --- a/packages/@vue/cli/lib/promptModules/vuex.js +++ b/packages/@vue/cli/lib/promptModules/vuex.js @@ -8,7 +8,7 @@ module.exports = cli => { cli.onPromptComplete((answers, options) => { if (answers.features.includes('vuex')) { - options.vuex = true + options.plugins['@vue/cli-plugin-vuex'] = {} } }) }