Создать исполняемый файл для проекта NodeJS с архитектурой MERN

#node.js #reactjs #express #mern #zeit-pkg

#node.js #reactjs #экспресс #mern #дух времени-pkg

Вопрос:

** Смотрите РЕДАКТИРОВАНИЕ ниже **

Я создал простое приложение MERN (Mongo, Express, React, NodeJS), чтобы сформировать основу проекта. Я изучаю возможные способы создания исполняемых файлов для развертывания после завершения приложения. Исполняемые файлы должны быть созданы для нескольких операционных систем и архитектур.

Приложение соответствует серверной части NodeJS, на которой запущен веб-сервер Express с доступом к экземпляру MongoDB (на самом деле это NeDB, но я просто назвал его Mongo для простоты), а интерфейс создается с помощью React.

Я пробовал использовать PKG и кратко ознакомился с nexe, и, похоже, любой из этих инструментов должен предоставить мне решение.

Однако из-за файловой структуры моего проекта у меня возникают некоторые проблемы. Моя структура папок для моего приложения выглядит следующим образом:

 /
/server
....<express files>
....package.json
/client
....<react files>
....package.json
package.json
  

Причина такой структуры папок заключается в том, чтобы позволить моему приложению запускать как серверные, так и клиентские приложения npm start из корневого каталога. Это делается с помощью package.json файла корневой папки, который имеет следующее содержимое:

 {
  "name": "MyApplication",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" amp;amp; exit 1",
    "client": "cd client amp;amp; npm start",
    "server": "cd server amp;amp; npm start",
    "start": "concurrently "npm run server" "npm run client" --kill-others"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "concurrently": "3.5.1"
  },
  "pkg": {
    "assets": [
      "client/*",
      "server/*"
    ]
  }
}
  

По сути, я пытаюсь создать исполняемый файл, который имитирует поведение при запуске npm start из корня. Исполняемый файл должен запускать серверные службы в server каталоге, а также должен выполнять код React в client каталоге.

Как вы можете видеть, я пытался добавить некоторые параметры в pkg , но, похоже, это не работает.

Есть ли способ настроить PKG или любой другой подобный инструмент для создания того, что я ищу? Или мне нужно будет иметь отдельный исполняемый файл как для сервера, так и для клиента? В идеале я бы хотел просто один файл.

Заранее спасибо.

** РЕДАКТИРОВАТЬ **

Я наткнулся на следующее шаблонное приложение, которое, по сути, достигает того, что я ищу:https://github.com/crsandeep/simple-react-full-stack

Тем не менее, я изо всех сил пытаюсь заставить его работать с PKG. Мне удалось успешно сгенерировать .exe файл, но, к сожалению, когда я загружаю корневую страницу в браузере (localhost: 8080), появляется сообщение об ошибке, Cannot GET / но пример вызова API работает нормально.

Я предполагаю, что это связано с тем, что в моем package.json файле чего-то не хватает, но, похоже, я не могу с этим разобраться. Без запуска приложения с использованием PKG оно работает нормально.

Вот дополнения к package.json файлу, которые я сделал:

 "pkg": {
    "scripts": "./dist/bundle.js",
    "assets": [
      "./dist/index.html",
      "./dist/favicon.ico"
    ]
  },
  "bin": "src/server/index.js"
  

Который я затем запускаю PKG со следующей инструкцией (из того же каталога, что и package.json )

 pkg . --target node10-win-x64 --out-dir ../
  

Я пробовал много разных комбинаций элементов в package.json , но, похоже, у меня не получается сделать это правильно.

У кого-нибудь есть решение для этого?

Комментарии:

1. Я думаю, вы здесь немного запутались. Для производства вы хотите, чтобы ваш сервер передавал ваши ресурсы в браузер, который будет автоматически выполнять Javascript. Итак, вам нужен какой-то связанный артефакт для вашего интерфейсного кода, а затем запустите серверный код на серверной части. Не должно быть необходимости запускать приложение React отдельно.

2. Спасибо за ваш вклад @Marcus. С тех пор, как я опубликовал этот вопрос, я изучал это, и я думаю, что лучшим решением для моего проекта будет перейти на рендеринг на стороне сервера, чтобы включить единую точку входа в мое приложение

3. Привет @Marcus, я изучал потенциальные решения моей проблемы, и, похоже, мне трудно найти решение, которое будет работать с PKG. Я ни в коем случае не эксперт по NodeJS, поэтому мог бы воспользоваться некоторой помощью в поиске решения. Есть ли шанс, что вы могли бы указать мне способ реализовать ваше предложение, которое будет работать с PKG? Спасибо.

4. Я действительно думаю, что лучше всего было бы для вас вернуться к основам и узнать об отношениях клиент / сервер и о том, что связано с публикацией веб-сайта. Взгляните на документы MDN: developer.mozilla.org/en-US/docs/Learn /…

5. Спасибо @Marcus, я освежу этот материал. Я создавал веб-приложения раньше, и я довольно хорошо знаком с общим процессом публикации веб-сайтов. Это больше касается разработки способа использования Express и React в одном приложении с единой точкой входа, чтобы его можно было упаковать в исполняемый файл, который можно развернуть. Независимо от того, использует ли это SSR или другую архитектуру. Это основная область, в которой я борюсь

Ответ №1:

Мне удалось сделать так, чтобы код boiler plate, который я получил отhttps://github.com/crsandeep/simple-react-full-stack теперь его можно сгенерировать как исполняемый файл с помощью PKG.

Я был очень близок к тому, чтобы заставить его работать в моем редактировании вопроса, но вот полное решение:

Убедитесь, что package.json содержит следующее:

 "pkg": {
  "scripts": "./dist/bundle.js",
  "assets": [
    "./dist/index.html",
    "./dist/favicon.ico"
  ]
},
"bin": "src/server/index.js"
  

Затем в src/server/index.js файле измените строку, которая гласит:

 app.use(express.static('dist'));
  

Для:

 const path = require('path');
app.use(express.static(path.join(__dirname, '../../dist')));
  

Затем необходимые файлы будут помещены в каталог dist с помощью package.json файла, а затем использование path.join(__dirname гарантирует, что он ищет их в нужном месте.