webpackで必要なパスを解決する


164

私はまだwebpackでモジュールパスを解決する方法を混同しています。今私は書きます:

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

でも書きたい

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

エイリアスとして使用している同様の例を見ることができるので、resolve.aliasが役立つかもしれないと考えていました{ xyz: "/some/dir" }require("xyz/file.js")

しかし、エイリアスをに設定すると{ mydir: '/absolute/path/mydir' }、機能しrequire('mydir/myfile.js') ません。

何度もドキュメントを読んだことがあり、何か不足しているように感じるので、私は馬鹿げていると感じます。相対的な必要事項をすべて書くことを避けるための正しい方法は何../../ですか?


resolve.aliasあなたが提案したとおりに動作します。あなたのresolve構成に他の何かが原因で失敗したのだろうか。私は使用alias{ mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )require( 'mydir/myfile.js' )て問題なく動作します。
sethro 2016年

回答:


142

Webpack> 2.0

wtkの回答を参照してください。

Webpack 1.0

これを行うより簡単な方法は、resolve.rootを使用することです。

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

resolve.root

モジュールを含むディレクトリ(絶対パス)。ディレクトリの配列の場合もあります。この設定を使用して、個々のディレクトリを検索パスに追加する必要があります。

あなたの場合:

webpack設定

var path = require('path');

// ...

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

消費モジュール

require('myfile')

または

require('myfile.js')

参照:http : //webpack.github.io/docs/configuration.html#resolve-modulesdirectories


1
おかげで、私が試したrootmodulesDirectoriesとの両方のミックスが、それはうまくいきませんでした。サブモジュール(例:)require("mydir/file")は受け入れられないようです。
gpbl 2014

彼らはそうあるべきです-あなたのwebpack設定を見ることができますか?
Jeff Ling

1
これを正しく理解している場合、この構成を使用するにはファイル名が一意である必要がありますか?
ジョニー2016

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'.
トマーシュZato -復活モニカ

1
「解決パスへの道としてのWebPACK 2取り外したすべてのものが、モジュールこの手段のルートが機能しません。」stackoverflow.com/a/36574982/588759
rofrol

72

将来の参考のために、webpack 2はmodulesパスを解決する方法として以外はすべて削除しました。この手段はrootなりません動作します。

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

設定例は次で始まります:

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

4
おかげで、これは本当に役に立ちます。modulesDirectorieswebpack 2でも、webpack-dev-serverで引き続き使用されているため、非常に混乱します。
2016年

63

resolve.alias は、あなたが説明したとおりに機能するはずです。そのため、元の質問で機能しないという提案から生じる可能性のある混乱を軽減するための回答としてこれを提供します。

以下のような解決構成により、望ましい結果が得られます。

// 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' )期待どおりに動作します。そうでない場合は、他の問題があるはずです。

検索パスに追加するモジュールが複数ある場合resolve.rootは理にかなっていますが、相対パスなしでアプリケーションコード内のコンポーネントを参照できるようにするだけの場合はalias、最も簡単で明確なようです。

の重要な利点は、コードを明確にすることができるsのalias名前空間requireを作成できることです。他requireのs からどのモジュールが参照されているかを簡単に確認できるのと同じように、内部モジュールが必要であることを明確にするalias説明的なrequiresを記述できますrequire( 'my-project/component' )resolve.rootさらに名前空間を指定する機会を与えずに、目的のディレクトリに移動するだけです。


46
Iエイリアスしたいとチルダ:alias: {'~': path.resolve(__dirname)},
ダニエルBuckmaster

ファイル拡張子のないサブディレクトリのインポートをサポートするようにこのソリューションを調整する方法のヒントはありますか?@sethro
Dima Feldman、

@DimaFeldman、あなたはrequire引数(require('mydir/myfile'))に拡張がないことを意味しますか?実際に動作するはずです。には複数のエントリを含めることができますalias。私はそれを使用してsrc、JavaScriptモジュールの場合はstylesディレクトリーからインポートし、cssの場合は別のディレクトリーからインポートします。あなたの質問を完全に誤解していたかどうか教えてください。
sethro 2016年

