mpen
mpen

Reputation: 282875

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"?

Upvotes: 0

Views: 2166

Answers (2)

fregante
fregante

Reputation: 31708

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.

Upvotes: 3

Salim
Salim

Reputation: 2546

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.

Upvotes: 1

Related Questions