В группе пользователей ThinkJS разработчики часто выдвигают необходимость шифрования и защиты исходного кода. Мы знаем, что JavaScript — это динамический язык, в отличие от других статических языков, которые можно компилировать в бинарные пакеты для предотвращения утечки исходного кода. Так оно и появилосьpkg,nexeТакие инструменты поддерживают упаковку JS-кода вместе с Node в исполняемый файл, что, во-первых, решает проблему зависимости от окружения, а во-вторых, решает волнующую всех проблему защиты исходного кода.
существуетpkgВ README модуля перечислены несколько основных его применений.Если у вас есть следующие требования, рекомендуется попробовать его.
- Предоставление коммерческих дистрибутивов для приложений без раскрытия исходного кода
- Предоставьте демонстрацию приложения, не раскрывая исходный код
- Упаковка всех исполняемых файлов платформы одним щелчком мыши без необходимости в соответствующих зависимостях от среды платформы.
- Предлагает самоизвлекающиеся или самоустанавливающиеся решения
- Запуск приложения не требует установки Node.js и npm.
- Для развертывания требуется только один файл, не нужно устанавливать множество зависимостей через npm.
- После упаковки ресурсов приложение удобнее мигрировать
- Протестировать приложение под указанной версией Node.js без установки соответствующей версии
как пользоваться
Об основном использовании модуля pkg вы можете узнать«Запускайте свои программы NodeJS для людей, у которых нет NodeJS»Эта статья. пройти черезnpm install -g pkg
После того, как модуль установлен глобально, его можно использовать из командной строки.pkg
заказ.pkg
В дополнение к поддержке указания параметров в командной строке, он также поддерживаетpackage.json
в конфигурации.
{
...
"bin": "production.js",
"scripts": {
"pkg": "pkg . --out-path=dist/"
},
"pkg": {
"scripts": [...]
"assets": [...],
"targets": [...]
},
...
}
Выше приведена простая конфигурация.bin
Используется для указания окончательного упакованного файла записи,pkg.scripts
а такжеpkg.assets
Используется для указания того, что необходимо упаковать в исполняемый файл в дополнение к файлу входа, где первый используется для указания других.js
файл, последний используется для указания не-.js
ресурс из.pkg.targets
Он используется для указания платформы, которую необходимо упаковать.Структура имени платформы выглядит следующим образом:node${version}-${platform}-${arch}
.version
Используется для указания версии конкретного узла,platform
Используется для указания платформы компиляции, может бытьfreebsd
, linux
, alpine
, macos
илиwin
,наконецarch
Используется для указания архитектуры платформы компиляции, которую можноx64
, x86
, armv6
илиarmv7
. Напримерnode10-macos-x64
На базе Node 10 представлена упакованная исполняемая программа, исполняемая на платформе MacOS.scripts
, assets
а такжеtargets
Оба поддерживают несколько конфигураций массива.
После настройки входного файла, зависимых сценариев и ресурсов, а также платформы для компиляции выполнитеnpm run pkg
для завершения компиляции.
Как упаковать ThinkJS
pkg
Принцип, вероятно, состоит в том, чтобы предоставить виртуальную файловую систему, которая будет__filename
, __dirname
и другие переменные, а метод операции ввода-вывода в официальном API, который указывает на локальную файловую систему, изменен, чтобы указывать на виртуальную систему. Сжатый и упакованный исходный код программы считывается через виртуальную файловую систему, чтобы обеспечить среду для выполнения сценария. Следует отметить, что виртуальная файловая система доступна только для чтения, поэтому, если программа имеет__dirname
Следует избегать метода выполнения операций чтения и записи.
предварительная обработка кода
В проекте ThinkJS будет два следующих места для операций записи файлов:
- После запуска проекта будет
runtime/config/${env}.json
Запишите окончательный файл конфигурации под - По умолчанию в производственной среде
logs/
Запись онлайн-журналов в каталог
Эти каталоги по умолчанию основаны на текущей папке проекта, поэтому их следует избегать, основываясь на предыдущей теории.pkg
изREADMEскажи намprocess.cwd()
Он по-прежнему будет указывать на реальную среду, поэтому мы можем изменить расположение указанного выше каталога наprocess.cwd()
Для решения этой проблемы.
//pkg.js
const path = require('path');
const Application = require('thinkjs');
const instance = new Application({
//在启动文件中可以自定义配置 runtime 目录
RUNTIME_PATH: path.join(process.cwd(), 'runtime'),
ROOT_PATH: __dirname,
proxy: true,
env: 'pkg',
});
instance.run();
на основеproduction.js
мы создаем новыйpkg.js
Файл запуска, который определяет проект после запускаRUNTIME_PATH
путь, иenv
назначить какpkg
, что удобно передать в последующей конфигурацииthink.env === 'pkg'
для переключения конфигурации.
//src/config/adapter.js
const {Console, DateFile} = require('think-logger3');
const isDev = think.env === 'development';
const isPkg = think.env === 'pkg';
exports.logger = {
type: isDev ? 'console' : 'dateFile',
console: {
handle: Console
},
dateFile: {
handle: DateFile,
level: 'ALL',
absolute: true,
pattern: '-yyyy-MM-dd',
alwaysIncludePattern: true,
filename: path.join(isPkg ? process.cwd() : think.ROOT_PATH, 'logs/app.log')
}
};
В конфигурации адаптера мы основываем оригиналthink.ROOT_PATH
Путь изменен, чтобы основываться наprocess.cwd()
. В дополнение к службам журнала, если есть служба, такая как кеш и сеанс, если она также основана на хранилище файлов, им также необходимо изменить соответствующую конфигурацию хранилища файлов. Конечно, это некоторые из сервисов, поставляемых с THINKJS, если вы используете какие-то другие сервисы в своем проекте или вам нужно изменить файл в своей бизнес-логике.
Конфигурация упаковки
После того, как операция записи проекта будет предотвращена, мы можем нормально настроить pkg, а затем упаковать его. Простая конфигурация модуля pkg выглядит так:
//package.json
{
"bin": "pkg.js",
"pkg": {
"assets": [
"src/**/*",
"view/**/*",
"www/**/*"
],
"targets": [
"node10-linux-x64",
"node10-macos-x64",
"node10-win-x64"
]
}
}
Здесь мы указываемpkg.js
Для упакованного входного файла укажите необходимость компиляцииlinux
, macos
, win
Исполняемые скрипты для трех платформ, при указанииsrc/
, view/
, www/
Три каталога упакованы как ресурс. Это связано с тем, что ThinkJS — это проект с динамическими требованиями, и конкретная бизнес-логика загружается в виде чтения файлов путем обхода файлового каталога во время выполнения.pkg
Для упаковки модуля эти зависимости не могут быть известны во время компиляции, поэтому их необходимо упаковать как «ресурсы» зависимостей запуска.
После настройки выполните его прямо в каталоге проекта.pkg .
, если все в порядке, вы должны увидеть три исполняемых файла в текущем каталоге и напрямую выполнить двоичный файл соответствующей платформы для запуска службы.
➜ www.thinkjs.org git:(master) npm run pkg-build
> thinkjs-official@1.2.0 pkg-build /Users/lizheming/workspace/thinkjs/www.thinkjs.org
> pkg ./ --out-path=dist
> pkg@4.4.0
➜ www.thinkjs.org git:(master) ✗ ls -alh dist
total 577096
drwxr-xr-x 5 lizheming staff 160B 12 28 17:35 .
drwxr-xr-x@ 30 lizheming staff 960B 12 28 17:34 ..
-rwxr-xr-x 1 lizheming staff 87M 12 28 17:34 thinkjs-official-linux
-rwxr-xr-x 1 lizheming staff 87M 12 28 17:35 thinkjs-official-macos
-rw-r--r-- 1 lizheming staff 82M 12 28 17:35 thinkjs-official-win.exe
➜ www.thinkjs.org git:(master) ✗
постскриптум
После того, как проект запакован, есть проблема, что нельзя модифицировать конфигурацию, если есть необходимость в динамической настройке, то это не очень удобно. Вот две идеи решения этой проблемы:
- Динамическая конфигурация настраивается в переменной среды, и программа перезаписывает конфигурацию по умолчанию, считывая переменную среды.
- Используйте ThinkJS
beforeStartServer()
Хук считывает файл конфигурации в реальном каталоге для охвата конфигурации перед запуском.//pkg.js const path = require('path'); think.beforeStartServer(() => { const configFile = path.join(process.cwd(), 'config.js'); const config = require(configFile); think.config(config); });
Кроме того, по мере увеличения сложности проекта в дело может быть введено большое количество сторонних модулей. Предыдущая статья решает только проблему динамического импорта самого проекта ThinkJS.Если импортируемые сторонние модули также динамически импортируются, их также необходимоpkg.assets
Он указан в окне конфигурации. Существует также для модулей C++,pkg
В настоящее время нет возможности добиться автоматического введения, а также необходимоpkg.assets
Укажите зависимые ресурсы в .
//package.json
{
"pkg": {
"assets": [
//以 node-sqlite3 模块为例
"node_modules/sqlite3/lib/binding/node-v64-darwin-x64/node_sqlite3.node"
]
}
}
вnode-v64-darwin-x64
Имена могут не совпадать в зависимости от платформы. нельзя импортировать.node
Причина для модуля в том, что модуль C++ установлен черезnode-gyp
Выполнение динамической компиляции, зависящей от платформы. То есть характеристика иpkg
Тот факт, что модули могут упаковывать бинарные пакеты для всех платформ на одной платформе, в конце концов является конфликтомpkg
Также нет возможности компилировать модули для платформы Windows на платформе Mac. Так что в этом случае помимо необходимости вручную импортировать скомпилированный.node
В дополнение к модулю, вам также нужно обратить внимание на введение.node
модули иpkg.targets
Соответствие указанной платформе компиляции.
Получать.node
Помимо установки модулей на соответствующую платформу, вы также можете загрузить скомпилированные модули, предоставленные другими учащимися. Исходный код Taobao предоставляет скомпилированные результаты многих двоичных модулей дляnode-sqlite3
Например, все его скомпилированные модули можно найти вЕжегодный рейтинг Taobao.org/mirrors/SQL…Скачать здесь и выбрать соответствующую версию и платформу самостоятельно.
Конфигурация упаковки, упомянутая в этой статье, ужеОфициальный сайт ThinkJSРеализовано в проекте, студенты, которые хотят попробовать, могут напрямую клонировать проект официального сайта и выполнять его после установки зависимостей.npm run pkg-build
доступны наdist/
каталог для получения двоичных исполняемых файлов.