[SOLVED] Webpack: Error in window is not defined during deploy with “window” used in necessary node modules

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
“Error in window is not defined” in main.js file during deploy.
I am not using “window” in my code and node_modules using it are all necessary so i have to use them.

If the current behavior is a bug, please provide the steps to reproduce.
There aren’t much steps to describe. I simply get this error, but this doesn’t provide me more infos…
Error blinks up during execution of “node node_modules/webpack/bin/webpack.js –mode=production –env.prod” command.

What is the expected behavior?
It should execute the command without any problem.
What can I do if window is used inside some necessary node_modules?

If this is a feature request, what is motivation or use case for changing the behavior?

Please mention other relevant information such as the browser version, Node.js version, webpack version, and Operating System.

Related to every other issue about this problem, which solutions haven’t been helpful, unluckily…


Webpack version: 4.6.0
Node version: 5.6.0
Operating system: windows 10.


ERROR:

Hash: db48015ae3f0b2bb936804152e501136ec85ed58
Version: webpack 4.6.0
Child
Hash: db48015ae3f0b2bb9368
Time: 12756ms
Built at: 2018-04-24 10:55:27
1 asset
Entrypoint main-client = main-client.js

ERROR in window is not defined

Child
Hash: 04152e501136ec85ed58
Time: 12750ms
Built at: 2018-04-24 10:55:27
1 asset
Entrypoint main-server = main-server.js

ERROR in window is not defined

webpack.config content:

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
var nodeExternals = require('webpack-node-externals');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    //mode: isDevBuild ? 'development' : 'production';
    const sharedConfig = {
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: ['.js', '.ts'] },
        output: {
            filename: '[name].js',
            publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                { test: /\.ts$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] : '@ngtools/webpack' },
                { test: /\.html$/, use: 'html-loader?minimize=false' },
                { test: /\.css$/, use: ['to-string-loader', 'style-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize'] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
                //font management
                {
                    test: /\.(svg|eot|ttf|woff|woff2)$/,
                    use: [{
                        loader: 'file-loader',
                        options: {
                            name: 'images/[name].[hash].[ext]'
                        }
                    }]
                }
            ]
        },
        plugins: [new CheckerPlugin()]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = './wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig, {
        entry: { 'main-client': './ClientApp/boot.browser.ts' },
        output: { path: path.join(__dirname, clientBundleOutputDir) },
        optimization: {
            minimizer: [
                // specify a custom UglifyJsPlugin here to get source maps in production
                new UglifyJsPlugin({
                    cache: true,
                    parallel: true,
                    uglifyOptions: {
                        compress: false,
                        ecma: 6,
                        mangle: true
                    },
                    sourceMap: true
                })
            ]
        },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
                // Plugins that apply in production builds only
                new AngularCompilerPlugin({
                    tsConfigPath: './tsconfig.json',
                    entryModule: path.join(__dirname, 'ClientApp/app/app.browser.module#AppModule'),
                    exclude: ['./**/*.server.ts']
                })
            ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        resolve: { mainFields: ['main'] },
        entry: { 'main-server': './ClientApp/boot.server.ts' },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./ClientApp/dist/vendor-manifest.json'),
                sourceType: 'commonjs2',
                name: './vendor'
            })
        ].concat(isDevBuild ? [] : [
            new AngularCompilerPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app.server.module#AppModule'),
                exclude: ['./**/*.browser.ts']
            })
        ]),
        output: {
            libraryTarget: 'commonjs',
            path: path.join(__dirname, './ClientApp/dist')
        },

        //exclude node modules
        target: 'node',
        externals: [nodeExternals()], // in order to ignore all modules in node_modules folder

        devtool: 'inline-source-map'
    });

    return [clientBundleConfig, serverBundleConfig];
};

Author: Fantashit

3 thoughts on “[SOLVED] Webpack: Error in window is not defined during deploy with “window” used in necessary node modules

  1. webpack runs in a Node environment, if some of your dependencies rely on window object, enclose them in a check:

    const isClient = typeof window !== 'undefined'

    or when loading dependencies

    let particles
    if (typeof window !== 'undefined') {
      particles = require('particles.js')
    }
  2. 🎉 🍻 SOLVED ✔️ 🍻 🎉

    Changed this:
    { test: /\.ts$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] : '@ngtools/webpack' },

    In this:
    { test: /\.ts$/, include: /ClientApp/, use: ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] },

    So I’ve actually:
    ✔️ ▶️ removed '@ngtools/webpack' from typescript module rules loaders since it was causing this issue

    I don’t know why it was causing errors in libraries but I’ve seen that with other loaders it works pretty fine.
    Website is now deployed and fully-working 😃

Comments are closed.