Proxy code snippets links with Nginx

  1. Simple example for redirect all traffic by location condition
        location /v1/ {
            proxy_pass http://eskso.wsofter.ru:22080/v1/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

Now all traffic from https://eskso.wsofter.ru/v1/ shall redirect to http://eskso.wsofter.ru:22080/v1/

2. Simple example for redirect all file traffic by location condition

        location ^~ /uploads/ {
            proxy_pass http://eskso.wsofter.ru:23080/uploads/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        }

Now all file traffic from https://eskso.wsofter.ru/uploads/ shall redirect to http://eskso.wsofter.ru:23080/uploads/

JavaScript add target to __blank on page if it is external

const url = {}

url.isExternal = function(link){
    var domain = function(link) {
        return link.replace('http://','').replace('https://','').replace('//','').split('/')[0];
    }   
    return domain(location.href) !== domain(link)
}

url.replaceAllLinks = function(html, link){
    let regex = /href\s*=\s*(['"])(https?:\/\/.+?)\1/ig;
    let l;
    while((l = regex.exec(html)) !== null) {
        html = html.replace(l[2], link);
    }
    return html;
}

url.addTargeBlankToExternal = function(html){
    let regex = /href\s*=\s*(['"])((https|http)?:\/\/.+?)\1/ig;
    let link;
    while((link = regex.exec(html)) !== null) {
      console.log(link[2])
      if(url.isExternal(link[2])){
          html = html.replace(link[2] + "\"", link[2] + "\" target=\"__blank\"");
      }
    }
    return html;
}



export default url

Конвертация класса компонента из JavaScript в TypeScript

Допустим, мы работаем в React Native и нам нужно преобразовать пример кода элемента ButtonGroup из JavaScript в TypeScript с обработкой состояния. Код взят отсюда и является элементом модуля компонентов React Native react-native-elements

import { ButtonGroup } from 'react-native-elements';
import * as React from 'react';
...
class BtnGroup extends React.Component{
 constructor () {
   super()
   this.state = {
     selectedIndex: 2
   }
   this.updateIndex = this.updateIndex.bind(this)
 }

 updateIndex (selectedIndex) {
   this.setState({selectedIndex})
 }

 render () {
   const buttons = ['Hello', 'World', 'Buttons']
   const { selectedIndex } = this.state

   return (
     <ButtonGroup
       onPress={this.updateIndex}
       selectedIndex={selectedIndex}
       buttons={buttons}
       containerStyle={{height: 100}}
     />
   )
 }
}

Данный код обработки состояния нажатия ButtonGroup в TypeScript будет следующим

import { ButtonGroup } from 'react-native-elements';
import * as React from 'react';
...

interface IProps {
}

interface IState {
  selectedIndex?: number;
}

class BtnGroup extends React.Component<IProps, IState> {
  constructor(props: IProps) {
    super(props);
    this.state = {
        selectedIndex: 0
    }
    this.updateIndex = this.updateIndex.bind(this)
  }

  updateIndex (selectedIndex : number) {
      console.log(selectedIndex)
    this.setState({selectedIndex})
  }

  render() {
    const buttons = ['Мои программы', 'Мои упражнения']
    return(
        <ButtonGroup
        onPress={this.updateIndex}
        selectedIndex={this.state.selectedIndex}
        buttons={buttons}
        containerStyle={{height: 40}}
      />
    );
  }
}

Решаем проблему Bad owner or permissions on C:\\Users\\USER/.ssh/config

Недавно случилась беда, мой любимы Visual Code перестал соединяться с удаленным сервером, ссылаясь на ошибку

Bad owner or permissions on C:\\Users\\USER/.ssh/config

В общем, звучит это в духе, что у нас нет прав на использование файлов внутри .ssh и попросту говоря, что мы не владельцы и система шлет нас н…уй, причем, шлют именно CMD и Powershell, которые используются Visual Code для удаленного соединения через плагин Remote SSH.

Решение этой непутевой ошибки довольно простое, для этого нужно клацать правой кнопкой мыши на файл .ssh/config и убрать все унаследованные права, проследуя командам Свойства -> Безопасность -> Дополнительно -> Убрать наследование -> Удалить все унаследованные разрешения от этого объекта

Предупреждение Warning message DNS SPOOFING DETECTED when SSHing into instances

Вы можете получить это сообщение, когда используете SSH в своем териминале:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @ 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The RSA host key for ec2-46-137-83-49.us-west-1.compute.amazonaws.com has changed, 
and the key for the corresponding IP address 10.56.63.182 
is unknown. This could either mean that 
DNS SPOOFING is happening or the IP address for the host 
and its host key have changed at the same time. 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! 
Someone could be eavesdropping on you right now (man-in-the-middle attack)! 
It is also possible that the RSA host key has just been changed. 
The fingerprint for the RSA key sent by the remote host is 
69:4e:bb:70:6a:64:e3:78:07:6f:b4:00:41:07:d8:9c.
Please contact your system administrator. 
Add correct host key in /home/deploy/.ssh/known_hosts to get rid of this message. 
Offending key in /home/deploy/.ssh/known_hosts:1 
Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks. 

Эта последовательность событий может привести к появлению предупреждения:

  1. Создание экземпляра с IP-адресом.
  2. SSHing в этот экземпляр, никаких предупреждений не происходит (как и ожидалось).
  3. Отключение этого экземпляра.
  4. Создание нового экземпляра, присвоение ему ранее использованного IP-адреса.
  5. SSHing в этот новый экземпляр. Это когда появляется предупреждение.

Почему появляется это сообщение?

Когда вы создаете новый экземпляр, это новый виртуализированный компьютер. Поэтому, когда вы возвращаетесь к тому же IP-адресу, ваш компьютер распознает, что это не тот компьютер, который был раньше. Хотя в некоторых случаях это может указывать на злонамеренную активность, указанную в предупреждении, в этом сценарии она ожидается и в порядке.

Решение: отредактируйте файл .ssh / known_hosts

Отредактируйте файл .ssh/known_hosts и удалите строку, содержащую неисправный ключ.

  1. На вашем локальном компьютере откройте файл ~ / .ssh / known_hosts для редактирования.
  2. Удалите строку, содержащую ключ-нарушитель и соответствующий IP-адресу, указанному в предупреждении.
  3. В приведенном выше примере это первая строка файла (номер строки указывается после двоеточия в предупреждении “Ключ-нарушитель в /home/deploy/.ssh/known_hosts:”): ec2–46–137–83– 49.us-west–1.compute.amazonaws.com… jkEkIXAIRJQ ==

Перенос WordPress с Apache на Nginx + php-fpm

Для нам потребуется создать новый файл конфигурации сайта в папке sites-available со следующим содержимым

server {
        server_name example.com www.example.com;
        root /var/www/example.com/public_html;
        index index.php;
	access_log /var/www/example.com/logs/example.com.access.log;
	error_log /var/www/example.com/logs/example.com.error.log;
	
    location / {
      try_files $uri $uri/ /index.php?$args;
    }
	
    location ~ \.php$ {
        root /var/www/example.com/public_html;
        fastcgi_pass   unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }


    location ~ /\.ht {
      deny  all;
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = wsofter.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;
    return 404; # managed by Certbot


}

Чтобы генерировать SSL сертификаты для домена можно почитать про сервисы для генерации на официальной странице или сразу же воспользоваться популярным клиентом для Linux Certbot.

Удаленное соединение через протокол ssh

SSH (англ. Secure Shell — «безопасная оболочка») — сетевой протокол прикладного уровня, позволяющий производить удалённое управление операционной системой и туннелирование TCP-соединений (например, для передачи файлов).

SSH позволяет безопасно передавать в незащищённой среде практически любой другой сетевой протокол. Таким образом, можно не только удалённо работать на компьютере через командную оболочку, но и передавать по шифрованному каналу звуковой поток или видео (например, с веб-камеры)[2]. Также SSH может использовать сжатие передаваемых данных для последующего их шифрования.

Для авторизации и входа можно воспользоваться ssh-клиентами с графическим интерфейсом, так и обычной консолью. Есть они для всех видов ОС, но, по моему, очень важно уметь входить в удаленную систему через консоль или любую командную оболочку. Протокол SSH работает через порт 22, поэтому, сначала необходимо убедиться, что на стороне сервера запущен сервис ssh на порту 22, чтобы по нему взаимодействовать.

В Linux, чтобы проверить и запустить сервис нужно выполнить команды:

$ service ssh status
$ service ssh start

Если в системе не установлена служба/сервис ssh, то ставим из репозитория системы. К примеру, под Ubuntu:

$ sudo apt-get install openssh-server

Процесс соединения по SSH

SSH предлагает 2 вида соединения между клиентом и сервером.

  • Первый способ – это обычный способ авторизации через ip, логин и пароль;
  • Второй способ – через публичный и приватный ключи.

Первый способ мне не особо интересен, потому что привычен, а вот второй, пожалуй, рассмотрим детально.

Авторизация через SSH по паролю и логину

Не буду приводить примеры соединения через различные GUI – оболочки, просто напишу команду авторизации через любую консоль

$ ssh user@server.com

Далее система попросит подтвердить распечатку ключа соединения по умолчанию и пароль входа.

Авторизация через SSH по ключам

Чтобы сделать авторизацию через ключей SSH на Windows нам необходимо сначала их создать. В Windows вы можете создавать ключи SSH разными способами. Этот пост объясняет, как использовать два приложения OpenSSH и Git Bash.

Установка Git и генерация ключей

Сначала нам потребуется Git и командная оболочка, которая поставляется с этой системой. Через него мы будем генерировать приватный и публичный ключи доступа в папку ~/.ssl. Скачать ее можно на официальном сайте.

После скачивания Git поэтапно выполняем команды.

Откройте Git Bash.

Для тех, кто не в курсе, как это делается
Замечу, что классическая консоль Git – не единственный способ ввода команд. Для этого, также, можно воспользоваться и встроенным терминалом в Visual Studio Code, выбрав тип оболочки Bash. Но учтите, что это вовсе не значит, что вы не должны поставить Git с Bash, потому что VS Code запускает не встроенный, а вами установленный, но удобно, когда консоль и редактор кода в одном окне
Пример запуска консоли Git Bash в терминале VS Code

Вставьте текст ниже, подставив в свой адрес электронной почты GitHub.

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Это создаст новый ключ ssh, используя предоставленный email в качестве метки

> Generating public/private rsa key pair.

Когда вам будет предложено « Enter a file in which to save the key», нажмите Enter. Это принимает местоположение файла по умолчанию

> Enter a file in which to save the key (/c/Users/you/.ssh/id_rsa):[Press enter]

Далее командная строка запросит фразу-пароль, который потребуется вводить 2 раза(пароль не видна при вводе)

> Enter passphrase (empty for no passphrase): [Type a passphrase]
> Enter same passphrase again: [Type passphrase again]

Запуска служб OpenSSL в Windows 10

На момент написания данной статьи в Windows 10 на уровне операционной системы уже была внедрена служба OpenSSL. Возможно, что она не активна по умолчанию и, чтобы соединиться, нам потребуется запустить службы SSL

Запускаем OpenSSL – службы в панели Службы

Соединение с удаленным терминалом Linux из Windows через публичный ключ SSL

Для соединения вашей машины Windows с удаленным сервером по протоколу SSH необходимо, чтобы был запущен OpenSSH Authentification Agent и OpenSSH SSH Server в режиме background, в предыдущем пункте я показал как это сделать через GUI, но повторю, как это делать через консоль Bash

$ eval $(ssh-agent -s)

после запуска консоль покажет идентификатор запуска службы

> Agent pid 59566

но как вы уже поняли, это недостаточное условие, нам еще необходимо передать в SSH агент наш приватный ключ

ssh-add ~/.ssh/id_rsa

Далее, необходимо убедится, что и на стороне сервера был запущен сервис ssh (так он именуется в Linux) на порту 22, про это и как это делается уже было сказано в начале данного поста, повторяться не буду.

Передача ключа в удаленный Linux

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

Самый простой и рекомендуемый способ скопировать ваш открытый ключ на сервер – использовать утилиту ssh-copy-id. На вашем локальном компьютере. Для этого набираем в терминале Bash

$ ssh-copy-id remote_username@server_ip_address

после этого вводите пароль к логину и ваш публичный ключ скопируется на удаленный сервер. Далее уже можно заходить в систему без надобности вводить пароль.

Передача ключа на GitHub

Для этого нужно сначала необходимо скопировать наш публичный ключ из Windows, который мы сгенерили выше командой в консоли

> clip < ~/.ssh/id_rsa.pub

Заходим в профиль нашего аккаунта GitHub, в правом верхнем углу любой страницы нажмите на фотографию своего профиля, затем нажмите «Настройки»

Настройки

На боковой панели настроек пользователя нажмите клавиши SSH и GPG

SSH и GPG ключи

Нажмите Новый ключ SSH или Добавить ключ SSH

Пункт добавления нового ключа

Вставьте свой ключ в поле «Ключ»

Вставляем скопированный выше публичный ключ

Жмем кнопку Добавить и вводим пароль подтверждения от своего аккаунта и все, можно работать в Git без пароля через публичный ключ SSH.

Использование exports/require в CommonJS и export/import в EcmaScript 2015

Начиная с ECMAScript 2015 (ES6), JavaScript имеет концепцию модулей. Модули выполняются в своей собственной области, а не в глобальной области.

Это означает, что переменные, функции, классы и т.д., объявленные в модуле, не видны вне модуля, если они явно не экспортированы с использованием одной из форм экспорта, о которых пойдет речь ниже.

И наоборот, чтобы использовать переменную, функцию, класс, интерфейс и т. д., Экспортированные из другого модуля, его необходимо импортировать с помощью одной из форм импорта.

Модули декларативные, а отношения между модулями определяются в терминах импорта и экспорта на уровне файлов с кодом, которые именуются модулями.

Как это используют в CommonJS? Модули импортируют друг друга, используя загрузчик модулей. Во время выполнения загрузчик модуля отвечает за поиск и выполнение всех зависимостей модуля перед его выполнением. Хорошо известные загрузчики модулей, используемые в JavaScript – это загрузчик Node.js для модулей CommonJS и загрузчик RequireJS для модулей AMD в веб-приложениях.

Как это используют в ECMAScript 2015? Любой файл, содержащий импорт или экспорт верхнего уровня, считается модулем. И наоборот, файл без каких-либо объявлений импорта или экспорта верхнего уровня обрабатывается как сценарий, содержимое которого доступно в глобальной области.

Различие в использовании модулей CommonJS и ES6

Что предпочтительнее использовать?

Вопрос, относительно использовании модулей ES6 против CommonJS не однозначен. Первые универсальны, последние в основном используются в Node.js, но также поддерживаются сборщиками Webpack и другими компоновщиками, поэтому в приложениях на подобии React, Angular или Vue могут потенциально использоваться как import, так и require.

Начало работы с модулями Node.js: require, exports, imports и не только

Модули являются важной концепцией для понимания проектов Node.js. В этом посте мы рассмотрим модули Node: requireexports и будущее import .

Модули Node.js позволяют писать повторно используемый код. Вы можете вкладывать их друг в друга. Используя Node Package Manager (NPM) вы можете опубликовать свои модули и сделать их доступными для сообщества. Кроме того, NPM позволяет повторно использовать модули, созданные другими разработчиками.

Мы используем Node 12.x для примеров и синтаксис ES6 +. Тем не менее, концепции действительны для любой версии.

В этом разделе мы рассмотрим, как создавать модули Node и каждый из его компонентов:

  • Require
  • Exports
  • Module (module.exports vs. export)
  • Import

require – подключение модулей в Node.js

require используются для подключения модулей. Это позволяет вам включать модули в ваши программы. Вы можете добавить встроенные базовые модули Node.js, модули, написанные сообществом разработчиков из папки node_modules и локальные модули.

Допустим, мы хотим прочитать файл из файловой системы. Node.js имеет для этого встроенный модуль под названием «fs»:

const fs = require('fs');

fs.readFile('./file.txt', 'utf-8', (err, data) => {
  if(err) { throw err; }
  console.log('data: ', data);
});

Как видите, мы импортировали модуль «fs» в наш код. Это позволяет нам использовать любую прикрепленную к нему функцию, например «readFile» и многие другие.

Функция require будет искать файлы в следующем порядке:

  1. Built-in. Встроенные в Node.js модули (такие как fs)
  2. NPM Modules. Устанавливаемые модули из репозитория npm, их можно посмотреть в папке node_modules.
  3. Local Modules. Локальные модули, которых надо подгружать из вашего локального места через обращение к пути .// or ../. Модули соответствуют расширениям: *.js*.json*.mjs*.cjs*.wasm и *.node.

Давайте теперь объясним каждый чуть подробнее

1. Встроенные модули Node.js

Когда вы устанавливаете Node.js, он поставляется со многими встроенными модулями. Node.js поставляется с батарейками в комплекте :).

Некоторые из наиболее используемых основных модулей:

  • fs: позволяет манипулировать (создавать / читать / писать) файлами и каталогами .
  • path: утилиты для работы с файлами и каталогами путей.
  • http: создавать HTTP-серверы и клиенты для веб-разработки .
  • url: утилиты для разбора URL и извлечения из него элементов .

Эти модули вам не нужно устанавливать, вы можете импортировать их и использовать в своих программах из коробки.

2. Модули из репозитория NPM

Модули NPM – это сторонние модули, которые вы можете использовать после их установки. Назвать несколько:

  • lodash: коллекция служебных функций для манипулирования массивами, объектами и строками.
  • request: HTTP-клиент проще в использовании, чем встроенный модуль  http.
  • express: HTTP сервер для создания сайтов и API. Опять же, проще в использовании, чем встроенный модуль http.

Это вы должны сначала установить их, вот так:

$ npm install express

и затем вы можете ссылаться на них, как на встроенные модули, но на этот раз они будут обслуживаться из папки node_modules, которая содержит все сторонние библиотеки.

const express = require('express');
3. Собственные модули

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

exports – экспорт данных из модуля Node.js

Ключевое слово export дает вам возможность «экспортировать» ваши объекты и методы. Давайте сделаем пример:

const PI = 3.14159265359;

exports.area = radius => (radius ** 2) * PI;
exports.circumference = radius => 2 * radius * PI;

В приведенном ниже коде мы экспортируем функции area и circumference. Мы определили константу PI, но она доступна только внутри модуля. Только элементы, связанные с exports, доступны за пределами модуля.

Итак, мы можем использовать его, используя require в другом файле, как показано ниже:

const circle = require('./circle');

const r = 3;
console.log(`Circle with radius ${r} has
  area: ${circle.area(r)};
  circumference: ${circle.circumference(r)}`);

Заметил, что на этот раз мы добавляем имя модуля к ./. Это означает, что модуль является локальным файлом.

Обертка модуля в Node.js

Вы можете рассматривать каждый модуль Node.js как отдельную функцию, подобную следующей:

(function (exports, require, module, __filename, __dirname) {
  module.exports = exports = {};

  // Your module code ...

});

Мы уже описывали exports и require. Обратите внимание на связь между module.exports и exports. Они указывают на одну и ту же ссылку. Но если вы назначите что-то напрямую для exports, вы прервете его ссылку на module.exports – подробнее об этом в следующем разделе.

Для нашего удобства определены __filename и __dirname. Они предоставляют полный путь к текущему файлу и каталогу. Последний исключает имя файла и печатает путь к каталогу.

Например, для нашего модуля ./circle.js это будет примерно так:

  • __filename : /User/websofter/code/circle.js
  • __dirname : /User/websofter/code

Хорошо, мы рассмотрели exports, require, __filename и __dirname. Единственное, что мы не рассмотрели, это module. Давай сделаем это!

Что использовать module.exports vs. exports ?

Модуль module не является глобальным и является локальным для каждого модуля. Он содержит метаданные о модуле, такие как id, exports, parent, children и так далее.

exports – это псевдоним module.exports. Следовательно, все, что вы назначаете для exports, также доступно в module.exports. Однако, если вы назначите что-то напрямую для экспорта, вы потеряете ярлык для module.exports. Например.

class Cat {
  makeSound() {
    return `${this.constructor.name}: Meowww`;
  }
}

// exports = Cat; // It will not work with `new Cat();`
// exports.Cat = Cat; // It will require `new Cat.Cat();` to work (yuck!)
module.exports = Cat;

Попробуйте следующий случай с exports, а затем с module.exports.

const Cat = require('./cat');

const cat = new Cat();
console.log(cat.makeSound());

Подводя итог, когда использовать module.exports против exports:

Используйте exports для:

  • Экспорт именованной функции. например exports.area, exports.circumference.

Используйте module.exports для:

  • если вы хотите экспортировать объект, класс, функцию на корневом уровне (например, module.exports = Cat)
  • Если вы предпочитаете возвращать один объект, который предоставляет несколько назначений. например module.exports = {area, circumference};

imports – новые возможности импорта модулей

Начиная с версии 8.5.0+, Node.js нативно поддерживает модули ES с флагом функции и новым расширением файла * .mjs.

Например, наш предыдущий circle.js можно переписать как circle.mjs следующим образом:

const PI = 3.14159265359;

export function area(radius) {
  return (radius ** 2) * PI;
}

export function circumference(radius) {
  return 2 * radius * PI;
}

Затем мы можем использовать импорт:

import { area, circumference } from './circle.mjs';

const r = 3;

console.log(`Circle with radius ${r} has
  area: ${area(r)};
  circunference: ${circumference(r)}`);

И, наконец, вы можете запустить его, используя флаг функции экспериментального модуля:

$ node --experimental-modules main.mjs

Если вам не нравятся экспериментальные модули, другой альтернативой является использование транспилятора. Это преобразует современный JavaScript в более старые версии для вас. Хорошими вариантами являются TypeScriptBabel и Rollup.

Устранение неполадок при использовании imports и require

Экспериментальный Флаг

Если вы не используете экспериментальный флаговый узел --experimental-modules и пытаетесь использовать import, вы получите ошибку, подобную этой:

internal/modules/cjs/loader.js:819
  throw new ERR_REQUIRE_ESM(filename);
  ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: bla bla blah
Расширения файлов .mjs vs .js (или .cjs)

Если у вас есть код модуля написан в файле с расширением *.mjs, то вы не можете использовать require, он выдаст ошибку (ReferenceError: require не определен). .mjs предназначен для импорта через imports в соответствии ECMAScript, а .js – для регулярного использования require.

Однако с помощью *.mjs вы можете загружать оба вида модулей!

import { area, circumference } from './circle.mjs';
import Cat from './cat.js';

const r = 3;
console.log(`Circle with radius ${r} has
  area: ${area(r)};
  circumference: ${circumference(r)}`);

const cat = new Cat();
console.log(cat.makeSound());

Обратите внимание, что cat.js использует модули commonJS.

Резюме

Мы узнали о том, как создавать модули Node.js, и использовали этот опыт в нашем коде. Модули позволяют легко повторно использовать код. Они обеспечивают функциональность, которая изолирована от других модулей. Функция require используется для загрузки модулей. exports и module.exports позволяют нам определить, какие части нашего кода мы хотим представить. Мы также исследовали разницу между module.exports и exports. Наконец, мы быстро выбрали, что будет с модулями, использующими imports.