31

Is there any way to receive current file path, like in requirejs?

define(['module'], function (module) {
    console.log(module.uri)
});
Sergey Lapin
  • 1,008
  • 3
  • 12
  • 21

3 Answers3

54

Yep there is one: __filename.

But by default webpack doesn't leak path information and you need to set a config flag to get real filename instead of a mock ("/index.js").

// /home/project/webpack.config.js
module.exports = {
  context: __dirname,
  node: {
    __filename: true
  }
}

Than you can use __filename get the current filename relative to the context option:

// in /home/project/dir/file.js
console.log(__filename);
// => logs "dir/file.js"

The filename is only embedded into modules where __filename is used. So you don't have to be affraid that paths are leaked from other modules.

Daniel Wolf
  • 12,855
  • 13
  • 54
  • 80
Tobias K.
  • 11,997
  • 4
  • 25
  • 25
  • 2
    Still relevant in 2017: I cannot get this to work when the target is `umd`, so if you're looking for an answer on getting `__dirname` and `__filename` to work with webpack for a `umd` build, this answer will probably not help you. – Mike 'Pomax' Kamermans Mar 15 '17 at 19:14
  • 1
    Does this have any impact on performance or any other known side effects to anyone's knowledge? Is there a downside to doing this? – RandallB Apr 09 '18 at 13:51
  • Just to add. You need to restart the webpack server anytime you update its config for your update to take effect. – GuruKay Jun 27 '19 at 19:13
7

To get the filename an the dir name I added this to the web pack config

node : {
   __filename: true,
   __dirname: true,
},

setting the context to __dirname messed up my web pack config since I have my webpackconfig not placed in root but the paths are setup that way

P-A
  • 1,161
  • 12
  • 16
5

Try webpack.DefinePlugin with webpack.DefinePlugin.runtimeValue. It gives real constants, which can be used in ES6 import and require().

Webpack configuration:

new webpack.DefinePlugin({
    __NAME: webpack.DefinePlugin.runtimeValue(
        v => {
            const res = v.module.rawRequest.substr(2)
            return JSON.stringify(res); // Strings need to be wrapped in quotes
        }, []
    )
})

// OR

new webpack.DefinePlugin(
    __NAME: webpack.DefinePlugin.runtimeValue(
        v => {
            const res = v.module.rawRequest.substr(2)
            return `'${res.substr(0, res.lastIndexOf('.'))}'`
        }, []
    )
})

Source file:

// require "<filename>.html" from "<filename>.js"
const html = require(`./${__NAME}.html`)
Eloims
  • 5,106
  • 4
  • 25
  • 41
ilya
  • 109
  • 1
  • 3
  • 2
    This is great! The feature hasn't been documented yet but it was added in https://github.com/webpack/webpack/pull/6793 – fregante Jun 22 '19 at 08:46
  • I don't understand how this snippet is related to the question. Please shed more light. Thank you. – GuruKay Jun 27 '19 at 12:36
  • Let's have report-1.0.0.js and report-1.0.0.html. Now you can include html into script with require(./${__NAME}.html) – ilya Jun 27 '19 at 13:07