Penyelesaian membutuhkan jalur dengan webpack

164

Saya masih bingung bagaimana menyelesaikan jalur modul dengan webpack. Sekarang saya menulis:

myfile = require('../../mydir/myfile.js') 

tapi saya ingin menulis

myfile = require('mydir/myfile.js') 

Saya berpikir bahwa resol.alias dapat membantu karena saya melihat contoh serupa menggunakan { xyz: "/some/dir" }alias maka saya bisa require("xyz/file.js").

Tetapi jika saya mengatur alias saya untuk { mydir: '/absolute/path/mydir' }, require('mydir/myfile.js') tidak akan berfungsi.

Saya merasa bodoh karena saya telah membaca dokumen berkali-kali dan saya merasa kehilangan sesuatu. Apa cara yang benar untuk menghindari penulisan semua persyaratan relatif dengan ../../dll?

gpbl
sumber
resolve.aliasbekerja persis seperti yang Anda sarankan. Saya ingin tahu apakah itu gagal karena ada hal lain dalam resolvekonfigurasi Anda . Saya menggunakan alias{ mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )dan require( 'mydir/myfile.js' )berfungsi dengan baik.
sethro

Jawaban:

142

Webpack> 2.0

Lihat jawaban wtk .

Webpack 1.0

Cara yang lebih mudah untuk melakukan ini adalah dengan menggunakan resol.root.

http://webpack.github.io/docs/configuration.html#resolve-root

resol.root

Direktori (jalur absolut) yang berisi modul Anda. Mungkin juga menjadi array direktori. Pengaturan ini harus digunakan untuk menambahkan direktori individual ke jalur pencarian.

Dalam kasus Anda:

konfigurasi webpack

var path = require('path');

// ...

  resolve: {
    root: path.resolve('./mydir'),
    extensions: ['', '.js']
  }

modul mengkonsumsi

require('myfile')

atau

require('myfile.js')

lihat juga: http://webpack.github.io/docs/configuration.html#resolve-modulesdirectories

AndyCunningham
sumber
1
Terima kasih, saya mencoba root,, modulesDirectoriesdan campuran keduanya, tetapi tidak berhasil. Tampaknya submodul (mis. require("mydir/file")) Tidak diterima.
gpbl
Seharusnya - bisakah kita melihat konfigurasi webpack Anda?
Jeff Ling
1
Jika saya memahami ini dengan benar, menggunakan konfigurasi ini akan mengharuskan nama file menjadi unik?
Jonny
1
WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema. - configuration.resolve has an unknown property 'root'.
Tomáš Zato - Kembalikan Monica
1
"webpack 2 menghapus semuanya kecuali modul sebagai cara untuk menyelesaikan jalur. Ini berarti root tidak akan berfungsi" stackoverflow.com/a/36574982/588759
rofrol
72

Untuk referensi di masa mendatang, webpack 2 menghapus semuanya tetapi modulessebagai cara untuk menyelesaikan jalur. Ini berarti tidakroot akan berfungsi.

https://gist.github.com/sokra/27b24881210b56bbaff7#resolving-options

Contoh konfigurasi dimulai dengan:

{
  modules: [path.resolve(__dirname, "app"), "node_modules"]
  // (was split into `root`, `modulesDirectories` and `fallback` in the old options)
wtk
sumber
4
Terima kasih, ini sangat membantu. modulesDirectoriesmasih digunakan oleh webpack-dev-server, bahkan dengan webpack 2, yang membuat ini sangat membingungkan.
Evan
63

resolve.alias harus bekerja persis seperti yang Anda gambarkan, jadi saya memberikan ini sebagai jawaban untuk membantu mengurangi kebingungan yang mungkin timbul dari saran di pertanyaan awal yang tidak berfungsi.

konfigurasi penyelesaian seperti yang di bawah ini akan memberi Anda hasil yang diinginkan:

// used to resolve absolute path to project's root directory (where web pack.config.js should be located)
var path = require( 'path' );
...
{
  ...
  resolve: {
    // add alias for application code directory
    alias:{
      mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )
    },
    extensions: [ '', '.js' ]
  }
}

require( 'mydir/myfile.js' )akan bekerja seperti yang diharapkan. Jika tidak, pasti ada masalah lain.

