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

[SOLVED] Webpack: Error in window is not defined during deploy with "window" used in necessary node modules #7112

Closed
MrSantaCloud opened this issue Apr 24, 2018 · 9 comments

Comments

@MrSantaCloud
Copy link

MrSantaCloud commented Apr 24, 2018

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];
};
@montogeek
Copy link
Member

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')
}

@montogeek
Copy link
Member

montogeek commented Apr 24, 2018

I encourage you to ask your question on StackOverflow instead. We try to use the issue tracker for bug reports and feature requests, as well as some discussions, but this appears to be a very localized question.

I’m closing for these reasons.

@MrSantaCloud
Copy link
Author

MrSantaCloud commented Apr 24, 2018

@montogeek I want to try with your suggested solution, but since I'm a newbie to webpack i really need to ask you: where should I put these code snippets exactly? In webpack.config.js, in my angular app entry point,...?

Thanks in advance!

( I've asked it on stackoverflow before but I didn't have a real working solution, looks like no one has a real workaround for this and looking on other related issues on github I've never found some pratical examples as solutions... So I'm asking here because I also want to give help to other users providing them a pratical example, obviously I hope It's not a problem or to not go against some rules with this )

@montogeek
Copy link
Member

You should put them whatever you need to use window or you need to import a library that uses window object as you see on my examples.

Read more about globals in different environment here: https://www.hacksparrow.com/global-variables-in-node-js.html

There is ton of articles about how globals differ on Browser and Node.JS environment but in a nutshell:

  1. Browsers have window global object.
  2. Node.JS global object is global and it doesn't have window object.
  3. Commands that run on your terminal are running on a Node environment, therefore any reference to window would result in an error.

@MrSantaCloud
Copy link
Author

MrSantaCloud commented Apr 26, 2018

🎉 🍻 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 😃

@montogeek
Copy link
Member

Congrats!

@MrSantaCloud MrSantaCloud changed the title Webpack: Error in window is not defined during deploy with "window" used in necessary node modules [SOLVED] Webpack: Error in window is not defined during deploy with "window" used in necessary node modules Apr 26, 2018
clodal added a commit to onextech/react-hocs that referenced this issue Jul 5, 2018
@stevemarksd
Copy link

@montogeek

Actually I need a part of the library, but the library is bloated and imports another file that depends on window. I can't use your solution.

For example I need PIXI.Point, which works fine on node.js, but importing pixi.js it will import the whole file which has a window reference.

@pundoo
Copy link

pundoo commented Oct 4, 2020

Shimming did the trick for me...

...
plugins: [
   new webpack.ProvidePlugin({
      window: 'global/window',
   }),
]
...

requires global package

@justintoth
Copy link

@pundoo's webpack config update suggestion to use ProvidePlugin just changed the error to:

NativeScript encountered a fatal error: Uncaught ReferenceError: Zone is not defined
at
(file: src/webpack:/housters/node_modules/zone.js/dist/zone.js:703:0)
at (file: src/webpack:/housters/node_modules/zone.js/dist/zone.js:8:63)
at ./node_modules/zone.js/dist/zone.js(file: src/webpack:/housters/node_modules/zone.js/dist/zone.js:10:1)
at __webpack_require__(file: src/webpack:/housters/webpack/bootstrap:24:0)
at fn(file: src/webpack:/housters/webpack/runtime/hot module replacement:61:0)
at ./src/polyfills.ts(file:///app/bundle.js:26385:75)
at __webpack_require__(file: src/webpack:/housters/webpack/bootstrap:24:0)
at __webpack_exec__(file:///app/bundle.js:33452:39)
at (file:///app/bundle.js:33453:71)
at __webpack_require__.X(file: src/webpack:/housters/webpack/runtime/startup entrypoint:6:0)
at (file:///app/bundle.js:33453:47)
at (file:///app/bundle.js:33458:3)
at require(:1:137)

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

5 participants