Skip to content

Commit 2e0ec28

Browse files
committed
proxy
1 parent 233b9d9 commit 2e0ec28

File tree

6 files changed

+600
-22
lines changed

6 files changed

+600
-22
lines changed

1-js/10-es-modern/13-modules/article.md

Lines changed: 192 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@
1010
Такие средства предлагались сообществом и ранее, например:
1111

1212
<ul>
13-
<li>[CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1)</li>
14-
<li>[AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition)</li>
15-
<li>[UMD](https://github.com/umdjs/umd)</li>
13+
<li>[AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- одна из самых древних систем организации модулей, требует лишь наличия клиентской библиотеки, к примеру, [require.js](http://requirejs.org/), но поддерживается и серверными средствами.</li>
14+
<li>[CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- система модулей, встроенная в сервер Node.JS. Требует поддержки на клиентской и серверной стороне.</li>
15+
<li>[UMD](https://github.com/umdjs/umd) -- система модулей, которая предложена в качестве универсальной. UMD-модули будут работать и в системе AMD и в CommonJS.</li>
1616
</ul>
1717

18-
Все они требуют различных библиотек или систем сборки для использования.
18+
Все перечисленные выше системы требуют различных библиотек или систем сборки для использования.
1919

20-
Новый стандарт отличается от них прежде всего тем, что это -- стандарт. А значит, со временем, будет поддерживаться браузерами без дополнительных утилит.
21-
22-
Сейчас браузерной поддержки почти нет. Поэтому ES-модули используются вместе с системами сборки, такими как [webpack](http://webpack.github.io/), [brunch](http://brunch.io/) и другими, при подключённом [Babel.JS](https://babeljs.io).
20+
Новый стандарт отличается от них прежде всего тем, что это -- стандарт. А значит, со временем, будет поддерживаться браузерами без дополнительных утилит.
2321

22+
Однако, сейчас браузерной поддержки почти нет. Поэтому ES-модули используются в сочетании с системами сборки, такими как [webpack](http://webpack.github.io/), [brunch](http://brunch.io/) и другими, при подключённом [Babel.JS](https://babeljs.io). Мы рассмотрим это далее.
2423

2524
## Что такое модуль?
2625

@@ -30,38 +29,214 @@
3029

3130
Другие модули могут подключать их через вызов `import`.
3231

33-
Нагляднее всего это проиллюстрировать примером.
32+
## export
33+
34+
Ключевое слово `export` можно ставить:
35+
36+
<ul>
37+
<li>перед объявлением переменных, функций и классов.</li>
38+
<li>отдельно, при этом в фигурных скобках указывается, что именно экспортируется.</li>
39+
</ul>
3440

35-
Модуль `one.js` экспортирует переменную `one`:
41+
Например:
3642

3743
```js
44+
// экспорт прямо перед объявлением
3845
export let one = 1;
46+
47+
// можно и раздельно, в две строки вместо одной
48+
let two = 2;
49+
export {two};
3950
```
4051

41-
Модуль `two.js`:
52+
Заметим, что в фигурных скобках указывается не блок, не произвольное выражение, а только имя.
53+
54+
Можно указать несколько:
55+
```js
56+
export {one, two};
4257
```
43-
let two = 2;
4458

45-
export {two}
59+
Также можно указать, что переменная `one` будет доступна снаружи под именем `once`, а `two` -- под именем `twice`:
60+
61+
```js
62+
export {one as once, two as twice};
63+
```
64+
65+
Экспорт функций и классов выглядит так же:
66+
```js
67+
export class User {
68+
constructor(name) {
69+
this.name = name;
70+
}
71+
};
72+
73+
export function sayHi() {
74+
alert("Hello!");
75+
};
76+
77+
// или export {User, sayHi}
78+
```
79+
80+
Заметим, что и у функции и у класса при таком экспорте должно быть имя.
81+
82+
Так будет ошибка:
83+
```js
84+
// функция без имени
85+
export function() { alert("Error"); };
86+
```
87+
88+
## import
89+
90+
Другие модули могут подключать экспортированные значения при помощи ключевого слова `import`.
91+
92+
Синтаксис:
93+
94+
```js
95+
import {one, two} from "./nums";
96+
```
97+
98+
Здесь:
99+
<ul>
100+
<li>`"./nums"` -- модуль, как правило это путь к файлу модуля.</li>
101+
<li>`one, two` -- импортируемые переменные, которые должны быть обозначены в `nums` словом `export`.</li>
102+
</ul>
103+
104+
В результате импорта появятся локальные переменные `one`, `two`, которые будут содержать значения соответствующих экспортов.
105+
106+
Например, при таком файле `nums.js`:
107+
108+
```js
109+
export let one = 1;
110+
export let two = 2;
111+
```
112+
113+
Модуль ниже выведет "1 and 2":
114+
115+
```js
116+
import {one, two} from "./nums";
117+
118+
alert( `${one} and ${two}` ); // 1 and 2
119+
```
120+
121+
Импортировать можно и под другим именем, указав его в "as":
122+
123+
```js
124+
// импорт one под именем item1, а two – под именем item2
125+
import {one as item1, two as item2} from "./nums";
126+
127+
alert( `${item1} and ${item2}` ); // 1 and 2
128+
```
129+
130+
[smart header="Импорт всех значений в виде объекта"]
131+
132+
Можно импортировать все значения сразу в виде объекта вызовом `import * as obj`, например:
133+
134+
```js
135+
*!*
136+
import * as numbers from "./nums";
137+
*/!*
138+
139+
alert( `${numbers.one} and ${numbers.two}` ); // 1 and 2
140+
```
141+
[/smart]
142+
143+
## export default
144+
145+
Выше мы видели, что модуль может экспортировать произвольное количество значений при помощи `export`.
146+
147+
Однако, как правило, код стараются организовать так, чтобы каждый модуль делал одну вещь. Иначе говоря, "один файл -- одна сущность, которую он описывает".
148+
149+
Например, файл `user.js` содержит `class User`, файл `login.js` -- функцию `login()` для авторизации, и т.п.
150+
151+
При этом модули, разумеется, будут взаимосвязаны. Например, `login.js`, скорее всего, будет импортировать класс `User` из модуля `user.js`.
152+
153+
Для такой ситуации, когда один модуль экспортирует одно значение, предусмотрено особое ключевое сочетание `export default`.
154+
155+
Если поставить после `export` слово `default`, то значение станет "экспортом по умолчанию".
156+
157+
Такое значение можно импортировать без фигурных скобок.
158+
159+
Например, файл `user.js`:
160+
161+
```js
162+
*!*export default*/!* class User {
163+
constructor(name) {
164+
this.name = name;
165+
}
166+
};
167+
```
168+
169+
...А в файле `login.js`:
170+
171+
```js
172+
import User from './user';
173+
174+
new User("Вася");
46175
```
47176

177+
Если бы в `user.js` не было `default`, то в `login.js` необходимо было бы указать фигурные скобки:
178+
179+
```js
180+
// если в бы user.js не было default:
181+
// export class User { ... }
182+
183+
// …то при импорте понадобились бы фигурные скобки:
184+
import {User} from './user';
185+
186+
new User("Вася");
187+
```
188+
189+
Как видно, "экспорт по умолчанию" -- лишь небольшой синтаксический сахар. Можно было бы и без него, импортировать значение обычным образом через фигурные скобки `{…}`.
190+
191+
Но на практике этот "сахар" весьма приятен, так как позволяет легко видеть, какое именно значение экспортирует модуль, а также обойтись без лишних символов при импорте.
192+
193+
## Использование
194+
195+
Современный стандарт EcmaScript описывает, как импортировать и экспортировать значения из модулей, но он ничего не говорит о том, как эти модули искать, загружать и т.п.
196+
197+
Такие механизмы предлагались в процессе создания стандарта, но были убраны по причине недостаточной проработанности. Возможно, они появятся в будущем.
198+
199+
Сейчас используются системы сборки, как правило, в сочетании с Babel.JS.
200+
201+
Система сборки обрабатывает скрипты, находит в них `import/export` и заменяет их на свои внутренние JavaScript-вызовы. При этом, как правило, много файлов-модулей объединяются в один или несколько скриптов, смотря как указано в конфигурации сборки.
202+
203+
Ниже вы можете увидеть полный пример использования модулей с системой сборки [webpack](http://webpack.github.io).
204+
205+
В нём есть:
206+
<ul>
207+
<li>`nums.js` -- модуль, экспортирующий `one` и `two`, как описано выше.</li>
208+
<li>`main.js` -- модуль, который импортирует `one`, `two` из `nums` и выводит их сумму.</li>
209+
<li>`webpack.config.js` -- конфигурация для системы сборки.</li>
210+
<li>`bundle.js` -- файл, который создала система сборки из `main.js` и `nums.js`.</li>
211+
<li>`index.html` -- простой HTML-файл для демонстрации.</li>
212+
</ul>
48213

49214
[codetabs src="nums"]
50215

51216

217+
## Итого
52218

53-
То есть, браузер, в котором есть поддержка модулей, или система сборки ("сегодняшний" вариант)
219+
Современный стандарт описывает, как организовать код в модули, экспортировать и импортировать значения.
54220

55-
Модуль -- это файл со специальными командами:
221+
Экспорт:
56222

57223
<ul>
58-
<li>Экспорты -- </li>
224+
<li>`export` можно поставить прямо перед объявлением функции, класса, переменной.</li>
225+
<li>Если `export` стоит отдельно от объявления, то значения в нём указываются в фигурных скобках: `export {…}`.</li>
226+
<li>Также можно экспортировать "значение по умолчанию" при помощи `export default`.</li>
227+
</ul>
228+
229+
Импорт:
230+
<ul>
231+
<li>В фигурных скобках указываются значения, а затем -- модуль, откуда их брать: `import {a, b, c as d} from "module"`.</li>
232+
<li>Можно импортировать все значения в виде объекта при помощи `import * as obj from "module"`.</li>
233+
<li>Без фигурных скобок будет импортировано "значение по умолчанию": `import User from "user"`.</li>
234+
</ul>
59235

236+
На текущий момент модули требуют системы сборки на сервере. Автор этого текста преимущественно использует webpack, но есть и другие варианты.
60237

61238

62239

63240

64241

65-
Общее между ними
66242

67-
Модуль -- способ организации кода по файлам. Каждый файл

1-js/10-es-modern/13-modules/nums.view/bundle.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949
var _nums = __webpack_require__(1);
5050

51-
console.log(_nums.one + _nums.two);
51+
document.write('Сумма импортов: ' + (_nums.one + _nums.two));
5252

5353
/***/ },
5454
/* 1 */
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
</head>
6+
<body>
7+
8+
<script src="bundle.js"></script>
9+
10+
</body>
11+
</html>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import {one, two} from './nums';
22

3-
console.log(one + two);
3+
document.write(`Сумма импортов: ${one + two}`);

1-js/10-es-modern/13-modules/nums.view/webpack.config.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
// Required:
2-
// npm i -g webpack
3-
// npm i babel-loader
1+
// Для использования нужен Node.JS
2+
// Поставьте его:
3+
// npm i -g webpack
4+
// Поставьте babel-loader:
5+
// npm i babel-loader
6+
// Запустите его в директории с файлами:
7+
// webpack
48

59
module.exports = {
610
entry: './main',

0 commit comments

Comments
 (0)