首页 > 解决方案 > Webpack:导出默认类未在 index.html 上定义

问题描述

我是 Webpack 的新手。

我有一个要导出并尝试在我的 index.html 上实例化的类。(这是原始线程的更新版本)

"use strict";

import {TimelineModule} from "./modules/timeline.module.js";
import {NavigationModule} from './modules/navigation.module.js';
import {FiltersModule} from "./modules/filters.module.js";
import VGLogger from "./modules/logger.module.js";
import {DataSourcesModule} from "./modules/data-sources.module.js";
import {EventsModule} from "./modules/events.module.js";


export default class extends EventsModule {
    constructor(params = null) {
        super();
        this.gridTimeline = null;
        this.gridNavigation = null;
        this.gridFilters = null;
        this.dataSources = new DataSourcesModule();
        this.uniqueID = (((1+Math.random())*0x10000)|0).toString(16).substring(1);

        this.settings.gridSettings = {
            ...this.settings.gridSettings,
            ...params
        };

        VGLogger.log(`New VanillaGrid Instance Created!`, `log`);
    }

    create(gridDOMIdentifier) {
        this.#setWrapper(gridDOMIdentifier);
        this.#renderNavigation();
        this.#renderFilters();
        this.#renderTimeline();
        this.initEvents();
    }

    #renderTimeline() {
        this.gridTimeline = new TimelineModule(this.gridWrapper);
    }

    #renderNavigation() {
        this.gridNavigation = new NavigationModule(this.gridWrapper, this.getSettingValue('navigation'));
    }

    #renderFilters() {
        this.gridFilters = new FiltersModule(this.gridWrapper);
    }

    #setWrapper(wrapper) {
        this.gridWrapper = document.querySelector(wrapper);
        const wrapperClass = this.getSettingValue('wrapperClass');
        this.gridWrapper.classList.add(`${wrapperClass}`);
        this.gridWrapper.classList.add(`vg-${this.uniqueID}`);
    }
}

我的 library.js 文件如下所示:

const VanillaGrid = require('./index.js').default;
module.exports = VanillaGrid;
// Based on this post -> https://www.seancdavis.com/blog/export-es6-class-globally-webpack/

我的配置文件如下所示:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "bundle.js",
        library: "VanillaGrid",
        libraryTarget: "var"
    },
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 9000
    },
    entry: {
        main: ['./src/library.js'],
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'sample/index.html'
        }),
    ],
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: [
                            '@babel/plugin-proposal-class-properties',
                            '@babel/plugin-syntax-class-properties',
                            '@babel/plugin-proposal-private-methods'
                        ]
                    }
                }
            },
            {
                test: /\.s[ac]ss$/i,
                use: [
                    "style-loader",
                    "css-loader",
                    "sass-loader",
                ],
            },
        ],
    },
};

和.babelrc:

{
"sourceType": "unambiguous",
  "presets": [
    [
      "@babel/preset-env",
      {
        "loose": true
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-syntax-class-properties"
  ]
}

我的 index.html 看起来像这样:

<html>
<head>
  <title>Samples</title>
  <script defer src="bundle.js"></script>
</head>
<body>
</body>
</html>

问题是 VanillaGrid 在我的 index.html 上未定义,无法弄清楚原因。在 Webpack 的流程上放置了一些断点,并且可以从 Webpack 内部访问该类,但我需要将其作为全局构造函数来访问。


更新:因此,一直在分析结果包,并在其最后几行中包含以下内容:

// startup
/******/    // Load entry module and return exports
/******/    // This entry module is referenced by other modules so it can't be inlined
/******/    __webpack_require__("./src/library.js");
/******/    var __webpack_exports__ = __webpack_require__("./node_modules/webpack-dev-server/client/index.js?http://localhost:9000");
/******/    VanillaGrid = __webpack_exports__;

它将这个似乎是 Webpack 开发服务器一部分的其他文件分配给我的插件的全局变量。这似乎与 webpack-dev-server 相关。

有什么想法吗?

标签: javascriptwebpackecmascript-6

解决方案


我已经尝试过您的代码的简化版本,并且效果很好:

"use strict";

export default class {
    constructor(params = null) {
        this.gridTimeline = null;
        this.gridNavigation = null;
        this.gridFilters = null;
        this.uniqueID = (((1+Math.random())*0x10000)|0).toString(16).substring(1);
    }

    create(gridDOMIdentifier) {
        this.#setWrapper(gridDOMIdentifier);
        this.#renderNavigation();
        this.#renderFilters();
        this.#renderTimeline();
        this.initEvents();
    }

    #renderTimeline() {

    }

    #renderNavigation() {

    }

    #renderFilters() {

    }

    #setWrapper(wrapper) {

    }
}

