markdalgleish / static-site-generator-webpack-plugin

Minimal, unopinionated static site generator powered by webpack
MIT License
1.61k stars 97 forks source link

Error: 'window is not defined' with Webpack 4 #130

Open chrishutchinson opened 6 years ago

chrishutchinson commented 6 years ago

I'm posting this issue for reference more than anything else, in case others are searching for a fix. The temporary fix is at the end, perhaps it's worth adding that to the README?


When using this plugin with a fresh install of Webpack 4 (4.6.0 in my test) I get the following error:

ERROR in ReferenceError: window is not defined

Having dug into it further, it appears it is a side effect of this issue where the umd target generates invalid code for running inside a Node.js context.

The temporary fix is detailed here, where you can add the following to your Webpack config to change the global keyword from window to this:

output: {
  // ...
  globalObject: "this"
}
kavehsajjadi commented 6 years ago

@chrishutchinson is there some magic involved with getting that fix to work? I'm getting Invalid configuration object errors

lorenzo-w commented 6 years ago

@kavehsajjadi same here. "self" is not defined now

dongdongmao commented 6 years ago

i added globalObject: "this" still not fix ERROR in window is not defined

chrishutchinson commented 6 years ago

In addition to the fix I outlined at the top of the issue, if you’re still getting ”window” is not defined errors, I’ve occasionally found it is because my application code is making a call to a DOM API (e.g. window.location) which doesn’t exist in Node-land.

Often wrapping these lines in a if (typeof window !== ‘undefined’) {} has helped, although that may not be the issue you’re having. Bear in mind this conditional check might have unexpected side effects depending on your exact implementation, so you may need to do some testing around that behaviour.

MartinRosenberg commented 5 years ago

Starting with a hello-world React setup (no router or anything) and this (partial) Webpack config:

output: {
  filename: '[name].bundle.js',
  path: path.join(__dirname, 'dist'),
  libraryTarget: 'umd',
},
plugins: [
  new StaticSiteGeneratorPlugin({ crawl: true })
],

I got this error on running webpack or webpack-dev-server:

