为REST API设置节点环境 - 我的头发变灰了

Pos*_*Guy 7 node.js

我在这里来到社区非常谦虚.我还不知道关于节点环境的插孔,以及这里唯一的Node开发人员.现在是一个单人团队,用于构建我的第一个Node REST API.(是的,我们真正需要的是那些已经比我知道更多节点的人来帮助这个学习过程).

我在网上无休止地搜索了几个小时来尝试尽职尽责.但坦率地说,我在设置Node.js 环境 以及设置本地与其他环境构建方面没有太多发现.首先从设置本地构建开始 - 我正在寻找婴儿步骤...在现实世界中.大多数博客帖子只展示了最简单的 开发 环境.所以更糟糕的是,大多数博客文章谈论网站设置(browsify sh__和类似的东西).我正在做REST API,而不是这里的网站.

我需要一些资源来开始,或者我只是没有为它们搜索节点,或者它们很难找到.我想深入了解你如何设置你的环境变量,你如何使用gulp与这些变量来运行不同的环境情况,以及人们如何管理他们的持久层事物,如数据库连接字符串等...我假设也是通过gulp任务自动读取包含连接字符串的配置文件?我真的不确定,那里没有很多好的例子..

这就是为什么我在这里希望找到这条路线,在这里张贴.(并且希望对我当前的gulpfile发表评论......它是不是已经或者甚至没有接近正确的轨道,或者我应该在哪里开始构建和环境约定和任务?)

什么是好的是找到一个好的帖子,让你在节点开发人员的生活中度过一天.

我现在在哪里?

我的API:我已经构建了一些Koa.js端点,我有一些接收请求的控制器,通过使用网关节点模块来处理它,我有罪,我称之为有一些CRUD持久性方法一个网关层,它调用底层的Model类集合,这意味着真正的CRUD调用真实数据库和一些模拟我的测试等等.此时非常基本...所有测试都是通过Mocha.js(BDD风格)驱动的.

我的日子:所以现在,我开始工作,我已经设置了我的mocha.js测试环境,我至少可以测试我的代码的驱动开发,并且测试运行得很好.我可以在终端中观看我的文件和我的测试与mocha报告一起运行.我的应用程序运行,所有这些.

我的问题:但除了通过gulp之外,我真的没有那么多自动化.我想知道更多关于设置环境变量的信息,开发人员在他/她准备构建和推送到git,yada yada然后最终如何切换环境时会做什么,在推送到其他服务器时这样做的动作,以及所有通过任何可以促进这一点的配置或gulp任务.我只需要一个这种生态系统的好例子.任何一个例子,但现实的东西将是如此有用.

所以...这是我当前gulpfile的一瞥.现在有针对babel转换程序的构建内容(是的,我在我的js中使用ES6到ES5代码),但是我从其他代码中得到了它,但实际上还没有弄清楚这一切是如何工作的.我设置的东西真的是我的测试运行和自动化.构建的东西我有点禁用,因为a)我真的不知道哪些文件应该是app.js,server.js之外的REST API构建的一部分,b)我从一些代码中抓取的构建代码我发现了js文件通过babel进入构建文件夹,但后来我遇到代码冲突/与常规代码冲突的问题.例如,下面的构建内容是将server.js推送到构建文件夹中,当我尝试在根目录中运行常规server.js时,它与build/server.js中的代码发生冲突,所以这就是f'd up显然我不喜欢

'use strict';

require('babel/register');
require("harmonize")();

var gulp = require('gulp'),
    mocha = require('gulp-mocha'),
    gutil = require('gulp-util'),
    babel = require("gulp-babel"),
    server = require('gulp-develop-server'),
    del = require('del');


var config = {
    core: {
        src: '*.js',
        build: {
            src: 'build'
        }
    },
    server: {
        path: ['app.js']
    },
    bs: {
        proxy: 'http://localhost:3000'
    },
    test:{
        root: 'test/**',
        src: {
            bdd: {
                features:'test/bdd/features/**/*-spec.js',
                unit:'test/bdd/unit/**/*-test.js',
                integration: 'test/bdd/integration/**/*-integration.js'
            }
        },
        mocha: {
            reporter: 'spec'
        }
    }
};

