From bcf22459512effe7db8f6239a9b2e06ecebe2bf6 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan Date: Mon, 23 Jun 2025 11:27:55 +0400 Subject: [PATCH 01/12] feat(vue): Implemented vte build for vue applications --- .../src/applications/application.vue.js | 9 +++---- .../templates/vue-v3/application/src/App.vue | 2 +- .../src/components/header-toolbar.vue | 2 +- .../src/layouts/side-nav-inner-toolbar.vue | 4 +-- .../src/layouts/side-nav-outer-toolbar.vue | 4 +-- .../templates/vue-v3/application/src/main.js | 2 +- .../vue-v3/application/src/router.js | 10 ++++---- .../vue-v3/application/vite.config.js | 25 +++++++++++++++++++ .../vue-v3/application/vue.config.js | 1 - 9 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js delete mode 100644 packages/devextreme-cli/src/templates/vue-v3/application/vue.config.js diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 9d02f04fa..8e7428a36 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -18,8 +18,7 @@ const preparePackageJsonForTemplate = (appPath, appName) => { const dependencies = [ { name: 'sass', version: '^1.34.1' }, { name: 'vue-router', version: '^3.0.1' }, - { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true }, - { name: 'sass-loader', version: '^10', dev: true } + { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true } ]; const nameDepends = dependencies.map(d => d.name); @@ -38,8 +37,8 @@ const preparePackageJsonForTemplate = (appPath, appName) => { }; async function createVueApp(name, depsVersionTag) { - const argList = ['-p', `@vue/cli@${depsVersionTag}`, 'vue', 'create', name, '--registry', 'https://registry.npmjs.org/', '-p "Default (Vue 3)"']; - + const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--default']; + return runCommand('npx', argList); } @@ -78,7 +77,7 @@ const create = async(appName, options) => { }; const modifyIndexHtml = (appPath, appName) => { - const indexHtmlPath = path.join(appPath, 'public', 'index.html'); + const indexHtmlPath = path.join(appPath, 'index.html'); let htmlContent = fs.readFileSync(indexHtmlPath).toString(); htmlContent = htmlContent.replace(/(\w+\s*)+<\/title>/, `<title>${appName}<\/title>`); diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/App.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/App.vue index acc13f153..be20ee334 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/App.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/App.vue @@ -17,7 +17,7 @@ </template> <script> -import AppFooter from "./components/app-footer"; +import AppFooter from "./components/app-footer.vue"; import { sizes, subscribe, unsubscribe } from "./utils/media-query"; import { getCurrentInstance, diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/header-toolbar.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/header-toolbar.vue index 1fe6a7725..759dc8909 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/header-toolbar.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/header-toolbar.vue @@ -52,7 +52,7 @@ import auth from "../auth"; import { useRouter, useRoute } from 'vue-router'; import { ref } from 'vue'; -import UserPanel from "./user-panel"; +import UserPanel from "./user-panel.vue"; import ThemeSwitcher from './theme-switcher.vue'; export default { diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue index b1a765f35..f7c42f0a4 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue @@ -57,8 +57,8 @@ import DxDrawer from "devextreme-vue/drawer"; import DxScrollView from "devextreme-vue/scroll-view"; import DxToolbar, { DxItem } from "devextreme-vue/toolbar"; -import HeaderToolbar from "../components/header-toolbar"; -import SideNavMenu from "../components/side-nav-menu"; +import HeaderToolbar from "../components/header-toolbar.vue"; +import SideNavMenu from "../components/side-nav-menu.vue"; import menuItems from "../app-navigation"; import { ref, watch, computed } from 'vue'; import { useRoute } from 'vue-router'; diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue index e466ecf82..365b39d72 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue @@ -39,8 +39,8 @@ import DxDrawer from "devextreme-vue/drawer"; import DxScrollView from "devextreme-vue/scroll-view"; import menuItems from "../app-navigation"; -import HeaderToolbar from "../components/header-toolbar"; -import SideNavMenu from "../components/side-nav-menu"; +import HeaderToolbar from "../components/header-toolbar.vue"; +import SideNavMenu from "../components/side-nav-menu.vue"; import { computed, ref, watch} from 'vue'; import { useRoute } from 'vue-router'; diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/main.js b/packages/devextreme-cli/src/templates/vue-v3/application/src/main.js index 578233357..b6feb9430 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/main.js +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/main.js @@ -2,7 +2,7 @@ import { createApp } from "vue"; import router from "./router"; import themes from "devextreme/ui/themes"; -import App from "./App"; +import App from "./App.vue"; import appInfo from "./app-info"; themes.initialized(() => { diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/router.js b/packages/devextreme-cli/src/templates/vue-v3/application/src/router.js index 0d99e35f3..89aa98ffa 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/router.js +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/router.js @@ -1,11 +1,11 @@ import auth from "./auth"; import { createRouter, createWebHashHistory } from "vue-router"; -<%=^empty%>import Home from "./views/home-page"; -import Profile from "./views/profile-page"; -import Tasks from "./views/tasks-page"; -<%=/empty%>import defaultLayout from "./layouts/<%=layout%>"; -import simpleLayout from "./layouts/single-card"; +<%=^empty%>import Home from "./views/home-page.vue"; +import Profile from "./views/profile-page.vue"; +import Tasks from "./views/tasks-page.vue"; +<%=/empty%>import defaultLayout from "./layouts/<%=layout%>.vue"; +import simpleLayout from "./layouts/single-card.vue"; function loadView(view) { return () => import (/* webpackChunkName: "login" */ `./views/${view}.vue`) diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js b/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js new file mode 100644 index 000000000..3cc6e2506 --- /dev/null +++ b/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js @@ -0,0 +1,25 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueDevTools from 'vite-plugin-vue-devtools' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + vueDevTools(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + }, + }, + css: { + preprocessorOptions: { + scss: { + api: 'legacy' + } + } + }, +}) diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/vue.config.js b/packages/devextreme-cli/src/templates/vue-v3/application/vue.config.js deleted file mode 100644 index f053ebf79..000000000 --- a/packages/devextreme-cli/src/templates/vue-v3/application/vue.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {}; From 76ea6f0f9387ba2bf63dffc3e2bc82d55eadc678 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 12:12:17 +0400 Subject: [PATCH 02/12] vhange npx to npm --- packages/devextreme-cli/src/applications/application.vue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 8e7428a36..fda2991f3 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -39,7 +39,7 @@ const preparePackageJsonForTemplate = (appPath, appName) => { async function createVueApp(name, depsVersionTag) { const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--default']; - return runCommand('npx', argList); + return runCommand('npm', argList); } const bumpVue = (appPath, versionTag) => { From 64df72899486b2cf26cf29df1df0100cb1462aaa Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 12:20:59 +0400 Subject: [PATCH 03/12] fix add view issue --- packages/devextreme-cli/src/applications/application.vue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index fda2991f3..a21ccf1de 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -174,7 +174,7 @@ const addView = (pageName, options) => { const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder'); const getCorrectExtension = (fileExtension) => fileExtension; templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension); - moduleUtils.insertImport(routingModulePath, `./views/${pageName}`, componentName, true); + moduleUtils.insertImport(routingModulePath, `./views/${pageName}.vue`, componentName, true); insertItemToArray(routingModulePath, navigationData.route); insertItemToArray(navigationModulePath, navigationData.navigation); }; From 037f59411104c52a1642f962f257a960ba0b0658 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 12:47:08 +0400 Subject: [PATCH 04/12] fix formatting --- packages/devextreme-cli/src/applications/application.vue.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index a21ccf1de..1e56c038c 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -38,7 +38,6 @@ const preparePackageJsonForTemplate = (appPath, appName) => { async function createVueApp(name, depsVersionTag) { const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--default']; - return runCommand('npm', argList); } From c2f8eb78acd1a095ca72cd0b3b90b7231b8775d4 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 13:30:35 +0400 Subject: [PATCH 05/12] fix: remove unnecessary bumps --- packages/devextreme-cli/src/applications/application.vue.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 1e56c038c..0d0702be7 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -45,9 +45,6 @@ const bumpVue = (appPath, versionTag) => { const dependencies = [ { name: 'vue', version: versionTag }, { name: 'vue-router', version: versionTag }, - { name: '@vue/cli-plugin-babel', version: versionTag, dev: true }, - { name: '@vue/cli-plugin-eslint', version: versionTag, dev: true }, - { name: '@vue/cli-service', version: versionTag, dev: true }, ]; packageJsonUtils.addDependencies(appPath, dependencies); From a8206384a03b7bbd534b1c16e0bb319443468b94 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 13:52:31 +0400 Subject: [PATCH 06/12] fix: Add lint to the new vue app --- packages/devextreme-cli/src/applications/application.vue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 0d0702be7..be336d743 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -37,7 +37,7 @@ const preparePackageJsonForTemplate = (appPath, appName) => { }; async function createVueApp(name, depsVersionTag) { - const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--default']; + const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--eslint', '--default']; return runCommand('npm', argList); } From e636531e66bfbb61d8d74b498dac1fa210df0e39 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 15:18:50 +0400 Subject: [PATCH 07/12] fix: remove example code --- packages/devextreme-cli/src/applications/application.vue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index be336d743..7e9d4906c 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -37,7 +37,7 @@ const preparePackageJsonForTemplate = (appPath, appName) => { }; async function createVueApp(name, depsVersionTag) { - const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--eslint', '--default']; + const argList = ['create', `vue${depsVersionTag ? `@${depsVersionTag}` : ''}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--eslint', '--default', '--bare']; return runCommand('npm', argList); } From 5f79c9957e8484021df12362c9e06fb6f30f9e97 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 15:45:13 +0400 Subject: [PATCH 08/12] fix non logical linter errors --- .../vue-v3/application/src/components/theme-switcher.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue index fbaf0711e..4dc476d50 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue @@ -8,6 +8,7 @@ </template> <script setup> +/* eslint-disable */ import { DxButton } from 'devextreme-vue/button'; import { themeService } from '../theme-service'; @@ -16,4 +17,5 @@ const currentTheme = themeService.currentTheme; function onClickButton() { themeService.switchAppTheme(); } +/* eslint-enable */ </script> From 6a0b0a5e33b0cff0bdc27d4a5c5999d74aa0b88e Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Mon, 23 Jun 2025 16:01:37 +0400 Subject: [PATCH 09/12] lint error fix for vue files --- .../vue-v3/application/eslint.config.js | 32 +++++++++++++++++++ .../src/components/theme-switcher.vue | 2 -- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 packages/devextreme-cli/src/templates/vue-v3/application/eslint.config.js diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/eslint.config.js b/packages/devextreme-cli/src/templates/vue-v3/application/eslint.config.js new file mode 100644 index 000000000..439abde1b --- /dev/null +++ b/packages/devextreme-cli/src/templates/vue-v3/application/eslint.config.js @@ -0,0 +1,32 @@ +import { defineConfig, globalIgnores } from 'eslint/config' +import globals from 'globals' +import js from '@eslint/js' +import pluginVue from 'eslint-plugin-vue' + +export default defineConfig([ + { + name: 'app/files-to-lint', + files: ['**/*.{js,mjs,jsx,vue}'], + }, + + globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), + + { + languageOptions: { + globals: { + ...globals.browser, + }, + }, + }, + + js.configs.recommended, + ...pluginVue.configs['flat/essential'], + + { + name: 'disable-unused-vars-in-vue', + files: ['**/*.vue'], + rules: { + 'no-unused-vars': 'off', + }, + }, +]) \ No newline at end of file diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue index 4dc476d50..fbaf0711e 100644 --- a/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue +++ b/packages/devextreme-cli/src/templates/vue-v3/application/src/components/theme-switcher.vue @@ -8,7 +8,6 @@ </template> <script setup> -/* eslint-disable */ import { DxButton } from 'devextreme-vue/button'; import { themeService } from '../theme-service'; @@ -17,5 +16,4 @@ const currentTheme = themeService.currentTheme; function onClickButton() { themeService.switchAppTheme(); } -/* eslint-enable */ </script> From 2149b4c1e98d43d274bdf7011422b93ffbb89027 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Wed, 25 Jun 2025 14:02:50 +0400 Subject: [PATCH 10/12] fix: Add sass-embedded for consistency --- .../src/applications/application.vue.js | 2 +- .../vue-v3/application/vite.config.js | 25 ------------------- 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 7e9d4906c..96b64cc2c 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -16,7 +16,7 @@ const defaultStyles = [ const preparePackageJsonForTemplate = (appPath, appName) => { const dependencies = [ - { name: 'sass', version: '^1.34.1' }, + { name: 'sass-embedded', version: '^1.85.1' }, { name: 'vue-router', version: '^3.0.1' }, { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true } ]; diff --git a/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js b/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js deleted file mode 100644 index 3cc6e2506..000000000 --- a/packages/devextreme-cli/src/templates/vue-v3/application/vite.config.js +++ /dev/null @@ -1,25 +0,0 @@ -import { fileURLToPath, URL } from 'node:url' - -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import vueDevTools from 'vite-plugin-vue-devtools' - -// https://vite.dev/config/ -export default defineConfig({ - plugins: [ - vue(), - vueDevTools(), - ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - }, - }, - css: { - preprocessorOptions: { - scss: { - api: 'legacy' - } - } - }, -}) From 2c505f261eb6d7d1f331e229ddca529c8712aec5 Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Wed, 25 Jun 2025 15:05:48 +0400 Subject: [PATCH 11/12] fix: Fix vite versions to avoid problems with the new 7.0.0 --- packages/devextreme-cli/src/applications/application.vue.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index 96b64cc2c..e0b571e9f 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -18,6 +18,8 @@ const preparePackageJsonForTemplate = (appPath, appName) => { const dependencies = [ { name: 'sass-embedded', version: '^1.85.1' }, { name: 'vue-router', version: '^3.0.1' }, + { name: 'vite', version: '^6.2.4', dev: true }, + { name: '@vitejs/plugin-vue', version: '^5.2.3', dev: true }, { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true } ]; From 576fb2fe3065bb25a2d002ff8481401743ea3a1f Mon Sep 17 00:00:00 2001 From: Arman Jivanyan <arman.jivanyan@devexpress.com> Date: Wed, 25 Jun 2025 15:29:07 +0400 Subject: [PATCH 12/12] revert fixing version --- packages/devextreme-cli/src/applications/application.vue.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/devextreme-cli/src/applications/application.vue.js b/packages/devextreme-cli/src/applications/application.vue.js index e0b571e9f..96b64cc2c 100644 --- a/packages/devextreme-cli/src/applications/application.vue.js +++ b/packages/devextreme-cli/src/applications/application.vue.js @@ -18,8 +18,6 @@ const preparePackageJsonForTemplate = (appPath, appName) => { const dependencies = [ { name: 'sass-embedded', version: '^1.85.1' }, { name: 'vue-router', version: '^3.0.1' }, - { name: 'vite', version: '^6.2.4', dev: true }, - { name: '@vitejs/plugin-vue', version: '^5.2.3', dev: true }, { name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true } ];