将具有本地依赖关系的Nodejs应用程序部署到Google App Engine

时间:2016-08-11 07:22:40

标签: google-app-engine gcloud

如何将具有本地依赖关系的NodeJS应用程序部署到GAE ???

我的应用在package.json中有本地依赖项,因此失败了。

谢谢!

2 个答案:

答案 0 :(得分:1)

没有帮助,所以我自己做了。这里的解决方案对每个人都有同样的问题。使用gulp将本地资源复制到当前目录中。

const gulp = require('gulp');
const merge = require('merge-stream');
const runSequence = require('run-sequence');
const del = require('del');
const fs = require('fs');
const resolve = require('path').resolve;

let getPackageGlobs = (dir) => {
  let paths = [
    dir + '/**',
    '!' + dir + '/node_modules/**',
    '!' + dir + '/npm-debug.log',
    '!' + dir + '/build',
  ];

  try {
    let data = fs.readFileSync(dir + '/.npmignore', {
      encoding: 'utf-8',
    });

    paths = paths.concat(data.split("\n")
      .filter((e) => e.length > 0)
      .map((e) => dir + '/' + e)
      .filter(fs.existsSync)
      .map((e) => fs.lstatSync(e).isDirectory() ? '!' + e + '/**' : '!' + e));
  } catch (err) { }

  return paths;
};

gulp.task('build.clean', () => {
  return del(__dirname + '/build');
});

gulp.task('build.copy', () => {
  return gulp.src(getPackageGlobs(__dirname))
    .pipe(gulp.dest('build'));
});

gulp.task('build.normalize', () => {
  let packageJson = require('./build/package.json');
  let tasks = [];

  for (let name in packageJson.dependencies) {
    for (let s of ['../', '~/', './', '/']) {
      if (packageJson.dependencies[name].startsWith(s)) {
        tasks.push(gulp
        .src(getPackageGlobs(resolve(packageJson.dependencies[name])))
        .pipe(gulp.dest('./build/local_modules/' + name)));

        packageJson.dependencies[name] = './local_modules' + '/' + name;

        break;
      }
    }
  }

  return new Promise((resolve, reject) => {
    fs.writeFile('./build/package.json',
      JSON.stringify(packageJson), (err) => {
        if (err) {
          reject(err);
        } else {
          resolve(merge(tasks));
        }
      });
  });
});

gulp.task('build', (done) => {
  runSequence('build.clean',
    'build.copy',
    'build.normalize',
    done);
});

使用gulp build && gcloud app deploy build/app.yaml

运行

答案 1 :(得分:0)

感谢@Hang Hoang的问题及其回答。他们的回答也解决了我的问题。我很想写一种无需使用Gulp即可达到相同结果(以及一些改进)的解决方案。

以下代码假定您有一个位于../local的本地程序包,并且当前工作目录包含Node.js应用程序和将要部署到App Engine的package.json

总体思路是在部署之前将../local的内容复制到Node.js应用程序目录中。这样,本地程序包代码将作为部署的一部分上载的代码的一部分,并且部署不会导致错误。但是,此外,为了使其正常工作,还需要更新package.json程序包的../local依赖项。

此过程分为三个步骤(以Makefile格式定义)。

deploy: _predeploy _deploy _postdeploy

部署前步骤准备要部署的文件。有关详细信息,请参见嵌入式注释。

_predeploy:
    # copy package to current directory
    cp -r ../local tmp-local
    # preserve original package.json,package-lock.json
    cp package.json package.json.original
    cp package-lock.json package-lock.json.original
    # rewrite local dependency value in package.json (../local -> ./tmp-local)
    sed -i '' 's/file:\.\.\/local/file:.\/tmp-local/g' package.json
    # update package-lock.json corresondingly
    npm i --package-lock-only

部署步骤使用gcloud命令进行实际部署。

_deploy:
    gcloud app deploy

最后,部署后步骤将清理在部署前步骤中创建的文件,并恢复package.json的原始状态(这样../local可以照常用于本地开发)。 / p>

_postdeploy:
    # undo package.json,package-lock.json changes
    mv package.json.original package.json
    mv package-lock.json.original package-lock.json
    # remove copied package
    rm -rf tmp-local

要运行,请执行make deploy