gulp.task('default', ['babel','development'], function(){
    gulp.task("watch", function(){
        gulp.watch('**/*.js', ['babel'])
    });
});

gulp.task('development',['mocha-bdd-features', 'mocha-bdd-unit'], function() {
    gulp.watch('**/*.js', ['mocha-bdd-features', 'mocha-bdd-unit']);
});

gulp.task('babel', function () {
    return gulp.src('./*.js')
        .pipe(babel());
        //.pipe(gulp.dest('build'));
});

gulp.task('build', ['clean'], function () {
});

gulp.task('clean', del.bind(
    null, ['build/*'], {dot: true}
));

gulp.task('server:start', function() {
    server.listen( { path: config.server.path});
});

gulp.task('server:restart', function() {
    server.restart();
});

gulp.task('mocha-bdd-features', function() {
    process.env.PORT = 8001;
    return gulp.src([config.test.src.bdd.features], { read: false })
        .pipe(mocha({
            compilers: {
                js: babel
            },
            reporter: config.test.mocha.reporter,
            ui: 'bdd'
        }))
        .on('error', gutil.log);
});

gulp.task('mocha-bdd-unit', function() {
    process.env.PORT = 8002;
    return gulp.src([config.test.src.bdd.unit], { read: false })
        .pipe(mocha({
            compilers: {
                js: babel
            },
            reporter: config.test.mocha.reporter,
            ui: 'bdd'
        }))
        .on('error', gutil.log);
});

gulp.task('mocha-bdd-integration', function() {
    process.env.PORT = 8003;
    return gulp.src([config.test.src.bdd.integration], { read: false })
        .pipe(mocha({
            compilers: {
                js: babel
            },
            reporter: config.test.mocha.reporter,
            ui: 'bdd'
        }))
        .on('error', gutil.log);
});

gulp.on('err', function(e) {
    console.log(e.err.stack);
});
Run Code Online (Sandbox Code Playgroud)

到目前为止我的package.json脚本:

  "scripts": {
    "start": "gulp",
    "build": "gulp build", // I was running this for a while
    "release": "gulp build --release", //I haven't used this yet or know if I even will yet
// I definitely use these, I set these up myself
    "test-bdd-features": "gulp mocha-bdd-features",
    "test-bdd-unit": "gulp mocha-bdd-unit",
    "test-bdd-integration": "gulp mocha-bdd-integration"
  },
Run Code Online (Sandbox Code Playgroud)

基本上作为开发人员,我现在拥有gulpfile的方式是在bash提示符下键入' gulp '(在我的情况下是Webstorm中的终端),它运行默认的gulp任务,然后在此时首先执行几个任务到目前为止发生了一些事情:

  1. 它在第一次吞咽时运行我所有的摩卡测试
  2. 监视mocha的所有js文件,以便在保存任何js代码更改时运行mocha测试

真的,这就是所有这一切.我可以运行节点服务器ok和所有这些.但在这一点上它是非常基本的.我有一个愚蠢的app.listen()端口硬编码在我的哑app.js文件中,显然是......很难编码!

老实说,我的不同测试套件有不同的端口,因为我发现我不得不因为端口冲突,但也许这只是因为我做了一些奇怪的事情,不确定这是否是运行验收测试的差异端口的标准单位,但我假设.

唉唉!请高手!

所以在这一点上,我喜欢把头发拉出来解决这个问题:

  1. 如何为REST API设置真正的构建(好吧你通过babel将js代码转移到哪里,以及什么呢?)
  2. 用于设置任务,配置等的生态系统,用于在差异环境中自动构建和推送和运行代码.这看起来像什么!
  3. 在不同的环境中下载代码并在不同的服务器方案(dev,QA,stage,prod)上运行这些代码.

