Unable to get fullpath with __dirname and __filename

08 Sep 2019

Recently, I faced a strange issue while trying to migrate my Visual Studio code extension (Redis Xplorer) to use webpack as the module builder/bundler. NodeJs provided globals like __dirname and __filename returned '/' and '/index.js' instead of complete system file-path, this code was 100% working before migration to webpack.

For Visual Studio Code extension migration, I followed simple "vscode extension sample" using webpack that is hosted under vscode-extension-samples repository. Then, in the src/extension.ts - activate method, I tried to log __dirname and __filename which returned relative paths like '/' and '/index.js'.

// Extension.ts
import * as vscode from 'vscode';
import { add } from './math';

export function activate(context: vscode.ExtensionContext) {

    console.log(__dirname); // logs /
    console.log(__filename);// logs /index.js

    let disposable = vscode.commands.registerCommand('extension.helloWebpack', () => {
        vscode.window.showInformationMessage(`41 + 1 = ${add(41, 1)}`);
    });

    context.subscriptions.push(disposable);
}?

After a long search through VsCode extension support threads and Github issues, I've identified a change in underlying Webpack package that caused this issue.

REASON
Since webpack 3.0.0, when you set your target:`node` in webpack.config,..

make sure that you also set your node property to false i.e., node:false. Otherwise, webpack will provide you additional features (try to `mock` nodejs global variable in a way to allow the same code to run on web browser environment) that will cause unexpected/unintended changes to your NodeJs application Global variables.

You can see all available options/properties provided by webpack's underlying/internal plugins - NodeStuffPlugin and NodeSourcePlugin that creates this issue in node environments.

// webpack.config.json

const path = require('path');

/**@type {import('webpack').Configuration}*/
const config = {
    target: 'node', // vscode extensions run in a Node.js-context ?? -> https://webpack.js.org/configuration/node/

    node: false,
    entry: './src/extension.ts', // the entry point of this extension, ?? -> https://webpack.js.org/configuration/entry-context/
    
    ...
}

module.exports = config;

Setting node:false in webpack.config.json will turn off the un-intended mocking.

Hope this post saves your time.