Importación de ES6 usando la ruta de inicio de sesión at ('@') en un proyecto vue.js usando Webpack

273

Estoy comenzando un nuevo proyecto vue.js, así que utilicé la herramienta vue-cli para construir un nuevo proyecto de paquete web (es decir vue init webpack).

Mientras recorría los archivos generados, noté las siguientes importaciones en el src/router/index.jsarchivo:

import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello' // <- this one is what my qusestion is about

Vue.use(Router)

export default new Router({
    routes: [
        {
            path: '/',
            name: 'Hello',
            component: Hello
        }
    ]
})

No he visto antes el signo ( @) en un camino. Sospecho que permite caminos relativos (¿tal vez?) Pero quería estar seguro de entender lo que realmente hace.

Traté de buscar en línea pero no pude encontrar una explicación (problema porque buscar "en el signo" o usar el carácter literal @no ayuda como criterio de búsqueda).

¿Qué hace el @en esta ruta (el enlace a la documentación sería fantástico) y es esto una cosa es6? ¿Una cosa de paquete web? ¿Una cosa de vue-loader?

ACTUALIZAR

Gracias Felix Kling por señalarme otra pregunta / respuesta de stackoverflow duplicada sobre esta misma pregunta.

Si bien el comentario en la otra publicación de stackoverflow no es la respuesta exacta a esta pregunta (no fue un complemento de babel en mi caso), me señaló en la dirección correcta para encontrar lo que era.

En el andamiaje que vue-cli produce para usted, parte de la configuración base del paquete web configura un alias para los archivos .vue:

Ubicación de alias dentro del proyecto

Esto tiene sentido tanto en el hecho de que le proporciona una ruta relativa desde el archivo src y elimina el requisito de .vueal final de la ruta de importación (que normalmente necesita).

¡Gracias por la ayuda!

Chris Schmitz
fuente
3
Ver mi comentario .
Felix Kling
1
@FelixKling No es un duplicado exacto porque no responde a toda la pregunta, ¿ es esto una cosa es6? ¿Una cosa de paquete web? ¿Una cosa de vue-loader?
Estus Flask
Sí, creo que la pregunta fue similar pero no un duplicado. Independientemente, descubrí de dónde provenía y actualicé la pregunta con una explicación, ya que no puedo agregarla como respuesta.
Chris Schmitz
@estus: la respuesta deja bastante claro que no es parte de ES6 sino una configuración de paquete web, ¿no te parece? Y ese es exactamente el caso aquí también, solo que la naturaleza de la configuración es un poco diferente.
Felix Kling
@FelixKling Creo que cuando Estus señaló que todavía había una pregunta sobre qué tipo de cosa es, todavía no había agregado la actualización (vi su comentario entrar mientras escribía la actualización). Estoy listo y hay una explicación detallada sobre mi instancia particular, así que estoy listo. Gracias chicos.
Chris Schmitz

Respuestas:

243

Esto se hace con la resolve.aliasopción de configuración de Webpack y no es específico de Vue.

En la plantilla Vue Webpack , Webpack está configurado para reemplazar @/con la srcruta :

  const path = require('path');

  ...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      ...
      '@': path.resolve('src'),
    }
  },
  ...

El alias se usa como:

import '@/<path inside src folder>';
Estus Flask
fuente
171
JavaScript ya no es JavaScript. Babel / webpack nos brinda este lenguaje de Frankenstein y, de alguna manera, los nuevos desarrolladores deben saber dónde termina la especificación ECMAScript y dónde comienzan los complementos / transformaciones del país de usuario. Es realmente triste, imo.
Gracias
3
@naomik Depende del usuario introducir tales trucos en la configuración o no. No es un gran problema para Vue, ya que de todos modos se basa en su formato de archivo .vue personalizado.
Estus Flask
15
Personalmente, creo que la capacidad de agregar flexibilidad si lo desea es algo bueno. Lo veo menos como frankenstein y más como voltron; puedes hacer cosas como un león o combinar diferentes leones para tener un robot más grande. Sí, a veces recibes preguntas como esta, pero no es que no se puedan encontrar las respuestas. Realmente, puede tomar la vista frankenstein o voltron con cualquier proyecto de cualquier tamaño, es solo "usar y comprender las dependencias".
Chris Schmitz
1
@ChrisSchmitz Depende del contexto y la perspectiva. Hacer algo como esto restringirá el proyecto para usar Webpack. Puede que no sea algo bueno si el proyecto intenta usar módulos ES6 nativos cuando lleguen, o es Nodo donde CommonJS puede usarse para módulos. Las rutas relativas largas pueden ser más difíciles de mantener y refactorizar, por otro lado.
Estus Flask
3
Cuando use vue-cliv3 +, debe usar ~@para hacer referencia a la srccarpeta. Por ejemplo:$font-path: '~@/assets/fonts/';
Consta de Gorgan
9

También tenga en cuenta que también puede crear variables en tsconfig:

"paths": {
  "@components": ["src/components"],
  "@scss": ["src/styles/scss"],
  "@img": ["src/assests/images"],
  "@": ["src"],
}

Esto se puede utilizar para fines de convenciones de nombres:

import { componentHeader } from '@components/header';
Tyler Canton
fuente
Pero este tipo de alias se dejará al descubierto en el JS de origen y luego, en el tiempo de ejecución, necesitará un intercesor de contenedor para que el alias funcione. ¿Tal vez hay una manera a través de babel para que esta sintaxis de TS se convierta en el momento de la compilación? Con Typecript's tscis not does y por lo tanto necesitarás algo como module-aliaso tsconfig-paths.
Ken
3

Termino con la siguiente combinación

import HelloWorld from '@/components/HelloWorld'
=>
import HelloWorld from 'src/components/HelloWorld'

IDE dejará de advertir la uri, pero esto causa una uri no válida cuando se compila, en "build \ webpack.base.conf.js"

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    'src': resolve('src'),
  }
},

Bingoo!

Luân Trương
fuente
1

resolver ('src') no funciona para mí, pero path.resolve ('src') funciona

resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': path.resolve('src')
    },
    extensions: ['*', '.js', '.vue', '.json']
  },
Marcelo Assis
fuente
1

Tal vez intente agregar en el paquete web. mix.webpackConfig hace referencia a laravel mix .

mix.webpackConfig({

    resolve: {
        alias: {
            '@imgSrc': path.resolve('resources/assets/img')
        }
    }
});

Y luego en vue uso.

<img src="@imgSrc/logo.png" />
Pablo
fuente