ES6-Import mit dem Anmeldepfad at ('@') in einem vue.js-Projekt mit Webpack

273

Ich beginne ein neues vue.js-Projekt, also habe ich das vue-cli-Tool verwendet, um ein neues Webpack-Projekt (dh vue init webpack) zu erstellen .

Als ich durch die generierten Dateien ging, bemerkte ich die folgenden Importe in der src/router/index.jsDatei:

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

Ich habe das at-Zeichen ( @) noch nie in einem Pfad gesehen. Ich vermute, dass es relative Pfade zulässt (vielleicht?), Aber ich wollte sichergehen, dass ich verstehe, was es wirklich tut.

Ich habe versucht, online zu suchen, konnte aber keine Erklärung finden (wahrscheinlich, weil die Suche nach "at sign" oder die Verwendung des Literalzeichens @nicht als Suchkriterium hilft).

Was macht das @auf diesem Weg (Link zur Dokumentation wäre fantastisch) und ist das eine es6-Sache? Eine Webpack-Sache? Eine Vue-Loader-Sache?

AKTUALISIEREN

Vielen Dank an Felix Kling, der mich auf eine andere doppelte Frage / Antwort zum Stapelüberlauf zu derselben Frage hingewiesen hat.

Obwohl der Kommentar zum anderen Stackoverflow-Beitrag nicht die genaue Antwort auf diese Frage ist (in meinem Fall war es kein Babel-Plugin), hat er mich in die richtige Richtung gelenkt, um herauszufinden, was es war.

In dem Gerüst, das vue-cli für Sie bereitstellt, richtet ein Teil der Basis-Webpack-Konfiguration einen Alias ​​für .vue-Dateien ein:

Alias-Position innerhalb des Projekts

Dies macht Sinn , sowohl in der Tatsache , dass es Ihnen einen relativen Pfad von der src - Datei gibt und es beseitigt die Notwendigkeit der .vueam Ende des Importpfades (die Sie normalerweise benötigen).

Danke für die Hilfe!

Chris Schmitz
quelle
3
Siehe meinen Kommentar .
Felix Kling
1
@FelixKling Es ist kein genaues Duplikat, weil es nicht die ganze Frage beantwortet. Ist das eine es6-Sache? Eine Webpack-Sache? Eine Vue-Loader-Sache?
Estus Flask
Ja, ich denke die Frage war ähnlich, aber kein Duplikat. Unabhängig davon habe ich herausgefunden, woher es kommt, und die Frage mit einer Erklärung aktualisiert, da ich sie nicht als Antwort hinzufügen kann.
Chris Schmitz
@estus: Die Antwort macht ziemlich deutlich, dass es nicht Teil von ES6 ist, sondern eine Webpack-Konfigurationssache, meinst du nicht auch? Und genau das ist auch hier der Fall, nur dass die Art der Konfiguration etwas anders ist.
Felix Kling
@FelixKling Ich glaube, als estus darauf hinwies, dass es immer noch eine Frage gab, was für eine Sache es ist, hatte ich das Update noch nicht hinzugefügt (ich sah seinen Kommentar, als ich das Update tippte). Ich bin fertig und es gibt eine detaillierte Erklärung zu meiner speziellen Instanz, also kann es losgehen. Danke Leute.
Chris Schmitz

Antworten:

242

Dies erfolgt mit der Webpack- resolve.aliasKonfigurationsoption und ist nicht spezifisch für Vue.

In der Vue Webpack-Vorlage ist Webpack so konfiguriert, dass es @/durch den folgenden srcPfad ersetzt wird :

  const path = require('path');

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

Der Alias ​​wird verwendet als:

import '@/<path inside src folder>';
Estus Flask
quelle
170
JavaScript ist einfach kein JavaScript mehr. Babel / Webpack gibt uns diese Frankenstein-Sprache und irgendwie sollen neue Entwickler wissen, wo die ECMAScript-Spezifikation endet und Userland-Plugins / -Transformationen beginnen. Es ist wirklich traurig, imo.
Vielen Dank, dass Sie
3
@naomik Es liegt am Benutzer, solche Tricks in das Setup einzuführen oder nicht. Für Vue ist dies keine große Sache, da es ohnehin auf seinem benutzerdefinierten .vue-Dateiformat basiert.
Estus Flask
15
Persönlich denke ich, dass die Fähigkeit, Flexibilität hinzuzufügen, wenn Sie es wollen, eine gute Sache ist. Ich sehe es weniger als Frankenstein als vielmehr als Voltron; Sie können Dinge als Löwe tun oder verschiedene Löwen miteinander kombinieren, um einen größeren Roboter zu erhalten. Ja, manchmal bekommt man Fragen wie diese, aber es ist nicht so, dass die Antworten nicht gefunden werden können. Wirklich, Sie können die Frankenstein- oder Voltron-Ansicht mit jedem Projekt jeder Größe einnehmen, es ist nur "Verwenden und Verstehen von Abhängigkeiten".
Chris Schmitz
1
@ChrisSchmitz Es kommt auf den Kontext und die Perspektive an. Wenn Sie so etwas tun, wird das Projekt auf die Verwendung von Webpack beschränkt. Dies ist möglicherweise keine gute Sache, wenn das Projekt beabsichtigt, native ES6-Module zu verwenden, wenn sie eintreffen, oder es ist der Knoten, auf dem CommonJS für Module verwendet werden kann. Lange relative Pfade können andererseits schwieriger zu pflegen und umzugestalten sein.
Estus Flask
3
Wenn Sie vue-cliv3 + verwenden, sollten Sie den Ordner ~@referenzieren src. ZB:$font-path: '~@/assets/fonts/';
Consta Gorgan
9

Denken Sie auch daran, dass Sie auch in tsconfig Variablen erstellen können:

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

Dies kann für Namenskonventionszwecke verwendet werden:

import { componentHeader } from '@components/header';
Tyler Canton
quelle
Diese Art von Alias ​​bleibt jedoch in der Quell-JS frei, und zur Laufzeit muss ein Wrapper interveniert werden, damit der Alias ​​funktioniert. Vielleicht gibt es über babel eine Möglichkeit, diese TS-Syntax beim Erstellen zu konvertieren? Mit Typescript tscist das nicht und deshalb brauchst du so etwas wie module-aliasoder tsconfig-paths.
Ken
3

Ich komme mit folgender Kombination vorbei

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

IDE beendet die Warnung der URL, hört jedoch beim Kompilieren in "build \ webpack.base.conf.js" zu einer ungültigen URL auf.

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

Bingoo!

Luân Trương
quelle
1

Auflösung ('src') funktioniert bei mir nicht, aber path.resolve ('src') funktioniert

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

Versuchen Sie vielleicht, ein Webpack hinzuzufügen. mix.webpackConfig verweist auf Laravel Mix .

mix.webpackConfig({

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

Und dann im Einsatz.

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