apeescape2.com
  • メイン
  • プロジェクト管理
  • モバイル
  • 製品の担当者とチーム
  • 革新
バックエンド

キャビンフィーバーコーディング:Node.jsバックエンドチュートリアル

COVID-19の封鎖により、私たちの多くは家に閉じ込められました。おそらく、単なるキャビン熱が私たちが経験する最悪の種類の熱であることを望んでいます。私たちの多くは、これまで以上に多くのビデオコンテンツを消費しています。現在、運動は特に重要ですが、ノートパソコンが手が届きにくいときに、古き良きリモコンの豪華さに懐かしさを感じることもあります。

そこで、このプロジェクトが登場します。更新がないために役に立たない古いスマートフォンであっても、次のNetflix / YouTube / Amazon PrimeVideoなどの便利なリモコンに変換する機会です。ビンジウォッチング。これはNode.jsバックエンドチュートリアルでもあります。ExpressフレームワークとPug(以前のJade)テンプレートエンジンを使用してバックエンドJavaScriptの基本を学ぶチャンスです。

それが気が遠くなるように聞こえるなら、完全な Node.js プロジェクトは最後に発表されます。読者は学習に興味がある分だけ学ぶ必要があり、経験豊富な読者がスキップできるように、いくつかの基本についてかなりの数の穏やかな説明があります。



なぜただ...?

読者は、「なぜNode.jsバックエンドのコーディングに取り掛かるのか」と疑問に思うかもしれません。 (もちろん、学習の機会は別として。)「そのためのアプリはもうありませんか?」

確かに、それらはたくさんあります。しかし、これが望ましくない可能性がある主な理由は2つあります。

  1. 古い電話を転用しようとしている人にとって、これはかもしれません 単にもはやオプションではありません 、使用したかったWindows Phone8.1デバイスの場合と同様です。 (アプリストアは2019年後半に正式に閉鎖されました。)
  2. 信頼(またはその欠如)。 あらゆるモバイルプラットフォームで見られる非常に多くのアプリと同様に、多くの場合、アプリが意図する目的よりもはるかに多くの権限をユーザーに付与する必要があります。ただし、この側面が適切に制限されている場合でも、リモートコントロールアプリの性質上、ユーザーは、アプリ開発者がスパイウェアやその他のマルウェアを含めてソリューションのデスクトップ側で特権を悪用していないことを信頼する必要があります。

これらの問題は長い間存在しており、GitHubで見つかった2014年の同様のプロジェクトの動機にもなりました。 nvm Node.jsの古いバージョンを簡単にインストールでき、いくつかの依存関係をアップグレードする必要がある場合でも、Node.jsは下位互換性があるという高い評価を得ていました。

残念ながら、bitrotが勝ちました。頑固なアプローチとNode.jsバックエンドの互換性は、Grunt、Bower、およびその他の数十のコンポーネントの古いバージョン間での無限の非推奨と不可能な依存関係ループに匹敵しませんでした。数時間後、最初から始める方がはるかに簡単であることが明らかになりませんでした。この著者自身のアドバイスは 車輪の再発明 それにもかかわらず。

古いものからの新しいギズモ:Node.jsバックエンドを使用したリモートコントロールとしての電話の転用

まず、このNode.jsプロジェクトは現在Linuxに固有であり、特にLinux Mint19とLinuxMint 19.3で開発およびテストされていますが、他のプラットフォームのサポートも確実に追加される可能性があることに注意してください。それ 五月 すでにMacで動作します。

の現代版を想定 Node.js がインストールされ、プロジェクトルートとして機能する新しいディレクトリでコマンドプロンプトが開かれると、Expressを開始する準備が整います。

npx express-generator --view=pug

注:ここでは、npxは、Node.jsに同梱されているNode.jsパッケージマネージャーであるnpmに付属している便利なツールです。 Expressのアプリケーションスケルトンジェネレーターを実行するために使用しています。この記事の執筆時点で、ジェネレーターはExpress / Node.jsプロジェクトを作成します。これは、Jadeプロジェクトであっても、デフォルトではJadeと呼ばれるテンプレートエンジンをプルします。 自分の名前を「パグ」に変更 バージョン2.0以降。そのため、最新の状態ですぐにPugを使用し、さらに非推奨の警告を回避するために、--view=pugのコマンドラインオプションであるexpress-generatorを使用します。 npxによって実行されているスクリプト。

