道招

webpack引入UMD风格JS报错Cannot set property xxx of undefined

我们在项目(比如vue项目)中可能会引入一些umd风格的js库,比如wangEditor,这类的库一般会这么写

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global.wangEditor = factory());
}(this, (function () { 'use strict';
...

// 返回
var index = window.wangEditor || Editor;

return index;

})));

它一般会这么报错 Uncaught TypeError: Cannot set property 'wangEditor' of undefined

file

我们查看上面的wangEditor.js文件,它很可能变成这样的

_webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */
(function(global, module) {
    /* harmony import */
    var _babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/symbol/iterator */
    "./node_modules/@babel/runtime-corejs2/core-js/symbol/iterator.js");
    /* harmony import */
    var _babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__);
    /* harmony import */
    var _babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/symbol */
    "./node_modules/@babel/runtime-corejs2/core-js/symbol.js");
    /* harmony import */
    var _babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_1__);
    /* harmony import */
    var _babel_runtime_corejs2_core_js_date_now__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/date/now */
    "./node_modules/@babel/runtime-corejs2/core-js/date/now.js");
    /* harmony import */
    var _babel_runtime_corejs2_core_js_date_now__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_core_js_date_now__WEBPACK_IMPORTED_MODULE_2__);
    /* harmony import */
    var _babel_runtime_corejs2_core_js_parse_int__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/parse-int */
    "./node_modules/@babel/runtime-corejs2/core-js/parse-int.js");
    /* harmony import */
    var _babel_runtime_corejs2_core_js_parse_int__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_core_js_parse_int__WEBPACK_IMPORTED_MODULE_3__);
    /* harmony import */
    var _babel_runtime_corejs2_core_js_object_assign__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/object/assign */
    "./node_modules/@babel/runtime-corejs2/core-js/object/assign.js");
    /* harmony import */
    var _babel_runtime_corejs2_core_js_object_assign__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_core_js_object_assign__WEBPACK_IMPORTED_MODULE_4__);
    /* harmony import */
    var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @babel/runtime-corejs2/helpers/typeof */
    "./node_modules/@babel/runtime-corejs2/helpers/typeof.js");
    /* harmony import */
    var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/
    __webpack_require__.n(_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_5__);

    (function(global, factory) {
        (typeof exports === "undefined" ? "undefined" : _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_5___default()(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && __webpack_require__(/*! !webpack amd options */
        "./node_modules/webpack/buildin/amd-options.js") ? define(factory) : global.wangEditor = factory();
    }
    )(undefined, function() {
    ...

        var index = window.wangEditor || Editor;
        return index;
    });
    // export default Editor;
    /* WEBPACK VAR INJECTION */
}
.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/global.js */
"./node_modules/webpack/buildin/global.js"), __webpack_require__(/*! ./../../../node_modules/webpack/buildin/harmony-module.js */
"./node_modules/webpack/buildin/harmony-module.js")(module)))

我们可以看到webpack做了很多“工作”,我们可以看到传入的global已经直接变成undefined了,那样后面会报错就很正常了。 其实我们在SPA项目里面,很可能还会使用babel-loader的,所以我们在src目录引入的其它js文件可能已经被babel-loader处理过了,所以这个锅很可能不是webpack,我们可以在设置babe-loader的时候排除掉改wangEditor.js文件

{
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')],
        exclude:[resolve('src/lib/wangEditor.js'), resolve('node_modules')]
      },

这是就不会报错了,果然跟我们使用babel-loader转换有关,我们可以将它直接排除在babel-loader处理外,应该也可以采用配置babel-loader

webpack笔记——在html-webpack-plugin插件中提供给其它插件是使用的hooks

从vuecli3学习webpack记录(四)vue是怎么进行默认配置的

webpack笔记——hook执行时call的是什么

从vuecli3学习webpack记录(二)webpack分析

从vuecli3学习webpack记录(零)整体流程

关注道招网公众帐号