Vue 3 se ha reconstruido desde cero usando TypeScript. Desde Vue v2, Vue ha soportado TypeScript y aún lo hace. Sin embargo, en estos días se siente cierto entusiasmo e interés por desarrollar aplicaciones con Vue usando TypeScript.
Sin lugar a dudas, desarrollar aplicaciones JavaScript con TypeScript es como un salvavidas. TypeScript, además de las muchas ventajas que trae, proporciona seguridad con los tipos. Tú estarás feliz, tu IDE estará feliz y, por supuesto, hace que la escritura de JavaScript sea más interesante y robusta.
Este artículo te trae una guía paso a paso para crear una aplicación Vue 2, agrega compatibilidad con TypeScript, actualiza la aplicación a Vue 3 RC 5, compila la aplicación, corrige algunos errores comunes en la etapa de compilación y finalmente se asegura que la aplicación pueda ejecutarse en el navegador.
Para acceder al código fuente que acompaña a este artículo, ve al Repositorio en GitHub.
Nota - Este artículo se aplica a aplicaciones Vue 2 existentes que deseen actualizar a Vue 3 y agregar TypeScript, así como a cualquier aplicación nueva.
Demo
Comencemos creando una aplicación Vue 2 y siguiendo los pasos necesarios.
Creando una Nueva App
Como sugiere el subtítulo, crearemos una aplicación Vue 2 utilizando la CLI de Vue.
Paso 1: Instala el paquete @vue/cli
Abre una terminal y ejecuta el comando:
npm install -g @vue/cli
Paso 2: Crea una nueva App Vue 2
vue create vue-ts
Selecciona el default preset
(ajuste predeterminado) cuando se solicite. La CLI(Herramienta de línea de comandos) hace un scaffolding de los archivos y también inicializa un repositorio Git para la aplicación.
Paso 3: Ejecuta la aplicación
Ejecuta la aplicación para asegurarte de que esta funciona correctamente:
cd vue-ts
npm run serve
¡Deberías tener una App corriendo ahora!
Agregando el Soporte de TypeScript
Ejecutemos el siguiente comando para agregar el soporte de TypeScript en nuestra app.
vue add typescript
El comando anterior descarga e instala el plugin(complemento) @vue/cli-plugin-typescript para brindar compatibilidad con TypeScript en nuestra aplicación.
Una vez instalado, se harán algunas preguntas que se muestran en la Figura 1.
Preguntas en la Instalación |
---|
Use class-style component syntax? Yes |
Use Babel alongside TypeScript? Yes |
Convert all .js files to .ts? Yes |
Allow .js files to be compiled? Yes |
Skip type checking of all declaration files? Yes |
Entre las muchas cosas que el plugin agrega a la aplicación, es importante señalar el archivo tsconfig.json
en la raíz de la carpeta de la aplicación. TypeScript usa este archivo para personalizar el proceso de compilación y te da la oportunidad de hacerlo según tus necesidades. Las siguientes configuraciones son recomendadas por el equipo de Vue. Sin embargo, siéntete libre de agregar o cambiar cosas como mejor lo consideres.
Para una lista completa de todas las opciones disponibles para este archivo, revisa este link tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
Finalmente, asegúrate de confirmar sus cambios en Git con un commit antes de continuar.
Actualizar la aplicación a Vue 3
Ahora que la aplicación soporta la definición de componentes Vue en TypeScript, sigamos adelante y actualicemos la aplicación a Vue 3.
Paso 1: Agrega el plugin Vue-Next
Abre una terminal y navega hasta la carpeta raíz de nuestra aplicación. Luego, ejecuta el siguiente comando:
vue agregar vue-siguiente
El comando previo descarga e instala el plugin vue-cli-plugin-vue-next para hacer un upgrade(actualizar) la aplicación a Vue 3.
La Figura 2 muestra todos los pasos que ha seguido la CLI(Interfaz de línea de comandos) para realizar la actualización.
Abre el archivo package.json
y asegúrate que las secciones de dependencies
y dev-dependencies
sean similares al contenido siguiente:
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0-rc.5"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.4.0",
"@vue/cli-plugin-eslint": "~4.4.0",
"@vue/cli-service": "~4.4.0",
"@vue/compiler-sfc": "^3.0.0-rc.5",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0-alpha.0",
"vue-cli-plugin-vue-next": "~0.1.3"
},
El plugin vue-next pasa automáticamente por los archivos de tu aplicación y los convierte para que sean compatibles con la sintaxis de Vue 3.
Paso 2: Corrige las advertencias y errores
En este punto, si compilas la aplicación, verás algunas warnings(advertencias) y errores. Estos están relacionados principalmente con el uso de TypeScript en Vue 3. Abordemos los mismos uno por uno.
Ejecuta el siguiente comando para compilar y levantar la aplicación en el navegador:
npm run serve
El resultado se muestra a continuación:
Advertencias(Warnings)
warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'
warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'
warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'
warning in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'
warning in ./node_modules/vue-property-decorator/lib/vue-property-decorator.js
"export 'default' (reexported as 'Vue') was not found in 'vue'
Errores
TS1238: Unable to resolve signature of class decorator when called as an expression.
Type '<VC extends VueClass<any>>(target: VC) => VC' is not assignable to type 'typeof HelloWorld'.
Type '<VC extends VueClass<any>>(target: VC) => VC' provides no match for the signature 'new (): HelloWorld'.
33 | import { Component, Prop, Vue } from 'vue-property-decorator';
34 |
> 35 | @Component
| ^^^^^^^^^^
36 | export default class HelloWorld extends Vue {
37 | @Prop() private msg!: string;
38 | }
ERROR in src/components/HelloWorld.vue:36:41
TS2507: Type 'typeof import("/Users/bhaidar/projects/vue-ts/node_modules/vue/dist/vue")' is not a constructor function type.
34 |
35 | @Component
> 36 | export default class HelloWorld extends Vue {
| ^^^
37 | @Prop() private msg!: string;
38 | }
39 | </script>
Las advertencias y los errores anteriores revelan que TypeScript no puede digerir el Componente HelloWorld
que está escrito en la antigua sintaxis de TypeScript para Vue 2. Procedamos a refactorizar este componente para usar la última sintaxis de TypeScript en Vue 3.
Actualmente, el componente /components/HelloWorld.vue
se define de la siguiente forma:
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
}
</script>
En primer lugar, note el uso de un atributo lang = "ts"
en el elemento <script>
. Esto define un bloque de código TypeScript en lugar de código JavaScript.
Reemplacemos este código como sigue:
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
required: false,
},
},
});
</script>
El código usa el nuevo método global defineComponent
. Este método permite a TypeScript inferir adecuadamente los tipos dentro de las opciones del componente Vue.
El método defineComponent
acepta un objeto como parámetro de entrada. Puede ser un objeto Options API o un objeto Composition API.
Ahora que se ha refactorizado el componente HelloWorld
. Sigamos adelante y actualicemos el componente App.vue
para usar la nueva sintaxis de TypeScript en Vue 3:
<script lang="ts">
import { defineComponent } from 'vue';
import HelloWorld from '@/components/HelloWorld.vue'
export default defineComponent({
name: 'App',
components: {
HelloWorld
},
});
</script>
Ejecutemos la aplicación usando el siguiente comando:
npm run serve
Wow, ¡Más errores y advertencias!
Argument of type 'typeof import(\"/.../vue-ts/
node_modules/vue/dist/vue\")' is not assignable to parameters of type 'PublicAPIComponent'.
Type 'typeof import(\"/.../vue-ts/node_modules/vue/dist/vue\")' is not
assignable to type 'ComponentOptionsWithObjectProps<any, any, any,
any, any, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions,
string, Readonly<{ [x: string]: any; }> | Readonly<...>>'.
...
Importando los Components en Vue
El error anterior se genera en la línea #2 en el archivo main.ts
:
import { createApp } from 'vue';
import App from './App.vue'
^^^
createApp(App).mount('#app')
Typecript, como ES 6, soporta módulos mediante el uso de las palabras clave import y export. Siempre que estés escribiendo tus módulos en TypeScript, esto es, archivos que terminan con .ts, entonces estás cubierto.
El error anterior indica que TypeScript no puede importar el componente App
, es como si TypeScript no entendiera lo que retorna el módulo App.vue
.
¿Cuál es la solución? Definir un archivo de declaración(declaration file) en la carpeta raíz de la app. Este archivo tiene la extensión .d.ts
. Básicamente, este archivo facilita que las herramientas sepan cómo manejar los archivos *.vue
, también conocidos como Single File Components(SFC) o Componentes de Archivo Único.
Busca el archivo shim-vue.d.ts
en la carpeta raíz de tu aplicación y reemplaza su contenido con lo siguiente:
declare module "*.vue" {
import { defineComponent } from "vue";
const component: ReturnType<typeof defineComponent>;
export default component;
}
El código anterior declara un módulo TypeScript para cada archivo que termina en *.vue
(SFC).
TypeScript procesa dicho módulo como si tuviera lo siguiente:
- Una declaración de import para el método global
defineComponent
- Declaración de una variable
component
de tipodefineComponent
- Finalmente, un export predeterminado de la variable
component
Teniendo el archivo de "corrección" anterior permite a TypeScript considerar cualquier componente de Vue como un módulo bien definido.
Ejecutar la aplicación
Ahora se puede ejecutar la aplicación de una forma segura sabiendo que correrá correctamente dentro del navegador.
Ejecute el siguiente comando para iniciar la aplicación:
npm run serve
Navega a la URL http://localhost:8080
dentro de tu navegador y deberías poder ver la página de inicio predeterminada de una aplicación Vue 3 recién creada usando TypeScript, como se muestra en la Figura 3 a continuación.
Usando Composition API con TypeScript
Ahora que la aplicación es compatible con TypeScript, permíteme mostrarte cómo puedes usar Composition API y la seguridad de tipos para definir una función con parámetros tipados.
Reemplaza el contenido script del componente HelloWorld
con lo siguiente:
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
required: false,
},
},
setup(props) {
const printMsg = (msg: string) => console.log(`The message is: ${msg}`);
return {
printMsg,
};
},
});
Observa cómo el código anterior define una nueva función usando la API de composición con un parámetro tipado. El parámetro se llama msg
y tiene un tipo de datos de cadena o string
.
Conclusión
Ya sea que estés actualizando tu aplicación Vue 2 existente o iniciando con una nueva, el artículo provee un enfoque paso a paso para agregar TypeScript a la aplicación actualizando al mismo tiempo a Vue 3, corrigiendo todas las advertencias y errores para finalmente levantar la aplicación con éxito en el navegador.
Este es tan sólo un paso en tu camino para crear aplicaciones Vue 3 con TypeScript. El siguiente paso será familiarizarse más con TypeScript.
Este artículo es una traducción al español de su versión en inglés