Vue 3 with TypeScript — Setup A New Project with the Vue-Cli

Damiano Fusco
vuetypescript.com
Published in
5 min readAug 8, 2020

To setup the project, you will use the terminal and the vue-cli. These steps are the same as a Vue 2 app, but at the end with use vue add vue-next to upgrade to Vue 3 and make a few changes to some of the files to complete the upgrade.

If you do not have this installed on your computer yet, you can install it globally using npm:

npm install -g @vue/cli

Create Project Wizard

To create our project, do:

vue create my-vue3-app

Next it will ask you if you want to choose a default preset or manually select individual features. Use the arrow key to move up/down choose Manually select features by pressing the enter key:

Vue CLI v4.4.6
? Please pick a preset:
default (babel, eslint)
❯ Manually select features

Now move up/down with arrows and use the space-bar to check/uncheck the features you want. For this project select TypeScript, Router, Vuex, CSS Pre-processors, Linter / Formatter, Unit Testing only then hit the Enter key::

Vue CLI v4.4.6
? Please pick a preset: Manually select features
? Check the features needed for your project:
◯ Babel
◉ TypeScript
◯ Progressive Web App (PWA) Support
◉ Router
◉ Vuex
◉ CSS Pre-processors
◉ Linter / Formatter
❯◉ Unit Testing
◯ E2E Testing

It will then ask you a series of questions. Make the following choices:

? Use class-style component syntax? (Y/n) n? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (y/N) N? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) n? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): 
Sass/SCSS (with dart-sass)
❯ Sass/SCSS (with node-sass)
Less
Stylus
? Pick a linter / formatter config: (Use arrow keys)
❯ ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
ESLint + Prettier
TSLint (deprecated)
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Lint on save
◯ Lint and fix on commit
? Pick a unit testing solution: (Use arrow keys)
❯ Mocha + Chai
Jest
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files
In package.json
? Save this as a preset for future projects? (y/N) N

NOTE: It might also ask you at this point if you want to use yarn or npm as your package manager. If so, please choose npm.

The vue-cli will now create the project, install all the required NPM packages, create the configuration files, and stub some preliminary code (Home and About views, a simple HelloWorld component, Vuex store, etc)

At the end it should display a message similar to this:

🎉  Successfully created project my-vue3-app.
👉 Get started with the following commands:
$ cd my-vue3-app
$ npm run serve

The first command will navigate to the current sub-directory called my-vue3-app, the second will serve the app with the vue-cli-service. You’ll see a message similar to this displayed:

DONE  Compiled successfully in 2415ms                                                                         10:48:46 AMType checking in progress...  App running at:
- Local: http://localhost:8080/
- Network: http://192.168.1.7:8080/
Note that the development build is not optimized.
To create a production build, run npm run build.
No type errors found
Version: typescript 3.9.7
Time: 2537ms

From the web browser, navigate to the http://localhost:8080/ address and you’ll see application home page rendered:

This image has an empty alt attribute; its file name is 1*AleQBckYNXTYjRky8BSMfw.png

Now stop the app from running by typing CTRL+C in the terminal.

Now let’s make it a Vue 3 app with this command:

> vue add vue-next

It should display something like this once it is done:

✔  Successfully invoked generator for plugin: vue-cli-plugin-vue-next
vue-next Installed vuex 4.0.
vue-next Documentation available at https://github.com/vuejs/vuex/tree/4.0
vue-next Installed vue-router 4.0.
vue-next Documentation available at https://github.com/vuejs/vue-router-next
vue-next Installed @vue/test-utils 2.0.
vue-next Documentation available at https://github.com/vuejs/vue-test-utils-next

Open the package.json file and verify that the vue, vue-router, vuex packages have been update to the latest version (version3 for Vue, and 4 for vue-router and vuex. Note that they might still be in alpha or beta). The “dependencies” section should look similar to this:

"dependencies": {
"vue": "^3.0.0-beta.1",
"vue-router": "^4.0.0-alpha.6",
"vuex": "^4.0.0-alpha.1"
}

Open the src/main.ts file and verify that it has been upgraded to use the new Vue 3 way of instantiating the app:

import { createApp } from 'vue';
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App)
.use(router)
.use(store)
.mount('#app')

Unfortunately, it won’t automatically update all the files so perform the following additional steps to update some of the files.

Replace the <script> section content of the src/components/HelloWorld.vue with this:

<script lang="ts">
export default {
name: 'HelloWorld',
props: {
msg: String,
},
setup() {
return {
}
}
}
</script>

Replace the src/store/index.ts code with this:

import { createStore, Store } from 'vuex'export default createStore({
state: {
},
mutations: {
},
actions: {
},
modules: {
}
})

For the src/router/index.ts file, it might not update the code copletely as expected. Just in case, replace it with this code:

import { RouteRecordRaw, createRouter, createWebHashHistory } from 'vue-router';
import Home from '../views/Home.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router

Finally, we have to also update the typescript shim declaration files. Since in this project we do not use tsx, just delete the src/shims-tsx.d.ts file.

For the src/shims-vue.d.ts, it might have updated it as expected, otherwise replace it with this:

declare module '*.vue' {
import { defineComponent } from "vue";
const Component: ReturnType<typeof defineComponent>;
export default Component;
}

Finally, also delete the tests/unit/example.spec.ts file.

Now try to run the app again with:

> npm run serve

In the browser, navigate to http://localhost:8080/ again and verify the app is rendering without errors.

What We Learned

  • How to create the basic plumbing for a Vue 3 app using the vue-cli and vue add vue-next
  • How to serve the app using the vue-cli service through the command npm run serve

Originally published at http://www.scalingvue.com on August 8, 2020.

--

--

Damiano Fusco
vuetypescript.com

Build "Large Scale Apps with Vue 3 and TypeScript" http://leanpub.com/vue-typescript/c/X3hLzl6Ygtr2 #Developer, #VueJS, #JavaScript, #TypeScript