注册插件 #

一、基本注册 #

1.1 注册单个插件 #

javascript
const Hapi = require('@hapi/hapi');

const myPlugin = {
    name: 'my-plugin',
    register: async (server, options) => {
        console.log('Plugin registered!');
    }
};

const init = async () => {
    const server = Hapi.server({ port: 3000 });
    
    await server.register(myPlugin);
    
    await server.start();
};

init();

1.2 注册多个插件 #

javascript
await server.register([pluginA, pluginB, pluginC]);

1.3 注册带选项的插件 #

javascript
await server.register({
    plugin: myPlugin,
    options: {
        setting1: 'value1',
        setting2: 'value2'
    }
});

二、注册配置 #

2.1 插件选项 #

javascript
const dbPlugin = {
    name: 'database',
    register: async (server, options) => {
        console.log('Database config:', options);
    }
};

await server.register({
    plugin: dbPlugin,
    options: {
        host: 'localhost',
        port: 5432,
        database: 'myapp'
    }
});

2.2 路由前缀 #

javascript
await server.register({
    plugin: apiPlugin,
    options: {},
    routes: {
        prefix: '/api/v1'
    }
});

插件中的路由 /users 会变成 /api/v1/users

2.3 路由配置 #

javascript
await server.register({
    plugin: myPlugin,
    routes: {
        prefix: '/api',
        vhost: 'api.example.com'
    }
});

三、注册npm插件 #

3.1 安装插件 #

bash
npm install @hapi/inert @hapi/vision

3.2 注册插件 #

javascript
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');

await server.register([Inert, Vision]);

3.3 带选项注册 #

javascript
await server.register({
    plugin: require('@hapi/vision'),
    options: {
        engines: {
            ejs: require('ejs')
        },
        path: './views'
    }
});

四、插件依赖 #

4.1 声明依赖 #

javascript
const authPlugin = {
    name: 'auth',
    register: async (server, options) => {
        server.auth.scheme('custom', customScheme);
    }
};

const userPlugin = {
    name: 'users',
    dependencies: ['auth'],
    register: async (server, options) => {
        server.route({
            method: 'GET',
            path: '/profile',
            options: { auth: 'custom' },
            handler: getProfile
        });
    }
};

await server.register([authPlugin, userPlugin]);

4.2 依赖版本 #

javascript
const plugin = {
    name: 'my-plugin',
    dependencies: {
        'auth': '>=1.0.0',
        'database': '>=2.0.0'
    },
    register: async (server, options) => {
    }
};

五、注册顺序 #

5.1 顺序注册 #

javascript
await server.register(pluginA);
await server.register(pluginB);
await server.register(pluginC);

5.2 并行注册 #

javascript
await server.register([pluginA, pluginB, pluginC]);

5.3 混合注册 #

javascript
await server.register([
    Inert,
    Vision,
    {
        plugin: customPlugin,
        options: { setting: 'value' }
    }
]);

六、插件状态 #

6.1 检查插件是否注册 #

javascript
const registrations = server.registrations;

if (registrations['my-plugin']) {
    console.log('Plugin is registered');
}

6.2 获取插件信息 #

javascript
const registrations = server.registrations;

Object.keys(registrations).forEach(name => {
    const plugin = registrations[name];
    console.log(`${name} v${plugin.version}`);
});

七、注册选项 #

7.1 once选项 #

插件只注册一次:

javascript
const plugin = {
    name: 'once-plugin',
    once: true,
    register: async (server, options) => {
        console.log('This runs only once');
    }
};

await server.register(plugin);
await server.register(plugin);

7.2 requirements选项 #

指定Hapi版本要求:

javascript
const plugin = {
    name: 'versioned-plugin',
    requirements: {
        hapi: '>=20.0.0'
    },
    register: async (server, options) => {
    }
};

八、完整示例 #

8.1 注册多个插件 #

javascript
const Hapi = require('@hapi/hapi');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');

const authPlugin = {
    name: 'auth',
    register: async (server, options) => {
        server.auth.scheme('simple', (server, options) => ({
            authenticate: (request, h) => {
                const token = request.headers.authorization;
                if (!token) {
                    throw Boom.unauthorized('Missing token');
                }
                return h.authenticated({ credentials: { token } });
            }
        }));
        
        server.auth.strategy('simple', 'simple');
    }
};

const routesPlugin = {
    name: 'routes',
    dependencies: ['auth'],
    register: async (server, options) => {
        server.route([
            {
                method: 'GET',
                path: '/',
                handler: (request, h) => {
                    return { message: 'Hello' };
                }
            },
            {
                method: 'GET',
                path: '/profile',
                options: {
                    auth: 'simple'
                },
                handler: (request, h) => {
                    return { user: request.auth.credentials };
                }
            }
        ]);
    }
};

const init = async () => {
    const server = Hapi.server({ port: 3000 });
    
    await server.register([
        Inert,
        Vision,
        authPlugin,
        {
            plugin: routesPlugin,
            routes: {
                prefix: '/api'
            }
        }
    ]);
    
    await server.start();
    console.log('Server running on %s', server.info.uri);
};

init();

8.2 配置化注册 #

javascript
const plugins = [
    {
        plugin: require('@hapi/inert'),
        options: {}
    },
    {
        plugin: require('@hapi/vision'),
        options: {
            engines: { ejs: require('ejs') },
            path: './views'
        }
    },
    {
        plugin: require('./plugins/auth'),
        options: {
            secret: process.env.JWT_SECRET
        }
    },
    {
        plugin: require('./plugins/routes'),
        routes: {
            prefix: '/api/v1'
        }
    }
];

await server.register(plugins);

九、错误处理 #

9.1 注册失败 #

javascript
try {
    await server.register(plugin);
} catch (error) {
    console.error('Plugin registration failed:', error);
    process.exit(1);
}

9.2 依赖缺失 #

javascript
const plugin = {
    name: 'dependent',
    dependencies: ['non-existent'],
    register: async (server, options) => {
    }
};

try {
    await server.register(plugin);
} catch (error) {
    console.error('Missing dependency:', error.message);
}

十、总结 #

注册插件要点:

方法 说明
server.register() 注册插件
options 插件配置
routes.prefix 路由前缀
dependencies 插件依赖

下一步,让我们学习如何编写自定义插件!

最后更新:2026-03-28