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

在这里,我对这个社区很谦虚。 我还不知道节点环境的问题,也是这里唯一的Node开发人员。 一个人的团队现在正在构build我的第一个节点REST API。 (是的,我们真正需要的是更多的人已经知道更多的节点比我帮助这个学习过程)。

我在网上search了好几个小时,尝试尽我所能的努力..但坦率地说,我只是没有find多less设置Node.js 环境 ,以及设置本地与其他环境的构build 。 首先刚刚开始build立一个本地构build – 婴儿的步骤是所有我正在寻找…在一个真实的世界场景。 大多数博客post只显示最简单的 开发 环境 。 所以更糟糕的是,大多数博客文章都提到了网站设置(浏览sh__和类似的东西)。 我正在做一个REST API,而不是一个网站。

我需要一些资源来开始,或者我只是不为他们search节点或他们只是很难find。 我真的想要了解如何设置环境variables,如何使用这些variables来运行不同的环境情况,以及人们如何pipe理持久层的东西,比如数据库连接string等等。我假设也部分通过读取包含连接string的configuration文件的gulp任务来自动化? 我真的不确定,那里没有很多好的例子。

这就是为什么我在这里希望find一些这条路线,在这里张贴这个。 (并希望对我目前的gulp文件发表评论……是否已经或即将接近正确的轨道,还是应该从构build和环境约定和任务开始?

最好的办法是find一个很好的post,让你度过一天的节点开发人员的生活。

我目前在哪里?

我的API :好吧,我已经构build了一些Koa.js端点,我有一些控制器接受请求,通过使用一个网关节点模块来处理它,我有罪,在我所谓的CRUD持久化方法一个网关层调用模型类的底层,这意味着真正的CRUD调用真正的数据库和一些模拟我的testing,等等。非常基本的在这一点…所有的testing通过Mocha.js(BDD风格)驱动。

我的日子 :所以现在,我开始工作,我已经设置了我的mocha.jstesting环境,并且至less能够testing我的代码的驱动器开发,并且testing在保存上运行良好。 我可以看到我的文件和我的testing运行在摩卡报告terminal。 我的应用程序运行,所有。

我的问题 :但我真的没有自动化这一点,而不是通过吞咽。 我想知道更多关于设置环境variables的信息,当开发人员准备构build并推送到git,yada yada,然后最终如何切换环境时,开发人员会做什么,在推送到其他服务器时所做的动作以及所有通过任何configuration或吞咽任务,这将有助于这一点。 我只需要一个这样的生态系统的好例子。 任何一个例子,但一些现实将是如此有帮助。

所以…这是我目前的gulp文件的一瞥 。 现在在那里为babel transpiler(是的,我正在使用ES6到ES5的代码在我的js中)构build的东西,但我从其他代码得到的,但真的没有弄清楚所有这些将如何工作呢。 真的,我设置的东西是我的testing运行和自动化在这一点上。 构build的东西我有点被禁用,因为a)我不知道哪些文件应该是您的app.js,server.js之外的REST API的构build的一部分,b)我从一些代码抓住的构build代码,我发现transpiles js文件通过巴贝尔生成文件夹,但后来我碰到代码碰撞/冲突与我的常规代码的问题。 例如,下面的构build东西是推送server.js到一个构build文件夹,当我试图运行在根中的常规server.js,它是与build / server.js中的代码冲突,所以这一切都已经启动而且显然我不知道我该怎么做,还有什么build设。

'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" }, 

基本上作为一个开发人员,我现在有我的gulp文件的方式是我运行缺省的gulp任务在bash提示符(terminal从Webstorm在我的情况下)input' gulp ' ,然后在这一点上首先几个任务到目前为止发生了一些事情:

  1. 它运行我的所有摩卡testing首次运行吞咽
  2. 观察摩卡的所有js文件,以便在保存任何js代码更改的情况下运行摩卡testing

真的这就是这样。 我可以运行节点服务器以及所有这一切。 但在这一点上,这是非常基本的。 我有愚蠢的app.listen()端口硬编码在我的笨app.js文件,显然是… …很好的硬编码!

说实话,我有不同的端口为我的不同的testing套件,因为我发现我不得不由于港口冲突,但也许这只是因为我奇怪,我不知道这是不同的口径运行您的验收testing与标准vs.单位,但我会这样认为。

唉唉! 拜托!

所以在这一点上,我想拉我的头发如何解决这个问题:

  1. 如何为REST API设置一个真正的构build(可以通过babel将js代码转移到哪里以及哪些内容?)
  2. 用于设置任务,configuration等的生态系统,用于在不同环境中自动构build和推送代码以及运行代码。这看起来像什么!
  3. 在不同的环境中下拉代码,运行那些不在不同的服务器场景(dev,QA,stage,prod)的代码。

而且因为我知道有人会肯定地回应。 是的,我明白“有一百万种方法可以做到这一点” 。 你正在向合唱团传道。 我明白了,但这不是重点。 我在这里要求了很多信息,所以可以自由select要回复的内容,希望能帮助我在正确的方向上构build或环境。 我只是要求一些例子,或者分析我的大文件,或者只是一个开始的地方!…所以我通常可以理解人们经历的过程以及什么是典型的任务types等等,以及如何pipe理环境variables以及Node应用程序中通常不会包含哪些内容。

在我有限的经验中,我认为迄今为止,通过构build和configuration这些东西(“系统pipe理员是我喝酒的原因”)学到的最有益的东西就是尽可能简单和可组合

configuration信息

对于初学者来说,如果这样做有帮助的话,我会保持configuration信息是一个.json并在整个项目中引用它。 例如:

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

这是整个“魔术串”避免的事情,所以你只有一个地方参考你所有的相关环境信息。

在你的gulpfile ,当你需要引用一些URL,或者某个端口,或者任何其他的时候,你只需要它:

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

testing的东西

有一千种方法可以做到这一点…我不熟悉你现有的设置,但如果它有效的话,它是有效的。 但是,我会告诫说,尽量保持事物的模块化(即使函数看起来像废话,至less它们都是彼此独立的……阅读:函数组合)。

build立不同的环境

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

我喜欢这样的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 ,因为它们是合成的。

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

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

情况1

我想在我的浏览器中运行应用程序,击中我的本地服务器

确保你的config-local.jsonconfig-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

花了很多时间在“如何让用户更容易”? 但是关于这个问题呢,我怎样才能让开发者更容易呢?

构build过程涉及的步骤越less意味着构build过程中失败点越less。

这也意味着你的代码需要尽可能 。 10个解决scheme可能会有相同的结果,但其中9个解决scheme可能是废话。