首先,感谢您阅读我的问题。这是我第一次使用 stackoverflow,我对可以帮助我的答案进行了大量研究。
语境
我正在开发一个用作 CMS 的 Meteor 应用程序,我创建内容并将数据存储在 mongoDb 集合中。目标是使用这些数据和一个 React 项目来构建一个静态网站,该网站被发送到 AWS S3 存储桶以进行托管。
我正在使用meteorUp 部署我的Meteor 应用程序(在AWS EC2 实例上)并根据MeteorUp 文档(http://meteor-up.com/docs.html#volumes),我在我的mup.js 中添加了一个docker 卷:
module.exports = {
...
meteor: {
...
volumes: {
'/opt/front': '/front'
},
...
},
...
};
部署后,卷在“/opt/myproject/config/start.sh”中设置得很好:
sudo docker run \
-d \
--restart=always \
$VOLUME \
\
--expose=3000 \
\
--hostname="$HOSTNAME-$APPNAME" \
--env-file=$ENV_FILE \
\
--log-opt max-size=100m --log-opt max-file=10 \
-v /opt/front:/front \
--memory-reservation 600M \
\
--name=$APPNAME \
$IMAGE
echo "Ran abernix/meteord:node-8.4.0-base"
# When using a private docker registry, the cleanup run in
# Prepare Bundle is only done on one server, so we also
# cleanup here so the other servers don't run out of disk space
if [[ $VOLUME == "" ]]; then
# The app starts much faster when prepare bundle is enabled,
# so we do not need to wait as long
sleep 3s
else
sleep 15s
fi
在我的 EC2 上,“/opt/front”包含用于生成静态网站的 React 项目。此文件夹包含一个 package.json 文件,每个模块都在“node_modules”目录中可用。'react-scripts' 就是其中之一,package.json 包含以下脚本行:
"build": "react-scripts build",
反应项目
React App 提供了一个 JSON 文件,位于 'opt/front/src/assets/datas/publish.json' 中。
这个 JSON 文件可以手写(所以项目可以独立开发),也可以由我的 Meteor App 生成。
流星应用
在客户端,在用户界面上,我们有一个“发布”按钮,当管理员想要生成静态网站(使用 CMS 数据)并将其部署到 S3 存储桶时,可以单击该按钮。
它调用 Meteor 方法(服务器端)
其作用分为 3 个步骤:
1.收集所有有用的数据并将它们保存到发布集合中
2. JSON 创建
一种。获取公共集合的第一个条目到一个 javascript 对象中。
湾。在 React 项目目录 ('opt/front/src/assets/datas/publish.json') 中使用该对象编写 JSON 文件。
这是代码:
import fs from 'fs';
let publishDatas = Publish.find({}, {sort : { createdAt : -1}}).fetch();
let jsonDatasString = JSON.stringify(publishDatas[0]);
fs.writeFile('/front/src/assets/datas/publish.json', jsonDatasString, 'utf8', function (err) {
if (err) {
return console.log(err);
}
});
2. 静态网站搭建
一种。运行 CD 命令以到达 React Project 的目录,然后使用以下代码运行“构建”脚本:
process_exec_sync = function (command) {
// Load future from fibers
var Future = Npm.require("fibers/future");
// Load exec
var child = Npm.require("child_process");
// Create new future
var future = new Future();
// Run command synchronous
child.exec(command, {maxBuffer: 1024 * 10000}, function(error, stdout, stderr) {
// return an onbject to identify error and success
var result = {};
// test for error
if (error) {
result.error = error;
}
// return stdout
result.stdout = stdout;
future.return(result);
});
// wait for future
return future.wait();
}
var build = process_exec_sync('(cd front && npm run build)');
湾。如果“构建”没问题,那么我将“前端/构建”内容发送到我的 S3 存储桶。
行为:
在本地环境(Meteor 在开发模式下运行):
仅供参考:React 项目目录的名称和位置略有不同。它位于我的流星项目目录中,所以不是“front”,而是命名为“.#front”,因为我不希望 Meteor 在每次修改、添加或删除文件时都重新启动。
一切运行良好,但我完全清楚我处于开发模式,并且我从本地环境中受益。
在生产环境中(在 docker 容器中以生产模式运行的 Meteor):
步骤 2.b:效果很好,我可以在 'opt/front/src/assets/datas/' 中看到新生成的文件
步骤 3.a:我收到以下错误:
“运行 ls 时出错:命令失败:(cd /front && npm run build)
(节点:39) ExperimentalWarning:WHATWG 编码标准实现是一个实验性 API。它还不应该在生产应用程序中使用。
npm 错误!代码 ELIFECYCLE npm 错误!errno 1 npm 错误!front@0.1.0 构建:
react-scripts build
npm 错误!退出状态 1 npm ERR!npm 错误!在 front@0.1.0 构建脚本中失败。npm 错误!这可能不是 npm 的问题。上面可能有额外的日志输出。
npm 错误!可以在以下位置找到此运行的完整日志:npm ERR!
/root/.npm/_logs/2021-09-16T13_55_24_043Z-debug.log [exec-fail]"
所以这是我的问题:在生产模式下,是否可以使用 Meteor 到达另一个目录并从 package.json 运行脚本?
几个月来我一直在寻找答案,但找不到类似或附近的案例。
难道我做错了什么?
我使用了错误的方法吗?
我疯了吗?:D
非常感谢您阅读到最后。
谢谢您的回答!
!!!!!!更新 !!!!!
我找到了解决方案!
事实上,我不得不用 ssh 检查我的 EC2 上的一些东西:
- 连接后,我必须转到“/opt/front/”并尝试使用“npm run build”构建 React-app
- 我遇到了第一个错误,因为该目录上的 CHMOD 未设置为 777(菜鸟!)
- 然后,由于 node-sass,我遇到了错误。
原因是我的 docker 使用的是 Node v8,而我的 EC2 使用的是 Node v16。
我必须安装 NVM 并使用 Node v8,然后删除我的 React-App node_modules(和 package-lock.json),然后重新安装它。
完成后,一切正常!
我现在有一个 Meteor 应用程序,充当托管在 EC2 实例上的 CMS / 预览网站,可以在 S3 存储桶上发布静态网站。
谢谢你读我!