Webpack and modernizr raises TypeError: document undefined error
I am using webpack to build javascript files.
My Webpack config (which is passed to webpack using gulp) looks like this:
var webpackConfig = {
context: __dirname,
entry: {
"app": "./js/app.js"
},
output: {
path: path.join(__dirname, ".."),
filename: "/js/[name].js",
chunkFilename: "/js/[id].js"
},
plugins: [
new webpack.ResolverPlugin(
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
)
],
resolve: {
modulesDirectories: ['js', 'bower_components', 'node_modules']
}
};
Mine app.js
is a simple requirement:
require('modernizr/modernizr.js');
Webpack builds the file without issue, and the generated file contains modernizr.
The problem is when I include the file in the page and check it, the modernizr errors are:
TypeError: document is undefined
docElement = document.documentElement,
The attached file from webpack looks like this:
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
__webpack_require__(1);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
/*!
* Modernizr v2.8.3
* www.modernizr.com
*
* Copyright (c) Faruk Ates, Paul Irish, Alex Sexton
* Available under the BSD and MIT licenses: www.modernizr.com/license/
*/
/*
* Modernizr tests which native CSS3 and HTML5 features are available in
* the current UA and makes the results available to you in two ways:
* as properties on a global Modernizr object, and as classes on the
* <html> element. This information allows you to progressively enhance
* your pages with a granular level of control over the experience.
*
* Modernizr has an optional (not included) conditional resource loader
* called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
* To get a build that includes Modernizr.load(), as well as choosing
* which tests to include, go to www.modernizr.com/download/
*
* Authors Faruk Ates, Paul Irish, Alex Sexton
* Contributors Ryan Seddon, Ben Alman
*/
window.Modernizr = (function( window, document, undefined ) {
var version = '2.8.3',
Modernizr = {},
/*>>cssclasses*/
// option for enabling the HTML classes to be added
enableClasses = true,
/*>>cssclasses*/
docElement = document.documentElement,
/** rest of modernizr code here **/
return Modernizr;
})(this, this.document);
/***/ }
/******/ ])
What is causing this problem?
source to share
This issue is caused by what Modernizr is passing this.document
on to the closure it creates. Unfortunately webpack wraps the whole thing in another closure, forcing it to this.document
return null
.
The problem can be solved by installing this
using import bootloader if needed:
require('imports?this=>window!modernizr/modernizr.js');
source to share
I had the same problem but didn't require Modernizr. I need the library in which "Modern" was packed. The previous solution does not work in this scenario. I ended up using script-loader :
require('script!package/vendor-bundle.js);
source to share
In Webpack 2, I think I was working using {test: /modernizr/, loader: 'imports-loader?this=>window!exports-loader?window.Modernizr'}
, in my module.rules
.
See this webpack bug here: https://github.com/webpack/webpack/issues/512#issuecomment-288143187
source to share