それが完了したら、Node.jsプロジェクトの新しく入力された依存関係リストからいくつかのパッケージをpackage.jsonにインストールする必要があります。これを行う従来の方法は、npm iを実行することです。 (i「インストール」の場合)。しかし、まだいくつかはの速度を好む 糸 、したがって、それがインストールされている場合は、yarnを実行するだけです。パラメータなし。

この場合、(できればすぐに修正される)を無視しても安全です。 非推奨の警告 ローカルネットワーク上で必要に応じてアクセスが維持されている限り、Pugのサブ依存関係の1つから。

簡単なyarn startまたはnpm start、その後に localhost:3000に移動します ブラウザで、基本的なExpressベースのNode.jsバックエンドが機能することを示しています。 Ctrl+Cで殺すことができます。

Node.jsバックエンドチュートリアル、ステップ2:ホストマシンでキーストロークを送信する方法

とともに リモート すでに途中で終わったので、注意を向けましょう コントロール 部。 Node.jsバックエンドを実行するマシンをプログラムで制御し、キーボードのキーを押しているふりをすることができるものが必要です。

そのために、xdotoolをインストールしますを使用して その公式の指示 。ターミナルでのコマンド例の簡単なテスト:

xdotool search 'Mozilla Firefox' windowactivate --sync key --clearmodifiers ctrl+l

…MozillaFirefoxがその時点で開いていると仮定すると、それが言っていることを正確に実行する必要があります。それは良い!すぐにわかるように、Node.jsプロジェクトでxdotoolなどのコマンドラインツールを呼び出すのは簡単です。

Node.jsバックエンドチュートリアル、ステップ3:機能の設計

これはすべての人に当てはまるわけではありませんが、個人的には、最近の物理的なリモコンの多くには、これまでに使用するボタンの約5倍のボタンがあります。そのため、このプロジェクトでは、3 x 3のグリッドがあり、大きくてターゲットが簡単なボタンを備えたフルスクリーンレイアウトを検討しています。これらの9つのボタンが何であるかは個人の好み次第です。

最も単純な機能でさえ、キーボードショートカットは全体で同一ではないことが判明しました Netflix 、 Youtube 、および アマゾンプライムビデオ 。また、これらのサービスは、ネイティブの音楽プレーヤーアプリのように一般的なメディアキーでは機能しません。また、一部の機能がすべてのサービスで利用できるとは限りません。

したがって、必要なのは、サービスごとに異なるリモコンレイアウトを定義し、それらを切り替える方法を提供することです。

リモートコントロールレイアウトの定義とキーボードショートカットへのマッピング

いくつかのプリセットを使用して、簡単なプロトタイプを作成してみましょう。複数のファイルからのこのデータを含めるため、それらをcommon/preset_commands.js —「共通」に配置します。

