# ModuleJS

### Описание
ModuleJS — это модульный менеджер JavaScript, совместимый с нормами CMD, AMD и UMD.

### Установка

```
npm i silis-modulejs
```

### Размеры файлов
|Файл|Размер файла|Описание|
|--|--|--|
|module.min.js.zip|1.18кБ|Сжатый JS-код + ZIP-сжатие, используется в рабочей среде с более высокими требованиями к сети|
|module.min.js|2.4кБ|Сжатый JS-код, используется в рабочей среде|
|module.js|7.3кБ|Исходный JS-код, используется при разработке и тестировании|

### Определение модулей (определение модуля)

1. Определение модуля
```
define(function(){
    ...
})
```

2. Определение альтернативного имени модуля
```
define("myModule.js", [], function(){
    ...
})
```

### Экспорт модулей (экспортирование модуля)

1. Экспорт модуля через `return`
```
define(function(){
    return ... //Экспортируется любой тип данных
})
```

2. Экспорт модуля через `exports`

- По умолчанию использует `exports` для экспорта модуля
```
define(function(require, exports, module){
    exports.sayHello = ...
})
```

- Указание использования `exports` для экспорта модуля
```
define(["exports"], function(exports){
    exports.sayHello = ...
})
```

3. Экспорт модуля через `module.exports`

- По умолчанию использует `module.exports` для экспорта модуля
```
define(function(require, exports, module){
    module.exports = ...
})
```

- Указание использования `module.exports` для экспорта модуля
```
define(["exports"], function(exports){
    module.exports = ...
})
```

4. Экспорт модуля через глобальные переменные

```
(
    (typeof window === 'object' && window) ||
    (typeof global === 'object' && global)
).myModule = ... //Экспортируется любой тип данных
```### Импорт модулей

1. Синхронный импорт модулей

- Синхронный импорт одного модуля
```
var myModule = require('myModule.js');
```
или
```
var myModule = require('myModule.js', false);
```

- Синхронный импорт нескольких модулей
```
var myModule1 = require('myModule1.js');
var myModule2 = require('myModule2.js');
```
или
```
var myModule1 = require('myModule1.js', false);
var myModule2 = require('myModule2.js', false);
```

2. Асинхронный импорт модулей

- Асинхронный импорт одного модуля
```
require('myModule.js', function(myModule){
    ...
});
```
или
```
var myModulePromise = require('myModule.js', true);
myModulePromise.then(function(myModule){
    ...
});
```

- Асинхронный импорт нескольких модулей
```
require(['myModule1.js'], function(myModule1){
    ...
});
```
или
```
var myModulesPromise = require(['myModule1.js'], true);
myModulesPromise.then(function(modules){
    var myModule1 = modules[0];
    ...
});
```

### Зависимые модули

1. Предварительная загрузка зависимого модуля
```javascript
define(["dependentModule1.js"], function(dependentModule1){
    var mainModule = {
        subModule1: dependentModule1
    };
    
    return mainModule;
})
```

2. Отложенная загрузка синхронного зависимого модуля

```
define(function(){
    var mainModule = {
        subModule1: require("dependentModule1.js")
    };

    return mainModule;
})
```

3. Отложенная загрузка асинхронного зависимого модуля
```
define(function(){
    var mainModule = {};

    return require(["dependentModule1.js"], function(dependentModule1){
        mainModule.dependentModule1 = dependentModule1;
        return mainModule;
    })
})
```

### Примеры AMD-нормата

> AMD-нормат указывает на асинхронное определение модулей (Asynchronous Module Definition), то есть загрузку модулей асинхронным способом.Определение модуля в соответствии с AMD-нормативом:

```javascript
define(function() {

    return function(text) {
        setTimeout(function() {
            document.body.innerText = text;
        }, 100);
    }

});
```

Файл кода: `/example/print-amd-module.js`

```javascript
define(["print-amd-module.js"], function(print) {

    return {
        sayHello: function() {
            print("Привет, мой модуль, определенный согласно нормативу AMD");
        }
    }

});
```

Файл кода: `/example/hello-amd-module.js`

Асинхронная загрузка модуля, определенного в соответствии с AMD-нормативом:

```html
<!DOCTYPE html>
<html>
<head>
<script>
require(["hello-amd-module.js"], function(helloAmdModule) {
    helloAmdModule.sayHello();
})
</script>
</head>
<body>
Загрузка асинхронного модуля...
</body>
</html>
```

Файл кода: `/example/async-load-amd-module-example.html`

### Примеры CMD-норматива

CMD-норматив указывает на синхронное определение модулей (Common Module Definition), то есть загрузку модулей синхронным способом.

Определение модуля в соответствии с CMD-нормативом:

```javascript
define(function(require, exports, module) {

    module.exports = function(text) {
        setTimeout(function() {
            document.body.innerText = text;
        }, 100);
    }

});
```

Файл кода: `/example/print-cmd-module.js`

```javascript
define(function(require, exports, module) {

    exports.sayHello = function() {
        var print = require("print-cmd-module.js");
        print("Привет, мой модуль, определенный согласно нормативу CMD");
    }

});
```

Файл кода: `/example/hello-cmd-module.js`

Синхронной загрузкой модуля, определённого в соответствии с CMD-нормой:

```html
<!DOCTYPE html>
<html>
    <head>
        <script>
            var helloCmdModule = require(["hello-cmd-module.js"]);
            helloCmdModule.sayHello();
        </script>
    </head>
    <body>
        Загрузка синхронного модуля...
    </body>
</html>
```> Код файла: /example/sync-load-cmd-module-example.html


### Пример CMD-нормы

```javascript
((root, factory) => {
    if (typeof define === "function" && define.amd) {
        // AMD
        define(["dependentModule1", "dependentModule2"], factory);
    } else if (typeof exports === 'object') {
        // CommonJS
        module.exports = factory(require("dependentModule1"), require("dependentModule2"));
    } else {
        root.currentModule = factory(root.dependentModule1, root.dependentModule2);
    }
})(
    (typeof window == "object" && window) || (typeof global == "object" && global),
    (dependentModule1, dependentModule2) => {
        // TODO
    }
)
```