documentation表示您必须更新app.yaml - 就像您对AppEngine中的任何语言一样。它稍后还说明对于本地开发,您可能希望服务器也响应静态请求。但是,当我更新我非常简单的app.yaml时:
runtime: nodejs8
handlers:
- url: /apiEndPoint
script: auto
- url: /.*
static_dir: public
似乎所有请求仍然最终进入我的脚本 - 这将在prod实例中返回404,因为这些文件将不会被上传。我可以强制他们上传,然后我的nodejs服务器响应静态请求 - 但我认为这个app.yaml的想法是配置它,以便静态文件在我的应用程序逻辑之外提供?
答案 0 :(得分:2)
所以要明确 - 你可以在生产Nodejs Standard AppEngine 中托管静态文件,而不需要使用JS服务器。但是,对于本地开发,您必须找到一种在计算机上运行时在本地提供这些文件的方法。出于这个原因,你将处理程序放在Express中,用于静态文件,因为app.yaml处理程序是第一次通过,因此永远不会在生产中触及它。
如果你想要肯定Express.js没有在生产中提供静态文件,你可以这样做:
// Production instances automatically have this environment variable.
const isLocal = (process.env.NODE_ENV !== "production");
if(isLocal) {
app.use(express.static('public'));
}
答案 1 :(得分:1)
静态文件在部署期间上传,但与应用程序代码不在同一位置。它们已上传到Google的基础上专门用于直接提供静态内容的基础设施。这可以通过增加部署命令的日志详细程度来确认。
当请求网址与其中一个静态处理程序匹配时,它应该定向到此专用基础设施,它不应该到达您的应用程序代码。通过实际部署确认相对容易。
至于本地开发,我并不完全确定Node.Js服务器的行为(实际上,文档似乎建议使用Express来处理静态文件),但是Python本身就是静态的文件完全基于17:28:25,571 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC000001: Failed to start service jboss.deployment.unit."Restaurant-1.1-SNAPSHOT.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."Restaurant-1.1-SNAPSHOT.war".WeldStartService: Failed to start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.weld.exceptions.WeldException: WELD-001524: Unable to load proxy class for bean Managed Bean [class com.naigoapps.restaurant.model.dao.RestaurantTableDao] with qualifiers [@Any @Default] with class class com.naigoapps.restaurant.model.dao.RestaurantTableDao using classloader ModuleClassLoader for Module "deployment.Restaurant-1.1-SNAPSHOT.war:main" from Service Module Loader
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:371)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.createEnhancedSubclass(SubclassedComponentInstantiator.java:114)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.initEnhancedSubclass(SubclassedComponentInstantiator.java:86)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.<init>(SubclassedComponentInstantiator.java:79)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.forInterceptedDecoratedBean(SubclassedComponentInstantiator.java:63)
at org.jboss.weld.injection.producer.BeanInjectionTarget.initializeAfterBeanDiscovery(BeanInjectionTarget.java:121)
at org.jboss.weld.injection.producer.InjectionTargetInitializationContext.initialize(InjectionTargetInitializationContext.java:42)
at org.jboss.weld.injection.producer.InjectionTargetService.initialize(InjectionTargetService.java:63)
at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:433)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:83)
at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:95)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
... 3 more
Caused by: org.jboss.weld.exceptions.WeldException: Method already exists. Method: getTargetClass Parameters:[] Return Type: Ljava/lang/Class;
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addSpecialMethods(InterceptedSubclassFactory.java:386)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethods(InterceptedSubclassFactory.java:116)
at org.jboss.weld.bean.proxy.ProxyFactory.createProxyClass(ProxyFactory.java:469)
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:364)
... 15 more
Caused by: org.jboss.classfilewriter.DuplicateMemberException: Method already exists. Method: getTargetClass Parameters:[] Return Type: Ljava/lang/Class;
at org.jboss.classfilewriter.ClassFile.addMethod(ClassFile.java:133)
at org.jboss.classfilewriter.ClassFile.addMethod(ClassFile.java:148)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addSpecialMethods(InterceptedSubclassFactory.java:378)
... 18 more
静态处理程序配置,无需点击任何应用程序代码。可能是因为仍然非常新的Node.JS标准环境支持。
答案 2 :(得分:0)
您需要使用gcloud app deploy
在应用程序代码中部署要提供的静态文件。
您的app.yaml
文件说:
/apiEndPoint
相匹配的请求都将被路由到您的Node.js应用public
文件夹提供一个静态文件,并且不会到达您的应用程序(一旦部署)。 例如:/index.html
将投放public/index.html
,如果尚未部署此文件,则它将返回404
页面。