Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node-polyfill-webpack-plugin maps to browserified modules that don't match node module completely #723

Open
digimezzo opened this issue Sep 24, 2022 · 2 comments

Comments

@digimezzo
Copy link

digimezzo commented Sep 24, 2022

First of all, many many many thanks for this amazing template. It has helped me a lot to get started.

In this bug report, I wanted to notify you of a problem I encountered, which is caused by the usage of node-polyfill-webpack-plugin. The problem is not limited to this template but happens in every electron project that maps to browserified modules (whether they do it manually in the webpack config or via node-polyfill-webpack-plugin).

You're most likely aware of this, but I'd like to summarize for others: in essence, node-polyfill-webpack-plugin maps node modules (which aren't available in the browser) to their browserified module. For example, if the module 'path' is required by some dependency, the module 'path-browserify' will be provided instead. For most browserified modules, I haven't encountered a problem of performing such mapping. However, for 'path', there is an issue. The module 'path-browserifiy' is not a one on one copy of node's 'path' module. Path-browserify only supports posix paths and does not support win32 paths. This causes errors when, for example, using the function path.resolve() (as well in my own code as in code of modules that my app uses). In path-browserify, path.resolve() only considers a path starting with "/" as an absolute path. When provided a win32 path like "C:\Users\johndoe\Music" it doesn't see it as an absolute path, so to make it an absolute path, it adds the execution directory of the application to it. The path then becomes "C:\Program Files (x86)\MyApp/C:\Users\johndoe\Music". This causes "path not found" errors of which the root cause is very hard to link to path-browserify.

The way I resolved this was to not use browserified modules at all and map to the modules available in the Electron envirmonent instead (which are full blown node modules). I did it by providing the following in angular.webpack.js:

module.exports = {
    externals: {
        electron: 'commonjs electron',
        ipc: 'commonjs ipc',
        'ipc-renderer': 'commonjs ipc-renderer',
        remote: 'commonjs remote',
        fs: 'commonjs fs',
        assert: 'commonjs assert',
        crypto: 'commonjs crypto',
        fs: 'commonjs fs',
        http: 'commonjs http',
        https: 'commonjs https',
        os: 'commonjs os',
        path: 'commonjs path',
        readline: 'commonjs readline',
        stream: 'commonjs stream',
        timers: 'commonjs timers',
        util: 'commonjs util',
        constants: 'commonjs constants',
    },
};

I hope this helps someone. I realize though that my webpack and web technologies knowlegde still needs a lot of refining, so I'm very open for more input or feedback on this solution.

@stale
Copy link

stale bot commented Nov 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Nov 2, 2022
@DaDummy
Copy link

DaDummy commented Sep 25, 2023

Just ran into the same issue regarding WebSockets in the render thread.

I managed to adapt above workaround like this for my situation:

//Polyfill Node.js core modules in Webpack. This module is only needed for webpack 5+.
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");

/**
 * Custom angular webpack configuration
 */
module.exports = (config, options) => {
    config.target = 'electron-renderer';

    if (options.fileReplacements) {
        for(let fileReplacement of options.fileReplacements) {
            if (fileReplacement.replace !== 'src/environments/environment.ts') {
                continue;
            }

            let fileReplacementParts = fileReplacement['with'].split('.');
            if (fileReplacementParts.length > 1 && ['web'].indexOf(fileReplacementParts[1]) >= 0) {
                config.target = 'web';
            }
            break;
        }
    }

    config.plugins = [
        ...config.plugins,
        new NodePolyfillPlugin({
			  excludeAliases: ["console"]
		})
    ];

    // https://github.com/ryanclark/karma-webpack/issues/497
    config.output.globalObject = 'globalThis';

    // https://github.com/maximegris/angular-electron/issues/723
    config.externals = {
        ws: 'commonjs ws',
    };

    return config;
}

I guess it might be a good idea to at least mention this in the documentation, since the common recommendation to adjust the webpack mainFields order or define an alias for the wanted modules will not work here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants