React 12 :: Docker-Compose + Nginx + React 部署到sub-folder

935 阅读2分钟

0. 背景

Wordpress的系列中,我介绍了如何在Wordpress中开启OAuth2服务,并简单做了一个html的网页,来验证OAuth的运行。

但是,一个纯html+javascript的网页毕竟能力相当有限,没法呈现出更多的功能。所以,就有了这个想法,我们如何将一个H5App (本文以React为例) 与Wordpress部署到一个gateway下面呢?

本文Demo Repo地址:gitlab.com/yafeya/reac…

1. Docker-Compose结构

其实本文中使用的Docker-Compose的结构与上面提到的文章中一致,只不过是在WordpressVolume文件夹中部署了一个ReactApp

image.png

2. React中的修改

React对于支持Sub-Folder需要做以下几部分修改:

2.1 修改PUBLIC_URL

由于我使用了create-react-app创建的React应用程序,所以,其中依赖于PUBLIC_URL这个环境变量,因为在public/index.html中,对PUBLIC_URL的引用如下,所以,如果在我们修改PUBLIC_URL之前,PUBLIC_URLstring.empty,所以网站会在gateway的绝对路径下寻找静态资源,那样的话这些资源都会返回404错误。

image.png

所以,我们需要作如下的修改:

# .env
# REACT_APP_SUB_DIR 的default值为undefined
REACT_APP_API_BASEURL=http://yafeya.com
REACT_APP_SUB_DIR=

# .env.production
# PUBLIC_URL设置为当前路径
REACT_APP_API_BASEURL=http://yafeya-production.com
PUBLIC_URL=.
REACT_APP_SUB_DIR=wp-react-dashboard

PUBLIC_URL设置为.代表当前路径,这样,上面的index.html中,在运行环境中就会被设置为./favicon.ico, ./logo192.png, ./manifest.json

2.2 修改bundle的相对位置

由于我们使用了router并且使用了code-split,所以,我们需要指定Routerbasenamesub-folder name,这样,才能routing到对应的bundle

// Router/Router.tsx

import { BrowserRouter, Redirect, Route, Switch } from "react-router-dom";
import { Home } from "../Home/Home";
import { Redux } from "../Redux/Redux";
import { ItemDetailWrapper } from "../ItemDetail/Item";
import { lazy, Suspense } from "react";


const TranslationWrapper = lazy(() => import("../i18n/translation"));
const ItemsWrapper = lazy(() => import("../ItemList/ItemList"));

export const Router = () => {
    // 使用dotenv获取REACT_APP_SUB_DIR,我们在.env.production中定义好的环境变量
    let subdir = process.env.REACT_APP_SUB_DIR;
    return (
        // basename设置为sub-folder
        <BrowserRouter basename={subdir}> 
            <Suspense fallback={<div>loading...</div>}>
                <Switch>
                    <Route exact={true} path="/" component={Home} />
                    <Route path="/redux" component={Redux} />
                    <Route path="/items" component={ItemsWrapper} />
                    <Route path="/item/:id" component={ItemDetailWrapper} />
                    <Route path="/i18n" component={TranslationWrapper} />
                    <Route component={() => <Redirect to="/" />} />
                </Switch>
            </Suspense>
        </BrowserRouter> 
    );
}

React的应用程序只需要修改如下几点,没有别的需要修改得了。

3. Nginx中的修改

需要在nginx.conf中添加React对应的location路由规则。

server {
    # ...
    # ...
    location /wp-react-dashboard {
        try_files $uri $uri/ /wp-react-dashboard/index.html;
        index index.html;
    }
}

重启docker-compose,就可以通过https://your-gateway-domain/wp-react-dashboard 访问sub-folder下的React App了。

docker-compose down && docker-compose up -d

4. 运行效果

screen-capture (1).gif