无法在 Azure App 服务上部署 React JS 应用程序

IT技术 node.js reactjs azure azure-web-app-service azure-appservice
2021-04-03 15:20:17

我正在浏览一些链接以在 azure 应用程序服务上部署 React Js 应用程序。但是我在部署应用程序时遇到了一些问题。

我已经添加了所有必要的东西,比如web.config文件到public文件夹,并将构建目录添加到工作区。

在 azure 应用服务上部署 Web 应用

使用 Visual Studio Code 将 Node.js 部署到 Azure 应用服务

遵循所有步骤,但当我尝试在 azure 应用程序服务上部署时出现以下错误。在部署之前我会运行这些命令

npm run build.

2020-08-19T10:44:45.762075166Z A P P   S E R V I C E   O N   L I N U X
2020-08-19T10:44:45.762079567Z 
2020-08-19T10:44:45.762083667Z Documentation: http://aka.ms/webapp-linux
2020-08-19T10:44:45.762088167Z NodeJS quickstart: https://aka.ms/node-qs
2020-08-19T10:44:45.762092268Z NodeJS Version : v12.16.3
2020-08-19T10:44:45.762096468Z Note: Any data outside '/home' is not persisted
2020-08-19T10:44:45.762100768Z 
2020-08-19T10:44:45.789282727Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
2020-08-19T10:44:45.792738514Z Build Operation ID: |OtQwveNuO0A=.83a2ec6c_
2020-08-19T10:44:47.255197638Z Writing output script to '/opt/startup/startup.sh'
2020-08-19T10:44:47.960307930Z Running #!/bin/sh
2020-08-19T10:44:47.960336532Z 
2020-08-19T10:44:47.960345833Z # Enter the source directory to make sure the script runs where the user expects
2020-08-19T10:44:47.960355334Z cd "/home/site/wwwroot"
2020-08-19T10:44:47.960363235Z 
2020-08-19T10:44:47.960370735Z export NODE_PATH=$(npm root --quiet -g):$NODE_PATH
2020-08-19T10:44:47.960378436Z if [ -z "$PORT" ]; then
2020-08-19T10:44:47.960386136Z      export PORT=8080
2020-08-19T10:44:47.960393937Z fi
2020-08-19T10:44:47.960401238Z 
2020-08-19T10:44:47.960408638Z echo Found tar.gz based node_modules.
2020-08-19T10:44:47.960416339Z extractionCommand="tar -xzf node_modules.tar.gz -C /node_modules"
2020-08-19T10:44:47.960424040Z echo "Removing existing modules directory from root..."
2020-08-19T10:44:47.960431740Z rm -fr /node_modules
2020-08-19T10:44:47.960439141Z mkdir -p /node_modules
2020-08-19T10:44:47.960446542Z echo Extracting modules...
2020-08-19T10:44:47.960453842Z $extractionCommand
2020-08-19T10:44:47.960461243Z export NODE_PATH="/node_modules":$NODE_PATH
2020-08-19T10:44:47.960468943Z export PATH=/node_modules/.bin:$PATH
2020-08-19T10:44:47.960476344Z if [ -d node_modules ]; then
2020-08-19T10:44:47.960483745Z     mv -f node_modules _del_node_modules || true
2020-08-19T10:44:47.960491245Z fi
2020-08-19T10:44:47.960498446Z 
2020-08-19T10:44:47.960505546Z if [ -d /node_modules ]; then
2020-08-19T10:44:47.960524748Z     ln -sfn /node_modules ./node_modules 
2020-08-19T10:44:47.960532849Z fi
2020-08-19T10:44:47.960540149Z 
2020-08-19T10:44:47.960547550Z echo "Done."
2020-08-19T10:44:47.960554951Z npm start
2020-08-19T10:44:48.258132115Z Found tar.gz based node_modules.
2020-08-19T10:44:48.258154316Z Removing existing modules directory from root...
2020-08-19T10:44:48.260461807Z Extracting modules...
2020-08-19T10:44:48.262765098Z tar (child): node_modules.tar.gz: Cannot open: No such file or directory
2020-08-19T10:44:48.262778299Z tar (child): Error is not recoverable: exiting now
2020-08-19T10:44:48.262970515Z tar: Child returned status 2
2020-08-19T10:44:48.262983816Z tar: Error is not recoverable: exiting now
2020-08-19T10:44:48.290740216Z Done.
2020-08-19T10:44:48.512406278Z npm info it worked if it ends with ok
2020-08-19T10:44:48.512836614Z npm info using npm@6.14.4
2020-08-19T10:44:48.512976126Z npm info using node@v12.16.3
2020-08-19T10:44:48.578204629Z npm info lifecycle adal_appp@0.1.0~prestart: adal_appp@0.1.0
2020-08-19T10:44:48.584464048Z npm info lifecycle adal_appp@0.1.0~start: adal_appp@0.1.0
2020-08-19T10:44:48.589867495Z 
2020-08-19T10:44:48.589881796Z > adal_appp@0.1.0 start /home/site/wwwroot
2020-08-19T10:44:48.589887297Z > react-scripts start
2020-08-19T10:44:48.589891697Z 
2020-08-19T10:44:48.597331914Z sh: 1: react-scripts: not found
2020-08-19T10:44:48.598224588Z npm info lifecycle adal_appp@0.1.0~start: Failed to exec start script
2020-08-19T10:44:48.599091959Z npm ERR! code ELIFECYCLE
2020-08-19T10:44:48.599182267Z npm ERR! syscall spawn
2020-08-19T10:44:48.599258573Z npm ERR! file sh
2020-08-19T10:44:48.599314678Z npm ERR! errno ENOENT
2020-08-19T10:44:48.600738196Z npm ERR! adal_appp@0.1.0 start: `react-scripts start`
2020-08-19T10:44:48.600749897Z npm ERR! spawn ENOENT
2020-08-19T10:44:48.600754497Z npm ERR! 
2020-08-19T10:44:48.600758798Z npm ERR! Failed at the adal_appp@0.1.0 start script.
2020-08-19T10:44:48.600763398Z npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2020-08-19T10:44:48.605436585Z npm timing npm Completed in 125ms
2020-08-19T10:44:48.605621800Z 
2020-08-19T10:44:48.605672405Z npm ERR! A complete log of this run can be found in:
2020-08-19T10:44:48.605750311Z npm ERR!     /root/.npm/_logs/2020-08-19T10_44_48_601Z-debug.log

但问题是相同的应用程序使用以下命令在本地完美运行 npm installnpm start

并且只是为了验证在npm run build工作之后生成的构建是否尝试使用以下命令从构建目录运行应用程序

npm install -g serve

然后

serve -s build

然后应用程序在浏览器中打开。

2个回答

做了一些谷歌搜索后找到了解决方案我们需要在 Linux 机器的应用服务配置中的启动命令中添加以下命令。

pm2 serve /home/site/wwwroot --no-daemon

脚步:

- Go to App Service

- Navigate to Configuration

- Click on General Settings

- add the above command in Start up command, click on save 

- then restart the server

从日志看来这不是一个Node.js应用程序,而是一个react应用程序。因此react-scripts start,Azure 应用服务对此一无所知。

当您react在 localhost 上运行应用程序时,它由development server确实是Node.js服务器的 a 提供支持,但是一旦您使用npm run build构建用于生产应用程序,它只不过是index.html由一堆.js文件和样式表提供支持的文件。它本身没有网络功能。

serve另一方面是一个单独的故事。根据他们在npmjs.com以下位置的描述:假设您想要提供静态站点、单页应用程序或只是一个静态文件(无论是在您的设备上还是在本地网络上),此软件包正是您的正确选择。

但这不是一种类似于 Azure 的方法。

但是,在生产中,如果您使用 Azure,我建议使用 Azure Blob Storage v2,它具有静态站点托管功能。在 blob 存储中启用静态站点托管,并将build文件夹部署在名为$web. Ofcourse所有这一切都是如果您正在使用自动完成vscodeAzure plugin假设您已通过 登录到 Azure vscode,右键单击该build文件夹并选择deploy to static site,按照步骤操作,您将使用 React 应用程序。

但是,如果您Node.js expressreact应用程序旁边确实有后端,那么您可以将build文件夹放入与文件夹Node.js相同级别项目中,node_modules并使用静态路由将前端和后端作为单个包工作。明确定义一个路由,当被要求时告诉express响应index.html文件。然后你可以将整个包部署到一个Azure App Service.

const express = require('express');
const path = require('path');
const port = process.env.PORT || 3006;

const app = express();

app.use(express.json())
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json({extended: true}));

app.use(express.static(__dirname + '/build'));
app.get('/', (req, res) => { 
  res.sendFile(path.join(__dirname + '/build/index.html'))
});

// Then prefix your API endpoints with /api
app.get('/api/user/:id', (req, res) => {
  // Code to get user by id
});

app.post('/api/user', (req, res) => {
  // Code to save user
});

app.listen(port, () => {
  console.log(`App bootstrapped on port ${port}...`);
});

/被击中时,然后index.html被送达。API 调用按/api/*. 我发现这种机制很多时候都很有用。

祝你好运。

后端是spring-boot。是的,它是一个反应应用程序。在此之前已经进行了多次部署,但从未遇到过这个问题。
2021-06-09 15:20:17