测试App Engine + Angularjs客户端 - 每个客户端在不同的端口上运行

时间:2014-12-04 02:50:32

标签: angularjs google-app-engine gruntjs

我确定我的标题需要一些调整,但问题是:

有没有办法让我使用在给定端口上运行的dev_appserver(web上8080,API 54381)来提供我的AppEngine / Google Endpoint(Python)项目,同时使用不同的服务器为我的AngularJS客户端提供服务(以及必要性不同的端口,也许是5000)?

背景:

  • 我遇到的问题是我的应用程序的结构和 我可以用于开发/测试的工具/流程。
  • 为了利用现有的GruntJS优势,我决定将项目的App Engine分层 服务器代码和AngularJS客户端代码进入目录结构 由Yeoman Generator为Angular创建。
  • 我想通过引入这种类似Grunt的环境,我可以很容易地进入 mobile-angular-ui代码作为bower_component并轻松链接它 进入我的主索引html页面。情况似乎如此。
  • 问题:App Engine最终监控bower_components下的文件夹/层次结构,超出了要监控的应用服务器的文件计数限制(dev_appserver.py表示'应用程序中有太多文件')。这通常让我觉得“必须有一个更聪明的方法”。

我看到的选项:

  • 使用正常的dev_appserver.py从Grunt-serve服务器和Google Endpoint服务器提供客户端代码。我相信如果在同一主机上,这些需要在不同的端口上运行。因此,我不知道如何将Google Endpoint客户端与服务器加载javascript。
  • Google向dev_appserver添加了一个补丁,以允许文件更改监控代码遵守排除规则(this Google App Engine Issue中讨论的内容)
  • 找到一种使用grunt插件移动文件的方法,这样我就可以为我使用的任何外部组件重新构建一个“dist”文件夹,我指向我提供的客户端代码。避免让我的App Engine app.yaml暴露整个bower_components文件夹以使我的脚本包含工作。

1 个答案:

答案 0 :(得分:0)

如果使用grunt-connect-proxy,在端口5000上运行的Grunt服务器将能够在端口8080上将请求转发到App Engine服务器。

这样你就可以保持Grunt不错的实时重载功能。

This article解释了如何在Java / Maven上进行,但Grunt部分完全相同。

以下是我使用代理修改的Gruntfile.js的摘录:

connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost',
                livereload: 35729
            }, proxies: [
                {
                    context: [
                        '/_ah',
                        '/admin'
                    ],
                    host: 'localhost',
                    port: 8080,
                    https: false,
                    changeOrigin: false,
                    xforward: false
                }
            ], livereload: {
                options: {
                    open: true,
                    base: [
                        '.tmp',
                        '<%= yeoman.app %>'
                    ],
                    middleware: function (connect, options) {
                        if (!Array.isArray(options.base)) {
                            options.base = [options.base];
                        }

                        // Setup the proxy
                        var middlewares = [require('grunt-connect-proxy/lib/utils').proxyRequest];

                        // Serve static files.
                        options.base.forEach(function (base) {
                            middlewares.push(connect.static(base));
                        });

                        // Make directory browse-able.
                        var directory = options.directory || options.base[options.base.length - 1];
                        middlewares.push(connect.directory(directory));

                        return middlewares;
                    }
                }
            },
...
grunt.loadNpmTasks('grunt-connect-proxy');
...
grunt.registerTask('server', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
            'concurrent:server',
            'autoprefixer',
            'configureProxies:server',
            'connect:livereload',
            'watch'
        ]);
    });