javascriptreactjsfunctionwebpackwindow-object

Attaching a function to window object in Webpack 5


I recently updated to Webpack 5 from Webpack 4, earlier I had a function on window object in index.js such that it looked something like

index.js

window.someFunction = function (...arguments) {
    // function body
}

when this index.js gets bundled I can find this same function in common.bundle.js file.

and my index.html looks something like this

index.html

<head>
    // rest of the head stuff
    <script src="./dist/common.bundle.js"></script>
</head>
<body>
    <script type="text/javascript">
        someFunction(); // calling someFunction from the window object
        // Also tried using window.someFunction() still doesn't work    
    </script>
</body>

In console I get ReferenceError: someFunction is not defined and I am not able to print the function defination in chrome console when I type window.someFunction which was working in Webpack 4 as expected.

How do I attach my functions to window object in Webpack 5, and how do I go about accessing it?

webpack.config.js

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

module.exports = (env) => {
  return {
    mode: "development",
    devtool: "source-map",
    entry: {
      common: "./index.js",
    },
    output: {
      pathinfo: true,
      path: path.join(__dirname, "dist"),
      filename: "[name].bundle.js",
    },
    plugins: [
      new webpack.DefinePlugin({
        "process.env.NODE_ENV": JSON.stringify("development"),
      }),
    ],
    module: {
      rules: [
        {
          test: /\.(js|jsx)$/,
          exclude: /(node_modules|bower_components)/,
          use: {
            loader: "babel-loader",
            options: {
              cacheDirectory: true,
              babelrc: false,
              presets: [
                [
                  "@babel/env",
                  {
                    modules: false,
                    loose: true,
                    targets: {
                      browsers: [">0.25%", "not ie 11", "not op_mini all"],
                    },
                  },
                ],
                "@babel/react",
              ],
              plugins: [
                [
                  "@babel/plugin-proposal-class-properties",

                  {
                    loose: true,
                  },
                ],
                ["@babel/plugin-transform-runtime"],
              ],
            },
          },
        },
        {
          test: /\.css$/,
          include: /node_modules/,
          use: [{ loader: "style-loader" }, { loader: "css-loader" }],
        },
      ],
    },
    resolve: {
      extensions: [".js", ".jsx"],
      modules: [path.resolve(__dirname, "node_modules")],
      fallback: {
        buffer: false,
        fs: false,
        tls: false,
        net: false,
        path: false,
        zlib: false,
        http: false,
        https: false,
        stream: false,
        crypto: false,
      },
    },
    optimization: {
      // namedModules: true,
      // namedChunks: true,
      minimize: false,
      // minimizer: [new TerserPlugin()],
      runtimeChunk: "single",
      moduleIds: "deterministic",
      chunkIds: "deterministic",
      nodeEnv: "development",
      flagIncludedChunks: false,
      concatenateModules: false,
      splitChunks: {
        hidePathInfo: false,
        minSize: 20000,
        maxAsyncRequests: Infinity,
        maxInitialRequests: Infinity,
        chunks: "all",
        // maxSize: 0,
        minChunks: 1,
        automaticNameDelimiter: "~",
        cacheGroups: {
          commons: {
            test: /[\\/]node_modules[\\/]/,
            name: "other.bundle",
            chunks: "all",
            minChunks: 2,
          },
          defaultVendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10,
          },
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true,
          },
        },
      },
      emitOnErrors: true,
      checkWasmTypes: false,
      removeAvailableModules: false,
    },
    performance: {
      hints: "warning",
    },
    stats: {
      all: false,
      assets: true,
      builtAt: true,
      cachedAssets: false,
      cachedModules: true,
      chunkGroups: true,
      colors: true,
      env: true,
      errors: true,
      hash: true,
      logging: "info",
      timings: true,
      modules: true,
      outputPath: true,
      performance: true,
      errorsCount: true,
      warnings: false,
      warningsCount: true,
      publicPath: true,
      reasons: true,
      ids: true,
      version: true,
    },
    cache: {
      type: "filesystem",
      version: "1.0.0",
      store: "pack",
      name: "AppBuildCache",
      maxMemoryGenerations: 1,
      idleTimeout: 60000,
      idleTimeoutAfterLargeChanges: 1000,
      idleTimeoutForInitialStore: 0,
      hashAlgorithm: "md4",
      cacheLocation: path.resolve(__dirname, ".cache"),
    },
    externals: [
      {
        react: "React",
        "react-dom": "ReactDOM",
        jquery: "jQuery",
      },
    ],
  };
};

Solution

  • Thank you for the answers, the issue turned out exactly to be due to missing polyfills for node core modules.

    In my case the I had to provide polyfill for process using ProvidePlugin.

    I did the same by adding below to my config

    new webpack.ProvidePlugin({
        process: "process/browser",
    })