Как стать автором
Обновить

Как объединить несколько JS приложений с .NET Core (Create React APP + Next JS + .NET Core)

Время на прочтение3 мин
Количество просмотров5.6K

Всем привет! Пару месяцев назад у нас возникла задача запилить лендос для нашего онлайн сервиса. Наш стек - Create React App + .Net Core. Погугля немного, мы решили, что хотим запилить лендос на Next JS, но возник вопрос - как это все вместе подружить.
Мы хотели, что бы приложение открывалось по ссылке: yourdomain.com/app, а все остальные ссылки вели бы на лендос.


Для начала в папке, где у Вас лежит ClientApp нужно создать папку LandingApp куда вы добавите второй проект. (Если что, папки можно назвать, как угодно)


После того, как Вы добавите второй проект нужно немного обновить startup.cs, чтобы .Net Core мог "переключать трафик" с одного проекта на другой.

Отключаем endpoint routing в методе ConfigureServices

            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
            });

В метод Configure добавляем статичные файлы для CRA

            app.UseSpaStaticFiles(new StaticFileOptions() { 
                RequestPath = "/app"
            });

Добавляем маппер, который при переходе по ссылке /app будет открывать наше приложение

app.MapWhen(context => context.Request.Path.Value.StartsWith("/app"), builder =>
            {
                builder.UseMvc(routes =>
                {
                    routes.MapSpaFallbackRoute(
                        "app",
                        new { controller = "", action = "app" }
                    );
                });
                builder.UseSpa(spa =>
                {
                    spa.Options.SourcePath = "ClientApp";
              
                    if (env.IsDevelopment())
                    {
                        spa.UseReactDevelopmentServer(npmScript: "start");
                    }

                });
            });

После по дефолту открываем наше Next JS приложение

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "LandingApp";
                // Для простоты билда, мы забилдили лендос отдельно
                // И там скрывается ссылка по типу 
                // https://yourapp.azurewebsites.net
                var url = Configuration.GetSection("urls")["landingUrl"];
                if (env.IsDevelopment())
                {
                    url = "http://localhost:3005";
                }
                spa.UseProxyToSpaDevelopmentServer(url);
                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "dev");
                }
            });
Весь метод Configure
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            _env = env;
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.Use(async (context, next) =>
            {
                context.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
                await next();
            });

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles(new StaticFileOptions() { 
                RequestPath = "/app"
            });

            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.MapWhen(context => context.Request.Path.Value.StartsWith("/app"), builder =>
            {
                builder.UseMvc(routes =>
                {
                    routes.MapSpaFallbackRoute(
                        "app",
                        new { controller = "", action = "app" }
                    );
                });
                builder.UseSpa(spa =>
                {
                    spa.Options.SourcePath = "ClientApp";
              
                    if (env.IsDevelopment())
                    {
                        spa.UseReactDevelopmentServer(npmScript: "start");
                    }

                });
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "LandingApp";
                var url = Configuration.GetSection("urls")["landingUrl"];
                if (env.IsDevelopment())
                {
                    url = "http://localhost:3005";
                }
                spa.UseProxyToSpaDevelopmentServer(url);
                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "dev");
                }
            });

        }

Далее, нам нужно сказать CRA откуда брать бандл т.к. теперь он находится не в корне, а в /app. Для этого, мы в package.json указываем свойство homepage: "/app/"

Если вы используете библиотеку history то нужно указать еще basename: '/app'

import { connectRouter } from 'connected-react-router';
import { createBrowserHistory } from 'history';

export const history = createBrowserHistory({
  basename: '/app',
});

export const routerReducer = connectRouter(history);

И на этом вроде все :)

Теги:
Хабы:
Всего голосов 5: ↑2 и ↓30
Комментарии8

Публикации

Истории

Работа

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань