`экспорт const` против` экспорт по умолчанию` в ES6


205

Я пытаюсь определить, есть ли какие-то большие различия между этими двумя, кроме возможности импортировать export default, просто выполнив:

import myItem from 'myItem';

И используя export constя могу сделать:

import { myItem } from 'myItem';

Мне интересно, есть ли какие-либо различия и / или варианты использования, кроме этого.


1
Использование constсделает идентификатор доступным только для чтения. Так что в случае примитивных ценностей, вы можете считать это неизменным. Обратите внимание, что само значение не является неизменным, поэтому объекты, массивы и т. Д. Могут быть изменены, но не переназначены.
spmurrayzzz

4
@spmurrayzzz: FWIW, привязки импорта также неизменны, как и const.
Феликс Клинг

спасибо за разъяснения @FelixKling, не знал, что
spmurrayzzz

@FelixKling: По крайней мере, со стороны. Хотя они не могут быть постоянными, экспорт может быть изменен.
Берги

@ Берги: верно, поэтому я сказал, что импортные привязки ;)
Феликс Клинг

Ответы:


327

Это именованный экспорт против экспорта по умолчанию. export constименованный экспорт, который экспортирует декларацию или декларации const.

Подчеркнем: здесь важно exportключевое слово as const, используемое для объявления объявления или объявлений const. exportможет также применяться к другим объявлениям, таким как объявления класса или функции.

Экспорт по умолчанию ( export default)

Вы можете иметь один экспорт по умолчанию для каждого файла. При импорте вы должны указать имя и импортировать так:

import MyDefaultExport from "./MyFileWithADefaultExport";

Вы можете дать этому любое имя, которое вам нравится.

Именованный экспорт ( export)

С именованным экспортом вы можете иметь несколько именованных экспортов на файл. Затем импортируйте нужный экспорт в фигурные скобки:

// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";

// use MyClass, MyOtherClass, and MyClass2Alias here

Или можно использовать значение по умолчанию вместе с именованным импортом в том же операторе:

import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";

Импорт пространства имен

Также возможно импортировать все из файла на объекте:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here

Ноты

  • Синтаксис предпочитает экспорт по умолчанию как несколько более краткий, потому что их вариант использования более распространен ( см. Обсуждение здесь ).
  • Экспорт по умолчанию - это именованный экспорт с именем, defaultтак что вы можете импортировать его с именованным импортом:

    import { default as MyDefaultExport } from "./MyFileWithADefaultExport";

24

export defaultвлияет на синтаксис при импорте экспортированной «вещи», когда разрешается импортировать все, что было экспортировано, путем выбора имени в importсамом имени, независимо от того, какое имя имело место при экспорте, просто потому, что оно помечено как «по умолчанию».

Полезный вариант использования, который мне нравится (и я использую), позволяет экспортировать анонимную функцию без явного указания ее имени, и только когда эта функция импортируется, ей должно быть присвоено имя:


Пример:

Экспорт 2 функции, одна из них default:

export function divide( x ){
    return x / 2;
}

// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){  // <---- declared as a default function
    return x * x;
}

Импортируйте вышеупомянутые функции. Составление имени дляdefault одного:

// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square" 

console.log( square(2), divide(2) ); // 4, 1

Когда {}синтаксис используется для импорта функции (или переменной), это означает, что все импортированное уже было имя названо при экспорте, поэтому необходимо импортировать его с точно таким же именем, иначе импорт не будет работать.


Ошибочные примеры:

  1. Функция по умолчанию должна быть первой для импорта

    import {divide}, square from './module_1.js
  2. divide_1не был экспортирован в module_1.js, таким образом, ничего не будет импортировано

    import {divide_1} from './module_1.js
  3. squareне был экспортирован в module_1.js, потому что {}говорит движку явно искать только именованные экспорты.

    import {square} from './module_1.js

Это не значит, что он экспортирует одну вещь. Вы можете иметь несколько именованных и один по умолчанию в одном модуле. По умолчанию просто означает именно это - это экспорт по умолчанию, если вы не указываете имя при импорте, то есть import something fromвместо import { somethingNamed } from.
Андрис

Я также выучил новое английское слово здесь: «Ошибочно» +1 за это
Юваль Леви

12

Небольшое примечание: учтите, что при импорте из экспорта по умолчанию наименование является полностью независимым. Это на самом деле влияет на рефакторинги.

Допустим, у вас есть такой класс Fooс соответствующим импортом:

export default class Foo { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export
import Foo from './Foo'

Теперь, если вы реорганизуете свой Fooкласс Barи переименовываете файл, большинство IDE НЕ коснется вашего импорта. Итак, вы закончите с этим:

export default class Bar { }

//the name 'Foo' could be anything, since it's just an
//identifier for the default export.
import Foo from './Bar'

Особенно в Typescript я очень ценю именной экспорт и более надежный рефакторинг. Разница лишь в отсутствии defaultключевого слова и фигурных скобок. Это, кстати, также не позволяет вам сделать опечатку в вашем импорте, так как у вас есть проверка типов сейчас.

export class Foo { }

//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'

2
« Foo» должно быть именем класса. »- нет! Вы можете сделать это так же легко, import { Foo as Anything } from …как и import Anything from …экспорт по умолчанию.
Берги

То, что вы можете переименовать его с помощью, asна самом деле не имеет значения в этом исходном комментарии. Спасибо за отрицание; p
Филипп Суми

1
Я не отрицал, однако я не уверен, является ли этот аргумент убедительным. Я не знаю, хочу ли я, чтобы моя IDE переименовывала все импортные файлы при рефакторинге одного модуля, это именно то, что представляет собой модульность :-) И, похоже, это скорее "проблема" IDE, а не причина выбора стиля экспорта. …
Берги

Я согласен, что я использую именованные экспорты для разработчиков UX здесь - но тогда вы можете утверждать, что Typescript сам по себе - все об этом. Я часто выполняю рефакторинг, и, учитывая, что у меня обычно есть один класс (в моем случае: React Component) на файл, я бы абсолютно хотел, чтобы импорт следовал за переименованным компонентом, чтобы не создавать разъединение. Конечно, это может иметь или не иметь смысла в зависимости от конкретного разработчика.
Филипп Суми

Я нашел статью, в которой говорится то же самое. Может быть, разумной позицией может быть: мы должны использовать export defaultдля экспорта основной объект проекта, в частности из пакетов npm (он заменяет a module.exports =). Но внутри проекта лучше использовать только именованные экспорты.
Палео

7

Из документации :

Именованные экспорты полезны для экспорта нескольких значений. Во время импорта можно использовать одно и то же имя для ссылки на соответствующее значение.

Что касается экспорта по умолчанию, существует только один экспорт по умолчанию на модуль. Экспорт по умолчанию может быть функцией, классом, объектом или чем-то еще. Это значение следует рассматривать как «основное» экспортируемое значение, поскольку его будет проще всего импортировать.


0

Когда вы ставите default, это называется экспорт по умолчанию. Вы можете иметь только один экспорт по умолчанию для каждого файла и можете импортировать его в другой файл с любым именем. Если вы не укажете default, он называется named export, вам придется импортировать его в другой файл, используя то же имя с фигурными скобками внутри.


0

У меня была проблема, что браузер не использует es6.

Я исправил это с помощью:

 <script type="module" src="index.js"></script>

Модуль type указывает браузеру использовать ES6.

export const bla = [1,2,3];

import {bla} from './example.js';

Тогда это должно работать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.