添加 .default 与否?:react router 3 中的动态导入,用于 webpack 代码拆分 [英] to add .default or not?: dynamic imports in react router 3 for webpack code-splitting

查看:41
本文介绍了添加 .default 与否?:react router 3 中的动态导入,用于 webpack 代码拆分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我正在将我的项目从 webpack 3 (v. 3.3.0) 升级到 webpack 4 (v. 4.44.2).编译和构建工作完美,但结果在屏幕上没有渲染任何内容.

在比较了 webpack 3 和 webpack 4 两个项目之间传递给 RouterContext 的参数后,我将根本原因缩小到动态导入组件.

以下脚本是我如何使用 react-router 3 (v. 3.0.5) getComponent 来导入组件,这在我升级到 webpack 4 之前是可行的:

const loadRoute = callback =>模块 =>回调(空,模块);const forceToReload = (err) =>{记录器错误(错误);window.location.reload();};导出默认值 (loadRoute, forceToReload) =>(<路由名称=订阅"path={appUtils.getRoutePath('/sample')}getComponent={(location, callback) =>import('./index.jsx').then(loadRoute(callback)).catch(forceToReload)}/>);

幸运的是,经过数天的试验 &错误,我终于使我的项目正确呈现.在 webpack 4 版本中,我必须将 .default 附加到 loadRoute 中的模块,如下所示:

const loadRoute = callback =>模块 =>回调(空,模块.默认);

问题是

即使问题解决了,我还是想知道是否有人可以解释一下何时添加.default.
webpack 4 在动态导入时编译是否不同?有什么想法吗?

解决方案

经过几天的研究,我终于找到了我的问题的答案,希望我以后能以某种方式帮助那些有同样问题的人.

Webpack 官网(

来自 Webpack 4 项目:

如您所见,非对象有不同的结果.这一发现与这篇文章(提供由 webpack 官方提供)

<块引用>

导出对象时没有那么大的问题.但是在将 module.exports 与非对象一起使用时会遇到麻烦.

我在我的代码中使用了export default 而不是module.exports,那为什么我还是得到了结果?实际上,Babel@6 会进行如下转换:(reference)

<块引用>

Babel@6 转换以下文件

导出默认的 'foo'

进入

'use strict';Object.defineProperty(exports, "__esModule", {值:真});export.default = 'foo';

现在,事情很清楚了.

我使用的软件包是:

节点:11.15.0babel 核心:^6.23.1",babel-loader:7.1.4",webpack:4.44.2",webpack-cli:^4.2.0",

Recently I'm working on upgrading my project from webpack 3 (v. 3.3.0) to webpack 4 (v. 4.44.2). Compiling and building worked perfectly, but it turned out to render nothing on the screen.

After I compared the parameters passed to RouterContext between two projects of webpack 3 and of webpack 4, I narrowed down the root cause to dynamic imported components.

The following script is how I use react-router 3 (v. 3.0.5) getComponent to import component, which is workable before I upgrade to webpack 4:

const loadRoute = callback => module => callback(null, module);

const forceToReload = (err) => {
  Logger.error(err);
  window.location.reload();
};

export default (loadRoute, forceToReload) => (
  <Route name="Subscribe" path={appUtils.getRoutePath('/sample')}
         getComponent={(location, callback) => import('./index.jsx').then(loadRoute(callback)).catch(forceToReload)}/>
);

Fortunately, after days of trials & errors, I finally made my project render correctly. In webpack 4 version, I have to append .default to module in loadRoute as follows:

const loadRoute = callback => module => callback(null, module.default);

The Question is

Even though the problem is solved, I still wonder if someone can provide an explanation about when to add .default.
Does webpack 4 compile differently on dynamic import? Any ideas?

解决方案

After days of research, I finally found the answer to my question, hoping I can somehow help those with the same question in the future.

Webpack official website (Code-Splitting: Dynamic Import) has a description as follows:

The reason we need default is that since webpack 4, when importing a CommonJS module, the import will no longer resolve to the value of module.exports, it will instead create an artificial namespace object for the CommonJS module.

Out of curiosity, I did some experiment logging out things I dynamic imports:

// exportObject.js
export default {a: 1, b: 2};
export const c = 3;

// exportString.js
export default "TEST_STRING";

// exportComponent.js
import React, {Component} from "react";
export default class exportComponent extends Component {
  constructor(props) {
    super(props);
    this.a = 1;
    this.b = 2;
  }
}

// exportFunction.js
export default () => ({a: 1, b: 2});

// index.js
componentDidMount() {
 import('./exportObject').then(module => {
    console.group('Object');
    console.warn('module', module);
    console.warn('module.a:', module.a);
    console.warn('module.b:', module.b);
    console.warn('module.default', module.default);
    console.warn('module.c', module.c);
    console.groupEnd();
  });

  import('./exportString').then(module => {
    console.group('String');
    console.warn('module', module);
    console.warn('module.default', module.default);
    console.groupEnd();
  });

  import('./exportComponent').then(module => {
    console.group('Component');
    console.warn('module', module);
    console.warn('module.default', module.default);
    console.groupEnd();
  });

  import('./exportFunction').then(module => {
    console.group('Function');
    try {
      console.warn('module()', module());
    } catch (e) {
      console.warn('module()', e);
    }
    try {
      console.warn('module.default()', module.default());
    } catch (e) {
      console.warn('module.default()', e);
    }
    console.groupEnd();
  });
}

This is the result from Webpack 3 Project:

While from Webpack 4 Project:

As you can see, non-objects have different results. This finding matches the description of this article (which is provided by webpack official)

It’s not that problematic when exporting an object. But you’ll get into trouble when using module.exports with non-objects.

I use export default in my code rather than module.exports, then why I still got the result? Actually, Babel@6 will do the transform as below: (reference)

Babel@6 transforms the following file

export default 'foo'

into

'use strict';
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = 'foo';

Now, things are crystal clear.

The packages I used was:

node: 11.15.0

babel-core: "^6.23.1",
babel-loader: "7.1.4",
webpack: "4.44.2",
webpack-cli: "^4.2.0",

这篇关于添加 .default 与否?:react router 3 中的动态导入,用于 webpack 代码拆分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