長野エンジニアライフ

東京から長野に移住しました。

長野でWebエンジニアになる方法

都内のSIerから長野のWebエンジニアへIターン転職しました。Wantedlyにも↓類似記事あげていますが、改めて個人ブログでも記事にしてみました。 www.wantedly.com

今回の記事では、自己紹介を踏まえながら長野Webエンジニアになるまでの経緯を書きました。

最初に、、

自己紹介

- 1994.7.15 東京都江戸川区生まれ
- 2017.3.31 都内の大学 卒業
- 2017.4.1 ~ 2019.3.31 都内でSIerエンジニア
- 2019.4.1 ~ 長野Webエンジニア ←イマココ

色々なご縁があり長野でWeb系エンジニアに転職することができました。SIerからWeb/リモートワーク/地方移住を考える人は多くいると思います。

今回は 、以下の3点についてまとめてみました。

  • Web系転職にむけてやったこと
  • 長野移住にむけてやったこと
  • 地方エンジニアはオワコンか

まずは、、

Web系転職にむけてやったこと

1. twitterで駆け出しエンジニアをフォローしてみた
2. ポートフォリオ作成
3. Wantedly/Greenに登録してWeb系企業を見た
4. Web系企業と面談(採用面接とは無関係)

1. twitterで駆け出しエンジニアをフォローしてみた

一番転職するにあたってモチベ維持になったかもしれません。twitter界隈の、駆け出しエンジニアの勢いの力を借りて行動力を上げていました。

2. ポートフォリオ作成

SIer時代に自分が長期的に趣味で作っていました(その趣味が転職に至ったのかもしれません)。メルカリで欲しい商品が1円でも安くなったら通知してくれるツーチンという名称のアプリを自作していました。また、レンタルサーバを借りてWordPressを触ったりもしていました。

3. Wantedly/Greenに登録してWeb系企業を見た

色んな会社を見ました。事業をもっている会社や、技術支援にフォーカスを当てている会社など色々ありました。個人的には、トレンドの技術のキャッチアップしている社員に与えられる裁量権が大きいに注目して企業探しをしていました。

4. Web系企業と面談

上記の転職支援サイトで見つけて本当に興味を持った会社に連絡しました。採用面接ではなく、面談という形で企業説明をしてくれる企業が多いので、遠慮せずに連絡してお願いすると良いです。実際に私が、面談した会社は2社だけ(東京の会社、長野の会社)でしたが。ここで面談した内の1社が、私が勤めている今の職場です。

地道にSIerからWeb系へと転職活動を行なっていきました。

ただ、地方移住を将来に描いているエンジニアでしたので、この後に続くて移住活動もしていました。

長野移住にむけてやったこと

1. 長野在住エンジニアをフォローしてみた
2. 実際に長野に行った
3. 長野移住説明会等に参加した
4. 物件をスピーディに決めた(一番大変だった)

1. 長野在住エンジニアをフォローしてみた

上記の駆け出しエンジニアをフォローすると似た理由ですが、移住のモチベ維持のためにフォローしていました。他にも長野関係なく、地方で活躍されているエンジニアのエンジニアライフのわかる呟きを見たりもしていました。

2. 実際に長野に行った

回数は4,5回ほど行きました。地方は車社会のイメージが強いですが、県庁のあるような市街地であれば電車も普通にありますし、思ったほど田舎感は無く感じられます。(移住後は、車はあった方が快適ですが、笑)

3. 長野移住説明会等に参加した

具体的に行ってしまうと銀座NAGANOという、銀座にあるシェアスペースで開催される移住交流説明会などに参加しました。長野県で活発な産業・行政についても知ることができるので、より住むイメージがしやすくなります。 www.ginza-nagano.jp

4. 物件をスピーディに決めた

転職先の内定後に速攻で内見予約して1日で決めました。移動中や移動時間にスーモとかでいいなと思う物件は目星つけておくとスピーディに決めれます。都会よりも、安い/広い部屋に住めます。(広すぎて困るくらい広い間取りの物件もあります、、笑)