Jika Anda memiliki beberapa modul yang ingin Anda tambahkan ke jalur pencarian, resolve.rootmasuk akal, tetapi jika Anda hanya ingin dapat referensi komponen dalam kode aplikasi Anda tanpa jalur relatif, aliastampaknya menjadi yang paling mudah dan eksplisit.

Keuntungan penting dari itu aliasadalah memberi Anda kesempatan untuk namespace Anda requireyang dapat menambah kejelasan kode Anda; sama seperti mudah untuk melihat dari requiremodul lain apa yang sedang direferensikan, aliasmemungkinkan Anda untuk menulis deskriptif requireyang membuatnya jelas Anda memerlukan modul internal, misalnya require( 'my-project/component' ). resolve.rootcukup masukkan Anda ke direktori yang diinginkan tanpa memberi Anda kesempatan untuk namespace lebih jauh.

sethro
sumber
46
Saya suka alias tilde:alias: {'~': path.resolve(__dirname)},
Daniel Buckmaster
ada petunjuk bagaimana menyesuaikan solusi ini untuk mendukung impor sub-direktori tanpa ekstensi file? @sethro
Dima Feldman
@DimaFeldman, maksud Anda tidak ada ekstensi dalam argumen memerlukan ( require('mydir/myfile'))? Itu seharusnya bekerja. Anda dapat memiliki beberapa entri di alias; Saya menggunakannya untuk mengimpor dari srcdirektori saya untuk modul JavaScript dan yang lain untuk mengimpor dari stylesdirektori saya untuk css. Beri tahu saya jika saya salah mengerti pertanyaan Anda.
sethro
@sethro Anda benar, izinkan saya ulangi pertanyaan saya - yang saya maksud adalah: Saya memiliki direktori, katakan Component1, dan di dalam dir ini saya memiliki file bernama Component1.js. sebelum menggunakan alias, saya bisa mengimpor file hanya dengan menelepon import './path/to/Component1';- hanya tanpa nama file dalam & ekstensi di jalan. webpack entah bagaimana berhasil mendeteksi bahwa file dalam memiliki nama direktori, dan baru saja mengimpornya. sekarang yang ingin saya lakukan adalah mengimpornya seperti itu: import 'shared\Component1';ketika 'dibagikan' adalah alias. tetapi tidak berfungsi tanpa menentukan nama file dalam. Terima kasih!
Dima Feldman
1
@DimaFeldman Maaf, saya tidak terbiasa dengan perilaku yang Anda gambarkan; jadi Anda harus memaafkan saya jika saya tidak tahu beberapa fitur yang diketahui (saya tidak dapat menemukan dokumentasi untuk itu). Saya bertanya-tanya apakah Anda memiliki beberapa loader di konfigurasi Anda yang menyediakan kemampuan untuk mengimpor modul dengan hanya menentukan lokasi (tetapi bukan nama file-nya)? Maaf, saya tidak membantu ... Mungkin yang terbaik untuk mengajukan pertanyaan baru dengan menyertakan file konfigurasi Anda.
sethro
13

Jika ada orang lain yang mengalami masalah ini, saya bisa membuatnya berfungsi seperti ini:

var path = require('path');
// ...
resolve: {
  root: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'node_modules')],
  extensions: ['', '.js']
};

di mana struktur direktori saya adalah:

.
├── dist
├── node_modules
├── package.json
├── README.md
├── src
   ├── components
   ├── index.html
   ├── main.js
   └── styles
├── webpack.config.js

Lalu dari mana saja di srcdirektori saya dapat menelepon:

import MyComponent from 'components/MyComponent';
Alex Klibisz
sumber
2
Tidak baik untuk menyelesaikan node_modules menggunakan path.resolve. Ini dapat menyebabkan masalah dengan sub-dependensi. Gunakan string 'node_modules'sebagai gantinya. [ path.resolve(__dirname, 'src'), 'node_modules' ],
spencer.sm
@ spencer.sm bagaimana jika saya hanya ingin modul diselesaikan dari proyek saat ini? Saya punya beberapa proyek yang saling mengimpor. Jika projectA mengimpor fileA dari projectB, dan fileA mengimpor lodash, saya ingin lodashdiselesaikan HANYA dari projectA/node_modules. Inilah yang resolve.modules: [path.resolve(__dirname, 'node_modules')]berguna untuk. Namun saya mengalami masalah dengan sub-dependensi seperti yang Anda katakan. Apakah ada cara untuk memberitahu webpack untuk juga menemukan sub-dependensi selain membatasi resolusi node_modules projectA/node_modules?
Eric Guan
@ spencer.sm terima kasih! setelah banyak perjuangan, akhirnya solusi Anda menyelesaikan masalah sub-ketergantungan saya: D
Saad Abdullah
5

