【问题标题】:ES6 script errors out after processed through webpack通过 webpack 处理后出现 ES6 脚本错误
【发布时间】:2017-04-28 19:12:56
【问题描述】:

我有一个用 ES6 编写的脚本。当我在现代浏览器中使用它时,它工作正常。一切都很好。然后我通过 webpack 传递它,以便它可以在旧浏览器上运行。但是,输出代码随后会在我的控制台窗口中删除以下内容。

Uncaught TypeError: Cannot read property 'dispatch' of undefined
    at Register.componentDidUpdate (Register.jsx:8)
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponent.js:729
    at CallbackQueue.notifyAll (CallbackQueue.js:76)
    at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
    at ReactReconcileTransaction.closeAll (Transaction.js:206)
    at ReactReconcileTransaction.perform (Transaction.js:153)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:140)
    at ReactUpdatesFlushTransaction.perform (ReactUpdates.js:89)
    at Object.flushBatchedUpdates (ReactUpdates.js:172)

如果您对第 8 行的 Register.jsx 中的内容感到好奇:

parent.globalBroadcaster.dispatch('react_app.Register.componentDidUpdate', true);

就像我说的,在我通过 webpack 运行代码之前,代码在现代浏览器中运行良好,所以我假设我的 webpack.config.js 有问题。任何帮助将不胜感激。

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  context: __dirname,
  devtool: 'inline-source-map',
  entry: {
    ReactApp: ['babel-polyfill', './src/index.jsx'],
    GlobalBroadcaster: './src/GlobalBroadcaster.js',
  },
  output: {
    path: path.join(__dirname, '../public'),
    publicPath: '/react',
    filename: 'js/[name].js',
  },
  resolve: {
    extensions: ['', '.scss', '.css', '.js', '.jsx', '.json'],
    modulesDirectories: [
      'node_modules',
      path.resolve(__dirname, './node_modules'),
    ],
  },
  module: {
    loaders: [
      {
        test: /(\.js|\.jsx)$/,
        exclude: /(node_modules)/,
        loader: 'babel',
        query: { presets: ['es2015', 'stage-0', 'react'] },
      }, {
        test: /(\.scss|\.css)$/,
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[local]!postcss!sass'),
      },
    ],
  },
  postcss: [autoprefixer],
  sassLoader: {
    data: '@import "styles/_variables.scss";',
    includePaths: [path.resolve(__dirname, './src')],
  },
  plugins: [
    new ExtractTextPlugin('css/reactApp.css', { allChunks: true }),
    new webpack.ProvidePlugin({
      Promise: 'es6-promise',
      fetch: 'imports?this=>global!exports?global.fetch!whatwg-fetch',
    }),
  ],
};

GlobalBroadcaster.js

/**
* Very basic means of dispatching messages from event generators to interested subscribers
*/
class GlobalBroadcaster {
  constructor() {
    this.events = {};
  }
  /**
   * Called by event generators to inform subscribers.
   *
   * @param string event: a string identifying the event name
   * @param mix data: message to communicate to subsribers
   */
  dispatch(event, data) {
    if (!this.events[event]) return; // no subscribers
    this.events[event].forEach(subscriber => subscriber(data));
  }
  /**
   * Means to subscribe a callback function to a given event.
   * @param string event: a string identifying the event name
   * @param function subscriber: a function to call back when the given event takes place
   */
  subscribe(event, subscriber) {
    if (!this.events[event]) this.events[event] = []; // new event
    this.events[event].push(subscriber);
  }
}

var globalBroadcaster = new GlobalBroadcaster();

【问题讨论】:

  • 错误是parent.globalBroadcasterundefined,所以我们需要查看设置它的代码。 parent 是什么,它来自哪里?
  • parent 是 javascript 的一部分。像 parent.window。 globalBroadcaster 是我通过上面粘贴的 GlobalBroadcaster.js 文件单独创建和加载的变量。所以我只是用 parent.globalBroadcaster 访问 globalBroadcaster。此外,在我通过 webpack 处理 GlobalBroadcaster.js 文件之前,parent.globalBroadcaster 工作正常。
  • 啊,好吧。如果您之前在没有 Webpack 的情况下加载它,那么您正在创建一个全局变量。 Webpack 将每个文件包装在一个模块包装器中,因此所有变量都是针对每个文件的,所以如果你想创建一个全局变量,你必须明确地这样做。
  • 啊,谢谢。现在我知道了问题所在,我可以努力让它再次成为全球性的。只需要弄清楚如何使用 webpack 来做到这一点。

标签: javascript reactjs webpack ecmascript-6


【解决方案1】:

对于任何好奇的人,我只需编辑 GlobalBroadcaster 文件的最后一行:

var globalBroadcaster = new GlobalBroadcaster();

window.globalBroadcaster = new GlobalBroadcaster();

如 cmets 中所述,webpack 将输出代码放在一个范围内。如果你想像我一样在全局范围内访问它,你必须将函数附加到窗口。

【讨论】:

  • 或者,配置 webpack 以将您的导出导出到全局范围。
猜你喜欢
  • 2018-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多