ERROR in ReferenceError: window is not defined
    at evalmachine.<anonymous>:1:224
    at Script.runInContext (vm.js:107:20)
    at Script.runInNewContext (vm.js:113:17)
    at module.exports (/Users/martin/Workspace/react-blog/node_modules/eval/eval.js:69:12)
    at /Users/martin/Workspace/react-blog/node_modules/static-site-generator-webpack-plugin/index.js:42:22
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/martin/Workspace/react-blog/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/martin/Workspace/react-blog/node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeChunkAssets.callAsync.err (/Users/martin/Workspace/react-blog/node_modules/webpack/lib/Compilation.js:1314:32)
    at _err0 (eval at create (/Users/martin/Workspace/react-blog/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:11:1)
    at taskRunner.run (/Users/martin/Workspace/react-blog/node_modules/terser-webpack-plugin/dist/index.js:315:9)

Following @chrishutchinson's links, and nested ones, I resolved it by adding this to my Webpack config:

output: {
  globalObject: `typeof self !== 'undefined' ? self : this`
}

However, now I get new errors. On running webpack, I get:

ERROR in ReferenceError: document is not defined
    at Module.<anonymous> (evalmachine.<anonymous>:6:44761)
    at n (evalmachine.<anonymous>:1:385)
    at Object.<anonymous> (evalmachine.<anonymous>:6:1192)
    at n (evalmachine.<anonymous>:1:385)
    at evalmachine.<anonymous>:1:1184
    at evalmachine.<anonymous>:1:1195
    at evalmachine.<anonymous>:1:84
    at evalmachine.<anonymous>:1:223
    at Script.runInContext (vm.js:107:20)
    at Script.runInNewContext (vm.js:113:17)

And on running webpack-dev-server, I get:

ERROR in ReferenceError: self is not defined
    at Object.<anonymous> (evalmachine.<anonymous>:41534:18)
    at Object../node_modules/webpack-dev-server/client/index.js?http://localhost:8080 (evalmachine.<anonymous>:41589:30)
    at __webpack_require__ (evalmachine.<anonymous>:30:30)
    at Object.0 (evalmachine.<anonymous>:41982:1)
    at __webpack_require__ (evalmachine.<anonymous>:30:30)
    at evalmachine.<anonymous>:94:18
    at evalmachine.<anonymous>:97:10
    at webpackUniversalModuleDefinition (evalmachine.<anonymous>:3:20)
    at evalmachine.<anonymous>:10:3
    at Script.runInContext (vm.js:107:20)
t47io commented 5 years ago

Same here. The globalObject: "this" tricked did work for me once, but when I introduced mini-css-extract-plugin, it no longer does.

darkouz commented 5 years ago

Still the same problem over here, is there someone with some solution ?

ufhy commented 5 years ago

up

ArcusDeri commented 5 years ago

new StaticSiteGeneratorPlugin({ entry: 'entry', globals: new JSDOM().window }), I came up with this idea. Now I face ERROR in SecurityError: localStorage is not available for opaque origins also from this plugin.

wendelcosta commented 5 years ago

Having the same issue here with bootstrap-loader.

ERROR in ./node_modules/bootstrap-loader/no-op.js (./node_modules/mini-css-extract-plugin/dist/loader.js!./node_modules/style-loader!./node_modules/css-loader/dist/cjs.js?sourceMap!./node_modules/resolve-url-loader?sourceMap!./node_modules/postcss-loader/src!./node_modules/sass-loader/lib/loader.js?sourceMap!./node_modules/bootstrap-loader/lib/bootstrap.styles.loader.js?{"bootstrapVersion":4,"bootstrapCustomizations":"/Users/wendel.costa/Desktop/qantas/src/shared/styles/01_settings/_bootstrap.scss","extractStyles":true,"styleLoaders":["style-loader","css-loader?sourceMap","resolve-url-loader?sourceMap","postcss-loader","sass-loader?sourceMap"],"styles":["mixins","grid"],"scripts":false,"configFilePath":"/Users/wendel.costa/Desktop/qantas/.bootstraprc","bootstrapPath":"/Users/wendel.costa/Desktop/qantas/node_modules/bootstrap","bootstrapRelPath":"../bootstrap"}!./node_modules/bootstrap-loader/no-op.js) Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ReferenceError: window is not defined

ssbarbee commented 5 years ago

Bump

BernardA commented 5 years ago

Having the same issue. Please see webpack.config below

Thanks

  const {InjectManifest} = require('workbox-webpack-plugin');
 const MiniCssExtractPlugin = require("mini-css-extract-plugin");
 const ManifestPlugin = require('webpack-manifest-plugin');
 const CleanWebpackPlugin = require('clean-webpack-plugin');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const ExtractCssChunks = require("extract-css-chunks-webpack-plugin");
 const CopyWebpackPlugin = require('copy-webpack-plugin');
 const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
 const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
 const path = require('path');
 //const StyleExtHtmlWebpackPlugin = require("style-ext-html-webpack-plugin");
 const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

 module.exports = {
mode: "development",
entry: "./client/index.js",
output: {
    path: __dirname+'/public/dist',
    filename: "[name].[contenthash].js",
    publicPath: "/dist/",
    libraryTarget: 'umd'
},
devtool: "source-map",
devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  },
module: {
    rules: [
        {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader",
            }
        },
        {
            test: /\.css$/,
            use: [
                ExtractCssChunks.loader,
                "css-loader",
                {
                    loader: "postcss-loader",
                    options: {
                        ident: "postcss",
                        plugins: (loader) => [
                            require('postcss-import')(),
                            require('postcss-preset-env')(),
                            require('autoprefixer')(),
                            require('cssnano')()
                        ]
                    }
                }
            ]
        }
    ]
},
plugins: [
    new HardSourceWebpackPlugin(),
    new CleanWebpackPlugin(['public/dist/*.*', 'public/img-cache/*.*']),
    new ExtractCssChunks( // old new MiniCssExtractPlugin( note sideEffect config on package.json for production
        {
            filename: "[name].[contenthash].css",
            chunkFilename: "[id].css"
        }
    ),
    new HtmlWebpackPlugin({
        showErrors: true,
        template: 'templates/webpack.html.twig', // base template
        filename: '../../templates/base.html.twig', // output
        inlineSource: '.(css)$' // embed all css inline
    }),
    // disable for development
    //new HtmlWebpackInlineSourcePlugin(), 
    //new StyleExtHtmlWebpackPlugin(),
    // disable copy while in development
    /*
    new CopyWebpackPlugin([
        { 
            from: './assets/img/', 
            to: '../img-cache/[name].070219.[ext]',
            //to: '../img/'
        },
    ]),
    */
    new StaticSiteGeneratorPlugin({
        crawl: true
    }),
    new ManifestPlugin(),
    new InjectManifest({
        swSrc: './client/sw-src.js',
        swDest: '../sw.js',
        exclude: [/\.twig$/, /\.DS*/],
    }),
],

}

