Я заметил, что React можно импортировать так:
import * as React from 'react';
... или вот так:
import React from 'react';
Первый импортирует все в модуль react (см.: Импорт всего содержимого модуля)
Второй импортирует только экспорт модуля default (см.: Импорт значений по умолчанию)
Кажется, что эти два подхода различны и принципиально несовместимы.
Почему они оба работают?
Пожалуйста, укажите исходный код и объясните механизм... Мне интересно понять, как это работает.
Обновлять
Это нет дубликат В чем разница между import * as react from 'react' vs import react from 'react'
На этот вопрос был дан ответ с общей информацией о модуле ES6.
Я спрашиваю о механизме, благодаря которому модуль react работает так. Кажется, это связано с «хакерским» механизмом экспорта в источнике здесь, но неясно, как это позволяет импортировать модуль весь и просто экспортировать По умолчанию в React и использовать оба этих подхода с транспилированием JSX и т. д.
Если импорт только значения по умолчанию и всего остального дает тот же результат, как вы думаете, что влечет за собой «все»? Вы смотрели на источник, который вы импортируете?
import * as React from 'react'; включить default, наверное.
В машинописном тексте вы можете указать от tsconfig.json до allowSyntheticDefaultImports. Это то, что позволит вам import React from 'react'. Javascript/babel «обманывает» здесь, позволяя вам делать этот синтетический импорт по умолчанию, когда его на самом деле нет. Правильный синтаксис для экспорта React должен быть import * as React from 'react'
@KevinB Я просмотрел источник, кажется, он связан с эта "хакерская" линия, но мне не ясно, как это работает.
@Vencovsky Why wouldn't they work?: потому что доступ к экспорту default будет осуществляться как React.default при импорте все, и будет доступен как React при импорте Только по умолчанию
@AlexanderYakushev да, импорт все включает значение по умолчанию, но тогда к нему будут обращаться по-другому (как React.default, а не просто React)
Отвечает ли это на ваш вопрос? В чем разница между import * as react from 'react' vs import react from 'react'



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Скорее всего, вы установили "allowSyntheticDefaultImports": true, в tsconfig.json, что, по сути, закрывает компилятору информацию об импорте по умолчанию, который он считает недопустимым. Добавлен машинописный текст esModuleInterop, который делает то же самое, что и Babel для загрузки модуля.
Это позволяет вам использовать импорт ES6 по умолчанию, даже если исходный код, который вы импортируете, ничего не экспортирует по умолчанию.
Typescript строг (соответствует правилам), когда дело доходит до этого, поэтому они требуют от вас import * as React from 'react'. Или требует, чтобы вы разрешили синтетический импорт по умолчанию в своей базовой конфигурации.
Интересно, что это могло бы объяснить это для TypeScript, но это работает и только для JavaScript, поэтому должно быть что-то еще. Вы упомянули Babel в своем комментарии выше... может ли транспилятор Babel для JSX делать что-то сложное?
@brian-lives-outdoors Да, Babel делает это по умолчанию. Я верю, что это здесь. Также это довольно хорошее чтение
На самом деле это esModuleInterop заставляет это работать. Babel делает что-то подобное при работе с модулем. Модули — это своего рода беспорядок, согласно спецификации ES6 import default и import * не должны быть одним и тем же, но часто они взаимозаменяемы в транспиляторах и сборщиках, чтобы избежать путаницы или несовместимости.
@ Аарон, да, я упомянул об этом. allowSyntheticDefaultImports было решением раньше esModuleInterop
Действительно, операторы импорта ES import default и import * — это не одно и то же, тот факт, что они ведут себя одинаково в этом случае, является комбинацией того, как авторы React решили опубликовать библиотеку и слои совместимости в TypeScript (используя esModuleInterop) или Babel и ваш сборщик для заставить их «просто работать». Вероятно, не должен работает в соответствии со спецификацией 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;
(Обратите внимание на комментарий, даже в исходном коде React они борются с совместимостью экспорта ES6 по умолчанию.)
Синтаксис module.exports = — CommonJS (NodeJS). Браузер этого не понимает. Вот почему мы используем упаковщики, такие как Webpack, Rollup или Parcel. Они понимают все виды синтаксиса модулей и создают пакеты, которые должны работать в браузере.
Но даже несмотря на то, что React не является библиотекой ES, и TypeScript, и Babel позволяют импортировать ее так, как если бы она была (используя синтаксис import, а не require() и т. д.), но между CJS и ES есть различия, которые необходимо устранить. Одним из них является тот факт, что export =могу дает вам вещи, которые ES не имеет соответствующего спецификации способа импортировать, например функцию или класс в качестве модуля. Чтобы обойти эти несовместимости, Babel некоторое время позволял вам импортировать модули CJS, как если бы они что-то экспортировали по умолчанию, или import как пространство имен. TypeScript какое-то время этого не делал, но совсем недавно добавил это в качестве опции под esModuleInterop. Итак, теперь и Babel, и TypeScript могут довольно последовательно разрешать импорт модуля CJS с использованием импорта ES по умолчанию или пространства имен.
С TypeScript это также зависит от того, как на самом деле определены определения типов для библиотеки. Я не буду вдаваться в подробности, но вы можете себе представить ситуации, когда благодаря транспиляторам и упаковщикам конкретный импорт работает во время выполнения, но TypeScript не компилируется без ошибок.
Еще одна вещь, о которой стоит упомянуть, это то, что если вы посмотрите на встроенный код для React, вы увидите версию UMD-модуль, а также версию CJS. Версия UMD включает в себя неуклюжий код времени выполнения, чтобы попытаться заставить его работать в любой модульной среде, включая браузер. Это в основном для использования, если вы хотите просто включить React во время выполнения (т.е. вы не используете упаковщик). Пример.
Сбивает с толку? Думаю, да. :)
Упомянутый здесь фрагмент кода больше не находится в файле index.js. есть ли обновление, которое вы могли бы дать нам здесь, @Aaron?
Вы спрашивали
Why do they both work?и я прошу вас,Why wouldn't they work?