2017年にGoでWebアプリを作成します。 パート3


以前の記事の結果として、小さなHTMLを提供できるGoアプリがあります。 この記事では、クライアント側について説明します。クライアント側は、Goではなく、主にJavaScriptで構成されています。


2017年のJavaScript


私のこの部分は最も悲しかった。 今日のJavaScriptの混乱を分類する方法も、説明する方法も本当に知りません。 それを理解しようとすると、優れた、しかし完全に異なる記事につながります。 それで、これを私たちが変えることのできない現実と考えて、それをどのように扱うのが最善かを考えましょう。


JSの種類


現在最も一般的なJSのバリアントはES2015(別名ES6またはECMAScript 6th edition)として知られており、 主に多かれ少なかれ最近のブラウザーでサポートされています。 リリースされた最新のJavaScript仕様はES7(別名ES2016)ですが、ブラウザーはまだES6に追いついているため、ES7は2017年にリリースされる可能性が高いため、ES7は受け入れられないようです。ブラウザの準備が整うまで待ってください。


これは奇妙ですが、ECMAScriptの特定のバージョンと完全に一貫した環境を作成する簡単な方法はないようです。 サポートされている古いバージョンのES5またはES4に戻すこともできないため、スクリプトのコンプライアンスを確認する方法はありません。 あなたができる最大のことは、利用可能なすべてのブラウザでテストし、最高のものを期待することです。


プラットフォームとブラウザー間で絶えず変化し、大幅に異なる言語サポートのために、この問題を解決するための一般的なアイデアとしてトランスピレーションが登場しました。 基本的に、トランスコンパイルは、コードをESの特定のバージョンまたは特定の環境に対応するコードに変換することです。 たとえば、 import Bar from 'foo'; var Bar = require('foo'); 。 したがって、特定の機能がサポートされていない場合は、適切なプラグインまたはトランスパイラーを使用して利用可能にすることができます。 トランスパイラーの普及現象により、サポートされていない機能が存在すると仮定したトランスパイラーが期待する入力が結論と一致するなど、追加の問題が発生したと思われます。 多くの場合、これは追加のプラグインで修正でき、それを把握するのは非常に困難です。 繰り返し、私は何か他のツールに組み込まれた新しいより良いソリューションのために私のアプローチ全体が古くなっていることを後で見つけるために、何かを機能させるために多くの時間を費やしました。


Jsフレームワーク


また、JSフレームワークが最適であるという論争も多くあります。 この問題は、同じフレームワークがバージョンごとに根本​​的に異なる可能性があるという事実によってさらに混乱しています。 名前を変更するだけではないのは驚くべきことです。


どれがベストかわからないので、2、3の忍耐しかありませんでした。 約1年前、AngularJSの整理に多くの時間を費やしました。今回は、さまざまな理由から、Reactをいじっていました。 Reactはより論理的に思えたので、このサンプルアプリケーションではそれを使用しています。


ReactとJSX


Reactがわからない場合は、ここに(技術的に間違った)説明があります:これはJavaScriptに埋め込まれたHTMLです。 JavaScriptはHTMLに埋め込み可能であり、これが自然な順序であるという事実について、私たちは皆洗脳されています。したがって、この関係を逆にすることは誰にも起こりません。 この革新的な(!)原理の基本的なシンプルさのため、Reactは素晴らしいと思います。


「Hello World!」 Reactでは次のようになります:


 class Hello extends React.Component { render() { let who = "World"; return ( <h1> Hello {who}! </h1> ); } } 

HTMLコードは、ラッパーや区切り文字なしで開始されることに注意してください。 奇妙なことに、開き山かっこ( "<")は、HTMLコードの始まりを示すマーカーとして十分に信頼性があります。 また、HTML内では、開き括弧は一時的にJavaScriptに戻ることを示しているため、変数の値はHTML内で置換されます。 これは、Reactを理解するために知っておく必要のあるほぼすべてのことです。


技術的には、前述のファイル形式はJSXとして知られていますが、Reactは、上記のReact.ComponentなどのReactオブジェクトを作成するためのクラスを提供するライブラリです。 JSXはBabelと呼ばれるツールを使用して通常のJavaScriptに変換されます。実際、JSXは不要です。Reactコンポーネントは純粋なJavaScriptで作成でき、JSXなしでReactを使用するアプローチがあります。 個人的には、「JSXを使用しない」方法は少しうるさいと思います。Babelを使用すると、よりモダンなJS方言を使用できます(トランスパイラーを処理する必要は間違いなくプラスになります)。


最小限の作業の例


まず、3つの外部JavaScriptライブラリが必要です。 これらは、(1)ReactおよびReactDOM、(2)Babelブラウザートランスポーター、および(3)JSON HTTPリクエストの作成に役立つAxiosと呼ばれる小さなライブラリです。 Cloudflare CDNから取得しますが、他の方法を使用することもできます。 ライブラリを接続するには、 indexHTML変数を次のindexHTMLに展開する必要があります。


 const ( cdnReact = "https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react.min.js" cdnReactDom = "https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-dom.min.js" cdnBabelStandalone = "https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js" cdnAxios = "https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.min.js" ) const indexHTML = ` <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Simple Go Web App</title> </head> <body> <div id='root'></div> <script src="` + cdnReact + `"></script> <script src="` + cdnReactDom + `"></script> <script src="` + cdnBabelStandalone + `"></script> <script src="` + cdnAxios + `"></script> <script src="/js/app.jsx" type="text/babel"></script> </body> </html> ` 

