diff --git a/1-js/10-modules/01-modules-intro/article.md b/1-js/10-modules/01-modules-intro/article.md new file mode 100644 index 00000000..c67c0c1d --- /dev/null +++ b/1-js/10-modules/01-modules-intro/article.md @@ -0,0 +1,318 @@ + +# Modules, the introduction + +As our application grows bigger, we want to split it into multiple files, so called 'modules'. +A module usually contains a class or a library of useful functions. + +For a long time, Javascript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple. So there was no need. + +But eventually scripts became more and more complex, so the community invented a variety of ways to organize code into modules. + +For instance: + +- [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- one of the most ancient module systems, initially implemented by the library [require.js](http://requirejs.org/). +- [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.JS server. +- [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS. + +Now all these slowly become a part of history, but we still can find them in old scripts. The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. + +## What is a module? + +A module is just a file, a single script, as simple as that. + +Directives `export` and `import` allow to interchange functionality between modules: + +- `export` keyword labels variables and functions that should be accessible from outside the file. +- `import` allows to import functionality from other modules. + +For instance, if we have a file `sayHi.js` exporting a function: + +```js +// πŸ“ sayHi.js +export function sayHi(user) { + alert(`Hello, ${user}!`); +} +``` + +...Then another file may import and use it: + +```js +// πŸ“ main.js +import {sayHi} from './sayHi.js'; + +alert(sayHi); // function... +sayHi('John'); // Hello, John! +``` + +## Modules in the browser + +In this tutorial we concentrate on the language itself, but we use browser as the demo environment, so let's see how modules work in the browser. + +To use modules, we must set the attribute ` + ``` + + That ensures better security by default. + +2. External scripts with same `src` run only once: + ```html + + + + ``` + +3. Module scripts are *always* deferred, same effect as `defer` attribute (described in the chapter [](info:onload-ondomcontentloaded)), for both external and inline scripts. + + In other words: + - external module scripts ` + + + + + ``` + + So, when we're using modules, we should be aware that HTML-document can show up before the Javascript application is ready. Certain functionality may not work yet. We should put transparent overlays or "loading indicators", or otherwise ensure that the visitor won't be confused because of it. + +4. Async attribute ` + ``` + +Also, in the browser, in scripts (not in HTML), `import` must get either a relative or absolute URL. So-called "bare" modules (without path) are not allowed. + +For instance, this `import` is invalid: +```js +import {sayHi} from 'sayHi'; // Error, "bare" module +// must be './sayHi.js' or wherever the module is +``` + +Certain environments, like Node.js or bundle tools allow bare modules, as they have own ways for finding modules and hooks to fine-tune them. But browsers do not support bare modules yet. + +### Build tools + +In real-life, browser modules are rarely used in their "raw" form. Usually, we bundle them together with a special tool such as [Webpack](https://webpack.js.org/) and deploy to the production server. + +One of the benefits of using bundlers -- they give more control over how modules are resolved, allowing bare modules and much more, like CSS/HTML modules. + +Build tools do the following: + +1. Take a "main" module, the one intended to be put in ` + + +``` + +If we use bundle tools, then as modules are bundled together, their `import/export` statements are replaced by special bundler calls, so the resulting build does not require `type="module"`, and we can put it into a regular script: + +```html + + +``` + + +## Core module features + +In the previous section we covered browser-specific features. Now it should be easy to start using modules in the browser. + +There are other module features, not bound to the host environment, valid both for browser and Node.js. + +### Always "use strict" + +Modules always `use strict`. E.g. assigning to an undeclared variable will give an error. + +```html run + +``` + +Here we can see it in the browser, but the same is true for any module. + +### Module-level scope + +Each module has its own top-level scope. In other words, top-level variables and functions from a module are not seen in other scripts. Modules are expected to `export` what they want to be accessible from outside. + +Independant top-level scope exists for ` + + +``` + +If we really need to share the variable, we can explicitly assign it to `window.user`. But that's an exception requiring a good reason. + +### A module code is evaluated only the first time when imported + +If a same module is imported into multiple other places, it's code is executed only the first time, then exports are given to all importers. + +That has important consequences. Let's see that on examples. + +First, if executing a module code brings side-effects, like showing a message, then importing it multiple times will trigger it only once -- the first time: + +```js +// πŸ“ alert.js +alert("Module is evaluated!"); +``` + +```js +// Import the same module from different files + +// πŸ“ 1.js +import `./alert.js`; // Module is evaluated! + +// πŸ“ 2.js +import `./alert.js`; // (nothing) +``` + +In practice, top-level module code is mostly used for initialization. We create data structures, pre-fill them, and if we want something to be reusable -- export it. + +Now, a more advanced example. + +Let's say, a module exports an object: + +```js +// πŸ“ admin.js +export let admin = { + name: "John" +}; +``` + +If this module is imported from multiple files, the module is only evaluated the first time, `admin` object is created, and then passed to all further importers. + +All importers get exactly the one and only `admin` object: + +```js +// πŸ“ 1.js +import {admin} from './admin.js'; +admin.name = "Pete"; + +// πŸ“ 2.js +import {admin} from './admin.js'; +alert(admin.name); // Pete + +*!* +// Both 1.js and 2.js imported the same object +// Changes made in 1.js are visible in 2.js +*/!* +``` + +So, let's reiterate -- the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other modules will see that . + +Such behavior is great for modules that require configuration. We can set required properties on the first import, and then in further imports it's ready. + +For instance, `admin.js` module may provide certain functionality, but expect the credentials to come into the `admin` object from outside: + +```js +// πŸ“ admin.js +export let admin = { }; + +export function sayHi() { + alert(`Ready to serve, ${admin.name}!`); +} +``` + +Now, in `init.js`, the first script of our app, we set `admin.name`. Then everyone will see it, including calls made from inside `admin.js` itself: + +```js +// πŸ“ init.js +import {admin} from './admin.js'; +admin.name = "Pete"; +``` + +```js +// πŸ“ other.js +import {admin, sayHi} from './admin.js'; + +alert(admin.name); // *!*Pete*/!* + +sayHi(); // Ready to serve, *!*Pete*/!*! +``` + +## Summary + +To summarize, the core concepts are: + +1. A module is a file. To make `import/export` work, browsers need ` + + + diff --git a/1-js/10-modules/01-modules-intro/example/weekdays.js b/1-js/10-modules/01-modules-intro/example/weekdays.js new file mode 100644 index 00000000..d44ec6ba --- /dev/null +++ b/1-js/10-modules/01-modules-intro/example/weekdays.js @@ -0,0 +1 @@ +export default ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; diff --git a/1-js/10-modules/01-modules-intro/nums.view/bundle.js b/1-js/10-modules/01-modules-intro/nums.view/bundle.js new file mode 100644 index 00000000..843371e4 --- /dev/null +++ b/1-js/10-modules/01-modules-intro/nums.view/bundle.js @@ -0,0 +1,70 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _nums = __webpack_require__(1); + + document.write('Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ' + (_nums.one + _nums.two)); + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + var one = 1; + + exports.one = one; + var two = 2; + + exports.two = two; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/1-js/10-modules/01-modules-intro/nums.view/index.html b/1-js/10-modules/01-modules-intro/nums.view/index.html new file mode 100644 index 00000000..c2f2d57f --- /dev/null +++ b/1-js/10-modules/01-modules-intro/nums.view/index.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/1-js/10-modules/01-modules-intro/nums.view/main.js b/1-js/10-modules/01-modules-intro/nums.view/main.js new file mode 100644 index 00000000..d5ad677d --- /dev/null +++ b/1-js/10-modules/01-modules-intro/nums.view/main.js @@ -0,0 +1,3 @@ +import {one, two} from './nums'; + +document.write(`Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ${one + two}`); \ No newline at end of file diff --git a/1-js/10-modules/01-modules-intro/nums.view/nums.js b/1-js/10-modules/01-modules-intro/nums.view/nums.js new file mode 100644 index 00000000..1cce84a7 --- /dev/null +++ b/1-js/10-modules/01-modules-intro/nums.view/nums.js @@ -0,0 +1,5 @@ +export let one = 1; + +let two = 2; + +export {two}; \ No newline at end of file diff --git a/1-js/10-modules/01-modules-intro/nums.view/webpack.config.js b/1-js/10-modules/01-modules-intro/nums.view/webpack.config.js new file mode 100644 index 00000000..0d1553f3 --- /dev/null +++ b/1-js/10-modules/01-modules-intro/nums.view/webpack.config.js @@ -0,0 +1,22 @@ +// Для использования Π½ΡƒΠΆΠ΅Π½ Node.JS +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ webpack: +// npm i -g webpack +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ babel-loader: +// npm i babel-loader +// ЗапуститС Π΅Π³ΠΎ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ: +// webpack + +module.exports = { + entry: './main', + + output: { + filename: 'bundle.js' + }, + + module: { + loaders: [ + { test: /\.js$/, loader: "babel" } + ] + } +}; + diff --git a/1-js/10-modules/01-modules-intro/say.view/index.html b/1-js/10-modules/01-modules-intro/say.view/index.html new file mode 100644 index 00000000..9a0429cf --- /dev/null +++ b/1-js/10-modules/01-modules-intro/say.view/index.html @@ -0,0 +1,6 @@ + + diff --git a/1-js/10-modules/01-modules-intro/say.view/say.js b/1-js/10-modules/01-modules-intro/say.view/say.js new file mode 100644 index 00000000..198a3be6 --- /dev/null +++ b/1-js/10-modules/01-modules-intro/say.view/say.js @@ -0,0 +1,3 @@ +export function sayHi(user) { + return `Hello, ${user}!`; +} diff --git a/1-js/10-modules/02-modules-browser/article.md b/1-js/10-modules/02-modules-browser/article.md new file mode 100644 index 00000000..46909fab --- /dev/null +++ b/1-js/10-modules/02-modules-browser/article.md @@ -0,0 +1,704 @@ + +# Modules + +As our application grows bigger, we want to split it into multiple files, so called 'modules'. +A module usually contains a class or a library of useful functions. Then, for browsers we bundle them together with a special tool such as [webpack](https://webpack.js.org/) and deploy to the production server. + +For a long time, Javascript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple. So there was no need. + +But eventually scripts became more and more complex, so the community invented a variety of ways to organize code into modules. + +For instance: + +- [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- one of the most ancient module systems, initially implemented by the library [require.js](http://requirejs.org/). +- [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.JS server. +- [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS. + +Now all these slowly become a part of history, but we still can find them in old scripts. + +The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. + +## What is a module? + +A module is just a file. One single script, as simple as that. + +Directives `export` and `import` allow to interchange functionality between modules: + +- `export` keyword labels variables and functions that should be accessible from outside the file. +- `import` allows to import functionality from other modules. + +For instance, if we have a file `sayHi.js` exporting a function: + +```js +// πŸ“ sayHi.js +export function sayHi(user) { + alert(`Hello, ${user}!`); +} +``` + +...Then another file may import and use it: + +```js +// πŸ“ main.js +import {sayHi} from './sayHi.js'; + +alert(sayHi); // function... +sayHi('John'); // Hello, John! +``` + +So, one Javascript file ("module") may import functionality from other ones. Not any functionality, but only what's intended (exported). + + + + + + + + +**Each module has its own top-level scope.** + +In other words, global variables from one file are only seen in that file, they do not get into other files. If we want something to be available for other modules -- let's export it. + +For browser scripts, that's something new, so modules require a special tag ` +``` + +Scripts with `type='module'` have several important differences: + +1. They always have enabled `use strict`. So e.g. assigning to undeclared variables will give an error: + ```html + + ``` +2. Scripts are always deferred, same effect as `defer` attribute (described in the chapter [](info:onload-ondomcontentloaded)), for both external and inline scripts. Or, to put it short, they always run after the HTML is fully downloaded and rendered. + ```html run + + + + + + ``` +3. Async attribute ` + + ``` +4. External scripts that are fetched from another domain require [CORS](mdn:Web/HTTP/CORS) headers. In other words, if a module script is fetched from another domain, the remote server must supply a header `Access-Control-Allow-Origin: *` (may use fetching domain instead of `*`) to indicate that the fetch is allowed. + ```html + + + + ``` +5. And, probably, the most notable difference: modules have their own global scope. In other words, top-level variables and functions from modules are not seen in other scripts. + + ```html + + + + ``` + That's natural: modules are expected to `export` what they want to be accessible from outside. And interact via export/import. If we really need the shared `window` scope, then we can use `window.user`, but that should be an exception requiring a good reason. + +If you look at the list, all items are a 'good thing', leading to correct coding practices. + +## export default + +As we've just seen, a module can export individual variables. + +But it's quite common for a file to implement a single thing. For instance, a file `user.js` describes `class User`, a file `login.js` -- `function login()` for authorization, and so on. One file -- one entity. + +There's a special `export default` statement to better implement that approch. Only one may exist per module, and it labels the export as 'the default one', that may be imported directly without figure brackets. + +For instance, `user.js`: + +```js +*!*export default*/!* class User { + constructor(name) { + this.name = name; + } +}; +``` + +...And in `login.js`: + +```js +import User from './user'; + +new User('John'); +``` + +The default export is technically just a syntax sugar. We can live without it. + +If `user.js` had the regular `export` without `default`, then `login.js` would need to import with figure brackets: + +```js +// if user.js had +// export class User { ... } + +// …then to import it we'd need figuree brackets: +import {User} from './user'; + +new User('John'); +``` + +In practice, such 'sugar' is very convenient, it allows to easily see what exactly is exported and omit extra characters while importing. + +Please note that default exports may be unnamed: +```js +// that's allowed: +export default function() {} +``` + +We can also export a regular value, like an array with days of week: +```js +// weekdays.js +export default ['Monday', 'Tuesday', ..., 'Sunday']; +``` + +That's fine, as the default export is only one per module, so `import` knows what to get: + +```js +// assuming export default is used +import weekdays from './weekdays'; + +alert(weekdays[0]); // Monday +``` + +Usually, there's a rule that the default export is imported under the name of the module itself, or under the name of the corresponding entity. Like `import weekdays from './weekdays'` or `import User from './user'`. + + +## ИспользованиС + +Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ стандарт ECMAScript описываСт, ΠΊΠ°ΠΊ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ значСния ΠΈΠ· ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ, Π½ΠΎ ΠΎΠ½ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ эти ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ΠΈΡΠΊΠ°Ρ‚ΡŒ, Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈ Ρ‚.ΠΏ. + +Π’Π°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π»ΠΈΡΡŒ Π² процСссС создания стандарта, Π½ΠΎ Π±Ρ‹Π»ΠΈ ΡƒΠ±Ρ€Π°Π½Ρ‹ ΠΏΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ нСдостаточной проработанности. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΎΠ½ΠΈ появятся Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. + +БСйчас ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ систСмы сборки, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π² сочСтании с Babel.JS. + +БистСма сборки ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ скрипты, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π½ΠΈΡ… `import/export` ΠΈ замСняСт ΠΈΡ… Π½Π° свои Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ JavaScript-Π²Ρ‹Π·ΠΎΠ²Ρ‹. ΠŸΡ€ΠΈ этом, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΌΠ½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ²-ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько скриптов, смотря ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ сборки. + +НиТС Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ с систСмой сборки [webpack](http://webpack.github.io). + +Π’ Π½Ρ‘ΠΌ Π΅ΡΡ‚ΡŒ: + +- `nums.js` -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ `one` ΠΈ `two`, ΠΊΠ°ΠΊ описано Π²Ρ‹ΡˆΠ΅. +- `main.js` -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `one`, `two` ΠΈΠ· `nums` ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΡ… сумму. +- `webpack.config.js` -- конфигурация для систСмы сборки. +- `bundle.js` -- Ρ„Π°ΠΉΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создала систСма сборки ΠΈΠ· `main.js` ΠΈ `nums.js`. +- `index.html` -- простой HTML-Ρ„Π°ΠΉΠ» для дСмонстрации. + +[codetabs src='nums'] + +## Π˜Ρ‚ΠΎΠ³ΠΎ + +Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ стандарт описываСт, ΠΊΠ°ΠΊ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ значСния. + +Экспорт: + +- `export` ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ прямо ΠΏΠ΅Ρ€Π΅Π΄ объявлСниСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, класса, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. +- Если `export` стоит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ объявлСния, Ρ‚ΠΎ значСния Π² Π½Ρ‘ΠΌ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобках: `export {…}`. +- Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ 'Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ' ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ `export default`. + +Π˜ΠΌΠΏΠΎΡ€Ρ‚: + +- Π’ Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобках ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ значСния, Π° Π·Π°Ρ‚Π΅ΠΌ -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΎΡ‚ΠΊΡƒΠ΄Π° ΠΈΡ… Π±Ρ€Π°Ρ‚ΡŒ: `import {a, b, c as d} from 'module'`. +- МоТно ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС значСния Π² Π²ΠΈΠ΄Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ `import * as obj from 'module'`. +- Π‘Π΅Π· Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобок Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ 'Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ': `import User from 'user'`. + +На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ систСмы сборки Π½Π° сСрвСрС. Автор этого тСкста прСимущСствСнно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ webpack, Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹. diff --git a/1-js/10-modules/02-modules-browser/example/index.html b/1-js/10-modules/02-modules-browser/example/index.html new file mode 100644 index 00000000..deff2a7d --- /dev/null +++ b/1-js/10-modules/02-modules-browser/example/index.html @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/1-js/10-modules/02-modules-browser/example/weekdays.js b/1-js/10-modules/02-modules-browser/example/weekdays.js new file mode 100644 index 00000000..d44ec6ba --- /dev/null +++ b/1-js/10-modules/02-modules-browser/example/weekdays.js @@ -0,0 +1 @@ +export default ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; diff --git a/1-js/10-modules/02-modules-browser/nums.view/bundle.js b/1-js/10-modules/02-modules-browser/nums.view/bundle.js new file mode 100644 index 00000000..843371e4 --- /dev/null +++ b/1-js/10-modules/02-modules-browser/nums.view/bundle.js @@ -0,0 +1,70 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _nums = __webpack_require__(1); + + document.write('Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ' + (_nums.one + _nums.two)); + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + var one = 1; + + exports.one = one; + var two = 2; + + exports.two = two; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/1-js/10-modules/02-modules-browser/nums.view/index.html b/1-js/10-modules/02-modules-browser/nums.view/index.html new file mode 100644 index 00000000..c2f2d57f --- /dev/null +++ b/1-js/10-modules/02-modules-browser/nums.view/index.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/1-js/10-modules/02-modules-browser/nums.view/main.js b/1-js/10-modules/02-modules-browser/nums.view/main.js new file mode 100644 index 00000000..d5ad677d --- /dev/null +++ b/1-js/10-modules/02-modules-browser/nums.view/main.js @@ -0,0 +1,3 @@ +import {one, two} from './nums'; + +document.write(`Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ${one + two}`); \ No newline at end of file diff --git a/1-js/10-modules/02-modules-browser/nums.view/nums.js b/1-js/10-modules/02-modules-browser/nums.view/nums.js new file mode 100644 index 00000000..1cce84a7 --- /dev/null +++ b/1-js/10-modules/02-modules-browser/nums.view/nums.js @@ -0,0 +1,5 @@ +export let one = 1; + +let two = 2; + +export {two}; \ No newline at end of file diff --git a/1-js/10-modules/02-modules-browser/nums.view/webpack.config.js b/1-js/10-modules/02-modules-browser/nums.view/webpack.config.js new file mode 100644 index 00000000..0d1553f3 --- /dev/null +++ b/1-js/10-modules/02-modules-browser/nums.view/webpack.config.js @@ -0,0 +1,22 @@ +// Для использования Π½ΡƒΠΆΠ΅Π½ Node.JS +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ webpack: +// npm i -g webpack +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ babel-loader: +// npm i babel-loader +// ЗапуститС Π΅Π³ΠΎ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ: +// webpack + +module.exports = { + entry: './main', + + output: { + filename: 'bundle.js' + }, + + module: { + loaders: [ + { test: /\.js$/, loader: "babel" } + ] + } +}; + diff --git a/1-js/10-modules/02-modules-browser/say.view/index.html b/1-js/10-modules/02-modules-browser/say.view/index.html new file mode 100644 index 00000000..44b948f2 --- /dev/null +++ b/1-js/10-modules/02-modules-browser/say.view/index.html @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/1-js/10-modules/02-modules-browser/say.view/say.js b/1-js/10-modules/02-modules-browser/say.view/say.js new file mode 100644 index 00000000..ed409cb3 --- /dev/null +++ b/1-js/10-modules/02-modules-browser/say.view/say.js @@ -0,0 +1,7 @@ +export function sayHi(user) { + alert(`Hello, ${user}!`); +} + +export function sayBye(user) { + alert(`Bye, ${user}!`); +} diff --git a/1-js/10-modules/03-modules-export-import/article.md b/1-js/10-modules/03-modules-export-import/article.md new file mode 100644 index 00000000..4e1844f9 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/article.md @@ -0,0 +1,693 @@ + +# Modules + +As our application grows bigger, we want to split it into multiple files, so called 'modules'. +A module usually contains a class or a library of useful functions. Then, for browsers we bundle them together with a special tool such as [webpack](https://webpack.js.org/) and deploy to the production server. + +For a long time, Javascript existed without a language-level module syntax. That wasn't a problem, because initially scripts were small and simple. So there was no need. + +But eventually scripts became more and more complex, so the community invented a variety of ways to organize code into modules. + +For instance: + +- [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition) -- one of the most ancient module systems, initially implemented by the library [require.js](http://requirejs.org/). +- [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) -- the module system created for Node.JS server. +- [UMD](https://github.com/umdjs/umd) -- one more module system, suggested as a universal one, compatible with AMD and CommonJS. + +Now all these slowly become a part of history, but we still can find them in old scripts. + +The language-level module system appeared in the standard in 2015, gradually evolved since then, and is now supported by all major browsers and in Node.js. + +## What is a module? + +A module is just a file. One single script, as simple as that. + +Directives `export` and `import` allow to interchange functionality between modules: + +- `export` keyword labels variables and functions that should be accessible from outside the file. +- `import` allows to import functionality from other modules. + +For instance, if we have a file `sayHi.js` exporting a function: + +```js +// πŸ“ sayHi.js +export function sayHi(user) { + alert(`Hello, ${user}!`); +} +``` + +...Then another file may import and use it: + +```js +// πŸ“ main.js +import {sayHi} from './sayHi.js'; + +alert(sayHi); // function... +sayHi('John'); // Hello, John! +``` + +So, one Javascript file ("module") may import functionality from other ones. Not any functionality, but only what's intended (exported). + +**Each module has its own top-level scope.** + +In other words, global variables from one file are only seen in that file, they do not get into other files. If we want something to be available for other modules -- let's export it. + +For browser scripts, that's something new, so modules require a special tag ` +``` + +Scripts with `type='module'` have several important differences: + +1. They always have enabled `use strict`. So e.g. assigning to undeclared variables will give an error: + ```html + + ``` +2. Scripts are always deferred, same effect as `defer` attribute (described in the chapter [](info:onload-ondomcontentloaded)), for both external and inline scripts. Or, to put it short, they always run after the HTML is fully downloaded and rendered. + ```html run + + + + + + ``` +3. Async attribute ` + + ``` +4. External scripts that are fetched from another domain require [CORS](mdn:Web/HTTP/CORS) headers. In other words, if a module script is fetched from another domain, the remote server must supply a header `Access-Control-Allow-Origin: *` (may use fetching domain instead of `*`) to indicate that the fetch is allowed. + ```html + + + + ``` +5. And, probably, the most notable difference: modules have their own global scope. In other words, top-level variables and functions from modules are not seen in other scripts. + + ```html + + + + ``` + That's natural: modules are expected to `export` what they want to be accessible from outside. And interact via export/import. If we really need the shared `window` scope, then we can use `window.user`, but that should be an exception requiring a good reason. + +If you look at the list, all items are a 'good thing', leading to correct coding practices. + +## export default + +As we've just seen, a module can export individual variables. + +But it's quite common for a file to implement a single thing. For instance, a file `user.js` describes `class User`, a file `login.js` -- `function login()` for authorization, and so on. One file -- one entity. + +There's a special `export default` statement to better implement that approch. Only one may exist per module, and it labels the export as 'the default one', that may be imported directly without figure brackets. + +For instance, `user.js`: + +```js +*!*export default*/!* class User { + constructor(name) { + this.name = name; + } +}; +``` + +...And in `login.js`: + +```js +import User from './user'; + +new User('John'); +``` + +The default export is technically just a syntax sugar. We can live without it. + +If `user.js` had the regular `export` without `default`, then `login.js` would need to import with figure brackets: + +```js +// if user.js had +// export class User { ... } + +// …then to import it we'd need figuree brackets: +import {User} from './user'; + +new User('John'); +``` + +In practice, such 'sugar' is very convenient, it allows to easily see what exactly is exported and omit extra characters while importing. + +Please note that default exports may be unnamed: +```js +// that's allowed: +export default function() {} +``` + +We can also export a regular value, like an array with days of week: +```js +// weekdays.js +export default ['Monday', 'Tuesday', ..., 'Sunday']; +``` + +That's fine, as the default export is only one per module, so `import` knows what to get: + +```js +// assuming export default is used +import weekdays from './weekdays'; + +alert(weekdays[0]); // Monday +``` + +Usually, there's a rule that the default export is imported under the name of the module itself, or under the name of the corresponding entity. Like `import weekdays from './weekdays'` or `import User from './user'`. + + +## ИспользованиС + +Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ стандарт ECMAScript описываСт, ΠΊΠ°ΠΊ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ значСния ΠΈΠ· ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ, Π½ΠΎ ΠΎΠ½ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ эти ΠΌΠΎΠ΄ΡƒΠ»ΠΈ ΠΈΡΠΊΠ°Ρ‚ΡŒ, Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΈ Ρ‚.ΠΏ. + +Π’Π°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π»ΠΈΡΡŒ Π² процСссС создания стандарта, Π½ΠΎ Π±Ρ‹Π»ΠΈ ΡƒΠ±Ρ€Π°Π½Ρ‹ ΠΏΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ нСдостаточной проработанности. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΎΠ½ΠΈ появятся Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ. + +БСйчас ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ систСмы сборки, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π² сочСтании с Babel.JS. + +БистСма сборки ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ скрипты, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Π½ΠΈΡ… `import/export` ΠΈ замСняСт ΠΈΡ… Π½Π° свои Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ JavaScript-Π²Ρ‹Π·ΠΎΠ²Ρ‹. ΠŸΡ€ΠΈ этом, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΌΠ½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ²-ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ ΠΈΠ»ΠΈ нСсколько скриптов, смотря ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ сборки. + +НиТС Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ с систСмой сборки [webpack](http://webpack.github.io). + +Π’ Π½Ρ‘ΠΌ Π΅ΡΡ‚ΡŒ: + +- `nums.js` -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ `one` ΠΈ `two`, ΠΊΠ°ΠΊ описано Π²Ρ‹ΡˆΠ΅. +- `main.js` -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ `one`, `two` ΠΈΠ· `nums` ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΡ… сумму. +- `webpack.config.js` -- конфигурация для систСмы сборки. +- `bundle.js` -- Ρ„Π°ΠΉΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создала систСма сборки ΠΈΠ· `main.js` ΠΈ `nums.js`. +- `index.html` -- простой HTML-Ρ„Π°ΠΉΠ» для дСмонстрации. + +[codetabs src='nums'] + +## Π˜Ρ‚ΠΎΠ³ΠΎ + +Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ стандарт описываСт, ΠΊΠ°ΠΊ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ значСния. + +Экспорт: + +- `export` ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ прямо ΠΏΠ΅Ρ€Π΅Π΄ объявлСниСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, класса, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. +- Если `export` стоит ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ объявлСния, Ρ‚ΠΎ значСния Π² Π½Ρ‘ΠΌ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобках: `export {…}`. +- Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ 'Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ' ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ `export default`. + +Π˜ΠΌΠΏΠΎΡ€Ρ‚: + +- Π’ Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобках ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ значСния, Π° Π·Π°Ρ‚Π΅ΠΌ -- ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, ΠΎΡ‚ΠΊΡƒΠ΄Π° ΠΈΡ… Π±Ρ€Π°Ρ‚ΡŒ: `import {a, b, c as d} from 'module'`. +- МоТно ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС значСния Π² Π²ΠΈΠ΄Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ `import * as obj from 'module'`. +- Π‘Π΅Π· Ρ„ΠΈΠ³ΡƒΡ€Π½Ρ‹Ρ… скобок Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ 'Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ': `import User from 'user'`. + +На Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ систСмы сборки Π½Π° сСрвСрС. Автор этого тСкста прСимущСствСнно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ webpack, Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹. diff --git a/1-js/10-modules/03-modules-export-import/example/index.html b/1-js/10-modules/03-modules-export-import/example/index.html new file mode 100644 index 00000000..deff2a7d --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/example/index.html @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/1-js/10-modules/03-modules-export-import/example/weekdays.js b/1-js/10-modules/03-modules-export-import/example/weekdays.js new file mode 100644 index 00000000..d44ec6ba --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/example/weekdays.js @@ -0,0 +1 @@ +export default ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; diff --git a/1-js/10-modules/03-modules-export-import/nums.view/bundle.js b/1-js/10-modules/03-modules-export-import/nums.view/bundle.js new file mode 100644 index 00000000..843371e4 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/nums.view/bundle.js @@ -0,0 +1,70 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _nums = __webpack_require__(1); + + document.write('Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ' + (_nums.one + _nums.two)); + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + var one = 1; + + exports.one = one; + var two = 2; + + exports.two = two; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/1-js/10-modules/03-modules-export-import/nums.view/index.html b/1-js/10-modules/03-modules-export-import/nums.view/index.html new file mode 100644 index 00000000..c2f2d57f --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/nums.view/index.html @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/1-js/10-modules/03-modules-export-import/nums.view/main.js b/1-js/10-modules/03-modules-export-import/nums.view/main.js new file mode 100644 index 00000000..d5ad677d --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/nums.view/main.js @@ -0,0 +1,3 @@ +import {one, two} from './nums'; + +document.write(`Π‘ΡƒΠΌΠΌΠ° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΎΠ²: ${one + two}`); \ No newline at end of file diff --git a/1-js/10-modules/03-modules-export-import/nums.view/nums.js b/1-js/10-modules/03-modules-export-import/nums.view/nums.js new file mode 100644 index 00000000..1cce84a7 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/nums.view/nums.js @@ -0,0 +1,5 @@ +export let one = 1; + +let two = 2; + +export {two}; \ No newline at end of file diff --git a/1-js/10-modules/03-modules-export-import/nums.view/webpack.config.js b/1-js/10-modules/03-modules-export-import/nums.view/webpack.config.js new file mode 100644 index 00000000..0d1553f3 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/nums.view/webpack.config.js @@ -0,0 +1,22 @@ +// Для использования Π½ΡƒΠΆΠ΅Π½ Node.JS +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ webpack: +// npm i -g webpack +// ΠŸΠΎΡΡ‚Π°Π²ΡŒΡ‚Π΅ babel-loader: +// npm i babel-loader +// ЗапуститС Π΅Π³ΠΎ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ: +// webpack + +module.exports = { + entry: './main', + + output: { + filename: 'bundle.js' + }, + + module: { + loaders: [ + { test: /\.js$/, loader: "babel" } + ] + } +}; + diff --git a/1-js/10-modules/03-modules-export-import/say.view/index.html b/1-js/10-modules/03-modules-export-import/say.view/index.html new file mode 100644 index 00000000..44b948f2 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/say.view/index.html @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/1-js/10-modules/03-modules-export-import/say.view/say.js b/1-js/10-modules/03-modules-export-import/say.view/say.js new file mode 100644 index 00000000..ed409cb3 --- /dev/null +++ b/1-js/10-modules/03-modules-export-import/say.view/say.js @@ -0,0 +1,7 @@ +export function sayHi(user) { + alert(`Hello, ${user}!`); +} + +export function sayBye(user) { + alert(`Bye, ${user}!`); +} diff --git a/1-js/10-modules/04-modules-dynamic-imports/article.md b/1-js/10-modules/04-modules-dynamic-imports/article.md new file mode 100644 index 00000000..a2a8d7ff --- /dev/null +++ b/1-js/10-modules/04-modules-dynamic-imports/article.md @@ -0,0 +1,4 @@ + +# Dynos + +...test diff --git a/1-js/10-modules/index.md b/1-js/10-modules/index.md new file mode 100644 index 00000000..edb7bfe8 --- /dev/null +++ b/1-js/10-modules/index.md @@ -0,0 +1,3 @@ + +# Modules +s