最後に、都会から離れると技術についていけなくなりそうって不安になる人もいると思います。 私も今の会社を知る前の転職活動時期はそう思っていました。

だけど、そんなことはありません。一番、今回の記事で伝えたい内容かもしれません。

地方エンジニアはオワコンか?

ぜひ、下のtweetのスライドを最後まで見てください。タイトルだけだと不安になりますが、最後まで見終えるとナルホドと思いました。

私の所属している株式会社日本システム技研(略称・JSL)は長野に拠点を置く会社です。

長野でWebエンジニアになる前の私が、都会から離れると技術力が落ちるだろうと不安にならなくなったのは、JSLが既に長野でも、東京でもエンジニア界隈を盛り上げていたからです。

PyCon JP/DjangoCongress JPでは、JSL社員が毎年スピーカとして登壇しています。この姿をみて、技術のキャッチアップをしていく事に場所なんて関係ない事に気づかされました。今年(2019年)のPyConではゴールドスポンサーとしてもJSLは参加しました。 www.wantedly.com

最後に、、、

2019年に長野県は、信州ITバレー構想を策定しました。
また、 2019年のDjangoCongress JPの開催地は長野県です。

長野から日本を、そして世界を盛り上げるエンジニアになりませんか? www.wantedly.com

他に聞きたい事があれば、気軽にコメント・twitterで絡んでください。笑

Module 8: Using Handlebars Templates(和訳)

JavaScriptで記述したHTMLを、DOMに挿入することは退屈/面倒なことです。アプリケーションが実装/メンテナンスしづらいものになってしまいます。HTMLテンプレートを使えば、(HTMLタグによる)UI定義をJSコードから分離するので、この課題を解決できます。HTMLテンプレートによる解決法はたくさんあります。(例をあげると、Mustache.js/Handlebars.js/Underscore.js などがあります。)


この章では、Employee Directoryアプリケーションのコードを合理化するために2つのテンプレートを作成します。今回は、Handlebars.jsを使用していきます。他のHTMLテンプレートライブラリを使っても同じ結果を得ることはできます。

ステップ1:テンプレートの定義

index.htmlを以下の手順で修正して下さい。

handlebarsライブラリの追加

1.handlebars.jsライブラリを参照するスクリプトタグを追加して下さい。

<body>
    <!-- add handlebars.js ::Module 8: Using Handlebars Templates -->
    <script src="lib/handlebars.js"></script>
    <script src="lib/fastclick.js"></script>
    <script src="cordova.js"></script>
    <script src="lib/jquery.js"></script>
    <script src="js/services/websql/EmployeeService.js"></script>
    <script src="js/app.js"></script>
</body>

スタイルシートの追加

2.ヘッダー部にratchet.cssstyles.cssを追加します。

<head>
    <meta charset="utf-8">
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <!-- add ratchet/styles ::Module 8: Using Handlebars Templates -->
    <link href="assets/ratchet/css/ratchet.css" rel="stylesheet">
    <link href="assets/css/styles.css" rel="stylesheet">
</head>

HTMLテンプレート(ヘッダーバー)の追加

3.Home Viewを表示させるためのHTMLテンプレートを作成します。bodyタグの最初の子要素として以下のscriptタグを追加して下さい。

<body>
    <!-- render HTML template ::Module 8: Using Handlebars Templates(step-1_3) -->
    <script id="home-tpl" type="text/template">
        <header class="bar bar-nav">
            <h1 class="title">Directory</h1>
        </header>
        <div class="bar bar-standard bar-header-secondary">
            <input class='search-key' type="search"/>
        </div>
        <div class="content"></div>
    </script>

HTMLテンプレート(リスト)の追加

