Importation ES6 à l'aide du chemin de connexion at ('@') dans un projet vue.js à l'aide de Webpack

273

Je commence un nouveau projet vue.js donc j'ai utilisé l'outil vue-cli pour échafauder un nouveau projet webpack (ie vue init webpack).

En parcourant les fichiers générés, j'ai remarqué les importations suivantes dans le src/router/index.jsfichier:

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
        }
    ]
})

Je n'ai jamais vu le signe at ( @) dans un chemin auparavant. Je soupçonne que cela permet des chemins relatifs (peut-être?) Mais je voulais être sûr de comprendre ce qu'il fait vraiment.

J'ai essayé de chercher autour en ligne mais je n'ai pas pu trouver d'explication (problème parce que la recherche de "au signe" ou l'utilisation du caractère littéral @n'aide pas comme critère de recherche).

Que fait @ce chemin (un lien vers la documentation serait fantastique) et est-ce une chose es6? Une chose webpack? Une chose vue-loader?

METTRE À JOUR

Merci Felix Kling de m'avoir indiqué une autre question / réponse en double stackoverflow sur cette même question.

Bien que le commentaire sur l'autre post de stackoverflow ne soit pas la réponse exacte à cette question (ce n'était pas un plugin babel dans mon cas), il m'a indiqué la bonne direction pour trouver ce que c'était.

Dans l'échafaudage que vue-cli lance pour vous, une partie de la configuration de base du webpack configure un alias pour les fichiers .vue:

Emplacement de l'alias dans le projet

Cela a du sens à la fois dans le fait qu'il vous donne un chemin relatif à partir du fichier src et qu'il supprime l'exigence de .vuela fin du chemin d'importation (dont vous avez normalement besoin).

Merci pour l'aide!

Chris Schmitz
la source
3
Voir mon commentaire .
Felix Kling
1
@FelixKling Ce n'est pas un doublon exact car il ne répond pas à toute la question, est-ce une chose es6? Une chose webpack? Une chose vue-loader?
Estus Flask
Oui, je pense que la question était similaire mais pas en double. Quoi qu'il en soit, j'ai compris d'où cela venait et j'ai mis à jour la question avec une explication car je ne peux pas l'ajouter comme réponse.
Chris Schmitz
@estus: la réponse montre clairement qu'il ne fait pas partie d'ES6 mais d'une configuration de webpack, vous ne pensez pas? Et c'est exactement le cas ici aussi, seulement que la nature de la configuration est un peu différente.
Felix Kling
@FelixKling Je crois que quand estus a souligné qu'il y avait encore une question sur le genre de chose, je n'avais pas encore ajouté la mise à jour (j'ai vu son commentaire arriver pendant que je tapais la mise à jour). Je suis prêt et il y a une explication détaillée sur mon cas particulier, donc je suis prêt à partir. Merci les gars.
Chris Schmitz

Réponses:

243

Cela se fait avec l' resolve.aliasoption de configuration Webpack et n'est pas spécifique à Vue.

Dans le modèle Vue Webpack , Webpack est configuré pour remplacer @/par srcchemin :

  const path = require('path');

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

L'alias est utilisé comme:

import '@/<path inside src folder>';
Flacon Estus
la source
171
JavaScript n'est tout simplement plus JavaScript. Babel / webpack nous donne ce langage de Frankenstein et en quelque sorte les nouveaux développeurs sont censés savoir où se terminent les spécifications ECMAScript et où commencent les plugins / transformations utilisateur. C'est vraiment triste, imo.
Merci
3
@naomik C'est à l'utilisateur d'introduire de telles astuces dans la configuration ou non. Ce n'est pas un gros problème pour Vue car il s'appuie de toute façon sur son format de fichier .vue personnalisé.
Estus Flask
15
Personnellement, je pense que la possibilité d'ajouter de la flexibilité si vous le souhaitez est une bonne chose. Je le vois moins comme Frankenstein et plus comme Voltron; vous pouvez faire des trucs de lion ou combiner différents lions pour avoir un robot plus gros. Oui, parfois vous obtenez des questions comme celle-ci, mais ce n'est pas comme si les réponses étaient introuvables. Vraiment, vous pouvez prendre la vue frankenstein ou voltron avec n'importe quel projet de n'importe quelle taille, c'est juste "utiliser et comprendre les dépendances".
Chris Schmitz
1
@ChrisSchmitz Cela dépend du contexte et de la perspective. Faire quelque chose comme ça limitera le projet à utiliser Webpack. Ce n'est peut-être pas une bonne chose si le projet a l'intention d'utiliser des modules natifs ES6 à leur arrivée, ou si c'est Node où CommonJS peut être utilisé pour les modules. D'un autre côté, les longs trajets relatifs peuvent être plus difficiles à entretenir et à refactoriser.
Estus Flask
3
Lorsque vous utilisez vue-cliv3 +, vous devez utiliser ~@pour référencer le srcdossier. Par exemple:$font-path: '~@/assets/fonts/';
Consta Gorgan
9

Gardez également à l'esprit que vous pouvez également créer des variables dans tsconfig:

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

Cela peut être utilisé à des fins de convention de dénomination:

import { componentHeader } from '@components/header';
Canton de Tyler
la source
Mais ce type d'alias sera laissé à nu dans le JS source, puis au moment de l'exécution, vous devrez avoir un wrapper intercéder pour faire fonctionner l'alias. Peut-être existe-t-il un moyen via babel pour que cette syntaxe TS soit convertie au moment de la construction? Avec Typescript, ce tscn'est pas le cas et vous aurez donc besoin de quelque chose comme module-aliasou tsconfig-paths.
ken
3

Je surmonte la combinaison suivante

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

IDE arrêtera d'avertir l'uri, mais cela provoquera un uri invalide lors de la compilation, dans "build \ webpack.base.conf.js"

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

Bingoo!

Luân Trương
la source
1

resolve ('src') ne fonctionne pas pour moi mais path.resolve ('src') fonctionne

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

Essayez peut-être d'ajouter dans le webpack. mix.webpackConfig fait référence à laravel mix .

mix.webpackConfig({

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

Et puis en vue utilisation.

<img src="@imgSrc/logo.png" />
Paul
la source