Разработка решений на платформе ELMA365 / Серверные зависимости пакетов npm

Серверные зависимости пакетов npm

В ELMA365 On-Premises вы можете подключать серверные зависимости в скриптах виджетов и пользовательских модулей. Это позволит решить ряд специфичных задач при разработке без написания своего микросервиса. Для этого используйте экосистему npm-пакетов при разработке серверных скриптов. Например, можно использовать пакет XLSX для чтения данных из excel-файла с помощью команд:

import * as XLSX from 'xlsx';
 
const url = await Context.data.file.getDownloadUrl();
const req = await fetch(url);
const data = await req.arrayBuffer();
 
const workbook = XLSX.read(data);
const sheets = workbook.Sheets;
const cellValue = sheets['List1']['A1'].v;
 

начало внимание

Подключение серверных зависимостей пакетов npm доступно только в ELMA365 On-Premises.

конец внимание

Чтобы собрать npm-пакет с зависимостями, упакуйте готовую папку node_modules и файл package.json в архив с названием dependencies.tar.gz. Подробнее о том, как это сделать, читайте ниже:

Для работы установите Docker.

Сборка пакета с серверными зависимостями с помощью Shell-скрипта для Linux, macOS

  1. Создайте пустую папку на своём компьютере. Скопируйте приведённый ниже скрипт и сохраните его как файл с названием makedeps.sh в созданной папке:

rm -rf ./deps
docker run -v `pwd`:/data -w /data/deps --platform linux/amd64 --rm node:14.16.0-alpine /bin/sh -c "npm init -y && npm i $*"
docker run -v `pwd`:/data -w /data --platform linux/amd64 --rm busybox tar -zcf dependencies.tar.gz -C /data/deps node_modules package.json
rm -rf ./deps

  1. Через консоль разработчика найдите сохранённый файл и сделайте его исполняемым:

$chmod 755 makedeps.sh

  1. Запустите скрипт, передав в качестве параметров список npm-пакетов. Например, для пакета XLSX:

$./makedeps.sh xlsx semver

В результате выполнения команды сформируется архив с зависимостями dependencies.tar.gz.

  1. Загрузите пакет в систему. Это можно сделать в настройках виджета в дизайнере интерфейсов и в пользовательском модуле при создании метода API: добавьте полученный архив с зависимостями на вкладке Файлы.

Упакованные серверные зависимости можно использовать в коде серверного скрипта.

Сборка пакета с серверными зависимостями помощью PowerShell-скрипта для Windows

  1. Создайте пустую папку на своём компьютере. Скопируйте приведённый ниже скрипт и сохраните его как файл с названием makedeps.ps1 в созданной папке:

$ErrorActionPreference = "SilentlyContinue" #This will hide errors
Remove-Item -Recurse -Force .\deps
$ErrorActionPreference = "Continue" #Turning errors back on
docker run -v ${PWD}:/data -w /data/deps --platform linux/amd64 --rm node:14.16.0-alpine /bin/sh -c "npm init -y && npm i $args"
docker run -v ${PWD}:/data -w /data --platform linux/amd64 --rm busybox:stable tar -zcf dependencies.tar.gz -C /data/deps node_modules package.json
Remove-Item -Recurse -Force .\deps

  1. Запустите скрипт, передав в качестве параметров список npm-пакетов. Например, для пакета XLSX:

$./makedeps.ps1 xlsx semver

В результате выполнения команды сформируется архив с зависимостями dependencies.tar.gz.

  1. Загрузите пакет в систему. Это можно сделать в настройках виджета в дизайнере интерфейсов и в пользовательском модуле при создании метода API: добавьте полученный архив с зависимостями на вкладке Файлы.

Упакованные серверные зависимости можно использовать в коде серверного скрипта.

Особенности подключения модулей

Обратите внимание на особенности импорта компонентов при подключении модулей.

В пользовательских скриптах

можно импортировать:

нельзя импортировать:

  • модули из package.json (раздел dependencies).
  • транзитивные зависимости;
  • модули хоста (по отношению к worker);
  • встроенные модули node.js (fs, path, tty и т. д.).

Внутри внешних модулей импортируемых в скрипте

можно импортировать:

нельзя импортировать:

  • любые другие модули, присутствующие в директории с зависимостями;
  • встроенные модули node.js (fs, path, tty и т. д.).
  • модули хоста (по отношению к worker).

Компиляция TypeScript на сервере выполняется со следующими параметрами tsconfig:

{
    allowJs: true,
    checkJs: false,
    declaration: false,
    module: "commonjs",
    moduleResolution: "node",
    noImplicitAny: true,
    strictNullChecks: true,
    stripInternal: true,
    skipDefaultLibCheck: true,
    target: "ES2017",
    typeRoots: ['node_modules/@types', 'node_modules'],
    lib: ['es2016']
}

Обратите внимание, не все npm-пакеты работают с такими параметрами без изменений. Возможно, вам понадобится обернуть их в тонкую прослойку, совместимую с CommonJS или AMD.

Поддерживаемые модульные системы JavaScript

В качестве серверных зависимостей вы можете использовать модули на основе двух модульных систем JavaScript: CommonJS и UMD (Universal Module Definition).

Примеры импорта модуля

На примере модуля CommonJS рассмотрим, как его импортировать.

Допустим, модуль содержит одну функцию и одну константу:

function add(a, b) {
 return a + b;
}
 
const name = 'noname'
 
module.exports = {
 add,
 name
}

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

// 1 named import
 
import { add, name } from 'module_name';
 
async function test(): Promise<void> {
   Context.data.res = add(1, 3);
   Context.data.text = name;
}
 
// 2 namespace import
 
import * as m from 'module_name';
 
async function test(): Promise<void> {
   Context.data.res = m.add(1, 3);
   Context.data.text = m.name;
}
 
// 3 alias import
 
import { add as plus } from 'module_name';
 
async function test(): Promise<void> {
   Context.data.res = plus(1, 3);
}

Часто документация к модулям содержит примеры, которые используют импорт с помощью require. Вместо него вы можете применить namespace import, как во втором примере выше:

var m = require('module_name');
m.example();
 
...
 
import * as m from 'module_name';
m.example();