Javascript 为Node/ES6模块提供更好的模块模式
我正在努力想出一种模式,既能满足我的测试,又能满足Travis运行脚本的能力 首先,我要说,我让Travis运行脚本的方式是,我在我的Travis.yml中指定要通过node babel命令运行的脚本,如下所示: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
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});}