Для вирішення потрібні шляхи з webpack


164

Я все ще плутаю, як вирішити шляхи модулів за допомогою webpack. Тепер я пишу:

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

але я хотів би написати

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

Я думав, що разрешение.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

Відповіді:


142

Вебпак> 2.0

Дивіться відповідь wtk .

Webpack 1.0

Більш простий спосіб зробити це було б використовувати resolution.root.

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

резолюція.корінь

Каталог (абсолютний шлях), який містить ваші модулі. Також може бути масив каталогів. Цей параметр слід використовувати для додавання окремих каталогів до шляху пошуку.

У вашому випадку:

конфігурація веб-пакету

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
Дякую, я спробував root, modulesDirectoriesі суміш обох, але це не вийшло. Здається, що субмодули (наприклад require("mydir/file")) не приймаються.
gpbl

Вони повинні бути - чи можемо ми побачити ваш конфігурацію веб-пакета?
Джефф Лінг

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'.
Томаш Зато - Відновіть Моніку

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
Дякую, це справді корисно. modulesDirectoriesдосі використовується webpack-dev-сервер, навіть із webpack 2, що робить це дуже заплутано.
Єван

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є те, що він надає вам можливість простору імен для вашого requires, що може додати ясності коду; так само, як легко зрозуміти від інших require, на який модуль посилається, aliasдозволяє писати описові дані require, які роблять очевидним, що вам потрібні внутрішні модулі, наприклад require( 'my-project/component' ). resolve.rootпросто переміщує вас у потрібний каталог, не даючи вам можливості надалі простору імен.


46
Мені подобається псевдонім тильди:alias: {'~': path.resolve(__dirname)},
Даніель Бакмастер

будь-які підказки, як налаштувати це рішення для підтримки імпорту підкаталогу без розширень файлів? @sethro
Діма Фельдман

@DimaFeldman, ви маєте на увазі відсутність розширень в аргументі вимагати ( require('mydir/myfile'))? Це насправді має працювати. Ви можете мати кілька записів у alias; Я використовую це для імпорту з мого srcкаталогу для модулів JavaScript, а інший для імпорту з мого stylesкаталогу для css. Повідомте мене, чи я повністю зрозумів ваше запитання.
sethro

@sethro ви маєте рацію, дозвольте перефразувати своє запитання - що я мав на увазі: у мене є каталог, скажімо, Component1, і всередині цього dir у мене є файл на ім’я Component1.js. Перш ніж використовувати псевдонім, я міг імпортувати файл, просто зателефонувавши import './path/to/Component1';- просто без внутрішнього імені та розширення файлу на шляху. webpack якимось чином вдалося виявити, що Внутрішній файл має ім'я каталогу, і просто імпортував його. тепер, що я хочу зробити, це імпортувати його так: import 'shared\Component1';коли "спільним" є псевдонім. але це не працює, не вказуючи ім'я внутрішнього файлу. Дякую!
Діма Фельдман

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
Недоцільно розв’язувати node_modules за допомогою path.resolve. Це може спричинити проблеми із субзалежностями. 'node_modules'Замість цього використовуйте рядок . [ path.resolve(__dirname, 'src'), 'node_modules' ],
spencer.sm

@ spencer.sm, що робити, якщо я хочу лише вирішити модулі з поточного проекту? У мене є кілька проектів, які імпортують один одного. Якщо projectA імпортує файлAA від projectB, а файлA імпортує lodash, я хочу lodashвирішити ТОЛЬКО з projectA/node_modules. Це те, що resolve.modules: [path.resolve(__dirname, 'node_modules')]корисно. Однак у мене виникають проблеми з субзалежностями, як ви сказали. Чи є спосіб сказати webpack також знайти підзалежності, крім обмеження роздільної здатності node_modules projectA/node_modules?
Ерік Гуан

@ spencer.sm дякую! після великої боротьби, нарешті, ваше рішення вирішило мої питання щодо залежності: D
Саад Абдулла

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для поточного файлу проекту. Це більш універсальне рішення, і воно допоможе, якщо ви хочете використовувати інші інструменти без веб-упаковки: тестування, підшивка ...


3

Я вирішую це з Webpack 2, як це:

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

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


Будьте уважні, абсолютні та відносні шляхи не обробляються однаково! Може вплинути на час збирання webpack.js.org/configuration/resolve/#resolve-modules
TeChn4K

1
Він буде працювати в обох випадках, але побудова (може) зайняти довший час відносними шляхами.
TeChn4K

3

Це вирішено за допомогою Webpack 2:

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


1

Цей потік старий, але оскільки ніхто не публікував інформацію про requ.context, я збираюся його згадати:

Ви можете використовувати Requ.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 в moduleDirectories у webpack, що має легко зробити трюк:

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

0

Просто використовуйте babel-plugin-module-resolutionver :

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

Потім створіть .babelrcфайл під коренем, якщо у вас його ще немає:

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

І все під коренем трактуватиметься як абсолютний імпорт:

import { Layout } from 'components'

Про підтримку VSCode / Eslint дивіться тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.