После обновления моего проекта Angular 8 до 9, я имею в виду, что я обновил практически все до последней версии, произошло несколько вещей.
1.- webpack.config.js
файл был переименован в .bak, поэтому кажется, что использование webpack больше не подходит, и действительно, если я пытаюсь повторно активировать сборку webpack, ничего не происходит, он создает сборку, но скрипт не запускается. Бег с node server.js
входит и исчезает, вообще ничего не говоря.
2.- Теперь в папке dist нет файла .js в корне, а папки браузеров и сборок сервера там, как и раньше, но даже редактирование файла web.config
, чтобы указать iisnode запускать server/main.js
вместо server.js
, все время выдает 500 нет имеет значение, что я делаю.
3.- Единственное, что работает сначала, это запускать локально
npm run dev:ssr
Это означает, что ссылка на представление в сборке браузера есть, но она работает так, как будто должна запускаться из корня с запросом dist / browser.
Я изменил путь сборки и путь сборки сервера в angular.json
, чтобы создать файл main.js в корне папки ./dist.
angular.json (outputPath изменен)
architect: {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/browser",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "tsconfig.app.json",
...
},
...
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist",
"main": "server.ts",
"tsConfig": "tsconfig.server.json"
},
...
},
...
}
Что ж, вот и проблема. Сборка браузера без проблем генерирует ./dist/browser, и сборка сервера действительно помещает файл main.js непосредственно в ./dist, но каким-то образом решила удалить папку ./dist/browser и при запуске узла main.js (web.config
указывает to main.js
) он не может найти ./browser/index.html и, конечно, не потому, что процессу сборки сервера удалось удалить папку браузера.
Хакерское решение, запустите третью сборку (снова сборку браузера)
Я надеюсь, что это можно решить, но, честно говоря, это меня совсем не беспокоит, компьютер запускает сборку, а не я, но вы знаете, могло бы быть лучше и быстрее, если бы процесс сборки сервера не удалял сборку браузера папка.
Теперь он прекрасно развертывается в службе приложений Azure прямо из AppVey или каждый раз, когда я развертываю выбранную сборку, никаких проблем.
package.json (обратите внимание на дополнительную производственную сборку после сборки сервера)
{
...
"scripts": {
...
"dev:ssr": "ng run Angular-Universal:serve-ssr",
"serve:ssr": "node dist/main.js",
"build:ssr": "npm run build:universal && ng run Angular-Universal:build:production",
"start:ssr": "npm run build:ssr && npm run serve:ssr",
"build:universal": "ng run Angular-Universal:build:production && ng run Angular-Universal:server:production",
"prerender": "ng run Angular-Universal:prerender"
},
...
}
Обратите внимание, что сценарий build:ssr
выполняет обе сборки, а затем снова сборку браузера. Также обратите внимание, что сценарий serve:ssr
был изменен для запуска dist/main.js
Наконец, необходимо было изменить файл server.ts, чтобы запросить представление из ./browser/index.html или ./dist/browser/index.html в зависимости от структуры папок целевой системы. При развертывании в службе приложений Azure main.js запрашивает browser / index.html, но если проект обслуживается с npm run dev:ssr
или node main.js
в моей локальной среде с запуском в macOS, он запрашивает dist / browser / index.html. В любом случае простой человек может преодолеть это препятствие.
server.ts (Изменения в функции приложения)
// The Express app is exported so that it can be used by serverless Functions.
export function app() {
const server = express();
let distFolder: string;
const path1 = join(process.cwd(), 'browser'); // Running from the deployed version (production)
const path2 = join(process.cwd(), 'dist/browser'); // Running from the source (macOS local development)
if (fs.existsSync(path1)) {
distFolder = path1;
} else if (fs.existsSync(path2)) {
distFolder = path2;
} else {
return null;
}
console.log('distFolder:', distFolder);
const indexHtml = fs.existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
На всякий случай, если вам интересно, как насчет копирования файла web.config
в корень папки dist
, ну, поскольку я использую AppVeyor для CI / CD, я изменил команду создания артефакта, чтобы включить web.config
(из исходных файлов репо непосредственно в .7z файл)
А почему бы не включить мой web.config
?
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<httpRuntime enableVersionHeader="false" />
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
<add name="X-Content-Type-Options" value="nosniff" />
<add name="X-Frame-Options" value="DENY" />
<add name="X-XSS-Protection" value="1; mode=block" />
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<webSocket enabled="false" />
<handlers>
<!-- Indicates that the main.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="main.js" verb="*" modules="iisnode"/>
</handlers>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
<!-- Do not interfere with requests for node-inspector debugging -->
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^main.js\/debug[\/]?" />
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<match url="^(?!.*login).*$"></match>
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
</conditions>
<action type="Rewrite" url="main.js"/>
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
<!-- 'bin' directory has no special meaning in node.js and apps can be placed in it -->
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin"/>
</hiddenSegments>
</requestFiltering>
</security>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
<!-- Restart the server if any of these files change -->
<iisnode watchedFiles="web.config;*.js;browser/*.*" />
</system.webServer>
</configuration>
Я надеюсь, что это может помочь другим в моей ситуации или, по крайней мере, полезно для обсуждения. Никто не любит ломать голову, пытаясь выполнить успешное развертывание в службе приложений Azure после обновления до версии 9. Пожалуйста, дайте мне знать, можно ли что-то улучшить, возможно, параметр сборки, чтобы избежать удаления папки сборки браузера или чего-то еще. Ваше здоровье.
person
Sparker73
schedule
28.05.2020