Библиотека jsrsasign распространяется в виде UMD-модуля и ориентирована на работу как в браузере, так и в Node.js, однако при использовании современных сборщиков модулей возникают специфические сложности, связанные с устаревшими предположениями о среде выполнения и отсутствием нативных Node.js-полифиллов в Webpack 5 и Rollup 3+.
jsrsasign содержит реализацию криптографических алгоритмов (RSA, ECDSA, SHA, HMAC, X.509) полностью на JavaScript. Это делает её независимой от WebCrypto API, но одновременно приводит к следующим особенностям:
При подключении через современные сборщики это требует явной настройки совместимости.
Основные сложности при интеграции:
В результате библиотека может либо не собираться, либо увеличивать итоговый bundle значительно сильнее ожидаемого.
npm install jsrsasign
Простейший импорт:
import KJUR from 'jsrsasign';
или более точечный:
import { KEYUTIL, KJUR } from 'jsrsasign';
Однако в большинстве случаев UMD-структура приводит к загрузке всей библиотеки.
Webpack 5 не предоставляет автоматические полифиллы Node.js, поэтому необходимо вручную добавить зависимости:
npm install crypto-browserify stream-browserify buffer process
Конфигурация webpack:
const webpack = require('webpack');
module.exports = {
resolve: {
fallback: {
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
buffer: require.resolve('buffer/'),
process: require.resolve('process/browser')
}
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser'
})
]
};
jsrsasign не использует WebCrypto напрямую, но внутри некоторых операций может ожидаться наличие криптографических примитивов Node.js. При использовании браузерного бандла критично обеспечить корректную подмену окружения.
Если требуется уменьшить размер сборки, часто используют альтернативный подход:
module.exports = {
externals: {
jsrsasign: 'jsrsasign'
}
};
В этом случае библиотека подключается через CDN:
<script src="https://cdn.jsdelivr.net/npm/jsrsasign/lib/jsrsasign-all-min.js"></script>
Rollup требует более явной конфигурации для CommonJS-зависимостей, так как jsrsasign не поставляется как ESM-модуль.
npm install @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-replace
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm',
sourcemap: true
},
plugins: [
resolve({
browser: true,
preferBuiltins: false
}),
commonjs(),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify('production')
})
]
};
При использовании Rollup важно отключить попытки подтянуть Node core modules:
resolve({
browser: true,
preferBuiltins: false
})
В некоторых случаях дополнительно требуется ручная заглушка:
export default {
plugins: [
resolve(),
commonjs(),
replace({
'global.Buffer': 'Buffer',
preventAssignment: true
})
]
};
jsrsasign изначально довольно тяжёлая библиотека, поэтому важны способы ограничения объёма включаемого кода.
Вместо полного объекта:
import KJUR from 'jsrsasign';
предпочтительнее точечные импорты:
import KEYUTIL from 'jsrsasign/lib/keyutil';
import KJUR from 'jsrsasign/lib/jsrsasign';
Однако структура пакета не всегда гарантирует стабильные пути, поэтому требуется проверка конкретной версии библиотеки.
При использовании CDN-версии:
externals: {
jsrsasign: 'KJUR'
}
и подключение:
<script src="https://cdn.jsdelivr.net/npm/jsrsasign/lib/jsrsasign-all-min.js"></script>
Такой подход полностью убирает библиотеку из бандла.
Rollup по умолчанию обеспечивает tree-shaking, но только при ESM-совместимых модулях. Так как jsrsasign CommonJS-ориентирован, реальная оптимизация ограничена, и чаще используется terser:
npm install @rollup/plugin-terser
import terser from '@rollup/plugin-terser';
plugins: [
terser()
]
Возникает при отсутствии полифилла:
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer']
});
Исправляется через fallback:
crypto: require.resolve('crypto-browserify')
Решается подключением:
@rollup/plugin-commonjs
или настройкой Webpack:
module: {
rules: [
{
test: /\.js$/,
type: 'javascript/auto'
}
]
}
Причина обычно в полном импорте:
import * as jsrsasign from 'jsrsasign';
Это подтягивает всю библиотеку, включая RSA, ECDSA, ASN.1 и вспомогательные утилиты.
Более контролируемый вариант требует прямого импорта конкретных модулей или использования CDN.
При работе с современными ES-модулями важно учитывать, что jsrsasign остаётся CommonJS-библиотекой. Это приводит к необходимости интеропа:
import jsrsasignPkg from 'jsrsasign';
const { KJUR } = jsrsasignPkg;
или через динамический импорт:
const jsrsasign = await import('jsrsasign');
В некоторых сборках это уменьшает проблемы с tree-shaking, но не устраняет их полностью.
Webpack чаще скрывает проблемы за polyfill-слоем, тогда как Rollup требует явной декларации каждого внешнего модуля. Это приводит к следующему различию поведения:
При использовании jsrsasign это различие становится особенно заметным из-за его монолитной структуры и отсутствия ESM-разделения