module.exports = { // We could use ️ but some older phones (e.g., Android 5.1.1) won't show it, hence ️ instead 'Netflix': { commands: { '-': 'Escape', '+': 'f', '': 'Up', '⇤': 'XF86Back', '️': 'Return', '': 'Down', '': 'Left', '': 'Right', '': 'm', }, }, 'YouTube': { commands: { '⇤': 'shift+p', '⇥': 'shift+n', '': 'Up', 'CC': 'c', '️': 'k', '': 'Down', '': 'j', '': 'l', '': 'm', }, }, 'Amazon Prime Video': { window_name_override: 'Prime Video', commands: { '⇤': 'Escape', '+': 'f', '': 'Up', 'CC': 'c', '️': 'space', '': 'Down', '': 'Left', '': 'Right', '': 'm', }, }, 'Generic / Music Player': { window_name_override: '', commands: { '⇤': 'XF86AudioPrev', '⇥': 'XF86AudioNext', '': 'XF86AudioRaiseVolume', '': 'r', '️': 'XF86AudioPlay', '': 'XF86AudioLowerVolume', '': 'Left', '': 'Right', '': 'XF86AudioMute', }, }, };

キーコード値は次のようになります xevを使用して見つかりました 。 (私にとって、「オーディオミュート」と「オーディオ再生」はこの方法では検出できなかったので、私も相談しました メディアキーのリスト 。)

読者はspaceの大文字小文字の違いに気付くかもしれませんおよびReturn —この理由に関係なく、xdotoolについてはこの詳細を尊重する必要があります。正しく動作します。これに関連して、明示的に記述されたいくつかの定義があります。たとえば、shift+p Pにもかかわらず私たちの意図を明確に保つためだけに、うまくいくでしょう。

Node.jsバックエンドチュートリアル、ステップ4:APIの「キー」エンドポイント(駄洒落を許してください)

POSTへのエンドポイントが必要ですtoは、xdotoolを使用してキーストロークをシミュレートします。送信できるキーのグループは異なるため(サービスごとに1つ)、特定のエンドポイントを呼び出しますgroup。生成されたusersを再利用します名前を変更してエンドポイントroutes/users.js routes/group.jsに移動し、app.jsで対応する変更を加えます。

// ... var indexRouter = require('./routes/index'); var groupRouter = require('./routes/group'); // ... app.use('/', indexRouter); app.use('/group', groupRouter); // ...

ザ・ キー 機能はxdotoolを使用していますroutes/group.jsのシステムシェル呼び出しを介して。ハードコーディングしますYouTubeテスト目的のためだけに、今のところ選択するメニューとして。

const express = require('express'); const router = express.Router(); const debug = require('debug')('app'); const cp = require('child_process'); const preset_commands = require('../common/preset_commands'); /* POST keystroke to simulate */ router.post('/', function(req, res, next) { const keystroke_name = req.body.keystroke_name; const keystroke_code = preset_commands['YouTube'].commands[keystroke_name]; const final_command = `xdotool search 'YouTube' windowactivate --sync key --clearmodifiers ${keystroke_code}`; debug(`Executing ${final_command}`); cp.exec(final_command, (err, stdout, stderr) => { debug(`Executed ${keystroke_name}`); return res.redirect(req.originalUrl); }); }); module.exports = router;

ここでは、要求されたキー「名前」をPOSTから取得します。 req.bodyという名前のパラメーターの下にあるリクエストの本文(keystroke_name)。 ️のようになります。次に、それを使用して、preset_commands['YouTube']のcommandsから対応するコードを検索します。オブジェクト。

最後のコマンドは複数の行にあるため、各行の終わりにあるは、すべての部分を1つのコマンドに結合します。

  • search 'YouTube'タイトルに「YouTube」が含まれる最初のウィンドウを取得します。
  • windowactivate --syncフェッチされたウィンドウをアクティブにし、キーストロークを受信する準備ができるまで待機します。
  • key --clearmodifiers ${keystroke_code}キーストロークを送信します。送信内容に干渉する可能性のあるCapsLockなどの修飾キーを一時的にクリアしてください。

この時点で、コードは有効な入力を提供していることを前提としています。これについては後で詳しく説明します。

簡単にするために、コードでは、タイトルに「YouTube」が含まれるアプリケーションウィンドウが1つだけ開いていることも前提としています。一致するものが複数ある場合、目的のウィンドウにキーストロークを送信する保証はありません。それが問題になる場合は、リモートコントロールするウィンドウ以外のすべてのウィンドウのブラウザタブを切り替えるだけで、ウィンドウのタイトルを変更できると便利です。

これでサーバーを再起動できますが、今回はデバッグを有効にして、debugの出力を確認できます。呼び出します。これを行うには、DEBUG=old-fashioned-remote:* yarn startを実行するだけです。またはDEBUG=old-fashioned-remote:* npm start。実行されたら、YouTubeでビデオを再生し、別のターミナルウィンドウを開いて、cURL呼び出しを試してください。

curl --data 'keystroke_name=️' http://localhost:3000/group

POSTを送信します要求されたキーストローク名を本体に含む要求を、バックエンドがリッスンしているポート3000のローカルマシンに送信します。そのコマンドを実行すると、Executingに関するメモが出力されます。およびExecuted npmでウィンドウ、そしてさらに重要なことに、ブラウザを起動し、そのビデオを一時停止します。そのコマンドを再度実行すると、同じ出力が得られ、一時停止を解除する必要があります。

Node.jsバックエンドチュートリアル、ステップ5:複数のリモートコントロールレイアウト

私たちのバックエンドは完全には完成していません。また、次のことができるようにする必要があります。

  1. preset_commandsからリモコンレイアウトのリストを作成します。
  2. 特定のリモコンのレイアウトを選択したら、キーストロークの「名前」のリストを作成します。 (すでにJavaScriptであるため、フロントエンドで直接common/preset_commands.jsを使用し、そこでフィルタリングすることもできます。これは、Node.jsバックエンドの潜在的な利点の1つであり、ここでは使用しません。 。)

これらの機能は両方とも、Node.jsバックエンドチュートリアルが、構築するPugベースのフロントエンドと交差する場所です。

パグテンプレートを使用してリモコンのリストを表示する

方程式のバックエンド部分は、routes/index.jsを変更することを意味しますこのように見えるように:

const express = require('express'); const router = express.Router(); const preset_commands = require('../common/preset_commands'); /* GET home page. */ router.get('/', function(req, res, next) { const group_names = Object.keys(preset_commands); res.render('index', { title: 'Which Remote?', group_names, portrait_css: `.group_bar { height: calc(100%/${Math.min(4, group_names.length)}); line-height: calc(100vh/${Math.min(4, group_names.length)}); }`, landscape_css: `.group_bar { height: calc(100%/${Math.min(2, group_names.length)}); line-height: calc(100vh/${Math.min(2, group_names.length)}); }`, }); }); module.exports = router;

ここでは、group_namesを呼び出して、リモコンのレイアウト名(Object.keys)を取得します。私たちのpreset_commandsファイル。次に、それらと必要なその他のデータを、res.render()を介して自動的に呼び出されるPugテンプレートエンジンに送信します。

keysの意味を混同しないように注意してくださいここに鍵があります ストローク 送信します:Object.keysすべてを含む配列(順序付きリスト)を提供します キー の キーと値のペア JavaScriptでオブジェクトを構成するもの:

const my_object = { 'a key': 'its corresponding value', 'another key': 'its separate corresponding value', };

common/preset_commands.jsを見ると、上記のパターンと キー (オブジェクトの意味で)は、グループの名前です:'Netflix'、'YouTube'など。対応する値はmy_objectのような単純な文字列ではありません。上記があります。これらはオブジェクト全体であり、独自のキーがあります。つまり、commandsそしておそらくwindow_name_override。

ここで渡されるカスタムCSSは、確かに、ちょっとしたハックです。最新のフレックスボックスベースのソリューションを使用する代わりにそれが必要な理由は、さらに素晴らしい古い化身のモバイルブラウザの素晴らしい世界との互換性を高めるためです。この場合、注意すべき主な点は、横向きモードでは、画面1つあたり2つ以下のオプションを表示することで、ボタンを大きく維持していることです。ポートレートモードでは、4つ。

しかし、それは実際にどこでHTMLに変換され、ブラウザーに送信されるのでしょうか。ここでviews/index.pug入ってくる、これは次のようになります。

extends layout block header_injection style(media='(orientation: portrait)') #{portrait_css} style(media='(orientation: landscape)') #{landscape_css} block content each group_name in group_names span(class='group_bar') a(href='/group/?group_name=' + group_name) #{group_name}

最初の行が重要です:extends layoutこれは、Pugがこのファイルをviews/layout.pugのコンテキストで取得することを意味します。これは、ここおよび別のビューで再利用する一種の親テンプレートです。 linkの後に数行追加する必要があります最終的なファイルが次のようになるように行します。

doctype html html head title= title link(rel='stylesheet', href='/stylesheets/style.css') block header_injection meta(name='viewport', content='user-scalable=no') body block content

ここではHTMLの基本については説明しませんが、HTMLに慣れていない読者のために、このPugコードは、ほぼすべての場所で見られる標準料金のHTMLコードを反映しています。ザ・ テンプレート その側面はtitle= titleで始まり、HTMLタイトルをtitleに対応する値に設定します。 res.renderを介してPugを渡すオブジェクトのキー。

後でblockを使用して2行をテンプレート化する別の側面を見ることができます。 header_injectionという名前を付けています。このようなブロックは、現在のブロックを拡張するテンプレートで置き換えることができるプレースホルダーです。 (関係ありませんが、meta行は、モバイルブラウザーの簡単な回避策であるため、ユーザーがボリュームコントロールを連続して何度もタップすると、電話はズームインまたはズームアウトを控えます。)

block sに戻る:これがviews/index.pugの理由ですblockにあるのと同じ名前で独自のviews/layout.pug sを定義します。このheader_injectionの場合、これにより、電話機が置かれる縦向きまたは横向きに固有のCSSを使用できます。

contentここに、Webページの主要な表示部分を配置します。この場合は次のようになります。

  1. group_namesをループします渡す配列、
  2. を作成しますCSSクラスgroup_barを持つそれぞれの要素それに適用され、そして
  3. 各内にリンクを作成しますgroup_nameに基づいています。

CSSクラスgroup_bar views/layout.pugを介してプルされたファイル、つまりpublic/stylesheets/style.cssで定義できます。

html, body, form { padding: 0; margin: 0; height: 100%; font: 14px 'Lucida Grande', Helvetica, Arial, sans-serif; } .group_bar, .group_bar a, .remote_button { box-sizing: border-box; border: 1px solid white; color: greenyellow; background-color: black; } .group_bar { width: 100%; font-size: 6vh; text-align: center; display: inline-block; } .group_bar a { text-decoration: none; display: block; }

この時点で、npm startの場合はまだ実行中です、http://localhost:3000/に移動しますデスクトップブラウザでは、NetflixとYouTubeの2つの非常に大きなボタンが表示され、残りは下にスクロールして利用できます。

デスクトップブラウザを使用したリモコンレイアウトセレクターのテスト。NetflixとYouTubeの2つの非常に大きなボタンが表示されます。

ただし、この時点でクリックすると、リンク先のルートがまだ定義されていないため、機能しません(GETの/group)。

選択したリモコンのレイアウトを表示する

そのために、これをroutes/group.jsに追加します決勝の直前module.exportsライン:

router.get('/', function(req, res, next) { const group_name = req.query.group_name || ''; const group = preset_commands[group_name]; return res.render('group', { keystroke_names: Object.keys(group.commands), group_name, title: `${group_name.match(/([A-Z])/g).join('')}-Remote` }); });

これにより、エンドポイントに送信されるグループ名が取得され(たとえば、?group_name=Netflixの末尾に/group/を配置することにより)、それを使用してcommandsの値が取得されます。対応するグループから。その値(group.commands)はオブジェクトであり、そのオブジェクトのキーは、リモコンのレイアウトに表示する名前(keystroke_names)です。

注:経験の浅い開発者は、その仕組みの詳細に立ち入る必要はありませんが、titleの価値はのビットを使用します 正規表現 グループ/レイアウト名を頭字語に変換するには、たとえば、YouTubeリモコンのブラウザタイトルはYT-Remoteになります。そうすれば、電話で試す前にホストマシンでデバッグしている場合、xdotoolはありません。制御しようとしているウィンドウではなく、リモコンのブラウザウィンドウ自体を取得します。一方、私たちの電話では、リモコンをブックマークしたい場合は、タイトルが短く短くなります。

以前のres.renderとの遭遇と同様に、これはテンプレートviews/group.pugと混合するためにデータを送信しています。そのファイルを作成し、次のように入力します。

extends layout block header_injection script(type='text/javascript', src='/javascript/group-client.js') block content form(action='/group?group_name=' + group_name, method='post') each keystroke_name in keystroke_names input(type='submit', name='keystroke_name', value=keystroke_name, class='remote_button')

views/index.pugと同様に、views/layout.pugの2つのブログを上書きします。今回は、ヘッダーに挿入するのはCSSではなく、クライアント側のJavaScriptです。これについては後ほど説明します。 (そして、はい、気難しい瞬間に、私は誤って複数形に変更されたjavascripts…の名前を変更しました)

メインcontentこれは、keystroke_nameごとに1つずつ異なる送信ボタンの束で構成されたHTMLフォームです。各ボタンは、フォームで送信する値として表示されているキーストローク名を使用してフォームを送信します(POSTリクエストを行います)。

また、メインのスタイルシートファイルにはもう少しCSSが必要です。

.remote_button { float: left; width: calc(100%/3); height: calc(100%/3); font-size: 12vh; }

以前、エンドポイントを設定したときに、次のコマンドでリクエストの処理を終了しました。

return res.redirect(req.originalUrl);

これは事実上、ブラウザがフォームを送信すると、Node.jsバックエンドが応答して、フォームが送信されたページ、つまりメインのリモコンレイアウトに戻るようにブラウザに指示することを意味します。ページを切り替えることなく、よりエレガントになります。ただし、老朽化し​​たモバイルブラウザの奇妙で素晴らしい世界との最大限の互換性が必要です。このように、フロントエンドJavaScriptがまったく機能していなくても、Node.jsバックエンドプロジェクト すべき まだ機能します。

フロントエンドJavaScriptのダッシュ

フォームを使用してキーストロークを送信することの欠点は、ブラウザーが待機してから、追加のラウンドトリップを実行する必要があることです。ページとその依存関係は、Node.jsバックエンドから要求されて配信される必要があります。次に、ブラウザで再度レンダリングする必要があります。

読者は、これがどれほどの効果をもたらすのか疑問に思うかもしれません。結局のところ、ページは小さく、その依存関係は非常に最小限であり、最終的なNode.jsプロジェクトはローカルのwifi接続を介して実行されます。低レイテンシのセットアップである必要がありますか?

結局のところ、少なくともWindows Phone8.1とAndroid4.4.2を実行している古いスマートフォンでテストした場合、残念ながら、すばやくタップして再生音量を数ノッチ上げたり下げたりする一般的なケースでは、その影響は非常に顕著です。ここで、HTMLフォームを介した手動のPOSTの優雅なフォールバックを損なうことなく、JavaScriptが役立ちます。

この時点で、最終的なクライアントJavaScript(public/javascript/group-client.jsに配置される)は、サポートされなくなった古いモバイルブラウザーと互換性がある必要があります。しかし、それはあまり必要ありません。

(function () { function form_submit(event) { var request = new XMLHttpRequest(); request.open('POST', window.location.pathname + window.location.search, true); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); request.send('keystroke_name=' + encodeURIComponent(event.target.value)); event.preventDefault(); } window.addEventListener('DOMContentLoaded', function() { var inputs = document.querySelectorAll('input'); for (var i = 0; i

ここで、form_submit関数は非同期呼び出しを介してデータを送信するだけであり、最後の行はブラウザの通常の送信動作を妨げます。これにより、サーバーの応答に基づいて新しいページが読み込まれます。このスニペットの後半は、ページが読み込まれるまで待機してから、すべての送信ボタンを接続してform_submitを使用します。全部が包まれている IIFE 。

最後の仕上げ

いくつかあります 変更 Node.jsバックエンドチュートリアルコードの最終バージョンの上記のスニペットに、主にエラー処理を改善する目的で:

  • Node.jsバックエンドは、送信されたグループとキーストロークの名前をチェックして、それらが存在することを確認するようになりました。このコードは、GETの両方に再利用される関数内にありますおよびPOST routes/group.jsの関数。
  • パグを利用しますerrorそうでない場合はテンプレート。
  • フロントエンドのJavaScriptとCSSは、サーバーからの応答を待っている間、ボタンの輪郭を一時的に灰色にし、信号がxdotoolを通過するとすぐに緑色になります。問題なく戻って、期待どおりに機能しなかった場合は赤になります。
  • Node.jsバックエンドは、スタックトレースが停止すると、スタックトレースを出力します。これは、上記の場合に発生する可能性が低くなります。

読者は、Node.jsプロジェクト全体を熟読(および/または複製)することができます。 GitHubで 。

Node.jsバックエンドチュートリアル、ステップ5:実際のテスト

実行中のホストと同じwifiネットワークに接続された実際の電話で試してみましょうnpm startそして映画や音楽プレーヤー。スマートフォンのウェブブラウザでホストのローカルIPアドレス(:3000の接尾辞が付いている)を指定するだけです。これは、hostname -I | awk '{print }'を実行することで簡単に見つけることができます。ホスト上の端末で。

Windows Phone 8.1ユーザーが気付く可能性のある問題の1つは、192.168.2.5:3000のようなものに移動しようとすることです。エラーポップアップが表示されます:

「WindowsPhone」エラーメッセージのスクリーンショット

ありがたいことに、落胆する必要はありません。単に接頭辞http://を付けるだけです。または末尾に/を追加しますそれ以上の苦情なしにアドレスを取得するためにそれを取得します。

リモコンレイアウト選択画面。

そこでオプションを選択すると、動作するリモコンが表示されます。

ザ・

さらに便利なように、ユーザーはルーターのDHCP設定を調整して、常に同じIPアドレスをホストに割り当て、レイアウト選択画面やお気に入りのレイアウトをブックマークすることができます。

プルリクエストへようこそ

誰もがこのプロジェクトをそのまま好きになるとは限らないでしょう。コードをさらに掘り下げたい人のために、改善のためのいくつかのアイデアがあります:

C言語が発明されたのはいつですか
  • レイアウトを微調整したり、DisneyPlusなどの他のサービス用に新しいレイアウトを追加したりするのは簡単です。
  • 「ライトモード」レイアウトと切り替えオプションを好む人もいるかもしれません。
  • Netflixを取り消すと、元に戻せないため、実際に「よろしいですか?」を使用できます。ある種の確認。
  • プロジェクトは確かに恩恵を受けるでしょう ウィンドウズ サポート。
  • xdotoolのドキュメントにはOSXが記載されていますが、このプロジェクトは最新のMacで機能しますか(または機能しますか?)
  • 高度なくつろぎのために、Netflix / Amazonプライムビデオの映画を1つ選んだり、コンピューターでYouTubeプレイリストを作成したりする代わりに、映画を検索して閲覧する方法。
  • 提案された変更のいずれかが元の機能を壊した場合の自動テストスイート。

このNode.jsバックエンドチュートリアルと、結果として改善されたメディアエクスペリエンスを楽しんでいただけたと思います。ハッピーストリーミング—そしてコーディング!

関連: Node.js / TypeScript REST APIの構築、パート1:Express.js

基本を理解する

Node.jsはバックエンド用ですか?

はい。 Node.jsは、JavaScriptコードを実行するコマンドラインプログラムであり、通常、Webホストで、Webページの提供、データベースへの接続などに使用されます。

Node.jsはバックエンドに十分ですか?

絶対に。正しく設計されたNode.jsバックエンドは、あらゆるテクノロジーと同様に拡張できます。とはいえ、アプリのデータベースレイヤーへのアクセスなど、他の重要なコンポーネントと統合されることがよくあります。

Express.jsとは何ですか?

ExpressはNode.jsのモジュールであり、一般的なWebサーバー機能の記述に必要な定型コードの量を削減します。それはそれ自身の成熟したサブエコシステムを持っています。ほとんどのNode.jsWebサーバーはExpressを使用します。

パグ/ジェイドとは何ですか?

Pug(以前のJade)は、Expressと統合するテンプレートエンジンです。実際、何年もの間、Expressプロジェクトジェネレーターが新しいプロジェクトに含めるデフォルトのテンプレートエンジンでした。

xdotoolとは何ですか?

コマンドラインプログラムxdotoolは、実行中のコンピューターでのキーストロークをシミュレートします。このプロジェクトでは、電話がWebページを介してコンピューター上でそのようなアクションを実行し、それをリモコンに変えます。

優れた質問は優れたデザインにつながる–デザイン思考プロセスのガイド

Uxデザイン

優れた質問は優れたデザインにつながる–デザイン思考プロセスのガイド
PhalconPHP:高負荷のRESTfulAPIのソリューション

PhalconPHP:高負荷のRESTfulAPIのソリューション

バックエンド

人気の投稿
プレトタイプを使用したビジネスケースのサポート
プレトタイプを使用したビジネスケースのサポート
タイムロックウォレット:イーサリアムスマートコントラクトの概要
タイムロックウォレット:イーサリアムスマートコントラクトの概要
女性エンジニアを擁護する
女性エンジニアを擁護する
製品アナリスト、成長マーケティング
製品アナリスト、成長マーケティング
意味のあるデザインと楽しいUXの芸術
意味のあるデザインと楽しいUXの芸術
 
Namekoを使用したPythonマイクロサービスの概要
Namekoを使用したPythonマイクロサービスの概要
完全なユーザー認証とアクセス制御– Laravel Passportチュートリアル、Pt。 1
完全なユーザー認証とアクセス制御– Laravel Passportチュートリアル、Pt。 1
Apache Luceneとのダイアログの全文検索:チュートリアル
Apache Luceneとのダイアログの全文検索:チュートリアル
安全でないモノのインターネット(IoT)を作成していますか?セキュリティの課題と懸念
安全でないモノのインターネット(IoT)を作成していますか?セキュリティの課題と懸念
ミラーAPIチュートリアル:Web開発者向けGoogle Glass
ミラーAPIチュートリアル:Web開発者向けGoogle Glass
人気の投稿
  • nodejsリアルタイムの例
  • ワードプレスにAPIを追加する方法
  • データ視覚化ソフトウェアとは
  • インターフェイス設計のベストプラクティス
  • 経験は感覚なので測定することは不可能です。
  • オープンソースプログラムのソースコードへの変更を製品に追加することはできません。
  • javascriptはタイムスタンプを日付に変換します
カテゴリー
財務プロセス 収益と成長 計画と予測 アジャイルタレント ツールとチュートリアル モバイル ライフスタイル データサイエンスとデータベース Uxデザイン Kpiと分析

© 2021 | 全著作権所有

apeescape2.com