Перейти к основному содержимому

Импорт

Введение​

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

Поэтому мы выносим полезный код в отдельный файл, который могут импортировать другие файлы, легко повторно используя его.

Здесь будут показаны некоторые решения, которые предлагает Netuno для повторного использования кода.

Полиглотное ядро​

В любом языке программирования, поддерживаемом Netuno, можно импортировать любой файл кода, находящийся в папке server/core приложения.

Упрощённый способ, который предлагает Netuno, — использовать специальный формат комментария для импорта кода: у комментированной строки есть префикс _core:, а затем указывается путь к файлу кода относительно папки server/core приложения.

Итак, чтобы импортировать файл кода:

  • server/core/exemplo/arquivo

Файл должен иметь расширение в соответствии с используемым языком программирования.

Можно импортировать другой файл в начале любого файла кода, например, в сервисах.

В случае JavaScript, Groovy и Kotlin:

// _core: exemplo/arquivo

...

В случае Python и Ruby:

# _core: exemplo/arquivo

...

В этом специальном комментарии импорта не нужно указывать расширение файла — Netuno определяет его автоматически.

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

Чтобы импортировать несколько файлов, достаточно повторить комментарий импорта с путями других файлов.

В случае JavaScript, Groovy и Kotlin, чтобы импортировать несколько файлов:

// _core: exemplo/arquivo1
// _core: exemplo/arquivo2
// _core: exemplo/arquivo3

...

В случае Python и Ruby, чтобы импортировать несколько файлов:

# _core: exemplo/arquivo1
# _core: exemplo/arquivo2
# _core: exemplo/arquivo3

...

Ресурс Exec​

С помощью ресурса _exec можно импортировать код в любой момент во время выполнения.

Переменные, константы, функции, классы и т. д., объявленные в импортированном файле кода, могут использоваться.

core​

Чтобы программно выполнить импорт файла кода, в данном случае из папки 📁 server/core:

_exec.core('путь/к/файлу')

Не нужно указывать расширение файла — Netuno определяет его автоматически.

services​

Чтобы программно выполнить импорт файла кода, в данном случае из папки 📁 server/services:

_exec.service('путь/к/файлу')

Не нужно указывать расширение файла — Netuno определяет его автоматически.

JavaScript​

Netuno создаёт основу для разработки на JavaScript — самом используемом языке, особенно потому что на JavaScript можно программировать как фронтенд, так и бэкенд, что позволяет вести full-stack-разработку, используя один и тот же язык программирования.

Netuno анализирует код и автоматически определяет, используется ли import (ECMAScript Modules) или require (CommonJS).

Не следует смешивать шаблон import с require; нужно использовать что-то одно.

Благодаря этому в файлах кода всегда можно использовать расширение .js, а при использовании инструкций с import Netuno будет обрабатывать их как ECMAScript Modules, и тогда можно использовать export default.

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

Импорт кода​

При использовании нативного импорта, в отличие от предыдущих примеров, будет импортировано только то, что явно экспортировано, в соответствии со стандартом CommonJS (require) или ECMAScript Modules (import).

В папке 📁 server находится файл package.json, в нём должна быть следующая инструкция:

...
"imports": {
"#actions/*": {
"default": "./actions/*"
},
"#components/*": {
"default": "./components/*"
},
"#core/*": {
"default": "./core/*"
},
"#reports/*": {
"default": "./reports/*"
},
"#services/*": {
"default": "./services/*"
},
"#setup/*": {
"default": "./setup/*"
},
"#templates/*": {
"default": "./templates/*"
}
},
...

Благодаря этому можно импортировать любой файл в любой другой файл кода, например:

server/services/профиль/get.js
import профиль from "#core/lib/профиль.js";

const профильБД = профиль.получитьТекущий();

Поскольку используется import, в импортируемом файле будет использоваться export default:

server/core/lib/профиль.js
import {_db, _user} from "@netuno/server-types";

export default {
получитьТекущий: () => {
return _db.form("профиль")
.where(_db.where("профиль_id_пользователя").equal(_user.id))
.first();
}
};

Не рекомендуется в одном и том же приложении или проекте смешивать использование import (ECMAScript Modules) и require (CommonJS) даже в разных файлах и разных ситуациях; предпочтительно всегда придерживаться единообразной стандартизации. Рекомендуем использовать import, так как это современный метод.