Sakit kepala terbesar saya adalah bekerja tanpa jalur nama. Sesuatu seperti ini:

./src/app.js
./src/ui/menu.js
./node_modules/lodash/

Sebelum saya biasa mengatur lingkungan saya untuk melakukan ini:

require('app.js')
require('ui/menu')
require('lodash')

Saya menemukan jauh lebih nyaman menghindari srcjalur implisit , yang menyembunyikan informasi konteks penting.

Tujuan saya adalah meminta seperti ini:

require('src/app.js')
require('src/ui/menu')
require('test/helpers/auth')
require('lodash')

Seperti yang Anda lihat, semua kode aplikasi saya hidup dalam namespace jalur wajib. Ini membuat cukup jelas yang membutuhkan panggilan membutuhkan perpustakaan, kode aplikasi atau file uji.

Untuk ini saya memastikan bahwa jalur tekad saya adil node_modulesdan folder aplikasi saat ini, kecuali jika Anda namespace aplikasi Anda di dalam folder sumber Anda sepertisrc/my_app

Ini adalah default saya dengan webpack

resolve: {
  extensions: ['', '.jsx', '.js', '.json'],
  root: path.resolve(__dirname),
  modulesDirectories: ['node_modules']
}

Akan lebih baik jika Anda mengatur lingkungan var NODE_PATHke file proyek Anda saat ini. Ini adalah solusi yang lebih universal dan ini akan membantu jika Anda ingin menggunakan alat lain tanpa paket web: pengujian, linting ...

SystematicFrank
sumber
3

Saya telah mengatasinya dengan Webpack 2 seperti ini:

module.exports = {
  resolve: {
    modules: ["mydir", "node_modules"]    
  }
}

Anda dapat menambahkan lebih banyak direktori ke array ...

Damjan Pavlica
sumber
Hati-hati, jalur absolut dan relatif tidak diproses sama rata! Dapat memengaruhi waktu pembuatan webpack.js.org/configuration/resolve/#resolve-modules
TeChn4K
1
Ini akan berfungsi dalam kedua kasus, tetapi membangun (mungkin) membutuhkan waktu lebih lama dengan jalur relatif.
TeChn4K
3

Selesaikan ini dengan menggunakan Webpack 2:

   resolve: {
      extensions: ['', '.js'],
        modules: [__dirname , 'node_modules']
    }
Aaqib
sumber
1

Utas ini sudah lama tetapi karena tidak ada yang memposting tentang membutuhkan.konteks saya akan menyebutkannya:

Anda dapat menggunakan require.context untuk mengatur folder untuk dilihat seperti ini:

var req = require.context('../../mydir/', true)
// true here is for use subdirectories, you can also specify regex as third param

return req('./myfile.js')
altShiftDev
sumber
0

Saya tidak mengerti mengapa ada orang yang menyarankan untuk memasukkan direktori induk myDir ke dalam modulesDirectories di webpack, yang seharusnya mempermudahnya:

resolve: {
    modulesDirectories: [
      'parentDir',
      'node_modules',
    ],
    extensions: ['', '.js', '.jsx']
  },
daniele bertella
sumber
0

Cukup gunakan babel-plugin-module-resolver :

$ npm i babel-plugin-module-resolver --save-dev

Kemudian buat .babelrcfile di bawah root jika Anda belum memilikinya:

{
    "plugins": [
        [
            "module-resolver",
            {
                "root": ["./"]
            }
        ]
    ]
}

Dan semua yang ada di bawah root akan diperlakukan sebagai impor mutlak:

import { Layout } from 'components'

Untuk dukungan VSCode / Eslint, lihat di sini .

Lucia
sumber