'How to get current filename without path and extension with webpack?

I can get the relative file path with __filename, and sure I could hack it apart to get just the basename with some JS-fu, but I want to do this at compile-time.

DefinePlugin will let me inject some globals like I want, but AFAICT I can't have a "dynamic" global based on the current file.

So how can I do this?

e.g. given I am in the file assets/scripts/lib/components/bpm/RecordAttendancePopup.jsx, how can I get webpack to inject a constant like __basename that evaluates to "RecordAttendancePopup"?



Solution 1:[1]

Generic version

If you're using modules or any supported bundler, you can access the pre-existing import.meta.url and manually extract the filename:

const filename = import.meta.url // Get current path
  .split(/[\\/]/).pop() // Get current filename
  .replace(/\.[^.]+$/, ''); // Drop extension

or you can use a better parser (which may or may not work depending on your config)

const path = require('path');
const filename = path.parse(import.meta.url).name;

Webpack-specific version

This is what I use in my webpack.config.js:

const path = require('path');
const webpack = require('webpack');

module.exports = {
    plugins: [
        new webpack.DefinePlugin({
            __filebasename: webpack.DefinePlugin.runtimeValue(
                info => JSON.stringify(path.parse(info.module.resource).name)
            )
        })
    ]
};

and then I'll have the __filebasename variable available everywhere in my source. Works in Webpack 4 and 5.

Solution 2:[2]

I guess there is no other way than creating your own "DefinePlugin" based on https://github.com/webpack/webpack/blob/master/lib/DefinePlugin.js to get what you want.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Salim