В качестве альтернативы, если используется require (CommonJS) вместо import (ECMAScript Modules):

server/services/профиль/get.js
const профиль = require("#core/lib/профиль.js");

const профильБД = профиль.получитьТекущий();

Поскольку используется require, в импортируемом файле будет использоваться module.exports:

server/core/lib/профиль.js
const {_db, _user} = require("@netuno/server-types");

module.exports = {
получитьТекущий: () => {
return _db.form("профиль")
.where(_db.where("профиль_id_пользователя").equal(_user.id))
.first();
}
};

Автодополнение и проверка кода​

Чтобы получить автодополнение кода со встроенной проверкой в редакторах, в папке 📁 server приложения нужно установить Типы сервера.

Типы сервера (@netuno/server-types) — это определение всех возможностей полиглотного low-code-программирования на TypeScript, что позволяет редакторам обнаруживать всё, что предлагает полиглотный low-code-фреймворк Netuno; но, поскольку это TypeScript, они служат только для помощи в коде на JavaScript.

Внутри папки 📁 server установите Типы сервера:

bun add @netuno/server-types

После этого в обычном коде можно импортировать любую из доступных возможностей полиглотного low-code фреймворка Netuno, например, этот код сервиса:

import {_req, _db, _out, _val} from "@netuno/server-types";

const имя = _req.getString("имя");

_db.form("товар")
.set("имя", имя)
.insert();

_out.json(
_val.map()
.set("имя", имя)
.set("результат", true)
);

Обратите внимание, что редактор будет проверять и дополнять код, что чрезвычайно полезно и значительно ускоряет разработку.

В некоторых редакторах может потребоваться настройка/активация, чтобы папка 📁 server определялась как корень кода: например, Visual Studio Code определяет это автоматически, а в WebStorm нужно щёлкнуть правой кнопкой мыши по папке server, выбрать Mark Directory As > Resource Root и заново открыть проект.

JS и NPM — внешние зависимости​

Внутри папки 📁 server приложения, где находится package.json, можно устанавливать внешние зависимости из NPM.

Однако, в отличие от того, что мы рекомендовали ранее, для импорта внешних библиотек мы используем require, и в этом случае можно смешивать его с import внутренних файлов проекта — это не очень элегантно, но возможно.

Итак, чтобы добавить зависимость, достаточно установить её командой bun add.

Например, можно установить momentjs:

  • bun add moment

Для импорта зависимостей используется require, пример:

import {_out} from "@netuno/server-types";
const moment = require('moment')
_out.json(moment().format())

Ещё один пример с dayjs, сначала установите:

  • bun add dayjs
import {_out} from "@netuno/server-types";
const dayjs = require("dayjs");
_out.json(dayjs().format());

Полный пример с использованием date-fns, сначала установите:

  • bun add date-fns
import {_out} from "@netuno/server-types";

import профиль from "#core/lib/профиль.js";

const профильБД = профиль.получитьТекущий();

const { formatDistance, subDays } = require('date-fns');

_out.println(formatDistance(
subDays(new Date(), 3), new Date(), { addSuffix: true }
));

Зависимость от внешних библиотек — исключительные ситуации; обычно всё необходимое есть в полиглотном low-code-фреймворке Netuno.

Нативные модули NodeJS​

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

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

Ниже приведён список модулей, используемых как альтернативы для замены нативных модулей NodeJS, и соответствующие команды установки:

  • Buffer: bun add buffer
  • Events: bun add events
  • Util: bun add util
  • Path: bun add path-browserify
  • Stream: bun add stream-browserify
  • HTTP: bun add http-browserify
  • HTTPS: bun add https-browserify

Помните: эти модули выше нужно устанавливать в папку 📁 server внутри приложения; обеспечивается совместимость с нативными модулями NodeJS за счёт использования этих альтернативных модулей.

Заключение​

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

Чем больше строк кода, тем выше вероятность ошибок.

Помните: хорошо организуйте код и централизуйте его повторное использование — это облегчает сопровождение, предотвращает ошибки и в целом повышает производительность.

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

Тем временем Netuno предлагает множество полиглотных low-code-ресурсов, которые покрывают большинство потребностей.