Разрешение требует путей с помощью webpack

Я все еще запутался, как разрешать пути модулей с помощью 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') не будет работать.

Я чувствую себя глупым, потому что много раз читал документ, и я чувствую, что что-то упускаю. Каков правильный способ избежать написания всех относительных потребностей с помощью ../../ и т.д.?

Ответ 1

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

Ответ 2

Для справки в будущем веб-пакет 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)

Ответ 3

resolve.alias должен работать точно так, как вы описали, поэтому я предоставляю это как ответ, чтобы помочь смягчить любую путаницу, которая может возникнуть в результате предложения в оригинальный вопрос, что это не работает.

конфигурация решения, подобная приведенной ниже, даст вам желаемые результаты:

// used to resolve absolute path to project 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 просто помещает вас в нужный каталог, не давая вам возможности пропустить его дальше.

Ответ 4

В случае, если кто-то еще сталкивается с этой проблемой, мне удалось заставить его работать следующим образом:

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';

Ответ 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: тестирование, листинг...

Ответ 6

Я разрешаю его с помощью Webpack 2 следующим образом:

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

Вы можете добавить больше каталогов в массив...

Ответ 7

Получив это решение, используя Webpack 2:

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

Ответ 8

Этот поток является старым, но поскольку никто не отправил о 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')

Ответ 9

Я не понял, почему кто-то предложил включить родительский каталог myDir в modulesDirectories в webpack, что должно легко сделать трюк:

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

Ответ 11

modulesDirectories выглядит устаревшим. с 2018 года я использовал это:

module.exports = (baseConfig, env) => {
  const config = genDefaultConfig(baseConfig, env);
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: require.resolve('ts-loader')
  });
  config.plugins.push(new TSDocgenPlugin());
  config.resolve = {
    extensions: config.resolve.extensions.concat(['.tsx', '.ts']),
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  };
  return config;
};

но он все еще не работает