<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yoshiya Hinosawa</title>
    <description>The latest articles on DEV Community by Yoshiya Hinosawa (@kt3k).</description>
    <link>https://dev.to/kt3k</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F42621%2F638053c2-5458-4981-b64c-0679858b97ab.jpg</url>
      <title>DEV Community: Yoshiya Hinosawa</title>
      <link>https://dev.to/kt3k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kt3k"/>
    <language>en</language>
    <item>
      <title>You can omit `run` from `deno run` command</title>
      <dc:creator>Yoshiya Hinosawa</dc:creator>
      <pubDate>Wed, 18 Dec 2024 07:34:34 +0000</pubDate>
      <link>https://dev.to/kt3k/you-can-omit-run-from-deno-run-command-33mb</link>
      <guid>https://dev.to/kt3k/you-can-omit-run-from-deno-run-command-33mb</guid>
      <description>&lt;p&gt;Since Deno version &lt;a href="https://deno.com/blog/v1.46" rel="noopener noreferrer"&gt;1.46&lt;/a&gt;, you can omit &lt;code&gt;run&lt;/code&gt; of &lt;code&gt;deno run&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;You can execute hello world program like the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hello.js&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ deno hello.js
hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy hacking!&lt;/p&gt;

</description>
      <category>deno</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Write AWS Lambda function in Deno</title>
      <dc:creator>Yoshiya Hinosawa</dc:creator>
      <pubDate>Fri, 10 May 2019 02:59:58 +0000</pubDate>
      <link>https://dev.to/kt3k/write-aws-lambda-function-in-deno-4b20</link>
      <guid>https://dev.to/kt3k/write-aws-lambda-function-in-deno-4b20</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update(2019-12-01)&lt;/strong&gt; &lt;a class="mentioned-user" href="https://dev.to/hayd"&gt;@hayd&lt;/a&gt; Andy Hayden created &lt;a href="https://github.com/hayd/deno-lambda" rel="noopener noreferrer"&gt;deno-lambda&lt;/a&gt; which is a very good starting point for writing Lambda function in Deno. The repository is well maintained. I highly recommend you try that tool as well.&lt;/p&gt;




&lt;p&gt;This guide describes how to write AWS Lambda function in &lt;a href="https://deno.land/" rel="noopener noreferrer"&gt;deno&lt;/a&gt; at the time of this writing (deno v0.4.0). Many things could be improved later and you'll be able to skip some of these steps in future.&lt;/p&gt;

&lt;p&gt;AWS Lambda supports &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html" rel="noopener noreferrer"&gt;Custom Runtimes&lt;/a&gt;. You can write your own runtime in any language and use it in AWS Lambda. In this guide, I'll show you how to write a custom runtime in deno and deploy it to AWS.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;This guide describes the 2 ways (Part 1 and Part 2) to create a lambda function in deno. In both cases, you need the followings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS IAM user which can create a lambda function&lt;/li&gt;
&lt;li&gt;AWS Role for lambda function (You need a role which has "AWSLambdaBasicExecutionRole" policy)

&lt;ul&gt;
&lt;li&gt;In this article, I suppose it has the name &lt;code&gt;arn:aws:iam::123456789012:role/lambda-role&lt;/code&gt;. Please replace it with your own one on your side.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;AWS CLI installed&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;See &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html" rel="noopener noreferrer"&gt;the Prerequisites section of AWS Lambda Custom Runtime tutorial&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h1&gt;
  
  
  Part 1. Do everything on your own
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Build Custom Deno
&lt;/h2&gt;

&lt;p&gt;The current official deno binary doesn't run on the operating system of Lambda because of the &lt;a href="https://github.com/denoland/deno/issues/1658" rel="noopener noreferrer"&gt;glibc compatibility issue&lt;/a&gt;. You need to build your own deno for it. What you need to do is to build deno in &lt;a href="https://console.aws.amazon.com/ec2/v2/home#Images:visibility=public-images;search=amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2" rel="noopener noreferrer"&gt;this image&lt;/a&gt; which is the exact image Lambda uses. (In addition, you need to set &lt;code&gt;use_sysroot = false&lt;/code&gt; flag on &lt;code&gt;.gn&lt;/code&gt; file. I don't understand this flag, but anyway it works. See &lt;a href="https://github.com/denoland/deno/issues/1658#issuecomment-460723060" rel="noopener noreferrer"&gt;the comment&lt;/a&gt; in the above issue if you're interested in details.)&lt;/p&gt;

&lt;p&gt;If you want to avoid building deno on your own, please download the binary from &lt;a href="https://github.com/kt3k/lambda-deno-runtime-wip/blob/master/deno" rel="noopener noreferrer"&gt;here&lt;/a&gt; which I built based on a recent version of deno with the above settings. I confirmed this works in the Lambda environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write Custom Runtime
&lt;/h2&gt;

&lt;p&gt;You need to write a custom runtime in deno. A custom runtime is a program which is responsible for setting up the Lambda handler, fetching events from Lambda runtime API, invoking the handler, sending back the response to Lambda runtime API, etc. The entrypoint of a custom runtime have to be named &lt;code&gt;bootstrap&lt;/code&gt;. The example of such program is like the below (This is Deno program wrapped by Bash script.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail

&lt;span class="nv"&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;HANDLER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$_HANDLER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f2&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;HANDLER_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$_HANDLER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"
import { &lt;/span&gt;&lt;span class="nv"&gt;$HANDLER_NAME&lt;/span&gt;&lt;span class="s2"&gt; } from '&lt;/span&gt;&lt;span class="nv"&gt;$LAMBDA_TASK_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$HANDLER_FILE&lt;/span&gt;&lt;span class="s2"&gt;.ts';
const API_ROOT =
  'http://&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;AWS_LAMBDA_RUNTIME_API&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/2018-06-01/runtime/invocation/';
(async () =&amp;gt; {
  while (true) {
    const next = await fetch(API_ROOT + 'next');
    const reqId = next.headers.get('Lambda-Runtime-Aws-Request-Id');
    const res = await &lt;/span&gt;&lt;span class="nv"&gt;$HANDLER_NAME&lt;/span&gt;&lt;span class="s2"&gt;(await next.json());
    await (await fetch(
      API_ROOT + reqId + '/response',
      {
        method: 'POST',
        body: JSON.stringify(res)
      }
    )).blob();
  }
})();
"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/runtime.ts
&lt;span class="nv"&gt;DENO_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/deno_dir &lt;span class="nv"&gt;$SCRIPT_DIR&lt;/span&gt;/deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-read&lt;/span&gt; /tmp/runtime.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;$HANDLER_NAME&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$LAMBDA_TASK_ROOT/$HANDLER_FILE.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this line, you import lambda function from the task directory. &lt;code&gt;$LAMBDA_TASK_ROOT&lt;/code&gt; is given by Lambda environment. &lt;code&gt;$HANDLER_NAME&lt;/code&gt; and &lt;code&gt;$HANDLER_FILE&lt;/code&gt; are the first and second part of &lt;code&gt;handler&lt;/code&gt; property of your lambda which you'll set through AWS CLI. If you set the handler property &lt;code&gt;function.handler&lt;/code&gt;, for example, then the above line becomes &lt;code&gt;import { handler } from '$LAMBDA_TASK_ROOT/function.ts'&lt;/code&gt;. So your lambda function need to be named &lt;code&gt;function.ts&lt;/code&gt; and it needs to export &lt;code&gt;handler&lt;/code&gt; as the handler in that case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This block creates the loop of event handling of Lambda. A single event is processed on each iteration of the loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;API_ROOT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reqId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lambda-Runtime-Aws-Request-Id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These 2 lines fetches the event from Lambda runtime API and stores the request id.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nc"&gt;$HANDLER_NAME&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line invokes the lambda handler with the given event payload and stores the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;API_ROOT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;reqId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line sends back the result to Lambda runtime API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DENO_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/deno_dir &lt;span class="nv"&gt;$SCRIPT_DIR&lt;/span&gt;/deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-read&lt;/span&gt; /tmp/runtime.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line starts the runtime script with &lt;code&gt;net&lt;/code&gt; and &lt;code&gt;read&lt;/code&gt; permissions. If you want to more permissions, you can add here the options you want. &lt;code&gt;DENO_DIR=/tmp/deno_dir&lt;/code&gt; part is very important. Because Lambda environment doesn't allow you to write to the file system except &lt;code&gt;/tmp&lt;/code&gt;, you need to set &lt;code&gt;DENO_DIR&lt;/code&gt; somewhere under &lt;code&gt;/tmp&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write Lambda function
&lt;/h2&gt;

&lt;p&gt;Now you need to write your lambda function in deno. The example looks like the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lambda function returns a simple object which contains status code 200 and deno's version information as body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy
&lt;/h2&gt;

&lt;p&gt;Now you have 3 files &lt;code&gt;deno&lt;/code&gt;, &lt;code&gt;bootstrap&lt;/code&gt; (bash script), and &lt;code&gt;function.ts&lt;/code&gt; (deno script). These are all files you need to run your Lambda function. You need to zip them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;zip &lt;span class="k"&gt;function&lt;/span&gt;.zip deno bootstrap &lt;span class="k"&gt;function&lt;/span&gt;.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can deploy it like the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aws lambda create-function &lt;span class="nt"&gt;--function-name&lt;/span&gt; deno-func &lt;span class="nt"&gt;--zip-file&lt;/span&gt; fileb://function.zip &lt;span class="nt"&gt;--handler&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;.handler &lt;span class="nt"&gt;--runtime&lt;/span&gt; provided &lt;span class="nt"&gt;--role&lt;/span&gt; arn:aws:iam::123456789012:role/lambda-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: Replace &lt;code&gt;arn:aws:iam::123456789012:role/lambda-role&lt;/code&gt; to your own role's arn.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--runtime provided&lt;/code&gt; option means this lambda uses a custom runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test
&lt;/h2&gt;

&lt;p&gt;You can invoke the above lambda like the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aws lambda invoke &lt;span class="nt"&gt;--function-name&lt;/span&gt; deno-func response.json
&lt;span class="go"&gt;{
    "StatusCode": 200,
&lt;/span&gt;&lt;span class="gp"&gt;    "ExecutedVersion": "$&lt;/span&gt;LATEST&lt;span class="s2"&gt;"
&lt;/span&gt;&lt;span class="go"&gt;}
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;response.json
&lt;span class="go"&gt;{"statusCode":200,"body":"{\"version\":{\"deno\":\"0.4.0\",...}}}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Part 2. Use the shared layer
&lt;/h1&gt;

&lt;p&gt;AWS Supports the Lambda Layer. A lambda layer is a ZIP archive that contains libraries, a custom runtime, or other dependencies. I published the above &lt;code&gt;deno&lt;/code&gt; binary and &lt;code&gt;bootstrap&lt;/code&gt; script as a public layer. You can reuse it as a custom deno runtime.&lt;/p&gt;

&lt;p&gt;In this case, what you need to do is just to write a lambda function in deno and deploy it to AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Deno Lambda Function using Public Deno Runtime
&lt;/h2&gt;

&lt;p&gt;An example &lt;code&gt;function.ts&lt;/code&gt; looks like the below (The same as the above):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Deno&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then zip it and deploy it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;zip &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="nt"&gt;-only&lt;/span&gt;.zip &lt;span class="k"&gt;function&lt;/span&gt;.ts
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aws lambda create-function &lt;span class="nt"&gt;--function-name&lt;/span&gt; deno-func-only &lt;span class="nt"&gt;--layers&lt;/span&gt; arn:aws:lambda:ap-northeast-1:439362156346:layer:deno-runtime:13 &lt;span class="nt"&gt;--zip-file&lt;/span&gt; fileb://function-only.zip &lt;span class="nt"&gt;--handler&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;.handler &lt;span class="nt"&gt;--runtime&lt;/span&gt; provided &lt;span class="nt"&gt;--role&lt;/span&gt; arn:aws:iam::123456789012:role/lambda-role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: Replace &lt;code&gt;arn:aws:iam::123456789012:role/lambda-role&lt;/code&gt; to your own role's arn.)&lt;/p&gt;

&lt;p&gt;Where the arn &lt;code&gt;arn:aws:lambda:ap-northeast-1:439362156346:layer:deno-runtime:13&lt;/code&gt; is a public lambda layer which implements deno runtime. The &lt;code&gt;--layers arn:aws:lambda:ap-northeast-1:439362156346:layer:deno-runtime:13&lt;/code&gt; option specifies this lambda function uses it as the shared layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test it
&lt;/h2&gt;

&lt;p&gt;You should be able to invoke the above lambda function like the below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aws lambda invoke &lt;span class="nt"&gt;--function-name&lt;/span&gt; deno-func-only response.json
&lt;span class="go"&gt;{
    "StatusCode": 200,
&lt;/span&gt;&lt;span class="gp"&gt;    "ExecutedVersion": "$&lt;/span&gt;LATEST&lt;span class="s2"&gt;"
&lt;/span&gt;&lt;span class="go"&gt;}
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;response.json
&lt;span class="go"&gt;{"statusCode":200,"body":"{\"version\":{\"deno\":\"0.4.0\",...}}}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Thank you for reading.&lt;/p&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;p&gt;All examples are available in &lt;a href="https://github.com/kt3k/lambda-deno-runtime-wip" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>serverless</category>
      <category>deno</category>
    </item>
    <item>
      <title>Markdown-based task runner - 'saku'</title>
      <dc:creator>Yoshiya Hinosawa</dc:creator>
      <pubDate>Sun, 13 May 2018 07:10:23 +0000</pubDate>
      <link>https://dev.to/kt3k/markdown-based-task-runner---saku-239o</link>
      <guid>https://dev.to/kt3k/markdown-based-task-runner---saku-239o</guid>
      <description>&lt;h1&gt;
  
  
  tl;dr
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;It's painful to use &lt;code&gt;make&lt;/code&gt; command as a task runner. It's especially intolerable when writing &lt;code&gt;.PHONY&lt;/code&gt; directives for evey task.&lt;/li&gt;
&lt;li&gt;I found some simple altenatives (like &lt;a href="https://github.com/go-task/task"&gt;go-task&lt;/a&gt;, &lt;a href="https://github.com/tj/robo"&gt;robo&lt;/a&gt;), but I didn't like them.&lt;/li&gt;
&lt;li&gt;I came up with the idea that markdown seems a better syntax for task definition.&lt;/li&gt;
&lt;li&gt;I made a markdown-based task runner, named &lt;a href="https://github.com/kt3k/node-saku"&gt;saku&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;Because I've been using JavaScript both at work and hobby always, I use &lt;a href="https://docs.npmjs.com/cli/run-script"&gt;npm run-script&lt;/a&gt; as my task runner. &lt;code&gt;run-script&lt;/code&gt; has some flaws such that it's unable to be documented well in a decent way, or that it's a little hard to read because it's written in JSON file. But in my opinion, it's sufficient tool for defining the necessary tasks with the support of the tools like &lt;a href="https://github.com/mysticatea/npm-run-all"&gt;npm-run-all&lt;/a&gt;, &lt;a href="https://github.com/kentcdodds/cross-env"&gt;cross-env&lt;/a&gt; etc.&lt;/p&gt;

&lt;p&gt;One day I started using &lt;a href="https://www.terraform.io"&gt;terraform&lt;/a&gt; for our team's infrastructure management and I was setting up the git repository for it.&lt;/p&gt;

&lt;p&gt;I was searching the web for how to set up the terraform project and many people seem using Makefile for organizing the commands in it.&lt;/p&gt;

&lt;p&gt;I thought it was a good idea to use task runner to invoke terraform because &lt;code&gt;terraform&lt;/code&gt; is too long to type, but I also felt uncomfortable about using Makefile in 2018. It's depressing to write enigmatic &lt;code&gt;.PHONY&lt;/code&gt; directive again and again. In the first place &lt;code&gt;make&lt;/code&gt; isn't a tool for running tasks, but a tool for compiling source code of the language like C, C++ etc. It is a &lt;em&gt;hack&lt;/em&gt; to use &lt;code&gt;make&lt;/code&gt; as a task runner and I thought there must be some other tools which are more appropriate for just running tasks in 2018.&lt;/p&gt;

&lt;h1&gt;
  
  
  go-task
&lt;/h1&gt;

&lt;p&gt;I found several tools. Among them, &lt;a href="https://github.com/go-task/task"&gt;go-task&lt;/a&gt; seemed the closest to what I was looking for. &lt;a href="https://github.com/go-task/task"&gt;go-task&lt;/a&gt; is a simple tool. It uses the yaml format for task configuration.&lt;/p&gt;

&lt;p&gt;However I felt something was wrong about it. That was the key names in the yaml DSL. In &lt;a href="https://github.com/go-task/task"&gt;go-task&lt;/a&gt;, you write commands and descripions as values of keys &lt;code&gt;cmds&lt;/code&gt; and &lt;code&gt;desc&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tasks:
  build:
    cmds:
      - go build -v -i main.go

  assets:
    cmds:
      - minify -o public/style.css src/css
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To my eyes, these key names look a little redundant and seem noisy. In Makefile, targets are expressed as their names and colons and the commands are expressed by tab indents.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build:
    go build -v -i main.go

assets:
    minify -o public/style.css src/css
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That was more elegant. Because I'm looking for more elegant replacement of &lt;code&gt;make&lt;/code&gt;, it's so unfortunate if the notations get less elegant.&lt;/p&gt;

&lt;h1&gt;
  
  
  Think syntax
&lt;/h1&gt;

&lt;p&gt;I considered whether it's possible or not to build more simpler version of configuration in yaml syntax, but I gave up because it seemed impossible because of the characteristics of yaml. In yaml, if you need to define something, you always need &lt;code&gt;key: value&lt;/code&gt; pair for anything and I felt it's impossible to get a simpler version than &lt;a href="https://github.com/go-task/task"&gt;go-task&lt;/a&gt;'s design.&lt;/p&gt;

&lt;p&gt;Then I thought about several languages which I was familiar with and finally I found markdown is very much suitable for my needs because it allows bare strings in many places in different contexts.&lt;/p&gt;

&lt;h1&gt;
  
  
  Markdown-based task runner
&lt;/h1&gt;

&lt;p&gt;I couldn't find markdown-based task runner and therefore I created one. I named it &lt;a href="https://github.com/kt3k/node-saku"&gt;saku&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;I used &lt;code&gt;remark&lt;/code&gt; as markdown parser and used &lt;code&gt;minimist&lt;/code&gt; as CLI option parser. I reused several toolchains for building CLI base structure which I had prepared for writing some other tools like &lt;a href="https://github.com/kt3k/kocha"&gt;kocha&lt;/a&gt; or &lt;a href="https://github.com/kt3k/bulbo"&gt;bulbo&lt;/a&gt;. I stole some techniques from yarn to show emojis only in TTY environment.&lt;/p&gt;

&lt;p&gt;I modeled the domain of saku according to what &lt;a href="http://dddcommunity.org/book/evans_2003/"&gt;DDD book&lt;/a&gt; teaches me. I like this style of progarmming these days quite a lot. Modeling makes the software development quite straightforward and easy for reasoning and testing. In the course of writing suku, I created the only one model class &lt;code&gt;Task&lt;/code&gt; and the entire implementation seemed very organized ☺️.&lt;/p&gt;

&lt;h1&gt;
  
  
  🐕 Dogfooding
&lt;/h1&gt;

&lt;p&gt;I started dogfooding it at &lt;a href="https://github.com/kt3k/saku/commit/270c72d08ee4612a9143774bae5eb713977a4ca5"&gt;12th commit&lt;/a&gt; by writing down the tasks in saku.md which are necessary to build saku itself.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# test&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Runs unit tests&lt;/span&gt;&lt;span class="sb"&gt;

    npx kocha --require src/__tests__/helper src{/,/**/}__tests__/*.js

&lt;/span&gt;&lt;span class="gh"&gt;# lint&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Runs lint checks&lt;/span&gt;&lt;span class="sb"&gt;

    npx standard

&lt;/span&gt;&lt;span class="gh"&gt;# fix&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Runs auto fixer of lint tool&lt;/span&gt;&lt;span class="sb"&gt;

    npx standard --fix

&lt;/span&gt;&lt;span class="gh"&gt;# cov&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Makes coverage reports&lt;/span&gt;&lt;span class="sb"&gt;

    npx nyc --reporter=text-summary --reporter=lcov saku test

&lt;/span&gt;&lt;span class="gh"&gt;# codecov&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Posts reports to codecov.io&lt;/span&gt;&lt;span class="sb"&gt;

    saku cov
    npx codecov
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As I expected, I felt it was easy to write, and unexpectedly I found that the rendering of the saku.md in github UI was &lt;a href="https://github.com/kt3k/node-saku/blob/master/saku.md"&gt;so beautiful&lt;/a&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;It's so fun to create things from scratch! 😄&lt;/li&gt;
&lt;li&gt;Though markdown doesn't have a natural logical structure like yaml, personally I think it has a great potential as DSL because it has various places where bare strings can be written without quotes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Update: 2018-05-12
&lt;/h1&gt;

&lt;p&gt;I've completely rewritten saku in &lt;a href="https://github.com/kt3k/saku"&gt;go language&lt;/a&gt;. Please check &lt;a href="https://github.com/kt3k/saku"&gt;this version&lt;/a&gt; as well 😉&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>taskrunner</category>
      <category>makefile</category>
      <category>diy</category>
    </item>
  </channel>
</rss>
