TypeScript ve Jest Desteğiyle Çalışmak: Bir AWS SAM Eğitimi
Yayınlanan: 2022-03-11Sunucusuz uygulamalar oluşturmak için güçlü bir araç olan AWS Sunucusuz Uygulama Modeli (SAM) sıklıkla JavaScript ile eşleşir: Orta ve büyük şirketlerdeki geliştiricilerin %62'si sunucusuz kodları için JavaScript'i seçer. Bununla birlikte, TypeScript'in popülaritesi hızla artıyor ve geliştiricilerin en sevilen üçüncü dili olarak JavaScript'i çok geride bırakıyor.
JavaScript ortak kalıbını bulmak zor olmasa da, AWS SAM projelerini TypeScript ile başlatmak daha karmaşıktır. Aşağıdaki öğretici, sıfırdan bir AWS SAM TypeScript projesinin nasıl oluşturulacağını ve farklı parçaların birlikte nasıl çalıştığını gösterir. Okuyucuların takip edebilmeleri için AWS Lambda işlevlerine yalnızca biraz aşina olmaları gerekir.
AWS SAM TypeScript Projemize Başlıyoruz
Sunucusuz uygulamamızın temeli çeşitli bileşenleri içerir. Önce AWS ortamını, npm paketimizi ve Webpack işlevselliğini yapılandıracağız; ardından uygulamamızı çalışırken görmek için Lambda işlevimizi oluşturabilir, çağırabilir ve test edebiliriz.
Ortamı Hazırlayın
AWS ortamını kurmak için aşağıdakileri yüklememiz gerekiyor:
- AWS CLI'si
- AWS SAM CLI'si
- Node.js ve npm
Bu öğreticinin, uygulamamızı yerel olarak test etmek için yukarıdaki 2. adımda Docker'ın yüklenmesini gerektirdiğini unutmayın.
Boş Bir Projeyi Başlatın
Proje dizini, aws-sam-typescript-boilerplate ve kodu tutacak bir src alt klasörü oluşturalım. Proje dizininden yeni bir npm paketi oluşturacağız:
npm init -y # -y option skips over project questionnaire Bu komut projemizin içinde bir package.json dosyası oluşturacak.
Web Paketi Yapılandırmasını Ekle
Webpack, öncelikle JavaScript uygulamaları için kullanılan bir modül paketleyicidir. TypeScript düz JavaScript ile derlendiğinden, Webpack kodumuzu web tarayıcısı için etkin bir şekilde hazırlayacaktır. İki kitaplık ve özel bir yükleyici kuracağız:
- web paketi: Çekirdek kitaplık
- webpack-cli: Webpack için komut satırı yardımcı programları
- ts-loader: Web paketi için TypeScript yükleyici
npm i --save-dev webpack webpack-cli ts-loader AWS SAM CLI build komutu, sam build , her bir işlev için npm install çalıştırmaya çalıştığından ve çoğaltmaya neden olduğundan geliştirme sürecini yavaşlatır. Ortamımızı hızlandırmak için aws-sam-webpack-plugin kitaplığından alternatif bir derleme komutu kullanacağız.
npm i --save-dev aws-sam-webpack-plugin Webpack varsayılan olarak bir yapılandırma dosyası sağlamaz. Kök klasörde webpack.config.js adlı özel bir yapılandırma dosyası oluşturalım:
/* 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] };Şimdi çeşitli bölümleri inceleyelim:
-
entry: Bu, giriş nesnesini (Webpack'in paketi oluşturmaya başladığı yer)AWS::Serverless::Functionkaynağından yükler. -
output: Bu, derleme çıktısının hedefini gösterir (bu durumda.aws-sam/build). Burada ayrıca giriş noktasının dönüş değerini module.exports'a atayan hedef kitaplığıcommonjs2olarakmodule.exports. Bu giriş noktası, Node.js ortamları için varsayılandır. -
devtool: Bu, derleme çıktı hedefimizdeapp.js.mapadlı bir kaynak haritası oluşturur. Orijinal kodumuzu web tarayıcısında çalışan kodla eşler ve NODE_OPTIONS ortam değişkeniniNODE_OPTIONSiçin--enable-source-mapsolarak ayarlarsak hata ayıklamaya yardımcı olur. -
resolve: Bu, Webpack'e TypeScript dosyalarını JavaScript dosyalarından önce işlemesini söyler. -
target: Bu, Webpack'e ortamımız olarak Node.js'yi hedeflemesini söyler. Bu, Webpack'in derlendiğinde parçaları yüklemek için Node.jsrequireişlevini kullanacağı anlamına gelir. -
module: Bu, TypeScript yükleyiciyitestkoşulunu karşılayan tüm dosyalara uygular. Başka bir deyişle,.tsveya.tsxuzantılı tüm dosyaların yükleyici tarafından işlenmesini sağlar. -
plugins: Bu, Webpack'inaws-sam-webpack-pluginplugin'imizi tanımlamasına ve kullanmasına yardımcı olur.
İlk satırda, bu dosya için belirli bir ESLint kuralını devre dışı bıraktık. Daha sonra yapılandıracağımız standart ESLint kuralları, require ifadesinin kullanılmasını önermez. require import aktarmayı tercih ediyoruz, bu yüzden bir istisna yapacağız.
TypeScript Desteğini Ayarlayın
TypeScript desteği eklemek, geliştirici deneyimini şu yollarla iyileştirecektir:
- Eksik tip bildirimleri ile ilgili uyarı mesajlarının engellenmesi.
- Tip doğrulamasının sağlanması.
- IDE içinde otomatik tamamlama sunar.
İlk olarak, projemiz için TypeScript'i yerel olarak yükleyeceğiz (global olarak TypeScript yüklediyseniz bu adımı atlayın):
npm i --save-dev typescriptKullandığımız kitaplıkların türlerini ekleyeceğiz:
npm i --save-dev @types/node @types/webpack @types/aws-lambda Şimdi, proje kökünde TypeScript yapılandırma dosyası tsconfig.json oluşturacağız:
{ "compilerOptions": { "target": "ES2015", "module": "commonjs", "sourceMap": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, }, "include": ["src/**/*.ts", "src/**/*.js"], "exclude": ["node_modules"] } Burada TypeScript topluluğu tarafından önerilen varsayılan yapılandırmayı izliyoruz. src klasörü altındaki dosyaları programa eklemek ve node_modules klasörü için TypeScript derlemesini önlemek için exclude için include ekledik; bu koda doğrudan dokunmayacağız.
Lambda İşlevi Oluşturun
Sunucusuz uygulamamız için şimdiye kadar herhangi bir Lambda kodu yazmadık, o yüzden başlayalım. Daha önce oluşturduğumuz src klasöründe, bu Lambda işleviyle bir app.ts dosyası içeren bir test-lambda alt klasörü oluşturacağız:
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; };Bu basit yer tutucu işlevi, gövdeli bir 200 yanıtı döndürür. Bir adım daha geçtikten sonra kodu çalıştırabileceğiz.
AWS Şablon Dosyasını Dahil Et
AWS SAM, kodumuzu aktarmak ve onu buluta dağıtmak için bir şablon dosyası gerektirir. template.yaml dosyasını kök klasörde oluşturun:
AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: AWS SAM Boilerplate Using TypeScript Globals: 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: Api Properties: Path: /test Method: get Bu şablon dosyası, bir HTTP GET API'sinden erişilebilen bir Lambda işlevi oluşturur. Runtime: satırında başvurulan sürümün özelleştirilmesi gerekebileceğini unutmayın.
Uygulamayı Çalıştır
Uygulamayı çalıştırmak için, projeyi Webpack ile oluşturmak için package.json dosyasına yeni bir script eklemeliyiz. Dosya, boş bir test komut dosyası gibi mevcut komut dosyalarına sahip olabilir. Derleme betiğini şu şekilde ekleyebiliriz:
"scripts": { "build": "webpack-cli" } Projenin kökünden npm run build , oluşturulan .aws-sam build klasörünü görmelisiniz. Mac ortamındaki bizlerin Command + Shift + tuşlarına basarak gizli dosyaları görünür hale getirmesi gerekebilir. klasörü görmek için
Şimdi işlevimizi test etmek için yerel bir HTTP sunucusu başlatacağız:
sam local start-apiBir web tarayıcısında test uç noktasını ziyaret ettiğimizde bir başarı mesajı görmeliyiz.
Konsol, işlevin çalışmadan önce bir Docker konteynerine monte edildiğini göstermelidir, bu yüzden Docker'ı daha önce kurduk:
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 containerProfesyonel Bir Ortam İçin Geliştirme İş Akışımızı Geliştirme
Projemiz çalışır durumda ve birkaç son rötuş ekleyerek üretkenliği ve işbirliğini artıracak olağanüstü bir geliştirici deneyimi sağlayacak.

Sıcak Yeniden Yükleme ile Yapıyı Optimize Edin
Her kod değişikliğinden sonra build komutunu çalıştırmak sıkıcıdır. Sıcak yeniden yükleme bu sorunu çözecektir. Dosya değişikliklerini izlemek için package.json başka bir komut dosyası ekleyebiliriz:
"watch": "webpack-cli -w" Ayrı bir terminal açın ve npm run watch . Artık, herhangi bir kodu değiştirdiğinizde projeniz otomatik olarak derlenecektir. Kodun mesajını değiştirin, web sayfanızı yenileyin ve güncellenmiş sonucu görün.
ESLint ve Prettier ile Kod Kalitesini Artırın
ESLint ve Prettier olmadan hiçbir TypeScript veya JavaScript projesi tamamlanmaz. Bu araçlar projenizin kod kalitesini ve tutarlılığını koruyacaktır.
Önce çekirdek bağımlılıkları kuralım:
npm i --save-dev eslint prettierESLint ve Prettier'in TypeScript projemizde birlikte çalışabilmesi için bazı yardımcı bağımlılıklar ekleyeceğiz:
npm i --save-dev \ eslint-config-prettier \ eslint-plugin-prettier \ @typescript-eslint/parser \ @typescript-eslint/eslint-plugin Ardından, proje kökünün içinde bir ESLint yapılandırma dosyası, .eslintrc oluşturarak linterimizi ekleyeceğiz:
{ "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"] } } } } Prettier hatalarını düzenleyicimizde görünen extends hataları olarak görüntülemek için dosyamızın extension bölümünün Prettier eklenti yapılandırmasını son satır olarak tutması gerektiğini unutmayın. rules bölümüne eklenen bazı özel tercihlerle, TypeScript için ESLint tarafından önerilen ayarları izliyoruz. Mevcut kurallara göz atmaktan ve ayarlarınızı daha fazla özelleştirmekten çekinmeyin. Dahil etmeyi seçtik:
- Tek tırnaklı dizeler kullanmazsak bir hata.
-
switchifadelerindedefaultbir durum sağlamadığımızda bir uyarı. - Bir fonksiyonun herhangi bir parametresini yeniden atarsak bir uyarı.
- Bir döngü içinde bir
awaitifadesi çağırırsak bir uyarı. - Kodu okunamaz ve zaman içinde hataya açık hale getiren, kullanılmayan değişkenler için bir hata.
Prettier biçimlendirme ile çalışmak için ESLint yapılandırmamızı zaten kurduk. (Daha fazla bilgiyi eslint-config-prettier GitHub projesinde bulabilirsiniz.) Şimdi, Prettier konfigürasyon dosyasını .prettierrc :
{ "trailingComma": "none", "tabWidth": 4, "semi": true, "singleQuote": true }Bu ayarlar Prettier'in resmi belgelerinden alınmıştır; bunları istediğiniz gibi değiştirebilirsiniz. Aşağıdaki özellikleri güncelledik:
- tailingComma :
trailingCommavirgüllerden kaçınmak için bunues5noneolarak değiştirdik. -
semi: Her satırın sonunda noktalı virgültruetercih ettiğimiz için bunufalsetrue'ya değiştirdik.
Son olarak, ESLint ve Prettier'i iş başında görmenin zamanı geldi. app.ts dosyamızda, const olan response değişkeni türünü let olarak değiştireceğiz. Bu durumda let kullanımı iyi bir uygulama değildir çünkü response değerini değiştirmeyiz. Düzenleyici bir hatayı, bozuk kuralı ve kodu düzeltmek için önerileri göstermelidir. Henüz kurulmamışlarsa, editörünüzde ESLint ve Prettier'i etkinleştirmeyi unutmayın.
Jest Testiyle Kodu Koruyun
Jest, Mocha ve Storybook gibi birçok kitaplık test için kullanılabilir. Jest'i projemizde birkaç nedenden dolayı kullanacağız:
- Öğrenmesi hızlı.
- Minimum kurulum gerektirir.
- Kullanımı kolay anlık görüntü testi sunar.
Gerekli bağımlılıkları yükleyelim:
npm i --save-dev jest ts-jest @types/jest Ardından, proje kökünün içinde bir Jest yapılandırma dosyası oluşturacağız, jest.config.js :
module.exports = { roots: ['src'], testMatch: ['**/__tests__/**/*.+(ts|tsx|js)'], transform: { '^.+\\.(ts|tsx)$': 'ts-jest' } };Dosyamızda üç seçeneği özelleştiriyoruz:
-
roots: Bu dizi, test dosyaları için aranacak klasörleri içerir; yalnızcasrcalt klasörümüzün altını kontrol eder. -
testMatch: Bu glob desenleri dizisi, Jest dosyaları olarak kabul edilecek dosya uzantılarını içerir. -
transform: Bu seçenek, testlerimizits-jestpaketini kullanarak TypeScript'te yazmamızı sağlar.
src/test-lambda içinde yeni bir __tests__ klasörü oluşturalım. Bunun içine, ilk testimizi oluşturacağımız handler.test.ts dosyasını ekleyeceğiz:
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 dosyamıza geri döneceğiz ve onu test betiğiyle güncelleyeceğiz:
"test": "jest" Terminale gidip npm run test , bir geçme testi ile karşılaşmalıyız:
.gitignore ile Kaynak Kontrolünü Yönetin
Git'i belirli dosyaları kaynak kontrolünden hariç tutacak şekilde yapılandırmalıyız. Gerekli olmayan dosyaları atlamak için gitignore.io kullanarak bir .gitignore dosyası oluşturabiliriz:
# Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* .pnpm-debug.log* # Runtime data pids *.pid *.seed *.pid.lock npm-debug.log package.lock.json /node_modules .aws-sam .vscode # TypeScript cache *.tsbuildinfo # Optional npm cache directory .npm # Optional ESLint cache .eslintcacheHazır, Ayarla, İnşa Et: Başarı Planımız
Artık TypeScript ile eksiksiz bir AWS SAM ortak projemiz var. ESLint, Prettier ve Jest desteğiyle temel bilgileri doğru almaya ve yüksek kod kalitesini korumaya odaklandık. Bu AWS SAM öğreticisinden alınan örnek, bir sonraki büyük projenizi en baştan doğru yola koyan bir plan işlevi görebilir.
Toptal Engineering Blog, bu makalede sunulan kod örneklerini gözden geçirdiği için Christian Loef'e şükranlarını sunar.
