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

时间:2015-08-01 05:59:05

标签: 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)我从一些代码中抓取的构建代码我发现通过babel将js文件转换为构建文件夹,但后来我遇到代码冲突/与常规代码冲突的问题。例如,下面的构建内容是将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);
});
到目前为止

我的 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"
  },

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

  1. 它在第一次gulp
  2. 上运行我的所有mocha测试
  3. 监视mocha的所有js文件,以便在保存任何js代码更改时运行mocha测试
  4. 真的,这就是他们所做的一切。我可以运行节点服务器ok和所有这些。但在这一点上它是非常基础的。我在我的哑app.js文件中硬编码了愚蠢的app.listen()端口,这显然是......很难编码!

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

    唉唉!!请高兴!

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

    1. 如何为 REST API设置真正的构建(好吧,你可以通过babel将js代码转换到哪里,以及什么呢?)
    2. 用于设置任务,配置等的生态系统,用于在差异环境中自动构建和推送和运行代码。这看起来像什么!
    3. 在不同的环境中下载代码并运行那些代码以及不同的服务器方案(dev,QA,stage,prod)。
    4. 因为我知道有人肯定会对此作出回应。 是的我理解"有一百万种方法可以做到这一点" 。你正在向合唱团讲道。 我明白了,但这不是重点。我在这里要求提供大量信息,所以请随意选择要回复的内容,希望能帮助我在构建或环境方面找到正确的方向。我只想询问方式的例子,或者我的gulp文件的分析,或者只是一个开始的地方!...所以我通常可以理解人们经历的过程以及执行什么操作的典型任务类型在gulp等中以及如何管理环境变量以及在Node应用程序中通常不会这样做。

1 个答案:

答案 0 :(得分:2)

在我有限的经验中,我认为到目前为止我用这个构建和配置的东西(“系统管理员就是为什么我喝酒”)学到的最有益的事情是保持它尽可能简单和可组合

配置信息

对于初学者来说,如果这有帮助的话,我很擅长保持配置信息是.json并在整个项目中引用它。例如:

// config.json
{
  "STAGING": "http://staging.yourdomain.com/api/",
  "PRODUCTION": "http://yourdomain.com/api/",
  "THE_BEST_PORT_EVER": 1337,
  "MY_DOGS_NAME": "Ginger"
}

这就是整个“神奇的字符串”避免的事情,所以你只有一个的地方来引用所有相关的环境信息。

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

var config = require('config.json');

测试东西

有1000种方法可以做到这一点......我不熟悉你现有的设置,但如果有效,它就可以了。但是,我会注意到,尽量保持模块尽可能模块化(例如,即使函数看起来像废话,至少它们都是彼此独立的......阅读:函数组合。)

为不同的环境构建

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

我喜欢看起来像这样的gulpfile

// 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']);
}

我喜欢看起来像那样的gulpfile,因为它们是成分。

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

以下是我们为应用程序提供的README的摘录:

  

案例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个解决方案可能是废话。