
بروزرسانی: 23 تیر 1404
ساخت پروژه های AWS SAM TypeScript با پشتیبانی Jest
یک ابزار قدرتمند برای ساخت برنامه های بدون سرور، مدل برنامه بدون سرور AWS (SAM) اغلب با جاوا اسکریپت جفت می شود: 62% توسعه دهندگان در شرکت های متوسط \u200b\u200bو بزرگ جاوا اسکریپت را برای کدهای بدون سرور خود انتخاب می کنند. با این حال، تایپ اسکریپت در حال افزایش محبوبیت است و به مراتب از جاوا اسکریپت به عنوان توسعه دهندگان بالاتر است. سوممحبوب ترین زبان
در حالی که پیدا کردن boilerplate جاوا اسکریپت کار سختی نیست، شروع پروژه های AWS SAM با TypeScript پیچیده تر است. آموزش زیر نحوه ایجاد یک پروژه AWS SAM TypeScript را از ابتدا و همچنین نحوه کار قسمت های مختلف با هم را نشان می دهد. خوانندگان فقط باید تا حدودی با توابع AWS Lambda آشنا باشند تا دنبال شوند.
شروع پروژه AWS SAM TypeScript ما
اساس برنامه بدون سرور ما شامل اجزای مختلفی است. ابتدا محیط AWS، بسته npm خود و عملکرد Webpack را پیکربندی می کنیم – سپس می توانیم عملکرد Lambda خود را ایجاد، فراخوانی و آزمایش کنیم تا برنامه خود را در عمل ببینیم.
محیط زیست را آماده کنید
برای راه اندازی محیط AWS باید موارد زیر را نصب کنیم:
توجه داشته باشید که این آموزش نیاز به نصب دارد داکر در مرحله 2 بالا برای آزمایش برنامه ما به صورت محلی.
یک پروژه خالی را راه اندازی کنید
بیایید دایرکتوری پروژه را ایجاد کنیم، aws-sam-typescript-boilerplate
، و الف src
زیر پوشه برای نگهداری کد از دایرکتوری پروژه، یک بسته جدید npm را راه اندازی می کنیم:
npm init -y # -y option skips over project questionnaire
این دستور یک را ایجاد می کند package.json
فایل داخل پروژه ما
پیکربندی Webpack را اضافه کنید
Webpack یک بسته ماژول است که عمدتاً برای برنامه های جاوا اسکریپت استفاده می شود. از آنجایی که TypeScript به جاوا اسکریپت ساده کامپایل می شود، Webpack به طور موثر کد ما را برای مرورگر وب آماده می کند. ما دو کتابخانه و یک لودر سفارشی نصب خواهیم کرد:
npm i --save-dev webpack webpack-cli ts-loader
دستور ساخت AWS SAM CLI، sam build
، روند توسعه را کند می کند زیرا سعی می کند اجرا شود npm install
برای هر تابع، باعث تکرار. ما از یک دستور ساخت جایگزین استفاده خواهیم کرد پلاگین aws-sam-webpack کتابخانه برای سرعت بخشیدن به محیط ما
npm i --save-dev aws-sam-webpack-plugin
به طور پیش فرض، Webpack یک فایل پیکربندی ارائه نمی کند. بیایید یک فایل پیکربندی سفارشی به نام بسازیم webpack.config.js
در پوشه ریشه:
/* eslint-disable @typescript-eslint/no-var-requires */const path = require(\'path\');const AwsSamPlugin = require(\'aws-sam-webpack-plugin\');const awsSamPlugin = new AwsSamPlugin();module.exports = { entry: () => awsSamPlugin.entry(), output: { filename: (chunkData) => awsSamPlugin.filename(chunkData), libraryTarget: \'commonjs2\', path: path.resolve(\'.\') }, devtool: \'source-map\', resolve: { extensions: [\'.ts\', \'.js\'] }, target: \'node\', mode: process.env.NODE_ENV || \'development\', module: { rules: [{ test: /\\.tsx?$/, loader: \'ts-loader\' }] }, plugins: [awsSamPlugin]};
حال بیایید قسمت های مختلف را بررسی کنیم:
entry
: این شیء ورودی (جایی که Webpack شروع به ساخت بسته نرم افزاری می کند) را از قسمت بارگیری می کندAWS::Serverless::Function
منبعoutput
: این به مقصد خروجی ساخت اشاره می کند (در این مورد،.aws-sam/build
). در اینجا کتابخانه هدف را نیز به عنوان مشخص می کنیمcommonjs2
، که مقدار بازگشتی نقطه ورودی را به آن اختصاص می دهدmodule.exports
. این نقطه ورودی پیش فرض برای محیط های Node.js است.devtool
: این یک نقشه منبع ایجاد می کند،app.js.map
، در مقصد خروجی ساخت ما. کد اصلی ما را به کدهای در حال اجرا در مرورگر وب نگاشت می کند و اگر متغیر محیط را تنظیم کنیم به اشکال زدایی کمک می کند.NODE_OPTIONS
به--enable-source-maps
برای لامبدای ماresolve
: این به Webpack می گوید که فایل های TypeScript را قبل از فایل های JavaScript پردازش کند.target
: این به Webpack می گوید که Node.js را به عنوان محیط ما مورد هدف قرار دهد. این بدان معناست که Webpack از Node.js استفاده خواهد کردrequire
عملکردی برای بارگذاری تکه ها هنگام کامپایل کردن.module
: این لودر TypeScript را برای همه فایل هایی که مطابق با آن هستند اعمال می کندtest
وضعیت. به عبارت دیگر، تضمین می کند که تمام فایل های دارای a.ts
یا.tsx
پسوند توسط لودر مدیریت خواهد شد.plugins
: این به Webpack کمک می کند تا ما را شناسایی و استفاده کندaws-sam-webpack-plugin
.
در خط اول، یک قانون ESLint خاص را برای این فایل غیرفعال کرده ایم. قوانین استاندارد ESLint که بعداً پیکربندی خواهیم کرد، استفاده از آن را متوقف می کنیم require
بیانیه. ما ترجیح می دهیم require
به import
در Webpack بنابراین ما یک استثنا قائل می شویم.
پشتیبانی TypeScript را تنظیم کنید
افزودن پشتیبانی TypeScript باعث بهبود تجربه توسعه دهنده می شود:
- جلوگیری از پیام های هشدار در مورد اعلان های نوع گمشده.
- ارائه اعتبارسنجی نوع
- ارائه تکمیل خودکار در داخل IDE.
ابتدا TypeScript را برای پروژه خود به صورت محلی نصب می کنیم (اگر TypeScript را به صورت سراسری نصب کرده اید از این مرحله بگذرید):
npm i --save-dev typescript
ما انواع کتابخانه هایی را که استفاده می کنیم شامل می کنیم:
npm i --save-dev @types/node @types/webpack @types/aws-lambda
اکنون، فایل پیکربندی TypeScript را ایجاد می کنیم، tsconfig.json
، در ریشه پروژه:
{ "compilerOptions": { "target": "ES2015", "module": "commonjs", "sourceMap": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, }, "include": ["src/**/*.ts", "src/**/*.js"], "exclude": ["node_modules"]}
در اینجا ما دنبال می کنیم پیکربندی پیش فرض توسط انجمن TypeScript توصیه شده است. اضافه کرده ایم include
برای ضمیمه کردن فایل های زیر src
پوشه به برنامه و exclude
برای جلوگیری از کامپایل TypeScript برای node_modules
پوشه - ما مستقیماً این کد را لمس نمی کنیم.
یک تابع لامبدا ایجاد کنید
ما تاکنون هیچ کد لامبدا برای برنامه بدون سرور خود ننوشته ایم، پس بیایید وارد آن شویم. src
پوشه ای که قبلا ایجاد کردیم، a ایجاد می کنیم test-lambda
زیر پوشه حاوی یک app.ts
فایل با این تابع لامبدا:
import { APIGatewayEvent } from \'aws-lambda\';export const handler = async (event: APIGatewayEvent) => { console.log(\'incoming event is\', JSON.stringify(event)); const response = { statusCode: 200, body: JSON.stringify({ message: \'Request was successful.\' }) }; return response;};
این تابع مکان نگهدار ساده یک پاسخ 200 را با یک بدنه برمی گرداند. پس از یک مرحله دیگر قادر خواهیم بود کد را اجرا کنیم.
فایل قالب AWS را وارد کنید
AWS SAM به a نیاز دارد فایل قالب برای انتقال کد ما و استقرار آن در فضای ابری. فایل را ایجاد کنید template.yaml
در پوشه ریشه:
AWSTemplateFormatVersion: "2010-09-09"Transform: AWS::Serverless-2016-10-31Description: AWS SAM Boilerplate Using TypeScriptGlobals: Function: Runtime: nodejs14.x # modify the version according to your need Timeout: 30 Resources: TestLambda: Type: AWS::Serverless::Function Properties: Handler: app.handler FunctionName: "Test-Lambda" CodeUri: src/test-lambda/ Events: ApiEvent:Type: ApiProperties: Path: /test Method: get
این فایل الگو یک تابع Lambda ایجاد می کند که از طریق یک HTTP GET API قابل دسترسی است. توجه داشته باشید که نسخه ارجاع شده در Runtime:
خط ممکن است نیاز به سفارشی سازی داشته باشد.
برنامه را اجرا کنید
برای اجرای برنامه، باید یک اسکریپت جدید در برنامه اضافه کنیم package.json
فایل ساخت پروژه با Webpack. فایل ممکن است دارای اسکریپت های موجود باشد، مانند یک اسکریپت آزمایشی خالی. می توانیم اسکریپت ساخت را به این صورت اضافه کنیم:
"scripts": { "build": "webpack-cli"}
اگر بدوید npm run build
از ریشه پروژه، باید پوشه ساخت را ببینید، .aws-sam
، ایجاد شده. کسانی از ما که در محیط Mac هستند ممکن است نیاز داشته باشند که فایل های مخفی را با فشار دادن قابل مشاهده کنند Command + Shift + . برای دیدن پوشه
اکنون یک سرور HTTP محلی را برای آزمایش عملکرد خود راه اندازی می کنیم:
sam local start-api
وقتی از نقطه پایانی آزمون در الف بازدید می کنیم مرورگر اینترنت، باید پیام موفقیت را ببینیم.
کنسول باید نشان دهد که این تابع قبل از اجرا در یک ظرف Docker نصب می شود، به همین دلیل است که ما Docker را زودتر نصب کردیم:
Invoking app.handler (nodejs14.x)Skip pulling image and use local one: public.ecr.aws/sam/emulation-nodejs14.x:rapid-1.37.0-x86_64.Mounting /Users/mohammadfaisal/Documents/learning/aws-sam-typescript-boilerplate/.aws-sam/build/TestLambda as /var/task:ro, delegated inside runtime container
افزایش گردش کار توسعه ما برای یک محیط حرفه ای
پروژه ما در حال اجراست، افزودن چند نکته تکمیلی، تجربه توسعه دهنده استثنایی را تضمین می کند که بهره وری و همکاری را افزایش می دهد.
بهینه سازی ساخت با بارگذاری مجدد داغ
اجرای دستور ساخت پس از هر تغییر کد خسته کننده است. بارگذاری مجدد داغ این مشکل را برطرف می کند. ما می توانیم یک اسکریپت دیگر را به ما اضافه کنیم package.json
برای مشاهده تغییرات فایل:
"watch": "webpack-cli -w"
یک ترمینال جداگانه باز کنید و اجرا کنید npm run watch
. اکنون، پروژه شما به طور خودکار با تغییر هر کدی کامپایل می شود. پیام کد را تغییر دهید، صفحه وب خود را بازخوانی کنید و نتیجه به روز شده را ببینید.
بهبود کیفیت کد با ESLint و Prettier
هیچ پروژه TypeScript یا JavaScript بدون ESLint و Prettier کامل نمی شود. این ابزارها کیفیت کد و سازگاری پروژه شما را حفظ خواهند کرد.
بیایید ابتدا وابستگی های اصلی را نصب کنیم:
npm i --save-dev eslint prettier
ما چند وابستگی کمکی اضافه می کنیم تا ESLint و Prettier بتوانند در پروژه TypeScript ما با هم کار کنند:
npm i --save-dev \\eslint-config-prettier \\eslint-plugin-prettier \\@typescript-eslint/parser \\@typescript-eslint/eslint-plugin
در مرحله بعد، با ایجاد یک فایل پیکربندی ESLint، لینتر خود را اضافه می کنیم. .eslintrc
، داخل ریشه پروژه:
{ "root": true, "env": { "es2020": true, "node": true, "jest": true }, "parser": "@typescript-eslint/parser", "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended" ], "ignorePatterns": ["src/**/*.test.ts", "dist/", "coverage/", "test/"], "parserOptions": { "ecmaVersion": 2018, "sourceType": "module", "ecmaFeatures": { "impliedStrict": true } }, "rules": { "quotes": ["error", "single", { "allowTemplateLiterals": true }], "default-case": "warn", "no-param-reassign": "warn", "no-await-in-loop": "warn", "@typescript-eslint/no-unused-vars": [ "error", { "vars": "all", "args": "none" } ] }, "settings": { "import/resolver": { "node": { "extensions": [".js", ".jsx", ".ts", ".tsx"] } } }}
توجه داشته باشید که extends
بخش فایل ما باید پیکربندی افزونه Prettier را به عنوان آخرین خط نگه دارد تا خطاهای زیباتر را به عنوان خطاهای ESLint در ویرایشگر ما نشان دهد. ما ESLint را دنبال می کنیم تنظیمات توصیه شده برای TypeScript، با برخی از اولویت های سفارشی اضافه شده در rules
بخش. با خیال راحت مرور کنید قوانین موجود و تنظیمات خود را بیشتر سفارشی کنید. ما انتخاب کردیم که شامل موارد زیر باشد:
- اگر از رشته های تک نقل قولی استفاده نکنیم یک خطا رخ می دهد.
- یک هشدار زمانی که ما ارائه می دهیم نه
default
مورد درswitch
بیانیه. - اگر هر پارامتری از یک تابع را مجدداً اختصاص دهیم یک هشدار.
- اخطار اگر با an تماس بگیریم
await
بیانیه داخل یک حلقه - خطا برای متغیرهای استفاده نشده، که کد را ناخوانا و در طول زمان مستعد اشکال می کند.
ما قبلاً پیکربندی ESLint خود را برای کار با قالب بندی Prettier تنظیم کرده ایم. (اطلاعات بیشتر در eslint-config-prettier
پروژه GitHub.) اکنون می توانیم فایل پیکربندی Prettier را ایجاد کنیم، .prettierrc
:
{ "trailingComma": "none", "tabWidth": 4, "semi": true, "singleQuote": true}
این تنظیمات از Prettier است اسناد رسمی; شما می توانید آنها را به دلخواه تغییر دهید. ما ویژگی های زیر را به روز کردیم:
trailingComma
: ما این را تغییر دادیمes5
بهnone
برای جلوگیری از کاماهای انتهاییsemi
: ما این را تغییر دادیمfalse
بهtrue
زیرا ترجیح می دهیم در انتهای هر خط یک نقطه ویرگول داشته باشیم.
در نهایت، زمان آن رسیده است که ESLint و Prettier را در عمل ببینیم. در ما app.ts
فایل، ما آن را تغییر می دهیم response
نوع متغیر از const
به let
. استفاده كردن let
در این مورد عمل خوبی نیست زیرا ما مقدار آن را تغییر نمی دهیم response
. ویرایشگر باید یک خطا، قانون شکسته و پیشنهادهایی برای رفع کد نمایش دهد. فراموش نکنید که ESLint و Prettier را در ویرایشگر خود فعال کنید اگر قبلاً تنظیم نشده اند.
کد را با Jest Testing حفظ کنید
بسیاری از کتابخانه ها مانند Jest، Mocha و Storybook برای آزمایش در دسترس هستند. ما استفاده خواهیم کرد است در پروژه ما به چند دلیل:
- یادگیری آن سریع است.
- به حداقل تنظیمات نیاز دارد.
- این آزمایش عکس فوری با استفاده آسان را ارائه می دهد.
بیایید وابستگی های مورد نیاز را نصب کنیم:
npm i --save-dev jest ts-jest @types/jest
بعد، ما یک فایل پیکربندی Jest ایجاد می کنیم، jest.config.js
، داخل ریشه پروژه:
module.exports = { roots: [\'src\'], testMatch: [\'**/__tests__/**/*.+(ts|tsx|js)\'], transform: { \'^.+\\\\.(ts|tsx)$\': \'ts-jest\' }};
ما در حال سفارشی سازی سه گزینه در فایل خود هستیم:
roots
: این آرایه حاوی پوشه هایی است که برای فایل های آزمایشی جستجو می شوند - فقط زیر ما را بررسی می کندsrc
زیر پوشهtestMatch
: این آرایه از الگوهای glob شامل پسوندهای فایلی است که فایل های Jest در نظر گرفته می شوند.transform
: این گزینه به ما اجازه می دهد تا با استفاده از عبارت، تست های خود را در TypeScript بنویسیمts-jest
بسته بندی
بیا جدید بسازیم __tests__
پوشه داخل src/test-lambda
. در داخل آن، ما فایل را اضافه می کنیم handler.test.ts
، جایی که ما اولین آزمایش خود را ایجاد خواهیم کرد:
import { handler } from \'../app\';const event: any = { body: JSON.stringify({}), headers: {}};describe(\'Demo test\', () => { test(\'This is the proof of concept that the test works.\', async () => { const res = await handler(event); expect(res.statusCode).toBe(200); });});
به خودمان باز خواهیم گشت package.json
فایل و آن را با اسکریپت تست به روز کنید:
"test": "jest"
وقتی به ترمینال می رویم و اجرا می کنیم npm run test
، باید با قبولی در آزمون استقبال کنیم:
کنترل منبع را با .gitignore
ما باید Git را طوری پیکربندی کنیم که فایل های خاصی را از کنترل منبع حذف کند. ما می توانیم یک ایجاد کنیم .gitignore
فایل با استفاده از gitignore.io برای رد شدن از روی فایل هایی که مورد نیاز نیستند:
# Logslogs*.lognpm-debug.log*yarn-debug.log*yarn-error.log*lerna-debug.log*.pnpm-debug.log*# Runtime datapids*.pid*.seed*.pid.locknpm-debug.logpackage.lock.json/node_modules.aws-sam.vscode# TypeScript cache*.tsbuildinfo# Optional npm cache directory.npm# Optional ESLint cache.eslintcache
آماده، تنظیم، ساخت: طرح اولیه ما برای موفقیت
ما اکنون یک AWS SAM کامل داریم پروژه دیگ بخار با TypeScript با پشتیبانی ESLint، Prettier، و Jest بر روی درست کردن اصول اولیه و حفظ کیفیت بالای کد تمرکز کرده ایم. مثال از این آموزش AWS SAM می تواند به عنوان یک طرح اولیه عمل کند و پروژه بزرگ بعدی شما را از همان ابتدا در مسیر درست قرار دهد.
وبلاگ مهندسی Toptal از کریستین لوف برای بررسی نمونه کدهای ارائه شده در این مقاله تشکر می کند.
ادامه مطلب در وبلاگ مهندسی تاپتال:
منبع