Когда я создаю свой проект Angular 17 SSR с помощью ng build
, я получаю следующее:
├── dist
│ └── my-project
│ ├── .DS_Store
│ ├── 3rdpartylicenses.txt
│ ├── browser
│ │ ├── .DS_Store
│ │ ├── assets
│ │ │ ├── ...
│ │ ├── chunk-5XNHKK4I.js
│ │ ├── ...
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main-OTXGCZUU.js
│ │ ├── media
│ │ │ └── ...
│ │ ├── polyfills-RT5I6R6G.js
│ │ ├── styles-6I36XN7I.css
│ ├── prerendered-routes.json
│ └── server
│ ├── chunk-2VXXU7NI.mjs
│ ├── ...
│ ├── index.server.html
│ ├── main.server.mjs
│ ├── polyfills.server.mjs
│ ├── render-utils.server.mjs
│ └── server.mjs
Теперь мой вопрос: как мне опубликовать это на своем cPanel/традиционном хостинг-провайдере?
Я полагаю, что Angular упростил развертывание SSR в Firebase и других основных облачных сервисах, но как насчет локальных облачных сервисов, использующих cPanel?
Перетащите /dist в папку /public_html в cPanel. Это не решение 😅
У меня такой же вопрос. Самый близкий ответ, который я нашел, находится по этой ссылке Как опубликовать универсальный проект Angular v17+ на свой хостинг-аккаунт. Они говорят «Универсальный», но это @angular/ssr, который включен в версию Angular 17; там вы найдете полную статью о том, как реализовать приложение angular ssr, но я думаю, вам нужно просмотреть только начиная с пункта 8; Однако они не уточняют, что это виртуальный хостинг. Я был бы признателен, если бы вы поделились любой другой информацией, которую найдете; Я сделаю то же самое.
Я нашел решение!
Небольшое предварительное условие: проверьте, позволяет ли ваша cPanel создавать NodeJS.
В корне проекта Angular я создал файл main.js
, и вот что внутри него:
async function run() {
try {
// Import the app from the ES module
const server = await import("./server/server.mjs");
const app = await server.app();
const port = process.env["PORT"] || 4000;
// Start up the Node server
app.listen(port, () => {
console.info(`Node Express server listening on http://localhost:${port}`);
});
} catch (error) {
console.error("Failed to import app:", error);
}
}
run();
А вот как выглядит мой файл server.ts
:
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join, resolve } from 'path';
import bootstrap from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', browserDistFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
'*.*',
express.static(browserDistFolder, {
maxAge: '1y',
})
);
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
export * from './src/main.server';
Затем в своем проекте я запустил ng build
, который создал вышеупомянутое дерево файлов.
Вот шаги, которые я предпринял:
main.js
как «Файл запуска приложения», это важно.Вот как экземпляр выглядел в конце:
Затем я перешел в корневую папку приложения на сервере. Это была приблизительная структура файла:
├── main.js
├── public
├── ... (some other files)
└── tmp
Затем я просто сбросил туда содержимое папки /dist/my-project
, поэтому конечный результат выглядит примерно так:
├── .htaccess
├── 3rdpartylicenses.txt
├── browser
├── main.js
├── prerendered-routes.json
├── public
├── server
└── tmp
Затем вернитесь к экземпляру Node.js в cPanel и нажмите «Перезапустить»!
Тогда экземпляр Node.js в cPanel просто знает, что делать, благодаря main.js
.
Надеюсь это поможет!