#6 ES6 - модули

poster
В ES6 (ES2015) ввели новый формат модулей в Javascript. Мы рассмотрим с вами различные варианты описания и импортирования модулей.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

В этом уроке мы продолжаем знакомится с ес6 и сегодня мы разберем модули.

Javascript не поддерживает модули на уровне языка, поэтому для ес5 были созданы отдельные реализации для модульности. Два самых популярных, но не совместимых стандарта были CommonJS и AMD.

СommonJS был реализован как модульная система NodeJS. Из плюсов

  1. Лаконичный синтаксис
  2. Модули загружаются синхронно
  3. В большинстве случаев используется на сервере

AMD или Asynchronous Module Definition с самой популярной библиотекой RequireJS был предназначен для

  1. Асинхронной загрузки
  2. В большинстве случаев использовался на клиенте

Смысл создания модулей в Ecmascript 6 было создание формата, который был такой же лаконичный как CommonJS и не были такими динамичными. Это дало возможность на этапе компиляции получать ошибки, когда вы пытаетесь импортировать что-то, что не было експортировано. Также тут поддерживается асинхронная загрузка.

Итак что же такое модуль ес6? Это просто файл с кодом внутри.

Давайте создадим функцию, которая будет складывать 2 числа

const addTwo = (a, b) => a + b;

Теперь для того, чтобы экспортировать функцию addTwo в другие места мы добавляем сложно export

export const addTwo = (a, b) => a + b;

Вот мы и написали первый модуль, который експортирует функцию addTwo.

Теперь давайте в нашем файле testing импортируем ее. Для этого нам поможет деструктуризация и слово import

import { addTwo } from './math';
console.log(addTwo(1, 2));

Здесь мы импортируем функцию addTwo из файла math. Дальше можно ее использовать как обычную функцию.

Давайте експортируем что-то еще из нашего модуля

export const API_URL = 'http://google.com';

и теперь мы можем просто добавить в деструктуризацию еще один параметр.

import { addTwo, API_URL } from './math';
console.log(addTwo(1, 2), API_URL);

и дальше выводим API_URL, как обычную константу. Таким образом код получает очень лаконичным.

Часто бывает, что имена, которые мы импортируем нам не подходят. например мы хотим получить локальную переменную URL, а не API_URL. Мы можем переопределить название переменной с помощью as

import { addTwo, API_URL as URL } from './math';
console.log(addTwo(1, 2), URL);

Иногда нам нужно, чтобы модуль еспортировал только одно значение и нам нет смысла использовать деструктуризацию.

Тогда мы можем написать export default

export default (a, b) => a + b;

Это експортирует только одну анонимную функцию. Тогда мы можем ее импортировать без деструктуризации

import addTwo from './math';
console.log(addTwo(1, 2));

Еще одним вариантом експорта, это когда мы хотим експортировать сразу все что есть в модуле в обьект.

export const addTwo = (a, b) => a + b;
export const multiplyTwo = (a,b) => a * b;

У нас есть две функции, которые експортируются и мы хотим использовать их из одного обьекта

import * as math from './math';
console.log(math.addTwo(1, 2), math.multiplyTwo(1, 2));

Символ звездочка говорит, что мы хотим импортировать все экспорты из модуля и поместить их в переменную math