4.従業員リストを表示させるためのHTMLテンプレートを作成します。上記のテンプレート要素の次に以下のscriptタグを追加して下さい。

    <!-- render HTML template ::Module 8: Using Handlebars Templates(step-1_4) -->
    <script id="employee-list-tpl" type="text/template">
        <ul class="table-view">
            {{#each this}}
            <li class="table-view-cell media">
              <a href="#employees/{{ id }}">
                  <img class="media-object pull-left" src="assets/pics/{{pic}}">
                  <div class="media-body">
                      {{firstName}} {{lastName}}
                      <p>{{title}}</p>
                  </div>
              </a>
            </li>
            {{/each}}
        </ul>
    </script>

ステップ2:テンプレートの使用

app.jsの即時実行関数を以下の手順で修正して下さい。

ローカル変数の追加

1.変数serviceの宣言の直前に、上記で定義したテンプレートをコンパイルした値を保持する変数をそれぞれ宣言して下さい。

// add two local variables ::Module 8: Using Handlebars Templates (step-2_1)
var homeTpl = Handlebars.compile($("#home-tpl").html());
var employeeListTpl = Handlebars.compile($("#employee-list-tpl").html());

renderHomeView関数の修正

  1. HTMLを挿入する代わりにhomeTplテンプレートを使用するため、renderHomeView関数を修正して下さい。
function renderHomeView() {
        // modify renderHomeView ::Module 8: Using Handlebars Templates (step-2_2)
        // var html =
        //     "<h1>Directory</h1>" +
        //     "<input class='search-key' type='search' placeholder='Enter name'/>" +
        //     "<ul class='employee-list'></ul>";
        // $('body').html(html);
        $('body').html(homeTpl());
        $('.search-key').on('keyup', findByName);
    }

findByName関数の修正

3.HTMLを挿入する代わりにemployeeListTplテンプレートを使用するため、findByName関数を修正して下さい。

function findByName() {
        // modify findByName ::Module 8: Using Handlebars Templates (step-2_3)
        // service.findByName($('.search-key').val()).done(function (employees) {
        //     var l = employees.length;
        //     var e;
        //     $('.employee-list').empty();
        //     for (var i = 0; i < l; i++) {
        //         e = employees[i];
        //         $('.employee-list').append('<li><a href="#employees/' + e.id + '">' + e.firstName + ' ' + e.lastName + '</a></li>');
        //     }
        // });
        service.findByName($('.search-key').val()).done(function (employees) {
            $('.content').html(employeeListTpl(employees));
        });
    }

動作確認

4.アプリを動作確認して下さい。 f:id:kawakeee:20201108130105g:plain

ステップ3:ステータスバーの修正(iOS7の考慮)

iOS7では、ステータスバーがアプリケーションビューと重なってしまいます。そのため、ステータスバーのテキストがヘッダーのテキストが被ってしまうことがあります。この課題は、statusbar pluginを使用することにより修正できます。

プラグインの追加

1.statusbar pluginの追加

cordova plugin add cordova-plugin-statusbar

app.jsの修正

2.app.jsにて、devicereadyハンドラーの上部に以下のコードを追加して下さい。

    document.addEventListener('deviceready', function () {
        // add ::Module 8: Using Handlebars Templates (step-3_2)
        StatusBar.overlaysWebView( false );
        StatusBar.backgroundColorByHexString('#ffffff');
        StatusBar.styleDefault();

動作確認

再度ビルドして、iOS端末/エミュレータで動作確認してみましょう。(本記事ではiOS7で動作確認していないため割愛、他iOSバージョンに影響がないことは確認済)

原文/参考記事

ccoenraets.github.io

次のチュートリアル

前のチュートリアル

kawakeee.hatenablog.com

Module 7: Setting Up a Single-Page Application(和訳)

Single-Page Application(SPA)とは、1つのHTMLページで生成されるWebアプリケーションです。ユーザの操作に応じて、SPAのViewはDOMに挿入されたり、DOMから削除されたりします。SPAのアーキテクチャはモバイルアプリに特に適しています。

  • ページの更新が必要ないため、(普通のWebページ)より流動的でネイティブアプリに似ています。
  • UIはサーバ側に依存せず、オフラインでも動作するアプリの理想的な構造を実現するため全てクライエントサイドで作られています。

この章では、Employee DirectoryをSPAに変換させるための基本的な環境を準備します。

ステップ

index.htmlの編集

1.index.htmlにて、bodyタグ内のHTMLマークアップを削除しましょう。(scriptタグは残しておいてください)

<body>

    <!-- remove HTML markup inside the body. ::Module 7: Setting Up a Single-Page Application -->
    <!-- <p><button class="help-btn">Help</button></p>
    <div class='header'>
        <h1>Directory</h1>
    </div>
    <div class='search-view'>
        <input class='search-key' type="search" placeholder="Enter name" />
        <ul class='list employee-list'></ul>
    </div> -->
    <script src="lib/fastclick.js"></script>
    <script src="cordova.js"></script>
    <script src="lib/jquery.js"></script>
    <script src="js/services/websql/EmployeeService.js"></script>
    <script src="js/app.js"></script>

</body>

renderHomeView()の実装

2.app.jsの即時実行関数内にて、renderHomeView()関数を定義しましょう。(findByName関数のすぐ後に定義して下さい。)関数を実装することで、Home View markupをbodyタグに追加してくれます。

// define renderHomeView() ::Module 7: Setting Up a Single-Page Application
function renderHomeView() {
    var html =
      "<h1>Directory</h1>" +
      "<input class='search-key' type='search' placeholder='Enter name'/>" +
      "<ul class='employee-list'></ul>";
    $('body').html(html);
    $('.search-key').on('keyup', findByName);
}

初期化ロジックの修正

3.app.jsにて、データを初期化する機能を修正しましょう。初期化に成功した後に、Home Viewを表示させるためrenderHomeView関数が呼ばれるように修正します。

    var service = new EmployeeService();
    service.initialize().done(function () {
        console.log("Service initialized");
        // call renderHomeView() ::Module 7: Setting Up a Single-Page Application
        renderHomeView();
    });

keyupイベントの移植

4.keyupイベントの登録をrenderHomeView関数に移動させたので、Event Registration部分に元々あったkeyupイベントを削除して下さい。

Helpボタンイベントの削除

5.Helpボタンはもう存在しないので、Event Registration部分からHelpボタンのクリックイベントハンドラーを削除して下さい。

/* --------------------------------- Event Registration -------------------------------- */
    // delete keyup event ::Module 7: Setting Up a Single-Page Application
    // $('.search-key').on('keyup', findByName);
    // $('.help-btn').on('click', function() {
    //     alert("Employee Directory v3.4");
    // });

動作確認

6.動作確認してみましょう。

f:id:kawakeee:20201107230256g:plain


ステップ4と5を見落としていないことを確認してください。そうしないと、チュートリアルの後半でファイル検索が二度実行されることによる原因調査が難しい問題に直面してしまいます。

原文/参考記事

ccoenraets.github.io

次のチュートリアル

前のチュートリアル

kawakeee.hatenablog.com

Module 6: Avoiding the 300ms Click Delay(和訳)

ステップ

待機処理の動作確認

1.iOSバイスiOSエミュレータで次の動作を確認してみましょう。
[Help]ボタンをタップして、ダイアログが表示されるまでの遅延を確認してください。


この遅延は、再度ユーザからタップがされるかどうか確認するために、OSが約300ミリ秒待機しているため発生しています。

スクリプトタグの追加

2.index.htmlにて、以下のスクリプトタグを追加します。

<script src="lib/fastclick.js"></script>

FastClickはFinancial Timesによるオープンソースのライブラリです。より詳細はこちらから確認して下さい。

FastClickの登録

3.app.jsにて、devicereadyイベントハンドラにFastClickを登録します。

    document.addEventListener('deviceready', function () {        
        // register FastClick  Module 6: Avoiding the 300ms Click Delay
        FastClick.attach(document.body);
        ...
    }

動作確認

4.[Help]ボタンをクリックして動作確認しましょう。遅延がなくメッセージが表示されるはずです。

(メモ)300msなのであまり遅延が無くなったことには気づかないです。。。

原文/参考記事

ccoenraets.github.io

次のチュートリアル

kawakeee.hatenablog.com

前のチュートリアル

kawakeee.hatenablog.com

Module 5: Using Native Notification(和訳)

JavaScriptのアラートは、アプリケーションがネイティブ でないことを伝えています。このセクションでは、デバイスでアプリを起動させている場合に、ネイティブアラートを表示する基盤をセットアップしていきます。そして、ブラウザでアプリが起動している時は、JavaScriptアラートを表示させます。


ステップ

cordova-plugin-dialogsの追加

1.workshopディレクトリで以下のコマンドを実行し、ネイティブダイアログ用のプラグインを追加します。

$ cordova plugin add cordova-plugin-dialogs

...
BUILD SUCCESSFUL

Total time: 7.146 secs
Installing "cordova-plugin-dialogs" for ios
Adding cordova-plugin-dialogs to package.json
Saved plugin info for "cordova-plugin-dialogs" to config.xml

(メモ)資料記載の org.apache.cordova.dialogs はエラーとなるためcordova-plugin-dialogsで実行する。

スクリプトタグの追加

2.index.htmlにて、以下のスクリプトタグを追加します。(body下のスクリプトタグに配置)

<script src="cordova.js"></script>

これによって、ビルド時にCordova CLIがプラットフォーム固有のcordova.jsが挿入されます。つまり、cordova.jsは今はproject/wwwディレクトリにある必要はありません。(あるべきでないです。)

window.alert()のオーバーライド

3.navigator.notificationオブジェクトが利用できるデバイスでアプリ(cordova-plugin-dialogsが追加された)を起動した場合は、window.alert()をnavigator.notification.alert()に書き換えます。

js/app.jsファイルを開いて、"Event Registration" blockに以下を追加します。

document.addEventListener('deviceready', function () {
  if (navigator.notification) { // Override default HTML alert with native dialog
      window.alert = function (message) {
          navigator.notification.alert(
              message,    // message
              null,       // callback
              "Workshop", // title
              'OK'        // buttonName
          );
      };
  }
}, false);

動作確認

4.クリックボタンを押して動作確認してみましょう

  • ブラウザで起動している場合は、デフォルトのJavaScripのアラートが確認できるはずです。 f:id:kawakeee:20201105003842p:plain

  • スマホバイスで起動している場合は、ネイティブアラートが確認できるはずです。 f:id:kawakeee:20201105003857p:plain

原文/参考記事

ccoenraets.github.io

次のチュートリアル

kawakeee.hatenablog.com

前のチュートリアル

kawakeee.hatenablog.com

Module 4: Choosing a Data Storage Strategy(和訳)

Cordovaアプリがどのようにして永続的にデータを保持しているのか確認していきます。

永続化メカニズムの調査

以下のファイルを開いて、それぞれの永続化サービスを覗いてみましょう。

  1. www/js/services/memory/EmployeeService.js
  2. www/js/services/json/EmployeeService.js
  3. www/js/services/localstorage/EmployeeService.js
  4. www/js/services/websql/EmployeeService.js

(メモ) ざっと目を通すくらいで良さそう👀

それぞれの永続化メカニズムでアプリの動作を確認

Cordovaアプリでは、in-memoryデータストアを使用する初期設定がされています。(上記の項番1.)


使用するローカルのデータストアを変更する場合は

1.index.htmlにて、js/services/memory/EmployeeService.jsをインポートしてる箇所を、他のデータストアを読み込むよう変更する必要があります。(例:js/services/websql/EmployeeService.js

<script src="js/services/memory/EmployeeService.js"></script>
↓(変更例)
<script src="js/services/websql/EmployeeService.js"></script>

2.変更後、アプリを動作させてみましょう。

(メモ)js/services/websql/EmployeeService.jsの中身を書き換えて、実行したアプリのデータも書き変わればOK


JSONサービスの動作を確認するため、チュートリアル資料のNode.jsサーバを起動させてみましょう。

1.ターミナルを開きcordova-tutorial/serverに移動します。
2.依存パッケージをインストールします。

.../cordova-tutorial/server/ $ npm install

3.Node.jsサーバを起動します。

$ node server

f:id:kawakeee:20201104235107p:plain


services/json/EmployeeService.jsはローカルホストを示しているため、ローカルのブラザウでアプリを起動している場合にのみ機能します。デバイスでは実機をローカルホストとして認識しないため動作しません。

バイスJSONサービスを確認するためには、コンピューター(サーバ起動しているマシン)とデバイスが同じサブネットにいる必要があります。そして、コンピューターのIPアドレスを確認しservices/json/EmployeeService.js.にてlocalhostoを確認したIPアドレスに書き換えて下さい。

代替案として、利用可能なサーバにこのサービスを公開する方法もあります。(実際のアプリケーションでは、構成ファイル内のホスト名は外部化することが普通です。)


www/js/services内の他のストレージサービスは、アプリをデバイスのブラウザで起動するとそのまますぐに動作します。

原文/参考記事

ccoenraets.github.io

次のチュートリアル

kawakeee.hatenablog.com

前のチュートリアル

kawakeee.hatenablog.com

Module 3: Setting Up the Workshop Files(和訳)

ステップ

wwwコンテンツの削除

1.workshop/wwwディレクトリ配下のコンテンツを削除して下さい。

サポートファイルのダウンロード

2.サポートファイルをこちらからダウンロードしてください。もしくは以下のリポジトリをクローンして下さい。

$ git clone https://github.com/ccoenraets/cordova-tutorial

3.zipファイルをダウンロードしたら、任意の場所で解凍して下さい。

コンテンツのコピー

4.starter-wwwディレクトリ配下のコンテンツを、workshop/www配下にコピーして下さい。

ビルドの再実行

5.アプリのビルドとテスト

  • Android/iOSSDKをインストールしている場合は、Module2の手順でビルドを実行して下さい。
  • インストールしていない場合は、www/index.htmlをブラウザで開いてみましょう。

アプリの動作確認

6.検索ボックスに文字を入力して従業員名で検索してみましょう。現時点では、従業員のリンクをクリックしても何も起こりません。

(メモ)画面はこんな感じ
f:id:kawakeee:20201103234956p:plain

原文/参考記事

ccoenraets.github.io

次のチュートリアル

kawakeee.hatenablog.com

前のチュートリアル

kawakeee.hatenablog.com

Module 2: Building a Cordova Project(和訳)

この章は任意です。もしModule1でプラットフォームのサポートを追加していない場合は、この章をスキップして次のModule3に進んでください。

iOSのビルド手順

workshopディレクトで以下のコマンドを実行します。

cordova build ios

ビルド成果物はworkshop_platforms/iosに作成されます。Workshop.xcoedprojをダブルクリックすると、Xcodeでプロジェクトが開かれます。Xcode上からエミュレータか実機で起動させることができます。



または、コマンドラインからiOSエミュレータを起動させる事もできます。そのために、ios-simを最初にインストールしておきます。

$ npm install -g ios-sim

or

$ sudo npm install -g ios-sim

その後に以下のコマンドを実行するとiOSエミュレータであなたのアプリが起動します。

$ cordova emulate ios

(メモ)起動するとこんな感じ
f:id:kawakeee:20201103230433p:plain

Androidのビルド

workshop/platforms/androidディレクトリのプロジェクトをビルドして、実機のAndroidバイスで実行するには以下のコマンドを実行します。

$ cordova run android

(メモ)起動するとこんな感じ
f:id:kawakeee:20201103231206p:plain

workshop/platforms/androidディレクトリのプロジェクトをビルドして、エミュレータAndroidバイスで実行するには以下のコマンドを実行します。

$ cordova emulate android

(メモ)Androidエミュレータで起動する場合は、Android Studioで事前にエミュレータを起動させておく必要がある。

原文/参考記事

ccoenraets.github.io

次のチュートリアル

kawakeee.hatenablog.com

前のチュートリアル

kawakeee.hatenablog.com