lorenzocadamuro commented 5 years ago

Same issue... So is it not possible to use it with webpack-dev-server? 🤨

AjitTK commented 5 years ago

facing similar issue on frontend module build from webpack

return window && document && document.all && !window.atob; ^ ReferenceError: window is not defined

coldpour commented 5 years ago

this worked for me

module.exports = {
  ...,
  plugins: [
    new StaticSiteGeneratorPlugin({
      globals: {
        window: {}
      }
    })
  ]
}

as documented https://github.com/markdalgleish/static-site-generator-webpack-plugin#globals

BernardA commented 5 years ago

@coldpour. Thanks but that does not solve my issue. I use servicer worker, which needs window to register itself. So on my registerServiceWorker.js there are several instances of calling the window object, like so:

 const isLocalhost = Boolean(
   window.location.hostname === 'localhost' ||
   // [::1] is the IPv6 localhost address.
   window.location.hostname === '[::1]' ||
    // 127.0.0.1/8 is considered localhost for IPv4.
   window.location.hostname === '127.0.0.1' ||
   window.location.hostname.match(
   /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
  )
);

There are a few other calls to window on the same file, which I skip here for brevity, but you get the idea. So, when I run webpack, I get the following error:

    ERROR in TypeError: Cannot read property 'hostname' of undefined
at Module.<anonymous> (evalmachine.<anonymous>:2440:43)
at Module../client/registerServiceWorker.js (evalmachine.<anonymous>:2509:30)
 ......

Any idea on how to solve that?

lofimob commented 4 years ago

@coldpour. Thanks but that does not solve my issue. I use servicer worker, which needs window to register itself. So on my registerServiceWorker.js there are several instances of calling the window object, like so:

 const isLocalhost = Boolean(
   window.location.hostname === 'localhost' ||
   // [::1] is the IPv6 localhost address.
   window.location.hostname === '[::1]' ||
    // 127.0.0.1/8 is considered localhost for IPv4.
   window.location.hostname === '127.0.0.1' ||
   window.location.hostname.match(
   /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
  )
);

There are a few other calls to window on the same file, which I skip here for brevity, but you get the idea. So, when I run webpack, I get the following error:

    ERROR in TypeError: Cannot read property 'hostname' of undefined
at Module.<anonymous> (evalmachine.<anonymous>:2440:43)
at Module../client/registerServiceWorker.js (evalmachine.<anonymous>:2509:30)
 ......

Any idea on how to solve that?

Were you able to fix this?

BernardA commented 4 years ago

@lofimob That was many moons ago! I'll see if I can go back and check, but make no promises.

ags1773 commented 4 years ago

Not sure if relevant, but I was working on a library meant to run in node env, and was getting this error even after setting output.globalObject = "this. Setting target: node got it working for me

module.exports = {
  entry: "./src/index.ts",
  mode: "development",
  target: "node",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: "ts-loader"
      }
    ]
  },
  resolve: { extensions: [".ts", ".tsx", ".js"] },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
    libraryTarget: "commonjs2",
    library: "amp"
  },
  plugins: []
};
brettdewoody commented 4 years ago

A simple globals option when initializing the StaticSiteGeneratorPlugin did the trick for me.

new StaticSiteGeneratorPlugin({
    ...
    globals: {
      window: {}
    }
  })

Documentation available here.