Итак в этом уроке мы разобрали базовую работу с модулями из es6. Научились применять import и export в различных вариациях.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
No_Name
5 месяцев назад
Здравствуйте, спасибо большое за Вашу плодотворную и качественную учительскую деятельность :). У меня небольшой вопрос, никак не могу понять? где во всей этой теме модулей ES6 используется (Куда? Где?) следующий атрибут со значением: т.е. type="module" Периодически о нём упоминают, но не понятно как его применять ... bundle.js вроде без него подключается, в общем не понятно(( подскажите пожалуйста :) Заранее Вам спасибо :)
monsterlessons
5 месяцев назад
Добрый день. type="module" нигде не поддерживается. Все используют webpack для модульной загрузки. Вот как применять, то что вы написали. https://jakearchibald.com/2017/es-modules-in-browsers/ Только его нигде не применяют так
No_Name
5 месяцев назад
Спасибо Вам огромное!!! Удачи в все делах! :)
49er
2 лет назад
Добрый день, спс за уроки (очень коротки и максимально понятно). Вопрос: в проекте (10 страничный сайт - проект) есть common.js (файл в котором скрипты должны отрабатывать на каждой стр.) и остальные js файлы (about.js, faq.js и тд) которые отрабатывают только на 1-й стр. Собираю webpack-ом. Как лучше построить структуры всех файлов.js для проекта? через експорт не удобно, ибо много импортов в каждый файл для отдельной стр. (добавив или удалив 1 функцию в общем файле, нужно ее импорт удалять/добавлять в 10 файлах). Есть ли более удобный способ?
monsterlessons
2 лет назад
Добрый день. Самый простой вариант тупо все бандлить и загружать на все страницы. Если у вас количество js для каждой отдельной страницы небольшое, то это не будет заметно. Например, если у вас в итоге минифаеный бандл 1 мб то это нормально для среднего проекта. Также модули в вебпаке можно загружать асинхронно при require. Тогда начальный бандл будет включать в себя только sharable вещи и асинхронно вы загружаете нужный модуль в зависимости от страницы. https://webpack.js.org/guides/code-splitting/ Смотрите раздел dynamic import.
Serhii Sakal
2 лет назад
спасибо за видео но с начало надо предупредить!!! что ето реализовано тока в Safari и чтоб ето использовать надо использовать транспилятор!!! к примеру Babel
monsterlessons
2 лет назад
В первом уроке этой серии я рассказывал, что использую webpack для сборки. Соотвественно в каждом уроке используется такая же сборка.
U.D.O
2 лет назад
все проделал также как у вас на видео :((( в мозилле вот такая ошибка SyntaxError: import declarations may only appear at top level of a module app.js:1 SyntaxError: export declarations may only appear at top level of a module math.js:1 в хроме такая Uncaught SyntaxError: Unexpected token import app.js:1 Uncaught SyntaxError: Unexpected token export math.js:1 может подскажите в чем проблемма? файлы тоже подключил вроде б правильно тот который с importom стоит ниже:))
monsterlessons
2 лет назад
Вы собирали ваш код с помощью webpack? Вот пример с исходным кодом. https://github.com/monsterlessons/es6-modules Попробуйте склонить его, запустить вебпак и посмотреть отличия от вашего кода.
U.D.O
2 лет назад
не совсем понятно каким образом мне запустить файл webpack.config:(( звените зарание только Учусь:))
U.D.O
2 лет назад
если что то я просто скопировал все ваши файлы :)) и пытался запустить через php server:)
monsterlessons
2 лет назад
Вам нужно: 1. Склонировать папку с проектом 2. Установить глобально yarn (npm i -g yarn) 3. Установить все пакеты (yarn install) 4. Запустить webpack, чтобы он собрал билд (./node_modules/webpack/bin/webpack.js) 5. Теперь открыв index.html в браузере, все должно работать Базовые уроки по webpack вы можете посмотреть в этой серии https://monsterlessons.com/project/series/sborshik-modulej-webpack
Rustam Apaev
2 лет назад
К сожалению webpack.config.js нельзя посмотреть. А эти модули в итоге объединяются в один файл? И экспорт/импорт фактически это разрешение доступа к блокам внутри одного файла? Или это раздельные файлы math.js & test.js общаются между собой? Я сейчас изучаю Meteor.js fullstack framework , и там один туториал который я прошел - старый, там без всяких экспортов/импортов все делается и работает, хотя ты сам разные файлики добавляешь (видимо они собираются потом в 1 файл). А другой туториал новый, и там все на этих импортах/экспортах завязано. Я вот не разобрался пока, что действительно их требует, а что просто бандлится и работает без них...
monsterlessons
2 лет назад
Залил исходный код к уроке. Там есть webpack.config.js. Все модули обьединяются в один файл bundle.js, который подключается к html файлу. В бандл файле все зависимости обращаются к друг другу.
Rustam Apaev
2 лет назад
Тогда такой вопрос. Меня всегда заморачивает это, разбираться во всех импортах-экспортах. Что, откуда, куда, почему? Ну все эти связи между модулями, я их не писал пока, но даже разбираться в них сложновато бывает. А зачем их делать, если все равно все эти функции и классы в одном файле в итоге находятся? Просто для реализации "инкапсуляции", чтобы отделить области видимостей того, что не соприкасается между собой?
monsterlessons
2 лет назад
Именно. Для того, чтобы было легче строить модульную структуру. Все файлы независимые друг от друга и связаны только импортами и экспортами.
Rustam Apaev
2 лет назад
ну это же сложнее наборот, так организовывать приложение. во первых приходит по 10 раз писать эти импорты (хотя можно было не писать, если все в одном файле в итоге) , во вторых - всегда держать в голове эти взаимосвязи, чтобы не забыть их указать. В чем преимущество? НАписал этот вопрос, а потом загуглил, щас почитаю))
monsterlessons
2 лет назад
Для того, чтобы все классы и методы не были доступны глобально. Модульная система нужна именно для работы с зависимостями. Вы всегда знаете от каких модулей зависит ваш модуль. Если у вас все файлы доступны глобально, то переименовав 1 вы даже не представляете в каких местах нужно поменять код. В случае с модулями оно просто не сможет найти модуль при сборке. Соответственно останется только поменять пути на которых оно падает.
Rustam Apaev
2 лет назад
Спасибо за уроки. Не сочти за придирку, в тексте к видео вместо "экспортировать" ты везде пиешь "експортировать". Вместо Е должно быть Э.
monsterlessons
2 лет назад
Спасибо. Нужно как-то сесть и вычитать все уроки на ошибки. Пока не хватает времени к сожалению.
vlad
2 лет назад
Вопрос по теме: import React, { Component } from 'react'; Это значит объект React через export default объявлен, а Component через простой export?
monsterlessons
2 лет назад
489 человек. Именно так. Вы все правильно написали.
vlad
2 лет назад
Тут уже много народа зарегилось?))