diff --git a/packages/serverless-spec-builder/package.json b/packages/serverless-spec-builder/package.json index 12cbb3ab1bc9..4b3cbc03643a 100644 --- a/packages/serverless-spec-builder/package.json +++ b/packages/serverless-spec-builder/package.json @@ -20,7 +20,8 @@ "dist", "fc", "scf", - "aws" + "aws", + "wrapper.ejs" ], "scripts": { "build": "midway-bin build -c", diff --git a/packages/serverless-spec-builder/src/wrapper.ts b/packages/serverless-spec-builder/src/wrapper.ts index 96d10cd63845..3172f113ed2a 100644 --- a/packages/serverless-spec-builder/src/wrapper.ts +++ b/packages/serverless-spec-builder/src/wrapper.ts @@ -1,60 +1,7 @@ -import { join } from 'path'; -import { writeFileSync, existsSync } from 'fs'; +import { join, resolve } from 'path'; +import { writeFileSync, existsSync, readFileSync } from 'fs'; import { render } from 'ejs'; import { getLayers } from './utils'; -export const wrapperContent = `const { FaaSStarter } = require('<%=faasModName %>'); -const { asyncWrapper, start } = require('<%=starter %>'); -<% layerDeps.forEach(function(layer){ %>const <%=layer.name%> = require('<%=layer.path%>'); -<% }); %> - -let starter; -let runtime; -let inited = false; - -const initializeMethod = async (initializeContext = {}) => { - runtime = await start({ - layers: [<%= layers.join(", ") %>] - }); - starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); - <% loadDirectory.forEach(function(dirName){ %> - starter.loader.loadDirectory({ baseDir: '<%=dirName%>'});<% }) %> - await starter.start(); - inited = true; -}; - -exports.initializer = asyncWrapper(async (...args) => { - await initializeMethod(...args); -}); - -<% handlers.forEach(function(handlerData){ %> -exports.<%=handlerData.name%> = asyncWrapper(async (...args) => { - if (!inited) { - await initializeMethod(); - } - <% if (handlerData.handler) { %> - return runtime.asyncEvent(starter.handleInvokeWrapper('<%=handlerData.handler%>'))(...args); - <% } else { %> - const picomatch = require('picomatch'); - const allHandlers = <%-JSON.stringify(handlerData.handlers)%>; - return runtime.asyncEvent(async (ctx) => { - let handler = null; - let ctxPath = ctx && ctx.path || ''; - if (ctxPath) { - handler = allHandlers.find(handler => { - return picomatch.isMatch(ctxPath, handler.router) - }); - } - - if (handler) { - return starter.handleInvokeWrapper(handler.handler)(ctx); - } - ctx.status = 404; - ctx.set('Content-Type', 'text/html'); - return '

404 Page Not Found


Request path: ' + ctxPath + '
Powered by Midway
'; - })(...args); - <% } %> -}); -<% }); %>`; // 写入口 export function writeWrapper(options: { @@ -64,7 +11,8 @@ export function writeWrapper(options: { starter: string; cover?: boolean; loadDirectory?: string[]; - faasModName?: string; + initializeName?: string; // default is initializer + faasModName?: string; // default is '@midwayjs/faas' }) { const { service, @@ -73,6 +21,7 @@ export function writeWrapper(options: { baseDir, cover, faasModName, + initializeName, loadDirectory = [], } = options; const files = {}; @@ -109,14 +58,15 @@ export function writeWrapper(options: { }); } } - + const tpl = readFileSync(resolve(__dirname, '../wrapper.ejs')).toString(); for (const file in files) { const fileName = join(distDir, `${file}.js`); const layers = getLayers(service.layers, ...files[file].originLayers); - const content = render(wrapperContent, { + const content = render(tpl, { starter, faasModName: faasModName || '@midwayjs/faas', loadDirectory, + initializer: initializeName || 'initializer', handlers: files[file].handlers, ...layers, }); diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js b/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js index 635aee366e6d..0fc84a644ee2 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js @@ -1,14 +1,17 @@ const { FaaSStarter } = require('@midwayjs/faas'); const { asyncWrapper, start } = require('testStarter'); +const picomatch = require('picomatch'); let starter; let runtime; let inited = false; + const initializeMethod = async (initializeContext = {}) => { runtime = await start({ - layers: [] + layers: [], + getHandler: getHandler }); starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); @@ -16,7 +19,31 @@ const initializeMethod = async (initializeContext = {}) => { inited = true; }; -exports.initializer = asyncWrapper(async (...args) => { +const getHandler = (hanlderName) => { + + if (hanlderName === 'handler') { + return async (ctx) => { + const allHandlers = [{"handler":"index.handler","router":"/api/test","pureRouter":"/api/test","level":2},{"handler":"render.handler","router":"/**","pureRouter":"/","level":1}]; + let handler = null; + let ctxPath = ctx && ctx.path || ''; + if (ctxPath) { + handler = allHandlers.find(handler => { + return picomatch.isMatch(ctxPath, handler.router) + }); + } + + if (handler) { + return starter.handleInvokeWrapper(handler.handler)(ctx); + } + ctx.status = 404; + ctx.set('Content-Type', 'text/html'); + return '

404 Page Not Found


Request path: ' + ctxPath + '
Powered by Midway Serverless
'; + }; + } +} + + +exports.initializeUserDefine = asyncWrapper(async (...args) => { await initializeMethod(...args); }); @@ -25,24 +52,7 @@ exports.handler = asyncWrapper(async (...args) => { if (!inited) { await initializeMethod(); } - - const picomatch = require('picomatch'); - const allHandlers = [{"handler":"index.handler","router":"/api/test","pureRouter":"/api/test","level":2},{"handler":"render.handler","router":"/**","pureRouter":"/","level":1}]; - return runtime.asyncEvent(async (ctx) => { - let handler = null; - let ctxPath = ctx && ctx.path || ''; - if (ctxPath) { - handler = allHandlers.find(handler => { - return picomatch.isMatch(ctxPath, handler.router) - }); - } - if (handler) { - return starter.handleInvokeWrapper(handler.handler)(ctx); - } - ctx.status = 404; - ctx.set('Content-Type', 'text/html'); - return '

404 Page Not Found


Request path: ' + ctxPath + '
Powered by Midway
'; - })(...args); - + const handler = getHandler('handler'); + return runtime.asyncEvent(handler)(...args); }); diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/index.js b/packages/serverless-spec-builder/test/fixtures/wrapper/index.js index a3fa8c0be141..16a21033c346 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/index.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/index.js @@ -1,14 +1,17 @@ const { FaaSStarter } = require('@midwayjs/faas'); const { asyncWrapper, start } = require('testStarter'); +const picomatch = require('picomatch'); let starter; let runtime; let inited = false; + const initializeMethod = async (initializeContext = {}) => { runtime = await start({ - layers: [] + layers: [], + getHandler: getHandler }); starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); @@ -16,7 +19,15 @@ const initializeMethod = async (initializeContext = {}) => { inited = true; }; -exports.initializer = asyncWrapper(async (...args) => { +const getHandler = (hanlderName) => { + + if (hanlderName === 'handler') { + return starter.handleInvokeWrapper('index.handler'); + } +} + + +exports.initializeUserDefine = asyncWrapper(async (...args) => { await initializeMethod(...args); }); @@ -25,7 +36,7 @@ exports.handler = asyncWrapper(async (...args) => { if (!inited) { await initializeMethod(); } - - return runtime.asyncEvent(starter.handleInvokeWrapper('index.handler'))(...args); - + + const handler = getHandler('handler'); + return runtime.asyncEvent(handler)(...args); }); diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/render.js b/packages/serverless-spec-builder/test/fixtures/wrapper/render.js index 86715b8f905a..e2bdbefb299f 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/render.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/render.js @@ -1,14 +1,17 @@ const { FaaSStarter } = require('@midwayjs/faas'); const { asyncWrapper, start } = require('testStarter'); +const picomatch = require('picomatch'); let starter; let runtime; let inited = false; + const initializeMethod = async (initializeContext = {}) => { runtime = await start({ - layers: [] + layers: [], + getHandler: getHandler }); starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); @@ -16,7 +19,15 @@ const initializeMethod = async (initializeContext = {}) => { inited = true; }; -exports.initializer = asyncWrapper(async (...args) => { +const getHandler = (hanlderName) => { + + if (hanlderName === 'handler') { + return starter.handleInvokeWrapper('render.handler'); + } +} + + +exports.initializeUserDefine = asyncWrapper(async (...args) => { await initializeMethod(...args); }); @@ -25,7 +36,7 @@ exports.handler = asyncWrapper(async (...args) => { if (!inited) { await initializeMethod(); } - - return runtime.asyncEvent(starter.handleInvokeWrapper('render.handler'))(...args); - + + const handler = getHandler('handler'); + return runtime.asyncEvent(handler)(...args); }); diff --git a/packages/serverless-spec-builder/test/wrapper.test.ts b/packages/serverless-spec-builder/test/wrapper.test.ts index 6a0482a80f97..768fa66f9d30 100644 --- a/packages/serverless-spec-builder/test/wrapper.test.ts +++ b/packages/serverless-spec-builder/test/wrapper.test.ts @@ -1,11 +1,14 @@ import { writeWrapper } from '../src/wrapper'; -import * as path from 'path'; +import { resolve } from 'path'; import * as assert from 'assert'; +import { existsSync, readFileSync } from 'fs'; describe('/test/wrapper.test.ts', () => { describe('test all format', () => { it('writeWrapper', () => { + const wrapperPath = resolve(__dirname, './fixtures/wrapper'); writeWrapper({ + initializeName: 'initializeUserDefine', cover: true, service: { functions: { @@ -26,11 +29,31 @@ describe('/test/wrapper.test.ts', () => { }, }, }, - baseDir: path.join(__dirname, './fixtures/wrapper'), - distDir: path.join(__dirname, './fixtures/wrapper'), + baseDir: wrapperPath, + distDir: wrapperPath, starter: 'testStarter', }); - assert(true); + const aggrePath = resolve(wrapperPath, 'aggre.js'); + const indexPath = resolve(wrapperPath, 'index.js'); + const renderPath = resolve(wrapperPath, 'render.js'); + assert(existsSync(aggrePath)); + assert(existsSync(indexPath)); + assert(existsSync(renderPath)); + assert( + /exports\.initializeUserDefine\s*=/.test( + readFileSync(aggrePath).toString() + ) + ); + assert( + /exports\.initializeUserDefine\s*=/.test( + readFileSync(indexPath).toString() + ) + ); + assert( + /exports\.initializeUserDefine\s*=/.test( + readFileSync(renderPath).toString() + ) + ); }); }); }); diff --git a/packages/serverless-spec-builder/wrapper.ejs b/packages/serverless-spec-builder/wrapper.ejs new file mode 100644 index 000000000000..882901b55056 --- /dev/null +++ b/packages/serverless-spec-builder/wrapper.ejs @@ -0,0 +1,64 @@ +const { FaaSStarter } = require('<%=faasModName %>'); +const { asyncWrapper, start } = require('<%=starter %>'); +const picomatch = require('picomatch'); +<% layerDeps.forEach(function(layer){ %>const <%=layer.name%> = require('<%=layer.path%>'); +<% }); %> + +let starter; +let runtime; +let inited = false; + + +const initializeMethod = async (initializeContext = {}) => { + runtime = await start({ + layers: [<%= layers.join(", ") %>], + getHandler: getHandler + }); + starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); + <% loadDirectory.forEach(function(dirName){ %> + starter.loader.loadDirectory({ baseDir: '<%=dirName%>'});<% }) %> + await starter.start(); + inited = true; +}; + +const getHandler = (hanlderName) => { + <% handlers.forEach(function(handlerData){ %> + if (hanlderName === '<%=handlerData.name%>') { + return <% if (handlerData.handler) { + %> starter.handleInvokeWrapper('<%=handlerData.handler%>'); <% } else { + %> async (ctx) => { + const allHandlers = <%-JSON.stringify(handlerData.handlers)%>; + let handler = null; + let ctxPath = ctx && ctx.path || ''; + if (ctxPath) { + handler = allHandlers.find(handler => { + return picomatch.isMatch(ctxPath, handler.router) + }); + } + + if (handler) { + return starter.handleInvokeWrapper(handler.handler)(ctx); + } + ctx.status = 404; + ctx.set('Content-Type', 'text/html'); + return '

404 Page Not Found


Request path: ' + ctxPath + '
Powered by Midway Serverless
'; + }; <% } %> + } + <% }); %> +} + + +exports.<%=initializer%> = asyncWrapper(async (...args) => { + await initializeMethod(...args); +}); + +<% handlers.forEach(function(handlerData){ %> +exports.<%=handlerData.name%> = asyncWrapper(async (...args) => { + if (!inited) { + await initializeMethod(); + } + + const handler = getHandler('<%=handlerData.name%>'); + return runtime.asyncEvent(handler)(...args); +}); +<% }); %> \ No newline at end of file