包.json:

"devDependencies": {
  "@babel/core": "^7.13.16",
  "@babel/plugin-proposal-class-properties": "^7.13.0",
  "@babel/plugin-proposal-private-methods": "^7.13.0",
  "@babel/plugin-syntax-class-properties": "^7.12.13",
  "@babel/preset-env": "^7.13.15",
  "babel-loader": "^8.2.2",
  "css-loader": "^5.2.4",
  "html-webpack-plugin": "^5.3.1",
  "webpack": "^5.35.1",
  "webpack-cli": "^4.6.0"
}

这是带有一些测试代码的输出:

// Beginning of webpack output

var VanillaGrid;
(() => {
  var t = {
    352: (t, e, n) => {
      "use strict";
      function i(t, e) {
        for (var n = 0; n < e.length; n++) {
          var i = e[n];
          i.enumerable = i.enumerable || !1,
          i.configurable = !0,
          "value" in i && (i.writable = !0),
          Object.defineProperty(t, i.key, i)
        }
      }
      function r(t, e, n) {
        if (!e.has(t))
          throw new TypeError("attempted to get private field on non-instance");
        return n
      }
      n.d(e, {
        Z: () => u
      });
      var a = new WeakSet,
      o = new WeakSet,
      s = new WeakSet,
      l = new WeakSet,
      u = function () {
        function t() {
          (function (t, e) {
            if (!(t instanceof e))
              throw new TypeError("Cannot call a class as a function")
          })(this, t),
          l.add(this),
          s.add(this),
          o.add(this),
          a.add(this),
          this.gridTimeline = null,
          this.gridNavigation = null,
          this.gridFilters = null,
          this.uniqueID = (65536 * (1 + Math.random()) | 0).toString(16).substring(1)
        }
        var e,
        n;
        return e = t,
        (n = [{
              key: "create",
              value: function (t) {
                r(this, l, d).call(this, t),
                r(this, o, h).call(this),
                r(this, s, f).call(this),
                r(this, a, c).call(this),
                this.initEvents()
              }
            }
          ]) && i(e.prototype, n),
        t
      }
      ();
      function c() {}
      function h() {}
      function f() {}
      function d(t) {}
    },
    509: (t, e, n) => {
      var i = n(352).Z;
      t.exports = i
    }
  },
  e = {};
  function n(i) {
    var r = e[i];
    if (void 0 !== r)
      return r.exports;
    var a = e[i] = {
      exports: {}
    };
    return t[i](a, a.exports, n),
    a.exports
  }
  n.d = (t, e) => {
    for (var i in e)
      n.o(e, i) && !n.o(t, i) && Object.defineProperty(t, i, {
        enumerable: !0,
        get: e[i]
      })
  },
  n.o = (t, e) => Object.prototype.hasOwnProperty.call(t, e);
  var i = n(509);
  VanillaGrid = i
})();

// End of webpack output

// Beginning of the test code

const grid = new VanillaGrid;

console.log(grid.uniqueID);

如果您的问题是同步标签中的类无法立即使用script,请尝试添加配置以从生成的标签中删除该属性。scriptLoading: "blocking"HtmlWebpackPlugindeferscript

如果这不能回答您的问题,您应该添加有关bundle.js输出的详细信息以及如何尝试使用生成的代码。


推荐阅读