ES6 mengimpor menggunakan jalur masuk ('@') dalam proyek vue.js menggunakan Webpack

273

Saya memulai proyek vue.js baru jadi saya menggunakan alat vue-cli untuk merancah proyek webpack baru (yaitu vue init webpack).

Saat saya sedang menelusuri file yang dihasilkan, saya perhatikan impor berikut dalam src/router/index.jsfile:

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

Saya belum pernah melihat tanda pada ( @) di jalur sebelumnya. Saya curiga ini memungkinkan untuk jalur relatif (mungkin?) Tapi saya ingin memastikan saya mengerti apa yang sebenarnya dilakukannya.

Saya mencoba mencari-cari di internet tetapi tidak dapat menemukan penjelasan (mungkin karena mencari "tanda" atau menggunakan karakter literal @tidak membantu sebagai kriteria pencarian).

Apa yang @dilakukan di jalur ini (tautan ke dokumentasi akan fantastis) dan apakah ini hal yang penting? Suatu hal webpack? Suatu hal yang memuat loader?

MEMPERBARUI

Terima kasih Felix Kling untuk mengarahkan saya ke pertanyaan / jawaban duplikat stackoverflow lain tentang pertanyaan yang sama ini.

Sementara komentar pada posting stackoverflow lainnya bukan jawaban yang tepat untuk pertanyaan ini (itu bukan plugin babel dalam kasus saya) itu memang mengarahkan saya ke arah yang benar untuk menemukan apa itu.

Di dalam scaffolding yang memberikan Anda clue-cli, bagian dari konfigurasi webpack dasar mengatur alias untuk file .vue:

Lokasi alias dalam proyek

Ini masuk akal baik dalam kenyataan bahwa itu memberi Anda jalur relatif dari file src dan menghapus persyaratan .vuedi akhir jalur impor (yang biasanya Anda butuhkan).

Terima kasih untuk bantuannya!

Chris Schmitz
sumber
3
Lihat komentar saya .
Felix Kling
1
@ Feliksling Ini bukan duplikat yang tepat karena tidak menjawab seluruh pertanyaan, apakah ini hal es6? Suatu hal webpack? Suatu hal yang memuat loader?
Estus Flask
Ya, saya pikir pertanyaannya serupa tetapi bukan duplikat. Bagaimanapun saya menemukan dari mana asalnya dan memperbarui pertanyaan dengan penjelasan karena saya tidak dapat menambahkannya sebagai jawaban.
Chris Schmitz
@estus: jawabannya membuatnya cukup jelas bahwa itu bukan bagian dari ES6 tetapi hal konfigurasi webpack, bukan begitu? Dan itulah yang terjadi di sini juga, hanya bahwa sifat konfigurasi agak berbeda.
Felix Kling
@FelixKling Saya percaya ketika estus menunjukkan bahwa masih ada pertanyaan tentang hal apa yang saya belum menambahkan pembaruan (saya melihat komentarnya masuk saat saya mengetik pembaruan). Saya siap dan ada penjelasan rinci tentang contoh khusus saya jadi saya baik untuk pergi. Terima kasih kawan
Chris Schmitz

Jawaban:

243

Ini dilakukan dengan resolve.aliasopsi konfigurasi Webpack dan tidak spesifik untuk Vue.

Di template Vue Webpack , Webpack dikonfigurasi untuk mengganti @/dengan srcpath :

  const path = require('path');

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

Alias ​​digunakan sebagai:

import '@/<path inside src folder>';
Estus Flask
sumber
171
JavaScript bukan lagi JavaScript. Babel / webpack memberi kita bahasa Frankenstein ini dan entah bagaimana pengembang baru dimaksudkan untuk mengetahui di mana spesifikasi ECMAScript berakhir dan plugin / transformasi userland dimulai. Sangat menyedihkan, imo.
Terima kasih
3
@naomik Terserah kepada pengguna untuk memperkenalkan trik seperti itu ke dalam pengaturan atau tidak. Ini bukan masalah besar bagi Vue karena tetap bergantung pada format file .vue kustomnya.
Estus Flask
15
Secara pribadi saya pikir kemampuan untuk menambah fleksibilitas jika Anda menginginkannya adalah hal yang baik. Saya melihatnya kurang sebagai frankenstein dan lebih seperti voltron; Anda dapat melakukan hal-hal sebagai singa atau menggabungkan singa yang berbeda untuk memiliki robot yang lebih besar. Ya, kadang-kadang Anda mendapatkan pertanyaan seperti ini, tetapi tidak seperti jawabannya tidak dapat ditemukan. Sungguh, Anda dapat mengambil tampilan frankenstein atau voltron dengan proyek apa pun dengan ukuran apa pun, hanya "menggunakan dan memahami dependensi".
Chris Schmitz
1
@ ChrisSchmitz Tergantung pada konteks dan perspektifnya. Melakukan sesuatu seperti ini akan membatasi proyek untuk menggunakan Webpack. Mungkin bukan hal yang baik jika proyek berniat untuk menggunakan modul ES6 asli ketika mereka akan tiba, atau itu Node di mana CommonJS dapat digunakan untuk modul. Sebaliknya, jalur relatif panjang bisa lebih sulit untuk dirawat dan diperbaiki.
Estus Flask
3
Saat menggunakan vue-cliv3 + Anda harus menggunakan folder ~@referensi src. Contoh:$font-path: '~@/assets/fonts/';
Consta Gorgan
9

Perlu diingat Anda juga dapat membuat variabel di tsconfig:

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

Ini dapat digunakan untuk tujuan konvensi penamaan:

import { componentHeader } from '@components/header';
Tyler Canton
sumber
Tapi alias semacam ini akan dibiarkan kosong di sumber JS dan kemudian pada saat run-time Anda harus meminta perantara untuk membuat alias berfungsi. Mungkin ada cara via babel untuk sintaks TS ini untuk dikonversi pada waktu build? Dengan TypeScript tsctidak dan karena itu Anda akan memerlukan sesuatu seperti module-aliasatau tsconfig-paths.
ken
3

Saya selesai dengan kombinasi berikut

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

IDE akan berhenti memperingatkan uri, tetapi ini menyebabkan uri tidak valid saat mengkompilasi, di "build \ webpack.base.conf.js"

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

Bingoo!

Luân Trương
sumber
1

tekad ( 'src') tidak bekerja untuk saya tapi path.resolve ( 'src') karya

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

Mungkin coba tambahkan di webpack. mix.webpackConfig referensi LARAVEL campuran .

mix.webpackConfig({

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

Dan kemudian dalam penggunaannya.

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