使用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') 将无法正常工作。

我很笨,因为我已经阅读了很多文档,并且觉得自己缺少一些东西。避免用../../etc 写下所有相对要求的正确方法是什么?


resolve.alias完全按照您的建议进行工作。我不知道它是否由于resolve配置中的其他原因而失败。我使用alias{ mydir: path.resolve( __dirname, 'path', 'to', 'mydir' )并且require( 'mydir/myfile.js' )工作正常。
sethro

Answers:


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
如果我正确理解这一点,则使用此配置将要求文件名唯一吗?
强尼

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删除了除模块以外的所有内容,以此作为解决路径的一种方法。这意味着root无法使用” 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
谢谢,这真的很有帮助。modulesDirectories仍然被webpack-dev-server使用,甚至与webpack 2一起使用,这也很令人困惑。
埃文(Evan)2013年

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似乎是最简单明了的方法。

的一个重要优点alias是,它使您有机会为命名空间require,这可以增加代码的清晰度。就像从其他对象很容易看到require所引用的模块一样,它alias允许您编写描述性require的,使您很明显地需要内部模块,例如require( 'my-project/component' )resolve.root只是使您进入所需的目录,而没有机会给它进一步命名空间。


46
我想给波浪号起别名:alias: {'~': path.resolve(__dirname)},
Daniel Buckmaster

有什么提示如何调整此解决方案以支持不带文件扩展名的子目录导入?@sethro
Dima Feldman

@DimaFeldman,您的意思是require参数(require('mydir/myfile'))中没有扩展名吗?那实际上应该工作。您可以在中有多个条目alias;我使用它从我的src目录导入JavaScript模块,并使用另一个从我的styles目录导入CSS。让我知道我是否完全误解了您的问题。
sethro

@sethro,您是对的,让我重新回答我的问题-我的意思是:我有一个目录,例如Component1,并且在此目录下有一个名为Component1.js的文件。在使用别名之前,我可以仅通过调用来导入文件import './path/to/Component1';-只需在路径中没有内部文件名和扩展名即可。webpack以某种方式设法检测到内部文件具有该目录的名称,然后将其导入。现在我想做的就是这样导入:import 'shared\Component1';当“ shared”是别名时。但如果不指定内部文件名,它将无法正常工作。谢谢!
Dima Feldman

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,而fileA导入lodash,我只想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']
}

如果将环境var设置为NODE_PATH当前项目文件,那就更好了。这是一种更通用的解决方案,如果您想在没有webpack的情况下使用其他工具,则将有所帮助:测试,整理...



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的支持,请参见此处

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.