Javascript 为Node/ES6模块提供更好的模块模式

Javascript 为Node/ES6模块提供更好的模块模式,javascript,node.js,ecmascript-6,Javascript,Node.js,Ecmascript 6,我正在努力想出一种模式,既能满足我的测试,又能满足Travis运行脚本的能力 首先,我要说,我让Travis运行脚本的方式是,我在我的Travis.yml中指定要通过node babel命令运行的脚本,如下所示: script: - babel-node ./src/client/deploy/deploy-feature-branch.js 这意味着,当babel节点运行此功能时,我需要一个方法来自动在我拥有的deployfeaturebranch.js中运行。这是一行让{failure

我正在努力想出一种模式,既能满足我的测试,又能满足Travis运行脚本的能力

首先,我要说,我让Travis运行脚本的方式是,我在我的Travis.yml中指定要通过node babel命令运行的脚本,如下所示:

script:
  - babel-node ./src/client/deploy/deploy-feature-branch.js
这意味着,当babel节点运行此功能时,我需要一个方法来自动在我拥有的
deployfeaturebranch.js
中运行。这是一行
让{failure,success,payload}=deployFeatureBranch()
。这将强制
deployFeatureBranch()
运行,因为它被设置为destructure命令

在那里我还有一个
选项
对象:

let options = {
  localBuildFolder: 'build',
  domain: 'ourdomain',
  branch: process.env.TRAVIS_PULL_REQUEST_BRANCH
}
在PR构建过程中,travis会自动设置
process.env.travis\u PULL\u REQUEST\u BRANCH
的值。太好了!但是,我设置此模块的方式在测试中效果不太好。我的问题是如果我试图从测试中设置选项,由于某种原因,选项对象没有被设置

我想我首先要解决的问题是,为什么我在测试中设置选项时没有设置选项。然后,有没有更好的方法来设计这个模块的整体

测试

import {options, deployFeatureBranch } from '../../../client/deploy/deploy-feature-branch'

    it.only('creates a S3 test environment for a pull request', async () => {
      options.branch = 'feature-100'
      options.domain = 'ourdomain'
      options.localDeployFolder = 'build'

      const result = await deployFeatureBranch()
      expect(result.success).to.be.true
    })
})
当在我的测试中运行上面的
deployFeatureBranch()
时 尝试引用
选项。分支
,但结果是
未定义
,即使我将其设置为
'feature-100'
。branch默认为process.env.TRAVIS_PULL_REQUEST_branch,但我希望能够覆盖它并从测试中设置它

部署功能分支.js

import * as deployApi from './deployApi'

let options = {
  localBuildFolder: 'build',
  domain: 'ourdomain',
  branch: process.env.TRAVIS_PULL_REQUEST_BRANCH
}

const deployFeatureBranch = async (options) => {
    console.log(green(`Deploying feature branch: ${options.branch}`))
    let { failure, success, payload } = await deployApi.run(options)
    return { failure, success, payload }
}

let { failure, success, payload } = deployFeatureBranch(options)

export {
  options,
  deployFeatureBranch
}

我真的想不出一个更好的方法来组织这个,并解决设置选项的问题。我也不局限于使用节点模块,我也可以使用ES6导出。

在测试中调用函数时,只需传入新的
选项
对象,而不是导出并修改它:

import {deployFeatureBranch } from '../../../client/deploy/deploy-feature-branch'

    it.only('creates a S3 test environment for a pull request', async () => {
      const options = {
        branch: 'feature-100',
        domain: 'ourdomain',
        localDeployFolder: 'build'
      };

      const result = await deployFeatureBranch(options)
      expect(result.success).to.be.true
    })
});
它不起作用的原因是您的
deployFeatureBranch()
函数期望在调用它时传入
选项
,而您没有这样做


此外,导出和更改对象虽然可能有效,但也非常奇怪,应该避免。创建一个新对象(或克隆导出的对象)无疑是一条路。

我知道,但我想强制执行一项合同。我只想允许某些字段,我想我是在向它传递选项:
const deployFeatureBranch=async(options)
async(options)=>{}
只声明一个函数,该函数使用在该函数内部调用的参数。分解结构的那一行实际上是调用函数并传递选项的那一行。此外,导出和修改对象并不是真正强制执行契约。你可以很容易地说,
option.crazycookiesmonsters
,这样就行了。但实际上,没有理由明确禁止其他参数。在99.9%的情况下,它不会损害任何东西。至于克隆,你不应该修改导出,因为它会导致不稳定的事情发生。这是导出的唯一版本,导入的所有内容都会发生更改。如果需要修改该对象,更好的解决方案是先克隆它,然后修改克隆。这是一个很好的做法,可以避免奇怪和难以跟踪的错误。如果您真的想强制执行约定,而不是接受选项:
async(options)=>{}
,请在参数进入时对其进行分解,并仅使用这些参数构建新对象。然后任何额外的内容都会被丢弃:
async({a,b,c})=>{myFunc({a,b,c});}