最後に、 "/js/app.jsx"ロードされましたが、まだ作成していません。 前のパートでは、 http.Dir()を使用して、 http.Dir()というUI構成構造のフィールドに入力しました。 次に、ファイルを提供するハンドラーでラップする必要があります。Goはこれを簡単に提供します。


  http.Handle("/js/", http.FileServer(cfg.Assets)) 

したがって、 "assets/js"ディレクトリ内のすべてのファイルは、パス"/js/"沿ってアクセスできます。


assets/js/app.jsxファイルassets/js/app.jsx作成します:


 class Hello extends React.Component { render() { let who = "World"; return ( <h1> Hello {who}! </h1> ); } } ReactDOM.render( <Hello/>, document.querySelector("#root")); 

前のリストとの唯一の違いは、最後の行にあり、実際にはアプリケーションを描画します。


ブラウザ(JS互換)でメインページに移動すると、「Hello World」が表示されます。


仕組み:ブラウザーは「app.jsx」を指示どおりにロードしましたが、「jsx」は見慣れないファイルタイプであるため、ブラウザーは単に無視しました。 Babelが仕事をする機会を得たとき、彼は「text / babel」タイプのスクリプトタグの存在をドキュメントで確認し、これらのページを再要求しました(したがって、開発者ツールに2回表示されますが、2番目の要求はブラウザキャッシュから完全に処理される必要があります)。 Babelはこのスクリプトを正しいJavaScriptに変換して実行し、Reactが実際に「Hello World」を表示するようにしました。


人のリスト


まず、サーバー側に戻り、人をリストするURIを作成する必要があります。 これを行うには、次のようなhttpハンドラーが必要です。


 func peopleHandler(m *model.Model) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { people, err := m.People() if err != nil { http.Error(w, "This is an error", http.StatusBadRequest) return } js, err := json.Marshal(people) if err != nil { http.Error(w, "This is an error", http.StatusBadRequest) return } fmt.Fprintf(w, string(js)) }) } 

そして、登録する必要があります。


  http.Handle("/people", peopleHandler(m)) 

ここで、 "/people"移動すると、応答で"[]"取得する必要があります。 Peopleテーブルにエントリを追加する場合:


 INSERT INTO people (first, last) VALUES('John', 'Doe'); 

答えは[{"Id":1,"First":"John","Last":"Doe"}]変わるはずです。


最後に、React / JSXコードを接続して、すべてを表示する必要があります。


これを行うには、 PersonItemコンポーネントと、 PersonItemを使用するPersonItemという別のコンポーネントを作成します。


PersonItemコンポーネントは、テーブル行として自身を表示する方法のみを知っている必要があります。


 class PersonItem extends React.Component { render() { return ( <tr> <td> {this.props.id} </td> <td> {this.props.first} </td> <td> {this.props.last} </td> </tr> ); } } 

PeopleList少し複雑です。


 class PeopleList extends React.Component { constructor(props) { super(props); this.state = { people: [] }; } componentDidMount() { this.serverRequest = axios .get("/people") .then((result) => { this.setState({ people: result.data }); }); } render() { const people = this.state.people.map((person, i) => { return ( <PersonItem key={i} id={person.Id} first={person.First} last={person.Last} /> ); }); return ( <div> <table><tbody> <tr><th>Id</th><th>First</th><th>Last</th></tr> {people} </tbody></table> </div> ); } } 

this.state変数を初期化するthis.stateます。 また、 componentDidMount()メソッドも宣言しcomponentDidMount() 。このメソッドは、コンポーネントがレンダリングの準備をする必要があるときに、Reactによって呼び出されます。 これは、サーバーからデータを取得する適切な場所(の1つ)です。 メソッドはAxios呼び出しを介してデータを受信し、結果をthis.state.peopleます。 最後に、 render()this.state.peopleのコンテンツをthis.state.peopleし、各要素のPersonItemインスタンスを作成します。


それだけです。私たちのアプリケーションは、データベースからの人々のリストを含むテーブル(かなり怖いテーブルですが)で応答します。


おわりに


基本的に、これは、完全に機能するGo Webアプリケーションを作成するために知っておく必要があるすべてです。 もちろん、このアプリケーションには多くの欠点があります。可能であれば、後で検討します。 たとえば、ブラウザーのトランスコンパイルは理想的ではありません。このオプションは、ページの読み込み時間が重要ではない、あまり価値のないアプリケーションには適していますが、プリコンパイルする方法を見つけることをお勧めします。 さらに、JSXは1つのファイルに制限されているため、このアプローチでは、多数のコンポーネントを使用して深刻なサイズのアプリケーションを管理することが困難になります。 アプリケーションにはナビゲーションがありません。 スタイルなし。 私が忘れていることがあります...


お楽しみください!


PSすべてのコードは完全にここにあります


継続



Source: https://habr.com/ru/post/J329612/


All Articles