การแก้ไขต้องใช้พา ธ ด้วย 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

คำตอบ:


142

Webpack> 2.0

ดูคำตอบของ wtk

Webpack 1.0

วิธีที่ง่ายกว่าในการทำเช่นนี้คือใช้ resol.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
ขอบคุณฉันพยายามroot, modulesDirectoriesและการผสมผสานของทั้งสอง แต่มันไม่ได้ทำงาน ดูเหมือนว่าrequire("mydir/file")จะไม่ยอมรับsubmodules (เช่น)
gpbl

ควร - เราจะเห็นการกำหนดค่า 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'.
Tomáš Zato - Reinstate Monica

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-dev-server ยังคงใช้งานอยู่แม้กับ webpack 2 ซึ่งทำให้เกิดความสับสนมาก
Evan

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คือมันให้โอกาสคุณในการกำหนด namespace ของคุณrequireซึ่งสามารถเพิ่มความชัดเจนให้กับโค้ดของคุณ เช่นเดียวกับที่มันเป็นเรื่องง่ายที่จะเห็นจากคนอื่น ๆrequireคือสิ่งที่โมดูลจะถูกอ้างอิงaliasช่วยให้คุณเขียนพรรณนาrequires require( 'my-project/component' )ที่ทำให้มันเห็นได้ชัดว่าคุณกำลังกำหนดโมดูลภายในเช่น resolve.rootเพียงแค่คุณลงในไดเรกทอรีที่ต้องการโดยไม่ให้คุณมีโอกาสที่จะ namespace มันต่อไป


46
ฉันชอบนามแฝงตัวหนอน:alias: {'~': path.resolve(__dirname)},
Daniel Buckmaster

คำแนะนำเกี่ยวกับวิธีการปรับแก้ปัญหานี้เพื่อรองรับการนำเข้าไดเรกทอรีย่อยที่ไม่มีนามสกุลไฟล์? @sethro
Dima Feldman

@DimaFeldman คุณหมายถึงไม่มีส่วนขยายในอาร์กิวเมนต์ที่ต้องการ ( require('mydir/myfile')) หรือไม่ มันควรจะใช้ได้จริง คุณสามารถมีหลายรายการในalias; ฉันใช้สิ่งนั้นเพื่อนำเข้าจากsrcไดเรกทอรีของฉันสำหรับโมดูล JavaScript และอีกอันเพื่อนำเข้าจากstylesไดเรกทอรีของฉันสำหรับ css แจ้งให้เราทราบหากฉันเข้าใจคำถามของคุณผิดโดยสิ้นเชิง
sethro

@Sethro คุณพูดถูกฉันขอใช้ถ้อยคำใหม่คำถามของฉัน - สิ่งที่ฉันหมายถึงคือฉันมีไดเรกทอรีพูดว่า Component1 และภายใน dir นี้ฉันมีไฟล์ชื่อ Component1.js ก่อนที่จะใช้นามแฝงฉันสามารถนำเข้าไฟล์เพียงแค่โทรimport './path/to/Component1';- โดยไม่มีชื่อไฟล์และนามสกุลในพา ธ webpack จัดการอย่างใดเพื่อตรวจสอบว่าไฟล์ Inner มีชื่อของไดเรกทอรีและเพิ่งนำเข้า ตอนนี้สิ่งที่ฉันต้องการทำคือนำเข้าแบบนี้: import 'shared\Component1';เมื่อ 'แบ่งใช้' เป็นนามแฝง แต่มันจะไม่ทำงานหากไม่ได้ระบุชื่อไฟล์ Inner ขอบคุณ!
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
ไม่ดีในการแก้ไข node_modules โดยใช้ path.resolve ซึ่งอาจทำให้เกิดปัญหากับการอ้างอิงย่อย ใช้สตริง'node_modules'แทน [ path.resolve(__dirname, 'src'), 'node_modules' ],
spencer.sm

@ spencer.sm จะทำอย่างไรหากฉันต้องการให้โมดูลได้รับการแก้ไขจากโครงการปัจจุบันเท่านั้น ฉันมีโครงการไม่กี่โครงการที่นำเข้าจากกัน หากนำเข้า Projecta fileA จาก projectB และการนำเข้า fileA lodashผมต้องการที่จะได้รับการแก้ไขจากlodash projectA/node_modulesนี่คือสิ่งที่resolve.modules: [path.resolve(__dirname, 'node_modules')]มีประโยชน์สำหรับ อย่างไรก็ตามฉันพบปัญหากับการอ้างอิงย่อยอย่างที่คุณพูด มีวิธีบอก webpack ให้ค้นหา sub-dependencies นอกเหนือจากการ จำกัด node_modules resolution projectA/node_modulesหรือไม่?
Eric Guan

@ spencer.sm ขอบคุณ! ในที่สุดการแก้ปัญหาของคุณก็แก้ไขปัญหาการพึ่งพาของฉันย่อยได้: D
Saad Abdullah

5

ปวดหัวที่ใหญ่ที่สุดของฉันทำงานโดยไม่มีเส้นทาง namespaced บางสิ่งเช่นนี้

./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: ทดสอบ linting ...


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

กระทู้นี้เก่า แต่เนื่องจากไม่มีใครโพสต์เกี่ยวกับ 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 ไว้ใน modulesDirectories ใน webpack ซึ่งควรทำให้ง่ายขึ้น:

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.