Bri*_*ams 14 javascript typescript ecmascript-6 reactjs react-native
我注意到React可以这样导入:
import * as React from 'react';
Run Code Online (Sandbox Code Playgroud)
...或像这样:
import React from 'react';
Run Code Online (Sandbox Code Playgroud)
第一个导入模块中的所有内容react(请参阅:导入整个模块的内容)
似乎这两种方法是不同的,并且根本上是不兼容的。
为什么它们都起作用?
请参考源代码并解释该机制...我有兴趣了解其工作原理。
更新资料
这与import *作为'react'的反应与import'react'的反应之间的区别不是重复的
ES6常规模块信息回答了该问题。
我在问使react模块像这样工作的机制。在这里,它似乎与源代码中的 “ hacky”导出机制有关,但尚不清楚如何将整个模块导入到默认的导出中React,以及如何将这两种方法都可以与转译JSX等一起使用。
Aar*_*all 10
事实上,ES import语句import default和import *不一样的东西,他们的行为在这种情况下,同样的事实是如何反应作者选择发布的库和兼容层以打字稿联合使用(使用esModuleInterop)或巴贝尔和你捆绑,使他们“就是工作”。根据ES6规范,它可能不应该工作,但是今天,我们仍处于一个JS模块混乱的时代,因此Babel,TypeScript,Webpack等工具试图规范行为。
React不是ES6库。如果您查看源代码,则会在以下代码中看到它index.js:
const React = require('./src/React');
// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest.
module.exports = React.default || React;
Run Code Online (Sandbox Code Playgroud)
(请注意注释,即使在React源代码中,它们也难以与ES6默认导出兼容性兼容。)
该module.exports =语法是CommonJS的(的NodeJS)。浏览器不会理解这一点。这就是为什么我们使用Webpack,Rollup或Parcel之类的捆绑器的原因。他们了解各种模块语法,并产生应在浏览器中工作的捆绑软件。
但是,尽管React不是ES库,但TypeScript和Babel都允许您将其导入为原样(使用import语法,而不是require(),等等),但是CJS和ES之间必须解决差异。其中一个事实是,您export = 可以得到ES没有符合规范的导入方式,例如函数或类作为模块。为了解决这些不兼容问题,Babel允许您将CJS模块导入就像默认情况下导出某些内容一样,或者作为命名空间导入。TypeScript暂时没有执行此操作,但是最近在下方将其添加为一个选项esModuleInterop。因此,现在Babel和TypeScript都可以一致地允许使用默认或名称空间ES导入来导入CJS模块。
使用TypeScript,它还取决于实际定义库的类型定义的方式。我不会对此进行介绍,但是您可以想象这样的情况:由于使用了编译器和捆绑器,特定的导入可以在运行时进行,但是TypeScript不会没有错误地进行编译。
值得一提的另一件事是,如果您查看React的内置代码,则有UMD模块版本和CJS版本。UMD版本包含一些粗糙的运行时代码,以尝试使其在任何模块环境(包括浏览器)中均可工作。如果您只想在运行时包含React(即您不使用捆绑程序),则主要用于此。实例。
令人困惑?是的,我是这样认为的。:)
您很可能已"allowSyntheticDefaultImports": true,在中设置tsconfig.json,这实际上会使编译器关闭了它认为无效的默认导入。添加了Typescript esModuleInterop,该脚本实际上执行了babel进行模块加载的工作。
即使您要导入的源代码未导出任何默认内容,这也允许您使用ES6默认导入
在此方面,打字稿非常严格(遵循规则),这就是为什么它们要求您这样做import * as React from 'react'。或者要求您告诉它在其基本配置中允许合成默认导入。
| 归档时间: |
|
| 查看次数: |
3069 次 |
| 最近记录: |