La risoluzione richiede percorsi con webpack


164

Sono ancora confuso su come risolvere i percorsi dei moduli con il webpack. Ora scrivo:

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

ma mi piacerebbe scrivere

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

Stavo pensando che resol.alias potrebbe essere d'aiuto poiché vedo un esempio simile usando { xyz: "/some/dir" }come alias allora posso require("xyz/file.js").

Ma se imposto il mio alias su { mydir: '/absolute/path/mydir' }, require('mydir/myfile.js') non funzionerà.

Mi sento stupido perché ho letto il documento molte volte e sento che mi manca qualcosa. Qual è il modo giusto per evitare di scrivere tutto il parente richiesto con ../../ecc?


resolve.aliasfunziona esattamente come hai suggerito. Mi chiedo se non abbia funzionato a causa di qualcos'altro nella tua resolveconfigurazione. Uso alias{ mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )e require( 'mydir/myfile.js' )funziona benissimo.
sethro,

Risposte:


142

Webpack> 2.0

Vedi la risposta di wtk .

Webpack 1.0

Un modo più semplice per farlo sarebbe usare resol.root.

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

resolve.root

La directory (percorso assoluto) che contiene i tuoi moduli. Può anche essere una serie di directory. Questa impostazione deve essere utilizzata per aggiungere singole directory al percorso di ricerca.

Nel tuo caso:

configurazione webpack

var path = require('path');

// ...

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

modulo di consumo

require('myfile')

o

require('myfile.js')

vedi anche: http://webpack.github.io/docs/configuration.html#resolve-modulesdirectories


1
Grazie, ho provato root, modulesDirectoriese un mix di entrambi, ma non ha funzionato. Sembra che i sottomoduli (ad es. require("mydir/file")) Non siano accettati.
gpbl,

Dovrebbero essere: possiamo vedere la configurazione del tuo webpack?
Jeff Ling,

1
Se lo capisco correttamente, l'utilizzo di questa configurazione richiederebbe che i nomi dei file siano univoci?
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 - Ripristina Monica il

1
"webpack 2 tutto rimosso ma moduli come un modo per percorsi risolvere questo mezzo principale non funzionerà." stackoverflow.com/a/36574982/588759
rofrol

72

Per riferimento futuro, webpack 2 ha rimosso tutto tranne modulesche per risolvere i percorsi. Questo significa rootche non funzionerà.

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

La configurazione di esempio inizia con:

{
  modules: [path.resolve(__dirname, "app"), "node_modules"]
  // (was split into `root`, `modulesDirectories` and `fallback` in the old options)

4
Grazie, è davvero utile. modulesDirectoriesè ancora usato da webpack-dev-server, anche con webpack 2, il che lo rende molto confuso.
Evan,

63

resolve.alias dovrebbe funzionare esattamente come descritto, quindi sto fornendo questo come una risposta per aiutare a mitigare qualsiasi confusione che potrebbe derivare dal suggerimento nella domanda originale che non funziona.

una configurazione di risoluzione come quella seguente ti darà i risultati desiderati:

// 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' )funzionerà come previsto. In caso contrario, ci deve essere qualche altro problema.

Se hai più moduli che vuoi aggiungere al percorso di ricerca, resolve.rootha senso, ma se vuoi solo essere in grado di fare riferimento ai componenti all'interno del codice dell'applicazione senza percorsi relativi, aliassembra essere il più semplice ed esplicito.

Un vantaggio importante di aliasè che ti dà l'opportunità di spaziare i tuoi messaggi requireche può aggiungere chiarezza al tuo codice; proprio come è facile vedere dagli altri requirequale modulo viene referenziato, aliasti permette di scrivere descrittivi requireche rendono ovvio che hai bisogno di moduli interni, ad es require( 'my-project/component' ). resolve.rootti fa semplicemente cadere nella directory desiderata senza darti l'opportunità di spaziarla ulteriormente.


46
Mi piace alias the tilde:alias: {'~': path.resolve(__dirname)},
Daniel Buckmaster

qualche suggerimento su come adattare questa soluzione per supportare l'importazione di sottodirectory senza estensioni di file? @sethro
Dima Feldman,

@DimaFeldman, intendi nessuna estensione nell'argomento request ( require('mydir/myfile'))? Questo dovrebbe effettivamente funzionare. Puoi avere più voci in alias; Lo uso per importare dalla mia srcdirectory per i moduli JavaScript e un altro per importare dalla mia stylesdirectory per css. Fammi sapere se ho completamente frainteso la tua domanda.
sethro,

@sethro hai ragione, lasciami riformulare la mia domanda - quello che volevo dire è: ho una directory, dì Component1, e all'interno di questa directory ho un file chiamato Component1.js. prima di usare l'alias, potrei importare il file semplicemente chiamando import './path/to/Component1';, semplicemente senza il nome del file interno e l'estensione nel percorso. webpack in qualche modo è riuscito a rilevare che il file interno ha il nome della directory e lo ha appena importato. ora quello che voglio fare è importarlo in quel modo: import 'shared\Component1';quando "condiviso" è l'alias. ma non funziona senza specificare il nome del file interno. Grazie!
Dima Feldman,

1
@DimaFeldman Siamo spiacenti, non ho familiarità con il comportamento che stai descrivendo; quindi dovrai perdonarmi se ignoro qualche caratteristica nota (non riesco a trovare la documentazione per questo). Mi chiedo se hai qualche caricatore nella tua configurazione che sta fornendo la possibilità di importare un modulo specificando solo la sua posizione (ma non il suo nome file)? Siamo spiacenti, non sono di aiuto ... Potrebbe essere meglio porre una nuova domanda con il file di configurazione incluso.
sethro,

13

Nel caso in cui qualcun altro incontri questo problema, sono stato in grado di farlo funzionare in questo modo:

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

dove è la mia struttura di directory:

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

Quindi da qualsiasi punto della srcdirectory posso chiamare:

import MyComponent from 'components/MyComponent';

2
Non è utile risolvere node_modules utilizzando path.resolve. Ciò può causare problemi con le dipendenze secondarie. Usa 'node_modules'invece la stringa . [ path.resolve(__dirname, 'src'), 'node_modules' ],
spencer.sm,

@ spencer.sm cosa succede se voglio solo che i moduli vengano risolti dal progetto corrente? Ho alcuni progetti che importano l'uno dall'altro. Se projectA importa fileA da projectB e fileA importa lodash, desidero lodashessere risolto SOLO da projectA/node_modules. Questo è resolve.modules: [path.resolve(__dirname, 'node_modules')]utile per. Tuttavia sto incontrando problemi con le dipendenze secondarie come hai detto. C'è un modo per dire al webpack di trovare anche dipendenze secondarie oltre a limitare la risoluzione di node_modules projectA/node_modules?
Eric Guan,

@ spencer.sm grazie! dopo molte lotte, finalmente la tua soluzione ha risolto i miei problemi di sub-dipendenza: D
Saad Abdullah

5

Il mio più grande mal di testa stava funzionando senza un percorso spaziale. Qualcosa come questo:

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

Prima di impostare il mio ambiente per fare questo:

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

Ho trovato molto più conveniente evitare un srcpercorso implicito , che nasconde importanti informazioni di contesto.

Il mio obiettivo è richiedere in questo modo:

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

Come vedi, tutto il mio codice app risiede in uno spazio dei nomi di percorso obbligatorio. Ciò rende abbastanza chiaro quale richiesta di chiamata richiede una libreria, un codice app o un file di prova.

Per questo mi assicuro che i miei percorsi di risoluzione siano giusti node_modulese la cartella dell'app corrente, a meno che tu non abbia spaziato l'app nella tua cartella di origine comesrc/my_app

Questo è il mio default con il webpack

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

Sarebbe ancora meglio se si imposta l'ambiente var NODE_PATHsul file di progetto corrente. Questa è una soluzione più universale e aiuterà se si desidera utilizzare altri strumenti senza webpack: test, sfilacciature ...


3

L'ho risolto con Webpack 2 in questo modo:

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

È possibile aggiungere più directory all'array ...


Attenzione, i percorsi assoluti e relativi non vengono elaborati allo stesso modo! Può influire sul tempo di compilazione webpack.js.org/configuration/resolve/#resolve-modules
TeChn4K

1
Funzionerà in entrambi i casi, ma le build (possono) impiegare più tempo con i relativi percorsi.
TeChn4K,

3

Risolto questo problema usando Webpack 2:

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


1

Questo thread è vecchio ma dal momento che nessuno ha pubblicato un post su request.context lo citerò:

È possibile utilizzare Require.context per impostare la cartella in modo che venga visualizzata in questo modo:

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

return req('./myfile.js')

0

Non ho capito perché qualcuno abbia suggerito di includere la directory principale di myDir nei moduliDirectory nel webpack, il che dovrebbe rendere facilmente il trucco:

resolve: {
    modulesDirectories: [
      'parentDir',
      'node_modules',
    ],
    extensions: ['', '.js', '.jsx']
  },

0

Usa semplicemente babel-plugin-module-resolver :

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

Quindi crea un .babelrcfile sotto root se non ne hai già uno:

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

E tutto ciò che è alla radice verrà trattato come importazione assoluta:

import { Layout } from 'components'

Per supporto VSCode / Eslint, vedere qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.