而且因为我知道有人肯定会对此作出回应. 是的,我理解"有一百万种方法可以做到这一点".你正在向合唱团讲道. 我明白了,但这不是重点.我在这里要求提供大量信息,所以请随意选择要回复的内容,希望能帮助我在构建或环境方面找到正确的方向.我只是想问一下方式周期的例子,或者我的gulp文件的分析,或者只是一个开始的地方!...所以我一般可以理解人们经历的过程以及什么是典型的任务类型运行,做什么在gulp等等,以及如何管理环境变量以及Node应用程序中通常不具备的内容.

Jos*_*eam 2

在我有限的经验中,我认为迄今为止我在构建和配置方面学到的最有益的事情(“sysadmin 是我喝酒的原因”)是让它尽可能简单和可组合

配置信息

对于初学者来说,如果这有帮助的话,我非常喜欢保留配置信息.json并在整个项目中引用它。例如:

// config.json
{
  "STAGING": "http://staging.yourdomain.com/api/",
  "PRODUCTION": "http://yourdomain.com/api/",
  "THE_BEST_PORT_EVER": 1337,
  "MY_DOGS_NAME": "Ginger"
}
Run Code Online (Sandbox Code Playgroud)

这就是整个“魔术字符串”避免的事情,因此您只有一个地方可以引用所有相关的环境信息。

在您的 中gulpfile,当您需要引用某个 URL、某个端口或其他任何内容时,您只需需要它:

var config = require('config.json');
Run Code Online (Sandbox Code Playgroud)

测试东西

有 1,000 种方法可以做到这一点...我不熟悉您当前的设置,但如果它有效,那就有效。但是,我要警告的是,尝试使事物尽可能模块化(例如,即使函数看起来像垃圾,至少它们都是彼此独立的......阅读:函数组合。)

适合不同环境的构建

我讨厌又长又混乱的gulpfiles。目前,我的团队正在开发各种不同的网络和移动应用程序,以及静态网站的各种迭代,所有这些都是为了一种产品。所有这些都需要在各种环境的版本控制中进行跟踪,并构建和部署到各种环境。然而,我希望我们的构建过程相对简单(尽管它们肯定可以改进)。

我喜欢gulpfile这样的 s:

// all your require'd stuff

// this is helpful, 'cause you can do stuff like "gulp --production"
var argv = require('yargs').argv;

var paths = {
  sass: ['some/path/to/sass'],
  // various other paths
};

gulp.task('sass', compileSass);
gulp.task('html', html);
gulp.task('default', watch);
// etc.

// then, in pretty alphabetical order
function compileSass() {
  return gulp.src(paths.sass)
         .pipe(doSomeCoolStuff());
}

function html() {
  // etc.
}

function watch() {
  compileSass();
  html();

  if(argv.production) {
    someSpecificProductionFunction();
  }

  gulp.watch(paths.someAwesomePaths, ['someTask']);
}
Run Code Online (Sandbox Code Playgroud)

我喜欢gulpfile这样的作品,因为它们具有构图性。

就构建而言,我什至不担心定义package.json脚本。您可以...吗?当然。我想这取决于项目和个人/团队风格的问题,但对于我们正在做的项目来说,目前添加额外的抽象层没有任何好处。为什么要运行类似 的东西npm doSomething,它只是 的别名./some-script,而它只是 的别名gulp --production

以下是我们为应用程序提供的自述文件的摘录:

情况1

我想在浏览器中运行该应用程序并访问我的本地服务器

确保您的config-local.json匹配config-example.json,但与您的本地服务器匹配(例如http://your.ip.here:1337/api/)。确保您安装并运行了最新版本的服务器。运行ionic serve

案例2

我想在浏览器中运行该应用程序并访问不同的服务器

更改您的服务器地址config-local.json并按照案例 1 进行操作。

案例3

我想在完整的暂存环境中的设备上运行该应用程序。

跑步gulp --staging。然后跑ionic run --device

案例4

我想在完整的生产环境中的设备上运行该应用程序。

跑步gulp --production。然后跑ionic run --device

大量时间花在“如何让用户更轻松?”上。但问题是“如何让开发人员更容易做到这一点?”

构建过程中涉及的步骤越少,意味着尝试构建时的故障点就越少。

这也意味着您的代码需要尽可能。10 个解决方案可能有相同的结果,但其中 9 个解决方案可能是糟糕的。