我有Spring Boot
作为后端,Angular2
作为前端。我想分别开发它们并部署到Heroku
。
它们不应该有任何共同的依赖关系,应该在单独的git-repos中。
据我了解,有两种主要方式可以实现:
运行npm build
并将dist
文件夹复制到resource
应用程序的Spring
文件夹中,以便最后将其作为静态内容处理
运行服务器以专门提供Angular
应用程序,该应用程序将与Spring
应用程序通信(此处出现CORS问题?)因此总共有两台服务器
我认为第一种方式有点“脏”,因为我不认为从一个项目到另一个项目的复制文件夹是好的。
第二种方法是矫枉过正,因为我有两台服务器(例如Tomcat
和Node.js
)。如果我可以将Angular
放在Angular
内,为什么我的服务器应该包含Spring
应用?
是否有更合理的方式来提出上述内容?
感谢。
答案 0 :(得分:7)
在我的组织中,我们有很多Spring Boot和Angular应用程序。当不需要两台服务器时,Spring Boot可以从任何支持的URL(例如" http:"或" file:")提供静态内容。只需在启动时将此参数传递给您的应用程序:
--spring.resources.static-locations=<url>
Spring Boot还可以通过包含以下Web MVC配置来支持Angular单页面应用程序路由。这样可以确保即使用户在浏览器中刷新页面,Spring Boot仍会为其他角度路径提供index.html的内容。
public class SinglePageAppWebMvcConfigurer extends WebMvcConfigurerAdapter
{
@Autowired
private ResourceProperties resourceProperties;
private String apiPath = "/api";
public SinglePageAppWebMvcConfigurer()
{
}
public SinglePageAppWebMvcConfigurer(String apiPath)
{
this.apiPath = apiPath;
}
protected String getApiPath()
{
return apiPath;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations(resourceProperties.getStaticLocations())
.setCachePeriod(resourceProperties.getCachePeriod()).resourceChain(true)
.addResolver(new SinglePageAppResourceResolver());
}
private class SinglePageAppResourceResolver extends PathResourceResolver
{
@Override
protected Resource getResource(String resourcePath, Resource location) throws IOException
{
Resource resource = location.createRelative(resourcePath);
if (resource.exists() && resource.isReadable()) {
return resource;
} else if (getApiPath() != null && ("/" + resourcePath).startsWith(getApiPath())) {
return null;
} else {
LoggerFactory.getLogger(getClass()).info("Routing /" + resourcePath + " to /index.html");
resource = location.createRelative("index.html");
if (resource.exists() && resource.isReadable()) {
return resource;
} else {
return null;
}
}
}
}
}
答案 1 :(得分:3)
选项1 托管REST API的一个服务器进程和托管Angular UI的另一个服务器进程
此选项是基于MicroServices的体系结构中的推荐选项,其中各个API(或小的相关API组)通过将它们托管在单独的服务器进程中来单独运行和扩展。在这种情况下,如果Angular UI也与REST API捆绑在一起,则意味着Angular UI中的每个错误修复或增强都需要重建和重新部署您的服务。当我们开始这样做时,它将破坏基于微服务架构的目的。
因此,在这样的体系结构中,一个或多个服务器实例将仅承载Angular UI。 Angular UI将使用一些服务发现机制通过API网关调用各个API。然而,基于微服务的架构并非易事 - 它与许多移动部件复杂。对于大型项目来说,这种复杂程度是合理的。
选项2 托管REST API和Angular UI的一个服务器进程
对于用户群为几百个用户的中小型项目,建议使用此选项。
在此类项目中,创建一个单独的存储库,其中Maven项目将包含两个子模块 - 一个用于REST API,另一个用于Angular UI。
使用Maven插件“frontend-maven-plugin”构建UI部分。这将自动下载指定的NodeJs版本并调用相应的npm命令来构建Angular项目。最后,使用Maven元素将Angular dist文件夹复制到resources文件夹下的Spring Boot静态文件夹。 (在.gitignore文件中排除静态文件夹,以便Angular分发文件不会与REST API一起检入源代码控制中。)
现在,随着Java构建的开始,它将自动包含fat jar中的静态文件夹,该文件夹现在将同时提供API和Angular UI。
答案 2 :(得分:2)
到目前为止,我使用一个git存储库创建了使用angular和spring-boot的应用程序,但是有两个不同的maven项目,一个用于后端,一个用于前端。
使用Maven,我构建了一个带有嵌入式Tomcat的胖jar并将其部署到Amazon EC2。
我也尝试过Heroku,你可以在那里部署相同的胖罐。
对于下一个项目,我会采用另一种方法,将所有静态资源(如html,javascript等)部署到Amazon S3,并将spring-boot应用程序部署到像heroku这样的提供程序。
这种方式的前端部署似乎更容易,更快,更便宜。
的博客文章