创建一个Feathers插件¶
创建插件的最简单方法是使用 Yeoman generator.
首先安装发电机
$ npm install -g generator-feathers-plugin
然后在新目录中运行:
$ yo feathers-plugin
这将支持开始编写插件所需的一切.
从发电机输出文件:
create package.json
create .babelrc
create .editorconfig
create .jshintrc
create .travis.yml
create src/index.js
create test/index.test.js
create README.md
create LICENSE
create .gitignore
create .npmignore
简单吧?我们在技术上可以称它为一天,因为我们创建了一个插件.但是,我们可能想要做更多.一般来说,插件是 服务.有趣的是,插件可以包含我们将在下面创建的多个服务.这个例子将构建2个服务.第一个将允许我们找到Feathers核心团队的成员,第二个将允许我们找到美国最好的州.
##验证我们的服务
在我们开始编写更多代码之前,我们需要看到事情正在发挥作用.
$ cd example && node app.js
Error: Cannot find module '../lib/index'
简单?我们可以在技术上称它为一天,因为我们创建了一个插件.但是,我们可能想要做更多.一般来说,插件是 ../api/services.有趣的是,该插件可以包含我们将在下面创建的多个服务.此示例将构建2个服务.第一个将允许我们找到Feathers核心团队的成员,第二个将允许我们找到美国最好的州.
"scripts": {
"prepublish": "npm run compile",
"publish": "git push origin && git push origin --tags",
"release:patch": "npm version patch && npm publish",
"release:minor": "npm version minor && npm publish",
"release:major": "npm version major && npm publish",
"compile": "rimraf lib/ && babel -d lib/ src/",
"watch": "babel --watch -d lib/ src/",
"jshint": "jshint src/. test/. --config",
"mocha": "mocha --recursive test/ --compilers js:babel-core/register",
"test": "npm run compile && npm run jshint && npm run mocha",
"start": "npm run compile && node example/app"
}
回到工作.该错误消息告诉我们,我们需要构建我们的项目.在这种情况下,这意味着babel需要做的事情.对于开发,您可以运行手表
$ npm run watch
> creatingPlugin@0.0.0 watch /Users/ajones/git/training/creatingPlugin
> babel --watch -d lib/ src/
src/index.js -> lib/index.js
之后,您可以运行示例应用程序,一切都应该很好.
$ node app.js
Feathers app started on 127.0.0.1:3030
扩展我们的插件¶
现在我们进行了验证,我们可以安全地改变一切.对于此示例,我们希望从插件中公开2个服务.让我们在src文件夹中创建一个服务目录.
// From the src directory
$ mkdir services
$ ls
index.js services
现在让我们创建两个服务.我们将只复制index.js文件.
$ cp index.js services/core-team.js
$ cp index.js services/best-state.js
$ cd services && ls
best-state.js core-team.js
$ cat best-state.js
if (!global._babelPolyfill) { require('babel-polyfill'); }
import errors from 'feathers-errors';
import makeDebug from 'debug';
const debug = makeDebug('creatingPlugin');
class Service {
constructor(options = {}) {
this.options = options;
}
find(params) {
return new Promise((resolve, reject) => {
// Put some async code here.
if (!params.query) {
return reject(new errors.BadRequest());
}
resolve([]);
});
}
}
export default function init(options) {
debug('Initializing creatingPlugin plugin');
return new Service(options);
}
init.Service = Service;
此时我们有index.js,best-state.js和core-team.js,内容相同.下一步将是更改index.js,以便它是我们的主文件.
我们新的index.js
if (!global._babelPolyfill) { require('babel-polyfill'); }
import coreTeam from './services/core-team';
import bestState from './services/best-state';
export default { coreTeam, bestState };
现在我们需要实际编写服务.我们只会实现find动作,因为您可以参考 服务 来了解更多信息.从core-team.js开始,我们想要找出github上的feathers.js org中列出的成员的名字.
//core-team.js
if (!global._babelPolyfill) { require('babel-polyfill'); }
import errors from 'feathers-errors';
import makeDebug from 'debug';
const debug = makeDebug('creatingPlugin');
class Service {
constructor(options = {}) {
this.options = options;
}
//We are only changing the find...
find(params) {
return Promise.resolve(['Mikey', 'Cory Smith', 'David Luecke', 'Emmanuel Bourmalo', 'Eric Kryski',
'Glavin Wiechert', 'Jack Guy', 'Anton Kulakov', 'Marshall Thompson'])
}
}
export default function init(options) {
debug('Initializing creatingPlugin plugin');
return new Service(options);
}
init.Service = Service;
现在,当调用service.find时,它将返回一个名称数组.继续使用最佳状态服务,我们可以遵循相同的模式
if (!global._babelPolyfill) { require('babel-polyfill'); }
import errors from 'feathers-errors';
import makeDebug from 'debug';
const debug = makeDebug('creatingPlugin');
class Service {
constructor(options = {}) {
this.options = options;
}
find(params) {
return Promise.resolve(['Alaska']);
}
}
export default function init(options) {
debug('Initializing creatingPlugin plugin');
return new Service(options);
}
init.Service = Service;
请注意,在上面的服务中,它返回一个列出最佳状态的单个项目数组.
用法¶
使用我们插件的最简单方法是在我们之前使用的app.js文件中.让我们在该文件中写出一些基本用法.
//app.js
const feathers = require('feathers');
const rest = require('feathers-rest');
const hooks = require('feathers-hooks');
const bodyParser = require('body-parser');
const errorHandler = require('feathers-errors/handler');
const plugin = require('../lib/index');
// Initialize the application
const app = feathers()
.configure(rest())
.configure(hooks())
// Needed for parsing bodies (login)
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }))
// Initialize your feathers plugin
.use('/plugin/coreTeam', plugin.coreTeam())
.use('/plugin/bestState', plugin.bestState())
.use(errorHandler());
var bestStateService = app.service('/plugin/bestState')
var coreTeamService = app.service('/plugin/coreTeam')
bestStateService.find().then( (result) => {
console.log(result)
}).catch( error => {
console.log('Error finding the best state ', error)
})
coreTeamService.find().then( (result) => {
console.log(result)
}).catch( error => {
console.log('Error finding the core team ', error)
})
app.listen(3030);
console.log('Feathers app started on 127.0.0.1:3030');
$ node app.js
Feathers app started on 127.0.0.1:3030
[ 'Alaska' ]
[ 'Mikey',
'Cory Smith',
'David Luecke',
'Emmanuel Bourmalo',
'Eric Kryski',
'Glavin Wiechert',
'Jack Guy',
'Anton Kulakov',
'Marshall Thompson' ]
测试¶
我们的发电机剔除了一些基本测试.我们将删除所有内容并将其替换为以下内容.
import { expect } from 'chai';
import plugin from '../src';
const bestStateService = plugin.bestState()
describe('bestState', () => {
it('is Alaska', () => {
bestStateService.find().then(result => {
console.log(result)
expect(result).to.eql(['Alaska']);
done();
});
});
});
$ npm run test
因为这只是一个快速的示例jshint可能会失败.您可以修复语法或更改测试命令.
$ npm run compile && npm run mocha
这应该为您提供创建Feathers插件的基本概念.