Сборщик Webpack позволяет легко упаковывать приложения JavaScript Node.js, чтобы вы могли быстро развернуть их для запуска везде, где установлен Node.js. Он объединяет и минимизирует файлы JavaScript, а также позволяет упаковывать зависимости.

Когда ваши приложения используют новый, чистый режим JavaScript в драйвере node-oracledb 6.0, «тонкий режим», который взаимодействует напрямую с базой данных Oracle, вы можете эффективно и переносимо распространять свои приложения базы данных, не требуя, чтобы ваши конечные пользователи устанавливали специфичные для платформы двоичные модули или Oracle. Клиентские библиотеки, и ваши пользователи не будут иметь сложностей с настройкой среды.

Использование Webpack с тонким режимом node-oracledb

«Тонкий» режим — это поведение по умолчанию во время выполнения node-oracledb 6.0. Давайте посмотрим на пример приложения Node.js и на то, как его связать.

Создайте проект Node.js:

$ npm init -y
$ npm install oracledb --save

Создайте свое приложение, index.js. Эта простая демонстрация создает таблицу, вставляет несколько строк и запрашивает их обратно из базы данных Oracle:

// index.js

const oracledb = require('oracledb');

if (process.argv.length != 5) {
  console.error('Usage: node ' + process.argv[1] + ' username password connect_string');
  process.exit(1);
}

const dbConfig = { user: process.argv[2], password: process.argv[3], connectString: process.argv[4] };

async function run() {

  const connection = await oracledb.getConnection(dbConfig);

  const stmts = [
    `BEGIN
       EXECUTE IMMEDIATE 'DROP TABLE no_example PURGE';
       EXCEPTION WHEN OTHERS THEN IF SQLCODE <> -942 THEN RAISE; END IF;
     END;`,
    `CREATE TABLE no_example (id NUMBER, data VARCHAR2(20))`
  ];

  for (const s of stmts) {
    await connection.execute(s);
  }

  let result = await connection.executeMany(
    `INSERT INTO no_example VALUES (:1, :2)`,
    [
      [101, "Alpha" ],
      [102, "Beta" ],
      [103, "Gamma" ]
    ],
    {
      bindDefs: [
        { type: oracledb.NUMBER },
        { type: oracledb.STRING, maxSize: 20 }
      ]
    });

  console.log(`Inserted ${result.rowsAffected} rows`);

  result = await connection.execute(
    `SELECT * FROM no_example`,
    [],
    { outFormat: oracledb.OUT_FORMAT_OBJECT }
  );

  console.log("Query results: ");
  console.dir(result.rows, { depth: null });

  await connection.close();
}

run();

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

$ node index.js cj mypw localhost/orclpdb1
Inserted 3 rows
Query results:
[
  { ID: 101, DATA: 'Alpha' },
  { ID: 102, DATA: 'Beta' },
  { ID: 103, DATA: 'Gamma' }
]

Нет другой установки, например. Oracle Instant Client, или для его запуска требовалась внешняя конфигурация. Единственное, что требовалось, это иметь работающую базу данных и знать учетные данные для подключения.

Чтобы упаковать это приложение, установите зависимости Webpack:

$ npm install webpack webpack-cli clean-webpack-plugin --save-dev

Отредактируйте package.json и измените начальную цель «scripts» для запуска Webpack:

"scripts": {
  "start": "webpack --config webpack.config.js"
},

Ваш package.json будет похож на:

{
  "name": "webpack-example-thin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack --config webpack.config.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "oracledb": "^6.0.0"
  },
  "devDependencies": {
    "clean-webpack-plugin": "^4.0.0",
    "webpack": "^5.81.0",
    "webpack-cli": "^5.0.2"
  }
}

В той же директории, что и index.js и package.json, создайте файл webpack.config.js:

const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

const config = {
  entry: './index.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'myapp.js',
  },
  mode: 'production',
  watch: false,
  plugins: [
    new CleanWebpackPlugin(),
  ],
};

module.exports = config;

Я использую плагин clean-webpack, чтобы упростить повторный запуск сборки.

Запустите сборку Webpack:

$ npm start

Вывод будет таким:

> [email protected] start
> webpack --config webpack.config.js

asset myapp.js 313 KiB [emitted] [minimized] (name: main)
runtime modules 88 bytes 1 module
modules by path ./node_modules/oracledb/lib/ 847 KiB
  modules by path ./node_modules/oracledb/lib/thin/ 475 KiB 40 modules
  modules by path ./node_modules/oracledb/lib/*.js 290 KiB 24 modules
  modules by path ./node_modules/oracledb/lib/impl/*.js 80.6 KiB
    ./node_modules/oracledb/lib/impl/index.js 2.09 KiB [built] [code generated]
    + 14 modules
  ./node_modules/oracledb/lib/ sync 160 bytes [built] [code generated]
+ 18 modules

WARNING in ./node_modules/oracledb/lib/oracledb.js 75:100-107
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
 @ ./node_modules/oracledb/index.js 27:0-45
 @ ./index.js 1:17-36

1 warning has detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.83.1 compiled with 1 warning in 1248 ms

Предупреждение «Критическая зависимость» можно игнорировать. Это происходит из-за того, что Webpack не может проанализировать двоичный файл режима Thick, который node-oracledb дополнительно загружает с require(), поэтому Webpack не может увидеть, есть ли какие-либо дополнительные зависимости. Поскольку в демоверсии не используется толстый режим, это предупреждение не является проблемой.

Выходной комплект находится в dist/myapp.js. Этот единственный файл JavaScript содержит как драйвер node-oracledb, так и пример приложения — и весит всего 316 КБ!:

$ ls -lR dist
-rw-r--r--  1 cjones  wheel  320686 24 May 16:41 myapp.js

Чтобы показать, что он содержит код приложения и драйвера, удалите node-oracledb из каталога node_modules:

$ npm uninstall oracledb

Запуск исходного приложения завершится ошибкой:

$ node index.js cj mypw localhost/orclpdb1
node:internal/modules/cjs/loader:1085
  throw err;
  ^
Error: Cannot find module 'oracledb'
. . .

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

$ node dist/myapp.js cj mypw localhost/orclpdb1
Inserted 3 rows
Query results:
[
  { ID: 101, DATA: 'Alpha' },
  { ID: 102, DATA: 'Beta' },
  { ID: 103, DATA: 'Gamma' }
]

Распространять и запускать упакованные приложения node-oracledb очень просто благодаря новому режиму чистого JavaScript «Тонкий» по умолчанию для node-oracledb 6. Пакет небольшой и автономный. Его можно использовать везде, где установлен Node.js.

Использование Webpack с толстым режимом node-oracledb

Если вы хотите использовать какие-либо функции толстого режима в своем приложении, вам нужно будет распространять двоичные файлы толстого режима node-oracledb вместе со связанным кодом JavaScript. Вы можете сделать это с помощью плагина копирования Webpack. Вам также необходимо убедиться, что библиотеки Oracle Client доступны везде, где вы развертываете приложение.

Сначала начните с кода приложения, показанного ранее, и измените его, используя толстый режим. Сделайте это, отредактировав index.js и добавив вызов initOracleClient() после вызова драйвера require():

const oracledb = require('oracledb');

let clientOpts = {};
if (process.platform === 'win32') {                                   // Windows
  clientOpts = { libDir: 'C:\\oracle\\instantclient_19_17' };
} else if (process.platform === 'darwin' && process.arch === 'x64') { // macOS Intel
  clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };
}
oracledb.initOracleClient(clientOpts);  // Enable node-oracledb Thick mode
console.log('Using Thick mode');

. . .

При необходимости измените пути к клиентской библиотеке. Подробности и альтернативы см. в документации по инициализации node-oracledb.

Убедитесь, что node-oracledb и инструменты Webpack установлены:

$ npm install oracledb --save
$ npm install webpack webpack-cli clean-webpack-plugin --save-dev

Package.json «scripts» должен быть:

"scripts": {
  "start": "webpack --config webpack.config.js"
},

Чтобы бинарный файл node-oracledb был скопирован в дистрибутив, установите плагин копирования Webpack:

$ npm install copy-webpack-plugin --save-dev

Обновите (или создайте, если вы не делали предыдущий пример) webpack.config.js, чтобы использовать плагин копирования. Файл должен выглядеть так:

const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

const config = {
  entry: './index.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'myapp.js',
  },
  mode: 'production',
  watch: false,
  plugins: [
    new CleanWebpackPlugin(),
    new CopyPlugin({
      patterns: [{
        // Copy Thick-mode Oracle Database driver binaries to dist
        from: path.resolve(__dirname, 'node_modules/oracledb/build'),
        to: 'node_modules/oracledb/build',
      }],
    })
  ],
};

module.exports = config;

Запустите сборку Webpack:

$ npm start

Вы увидите то же предупреждение «Критическая зависимость», что и в тонком режиме. Это можно игнорировать, потому что единственными зависимостями являются бинарные модули режима node-oracledb Thick, которые будут обрабатываться плагином копирования.

В каталоге dist теперь вы увидите файл myapp.js, который объединяет ваше приложение вместе с кодом JavaScript node-oracledb, а также вы увидите двоичные файлы режима node-oracledb «Толстый»:

$ ls -lR dist
-rw-r--r--  1 cjones  wheel  320934 24 May 16:47 myapp.js
drwxr-xr-x  3 cjones  wheel      96 24 May 16:47 node_modules

dist/node_modules:
drwxr-xr-x  3 cjones  wheel  96 24 May 16:47 oracledb

dist/node_modules/oracledb:
drwxr-xr-x  3 cjones  wheel  96 24 May 16:47 build

dist/node_modules/oracledb/build:
drwxr-xr-x  11 cjones  wheel  352 24 May 16:47 Release

dist/node_modules/oracledb/build/Release:
-rw-r--r--  1 cjones  wheel  519400 24 May 16:47 oracledb-6.0.0-darwin-x64.node
-rw-r--r--  1 cjones  wheel     152 24 May 16:47 oracledb-6.0.0-darwin-x64.node-buildinfo.txt
-rw-r--r--  1 cjones  wheel      41 24 May 16:47 oracledb-6.0.0-js-buildinfo.txt
-rw-r--r--  1 cjones  wheel  612024 24 May 16:47 oracledb-6.0.0-linux-arm64.node
-rw-r--r--  1 cjones  wheel     153 24 May 16:47 oracledb-6.0.0-linux-arm64.node-buildinfo.txt
-rw-r--r--  1 cjones  wheel  589952 24 May 16:47 oracledb-6.0.0-linux-x64.node
-rw-r--r--  1 cjones  wheel     151 24 May 16:47 oracledb-6.0.0-linux-x64.node-buildinfo.txt
-rw-r--r--  1 cjones  wheel  590848 24 May 16:47 oracledb-6.0.0-win32-x64.node
-rw-r--r--  1 cjones  wheel     151 24 May 16:47 oracledb-6.0.0-win32-x64.node-buildinfo.txt

Вам нужно будет раздать все эти файлы вашим конечным пользователям, при желании опуская *.node исполняемые файлы для платформ, в поддержке которых вы не заинтересованы. Файлы buildinfo содержат тег сборки, который полезен для нас как сопровождающих, если вы сообщаете о проблемах с драйверами, но файлы также могут быть опущены, если хотите. Вы должны будете отдельно убедиться, что у всех, кто использует ваше приложение, установлены библиотеки Oracle Client, и они находятся в месте, которое может найти вызов приложения initOracleClient(). Для этого существуют различные способы для конкретных платформ: см. документацию по node-oracledb по инициализации.

Краткое содержание

Webpack — это удобный способ упаковки приложений Node.js для развертывания. Благодаря тонкому режиму node-oracledb 6.0 ваши упакованные приложения базы данных Oracle имеют небольшой размер и легко развертываются: без зависимости от клиентских библиотек Oracle и без связанных с этим сложностей поиска библиотек. Всего за несколько сотен килобайт вы можете получить эффективное, быстрое и функциональное приложение, которое может подключаться к базе данных Oracle из любой поддерживаемой установки Node.js.

Ресурсы

Домашняя страница: https://oracle.github.io/node-oracledb/

Установка: https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html

Документация: https://node-oracledb.readthedocs.io/ru/latest/

Вопросы: https://github.com/oracle/node-oracledb/discussions/

Исходный код: https://github.com/oracle/node-oracledb

Репозиторий Npm: https://www.npmjs.com/package/oracledb