@sethro正解です、私の質問を言い換えましょう-私が意味したことは、ディレクトリがあります。たとえば、Component1で、このディレクトリ内にComponent1.jsという名前のファイルがあります。エイリアスを使用する前に、呼び出すだけでファイルをインポートできimport './path/to/Component1';ます。パスに内部ファイル名と拡張子を指定しないでください。webpackはなんとかして内部ファイルにディレクトリの名前が付いていることを検出し、インポートしました。今私がしたいことはそのようにそれをインポートすることです:import 'shared\Component1';'shared'がエイリアスであるとき。ただし、内部ファイル名を指定しないと機能しません。ありがとう!
Dima Feldman 2016年

1
@DimaFeldman申し訳ありませんが、私はあなたが説明している動作に精通していません。そのため、既知の機能を知らない場合は、私を許さなければなりません(そのためのドキュメントが見つかりません)。場所を指定するだけでモジュールをインポートする機能を提供するローダーがありますか(ファイル名ではありません)?申し訳ありませんが、助けにはなりません...構成ファイルを含めて、新しい質問をするのが最善です。
sethro

13

他の誰かがこの問題に遭遇した場合、私はそれを次のように機能させることができました:

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

私のディレクトリ構造は次のとおりです:

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

次に、srcディレクトリのどこからでも呼び出すことができます:

import MyComponent from 'components/MyComponent';

2
path.resolveを使用してnode_modulesを解決するのはよくありません。これにより、サブ依存関係で問題が発生する可能性があります。'node_modules'代わりに文字列を使用してください。[ path.resolve(__dirname, 'src'), 'node_modules' ],
spencer.sm

@ spencer.sm現在のプロジェクトからモジュールのみを解決したい場合はどうすればよいですか?相互にインポートするプロジェクトがいくつかあります。projectAがprojectBからfileAをインポートしlodash、fileAがをインポートする場合、私はlodashからのみ解決したいと思いprojectA/node_modulesます。これはresolve.modules: [path.resolve(__dirname, 'node_modules')]便利です。しかし、私はあなたが言ったようにサブ依存関係の問題に直面しています。node_modulesの解決を制限するだけでなく、サブ依存関係も検索するようにwebpackに指示する方法はありprojectA/node_modulesますか?
Eric Guan

@ spencer.smありがとうございます!多くの苦労の後、ようやくあなたの解決策は私の従属関係の問題を解決しました:D
Saad Abdullah

5

私の最大の問題は、名前空間付きのパスなしで機能していました。このようなもの:

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

これを行うように環境を設定する前に、

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

src重要なコンテキスト情報を隠す暗黙のパスを回避する方がはるかに便利であることがわかりました。

私の目的は次のように要求することです:

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

ご覧のとおり、すべてのアプリコードは必須のパス名前空間内にあります。これにより、ライブラリ、アプリコード、またはテストファイルを必要とする呼び出しがどれであるかが明確になります。

このために、私は私の解決パスがちょうどであることを確認します node_modulesソースフォルダー内でアプリの名前空間を指定しない限り現在のアプリフォルダーであるますsrc/my_app

これはwebpackのデフォルトです

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

環境変数NODE_PATHを現在のプロジェクトファイルに設定すると、さらに良いでしょう。これはより一般的なソリューションであり、webpackなしで他のツールを使用する場合に役立ちます:テスト、リンティング...


3

私はこのようにWebpack 2でそれを解決しました:

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

配列にさらにディレクトリを追加できます...


絶対パスと相対パスは等しく処理されないことに注意してください。ビルド時間に影響を与える可能性があるwebpack.js.org/configuration/resolve/#resolve-modules
TeChn4K

1
どちらの場合でも機能しますが、相対パスを使用するとビルドに時間がかかる場合があります。
TeChn4K 2017年

3

Webpack 2を使用してこれを解決しました:

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


1

このスレッドは古いですが、require.contextについて誰も投稿していないので、これについて触れます。

require.contextを使用して、フォルダを次のように設定できます。

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

だれかがmyDirの親ディレクトリをwebpackのmodulesDirectoriesに含めることを提案した理由がわかりませんでした。

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

0

単にbabel-plugin-module-resolverを使用してください:

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

次に、.babelrcルートにファイルがない場合は作成します。

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

そして、ルートの下のすべては絶対インポートとして扱われます:

import { Layout } from 'components'

VSCode / Eslintのサポートについては、こちらを参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.