Javascript require vs require .default

时间:2017-04-06 06:47:24

标签: javascript reactjs

我正在使用react-hot-loader,我对其示例代码非常困惑:

import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './containers/App'

ReactDOM.render(
  <AppContainer>
    <App/>
  </AppContainer>,
  document.getElementById('root')
);

// Hot Module Replacement API
if (module.hot) {
  module.hot.accept('./containers/App', () => {
    const NextApp = require('./containers/App').default;
    ReactDOM.render(
      <AppContainer>
        <NextApp/>
      </AppContainer>,
      document.getElementById('root')
    );
  });
}

我不明白的是:

a)为什么我需要使用App和NextApp? AppNextApp不一样,因为它们是从同一个文件导入的吗?

b)我认为最佳做法是将requires保留在代码的开头。但我已经import App from '../containers/App'了。所以:

import App from './containers/App'
const NextApp = require('./containers/App').default;

AppNextApp不应该相同吗?

c)要完成,以下代码行是否等效?使用纯requirerequire .default

有什么区别
const NextApp = require('./containers/App');
const NextApp = require('./containers/App').default;

很抱歉,如果这些是非常基本的问题,但我需要提示如何更好地理解此代码。

1 个答案:

答案 0 :(得分:13)

为了更好地理解这一点,您需要了解webpack offers hot module loading对其他非反应案例的看法。

实际上这个想法非常简单...... Webpack检测到代码发生的变化并重新编译相应的模块。但是,它无法安全地替换模块引用本身。这就是您需要自己实现HMR接口的原因,因此您的示例代码中会调用module.hot

当一个较新版本的模块可用时,Webpack上升到模块链(即,如果X导入Y和Y已经改变,webpack开始从X&gt; W&gt; V ...开始)直到它找到一个为Y或X或W或V等实现HMR的模块然后从那里重新加载整个链。

如果它在没有任何HMR接受更改的情况下到达root,它将刷新整个页面:)。

现在App和NextApp的问题... App是你模块的静态导入版本。由于模块在默认情况下仅被解析和加载一次,因此App指向永不改变的常量引用。这就是在示例中使用另一个变量NextApp的原因,该变量接收HMR代码中的已更改模块。

最后,require和require.default ...在处理ES6导入(导出默认MyComponent)时,导出的模块的格式为{“default”:MyComponent}。 import语句正确地为您处理此分配,但是,您必须自己进行require("./mycomponent").default转换。 HMR接口代码无法使用import,因为它不能内联工作。如果您想避免这种情况,请使用module.exports代替export default