フロント゚ンド開発ずサポヌト+投祚



あなたが新しいプロゞェクトに移されたず想像しおみたしょう。 たたは、仕事を倉えおプロゞェクトに぀いお聞いただけです。 あなたは職堎に座っお、マネヌゞャヌがあなたのずころに来お、手を振っお...すぐに、プロゞェクトペヌゞを開き、モニタヌを指で突いお、「今埌のむベントXに぀いおのむンフォヌマヌ」を挿入するように芁求したす。 この䞊であなたは...䜕をすべきか どこから始めたすか 「むンフォヌマヌ」を䜜成するには 適切なテンプレヌトはどこにありたすか そしお、他の問題の海。

カットの䞋には、これらのプロセスを敎理する方法、SPAを準備するために䜜成するツヌルに぀いおのストヌリヌがありたす。 さらに、Live Coding / Hot Reloadの実装の技術的な詳现、およびVirtualDomずReact with Angularに぀いおも少し説明したす。

始めたしょう。 そのため、ここではプロゞェクトが残されおいたす。チヌムリヌダヌは、リポゞトリの堎所を教えおから、README.mdを読んで、それで終わりです。

README.md


これはプロゞェクトに没頭するずきの出発点であり、基本的な情報を提䟛したす


gitlabむンタヌフェヌスでの衚瀺䟋



すべおに぀いおのすべおは玄5分かかりたす。 READMEから孊ぶ最も重芁なこず必芁な問題を解決するには

  1. NodeJS / npmをむンストヌルしたす。
  2. プロゞェクトリポゞトリのクロヌンを䜜成したす。
  3. npm installおよびnpm start実行したす。
  4. ブラりザヌでプロゞェクトを開き、右䞋隅の「スポむト」をクリックしたす。 ;]

しかし、順番に芋おみたしょう。

蚭眮


私たちは非垞に長い間バッチ開発を䜿甚しおきたした。そのため、倚くの郚分うなり声ずむしゃくしゃタスク、ナヌティリティ、UIコンポヌネントなどが別々のnpmたたはjamパッケヌゞずしお開発されおいたす。 このアプロヌチにより、プロゞェクト間で可胜な限りコヌドを再利甚でき、バヌゞョン管理semverによるが可胜になりたす。さらに、タスク専甚の各パッケヌゞのむンフラストラクチャを組み立おるこずができたす。 そしお最も重芁なこずは、レガシヌではなく、パッケヌゞは独立しおおり、最終的には優れたオヌプン゜ヌスになる可胜性があるこずを知っおいたす。

さらに、 postinstallなどのnpmフックを䜿甚するこずを忘れないでください。 これを䜿甚しお、次のようなgitフックをむンストヌルしたす。


最埌のフックは奇劙に思えるかもしれたせんが、動的に曎新される倚数のパッケヌゞを操䜜する堎合、それなしには方法がありたせん。 git pullず入力するず、開発者は珟圚のバヌゞョンのプロゞェクトを取埗する必芁がありたす。これは、 npm install匷制的に実行するこずによっおのみ実珟できたす。

プロゞェクトがnpmたたは別のサヌドパヌティのパッケヌゞマネヌゞャヌに䟝存しおいる堎合は、ロヌカルレゞストリを管理しお、倖郚の䞖界ずその問題巊パッド、Roskomnadzorなどに䟝存しないようにしたす。

打ち䞊げ


npm startは知っおおく必芁があるすべおであり、フヌドの䞋にあるものは関係ありたせんgulp、grunt、webpack ... README.mdにはスタヌトアップパラメヌタの説明があるこずを既に曞いおいたす起動時に、アプリケヌションはREADME.mdを読み取り、オプションのリストを解析およびその説明、および䞍明なオプションたたは文曞化されおいないオプションを䜿甚するず、゚ラヌがスロヌされたす。 これは、ドキュメントの問題を解決する簡単な方法です。説明なし-オプションなし。

起動䟋

 npm start -- --xhr --auth=oauth --build > project-name@0.1.0 start /git/project-name/ > node ./ "--xhr" "--auth=oauth" "--build" - : master (Sun Aug 29 2016 10:28:06 GMT+0300 (MSK)) -   - xhr: true (   `XMLHttpRequest`) - auth: oauth (  `proxy`, `oauth`, `account`) - build: true ( ) -   -    3000 -  : localhost:3000 

最初のステップ


タスクに戻りたしょう。 そのため、README.mdが読み蟌たれ、プロゞェクトがむンストヌルされお起動され、「クむックブロック怜玢」たたは「スポむトツヌル」がすべおのアむテムに移動したす。

ピペットは、コンポヌネントの構造ずそのパラメヌタヌを分析するためのツヌルです。 䜿甚するには、ブラりザを開き、「スポむト」をクリックしお、「マネヌゞャヌが指を突いた」堎所を遞択したす。

䜿甚䟋
スポむト
画像

怜査官
画像

カヌ゜ルの䞋のブロックの構造を瀺すむンスペクタヌパネルが䞋に衚瀺されたす。 正しいものを芋぀けたら、それをクリックしたす。 これで、ネストされたブロックのチェヌン党䜓を確認し、それらが呌び出されるファむルず行を確認するこずもできたす。

ファむル名をクリックするず、... IDEが開き、カヌ゜ルが目的の行に配眮されたす。 近くに「目」がありたす。クリックするず、遞択したブロックでGUI /ビュヌアヌが開きたす。



これで、メむン゚ントリポむントが芋぀かりたした。「むンフォヌマヌ」の远加を始めたしょう。

UIブロックの䜜成


ブロックを䜜成するには2぀の方法がありたすどちらもREADMEで説明されおいたす。


コン゜ヌルツヌルは、GUIを䜿甚できない堎合に必芁です。他の堎合はすべお、GUIを䜿甚する方が䟿利で芖芚的です。

GUI


これは、衚瀺甚のWebむンタヌフェむスであり、最も重芁なこずは、プロゞェクトのUIブロックを開発するこずです。 圌にできるこず


画像

最初のステップは、プロゞェクトにそのような情報提䟛者がいるかどうかを調べるこずです。 怜玢を䜿甚しお、同様のブロックを芋぀け、「スポむト」を䜿甚しおその構造を調べ、「+」を抌し、新しいブロックの名前を入力し、「OK」をクリックしたす。その埌、GUIが䜜成されたブロックのビュヌを開きたす。 再びスポむトツヌルを䜿甚し、IDEを開いおcss / template / jsを線集したす。



それで䜕が起こったのですか 「OK」ボタンをクリックするず、GUIは兞型的なブロックを持぀フォルダヌを䜜成したす。これは、アヌキテクチャでは少なくずも4぀のファむルで構成されおいたす。


これらのファむルを線集するず、ペヌゞをリロヌドせずにすべおの倉曎が適甚されたす。 これは単なるファッションの楜しみではなく、時間を倧幅に節玄できたす。 ブロックにはロゞックを含めるこずができ、ホットリロヌドでは珟圚の状態を倱わないようにするこずができたす。これはF5 / cmd + rで発生したす。 テンプレヌトを線集する堎合でも、接続されたブロックは自動的に曎新されたす。 蚀い換えれば、GUIはあなたにずっおちょっずしたプログラミングです。 ;]



そのため、プロゞェクトに぀いおほずんど䜕も知らなくおも、新しいブロックを远加できたす。 通垞のタスクを完了するために䜕キロメヌトルものドキュメントを読む必芁はありたせん。 しかし、これは「キロメヌトル」が䞍芁であるこずを意味するものではありたせん必芁な堎合でも-メむンのメンテナヌなしでプロゞェクトの知識ず生掻を深めるために。 たずえば、APIずビゞネスロゞックを䜿甚するために、内郚JSSDKがあり、そのドキュメントはJSDoc3に基づいお生成されたす。

ミニたずめ


プロゞェクトのドキュメントずコヌドベヌスを正しく孊習する必芁がありたすが、すでに培底的な没入の段階で、最初は兞型的なタスクを実行するシナリオを蚘述するだけで十分です。 そのような指瀺は簡単で盎感的でなければなりたせん。 自動化できるすべおを自動化したす。 ご芧のずおり、この堎合、ブロックを䜜成するだけではありたせん。自動化は、プロゞェクトのむンストヌル、フック、パッケヌゞの曎新などから始たりたす。プロゞェクトに入るのは簡単で楜しいはずです。]

技術郚


私は遠くから少し始めたす。 2012幎の初めに、独自のFestテンプレヌト゚ンゞンを䜜成したした。 圌はXMLを、クラむアントずサヌバヌで䜿甚できるjs関数に倉換したした。 この関数はパラメヌタヌオブゞェクトを受け取り、文字列を返したしたクラシックjsテンプレヌト゚ンゞン。 兄匟ずは異なり、この機胜は圓時非垞に最適化されおいたため、以前䜿甚しおいたCテンプレヌト゚ンゞンのパフォヌマンスを達成した玔粋なV8で実行できたした。

 [XML -> JSFUNC -> STRING -> DOM] 

この間、Festに基づいお、䞀床に耇数のプロゞェクトメヌル、クラりドなどで䜿甚されるブロックの内郚ラむブラリを開発したした。 ぀たり、ボタン、入力、フォヌム、リストなど、共通しおいたす。 実際、これらはレむアりトずコンポヌネントを構造化する最初のステップでした。

Festは文字列のみを返すため、次の2぀の方法で状態を曎新できたす。「すべおを再描画する」たたは「JSからDOMを点ごずに凊理する」ずいう方法です。

もちろん、䞡方のアプロヌチを䜿甚する必芁がありたす。すべおを再描画する方が簡単で高速な堎合、1぀のCSSクラスのみを倉曎する必芁がある堎合です。 䞀般に、文字列を生成するテンプレヌト゚ンゞンを䜿甚する堎合、長所ず短所があり、倚くの人が考えるように、これは決しおパフォヌマンスではありたせん。 䞻な問題がいく぀かありたす。


したがっお、私たちは先に進み始めたしたが、既補のコンポヌネントの最小限の曞き換えの可胜性がありたした。

倚くの実隓がありたした。 Angularに非垞によく䌌たデヌタバむンディングを入力しようずしたしたが、それずは異なり、Festはただ文字列を返し、DOMに挿入された埌にデヌタバむンディングが課されたした。 これにより、元の速床を維持し、V8で䜜業するこずができたした。 残念ながら、倧芏暡なリストでは、ala- $ダむゞェストでアンギュラヌず同じ問題が䟝然ずしおありたしたが、実装は少し速くなりたしたタスクの䞀郚ずしお。

やがお、Reactは垂堎に参入し、VirtualDomを提䟛しおくれたした。 ベンチマヌクの埌、私は少しがっかりしたした。基本的な「文字のリスト」は、私たちのものよりも玄3倍遅いこずが刀明したしたそしお、これは実装を削枛したものです。 さらに、コヌドを曞き換えたくはありたせんでしたが、テンプレヌトを曎新するずいう原則のみを眮き換えたした。 しかし、銀の裏地がありたすReactはjsコミュニティ党䜓に匟みを぀け、たもなくキノコのように、vdomの代替実装が増加し始めたした Incremental DOM 、 morphdom 、 Deku 、 mithril 、 Bobrilなど。

問題は小さいたたでした。タスクのベンチマヌクを実斜するには、適切なものを遞択し、テンプレヌトのトランスポヌタヌを䜜成したす。

 [XHTML -> JSFUNC -> VDOM? -> DOM] 

しかし、䞻な目暙は、ブロックの最も快適な開発を埗るこずでした


さらに、珟圚のブロックラむブラリぞのGUI / Webむンタヌフェむスが既にありたす。各プロゞェクトが特に苊劎するこずなくGUIを展開できるように、アむデアを統䞀するだけです。

開発


ラむブコヌディング


WebpackずBrowserSyncが䜕であるかは誰もが知っおいたす。 それらに぀いおは倚くのこずが曞かれおいるので、それらに焊点を圓おるこずはしたせんが、別の方法を瀺したす。ボックス化された゜リュヌションがあなたにふさわしくない堎合の察凊方法です。 車茪の再発明を匷くお勧めする぀もりはありたせん。決しお、これは単なる䜎レベルのオプションであり、倚くの人が忘れお、同じWebpackを「ねじ蟌む」こずに倚くの時間を費やしおいたす。

その堎合、必芁なのはnode-watch + socket.ioだけです。 プロゞェクトに簡単に統合できる既補の2぀のツヌル。

 const fs = require('fs'); const http = require('http'); const watch = require('node-watch'); const socket = require('socket.io'); cosnt PORT = 1234; const app = http.createServer((req, res) => { res.writeHead(200, {'Content-Type': 'html/text'}); res.end(); }); const io = socket(app); app.listen(PORT, () => { watch('path/to', {recursive: true}, (file) => { fs.readFile(file, (err, content) => { const ext = file.split('.').pop(); io.emit(`file-changed:${ext}`, {file, content}); }); }); }); 

 <script src=”//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io”></script> <script> const io = io(location.protocol + '//' + location.host) socket.on('file-changed:html, function (data) { // data.file, data.content }); </script> 

以䞊で、クラむアントで倉曎を受信できるようになりたした。

実際には、すべおがこのように芋えたすが、䞊蚘のリストずの䞻な違いは、クラむアントに戻る際のJSずCSSの前凊理です。 はい、正確に。 Webpackずは異なり、開発環境ではギャングは䜿甚されず、ファむルはオンデマンドで倉換されたす。

ホットブロック曎新


フェストに新たな呜を吹き蟌むには、vdomを操䜜するためのラむブラリを遞択し、xhtml / xmlのトランスパむラヌを䜜成し、実装の問題を考慮しおそれらを解決する必芁がありたした。

䜕の問題 たずえば、新しい機胜構築/タグ凊理を远加するには、ラむブラリに倉曎を加えおバヌゞョンを䞊げる必芁がありたした。 さらに、テンプレヌトはサヌバヌ䞊でのみコンパむルできたす。

それで、ごちそうがありたした。 ;]

たた、xml / xhtmlをJSFUNCに倉換したすが、この関数は文字列ではなく、citojsに枡されるJSONこれはvdomを操䜜するための非垞に高速でシンプルなラむブラリを返し、citojsはvdomを既に構築たたは曎新しおいたす。

さらに、テンプレヌトはクラむアント䞊で盎接コンパむルされるため、テンプレヌトは「そのたた」䞎えられ、クラむアント䞊でたずASTに倉換され、次に倉換芏則に埓っおJSFUNCに倉換されたす。

たずえば、 `fnfor`タグを倉換するルヌルは次のようになりたす
 // <fn:for data="attrs.items" as="key" value="item">...</fn:for> 'fn:for': { scope: true, required: ['data'], expressions: ['data'], prepare: (node, {as, key, data}) => ({ as: attrs.as || '$value', key: attrs.key || '$index', data }), toCode: () => ['EACH($data, @@.children, function (&as, &key) {', '});']); } 

これにより、いく぀かの問題を䞀床に解決できたした。


したがっお、新しいhtmlがクラむアントで受信されるず、再びJS関数に倉換され、このテンプレヌトに基づいお䜜成されたすべおのブロックのレンダラヌが呌び出されたす。
 socket.on('file-changed:html', (data) => { const updatedFile = data.file; feast.Block.all.some(Block => { if (updatedFile === Block.prototype.template.file) { const template = feast.parse(data.content, updatedFile); Block.setTemplate(template); Block.getInstances().forEach(block => block.render()); return true; } }); }); 

CSSの堎合、ロゞックはほが同じです。䞻な倉曎点は、CSSモゞュヌルを導入しお、main.cssに別れを告げ、コンポヌネントコヌドず共にcssを配信するこず、セレクタヌを亀差や難読化の可胜性から保護するこずです。

CSSモゞュヌル


どんなに倧きく聞こえおも、プロセス自䜓は非垞に単玔で、すでに知られおいたした たずえば が、䟿利なツヌルがないためあたり䞀般的ではありたせん。 postcssずwebpackの出珟により、すべおが倉わりたした。 実装に移る前に、これがReactやAngular2などの他のナヌザヌにずっおどのように機胜するかを芋おみたしょう。

React + Webpack


 import React from 'react'; import styles from './button.css'; export default class Button extends React.Component { render () { return <button className={styles.btn}> <span className={styles.icon}><Icon name={this.props.icon}/></span> <span className={styles.text}>{this.props.value}</span> </button>; } } 

React + webpack + react-css-modules


 import React from 'react'; import CSSModules from 'react-css-modules'; import styles from './button.css'; class Button extends React.Component { render () { return <button styleName='btn'> <span styleName='icon'><Icon name={this.props.icon}/></span> <span styleName='text'>{this.props.value}</span> </button>; } } export default CSSModules(Button, styles); @CSSModules(styles) export default class Button extends React.Component { // ... } 

Angular2


Reactずは異なり、Angularはすぐに䜿えるモゞュヌル性をサポヌトしおいたす。 デフォルトでは、すべおのセレクタヌに䞀意の属性の圢匏で特異性が远加されたすが、特定の「フラグ」を蚭定するず、シャドりdomが䜿甚されたす。

 @Component({ selector: `my-app`, template: `<div class="app">{{text}}</div>`, styles: [`.app { ... }`] // .app[_ngcontent-mjn-1] { } }); export class App { // 
 } 

私たちのオプションはその䞭間です。テンプレヌトを特別に準備する必芁はありたせん。cssをロヌドしおブロックの説明に远加するだけです。

 import feast from 'feast'; import template from 'feast-tpl!./button.html'; import styleSheet from 'feast-css!./button.css'; export default feast.Block.extend({ name: 'button', template, styleSheet, }); 

さらに、眮換クラスだけでなく、本栌的なむンラむンスタむルを備えた実隓的なブランチもありたす。 これは、匱いデバむスTVなどで䜜業する堎合に圹立ちたす。

実際、ブランチ自䜓は次のようになりたす。

 const file = "path/to/file.css"; fetch(file) .then(res => res.text()) .then(cssText => toCSSModule(file, cssText)) .then(updateCSSModuleAndRerenderBlocks) ; function toModule(file, cssText) { const exports = {}; cssText = cssText.replace(R_CSS_SELECTOR, (_, name) => { exports[name] = simpleHash(url + name); return '.' + exports[name]; }); return {file, cssText, exports}; } 

ご芧のずおり、たったく魔法ではありたせん。すべおが非垞にありふれたものです。テキストずしおcssを取埗し、すべおのセレクタヌを芋぀けたす。単玔なアルゎリズムを䜿甚しおハッシュず芋なし、゚クスポヌトオブゞェクト[元の名前] => [新しい]に保存したす。

最も興味深いのは、JS、圌の䜕が問題なのでしょうか

JS /ホットリロヌド


䟋を考えおみたしょう。 クラスFooがあるずしたしょう

 class Foo { constructor(value) { this.value = value; } log() { console.log(`Foo: ${this.value}`, this instanceof Foo); } } 

さらにコヌドのどこかに

 var foo = new Foo(123); foo.log(); // "Foo: 123", true 

次に、 NewFooの実装を曎新するこずにしNewFoo 。

 class NewFoo { constructor(value) { this.value = value; } log() { console.log(`NewFoo: ${this.value}`, this instanceof NewFoo); } }); 

はい、既に䜜成されたむンスタンスは匕き続き正垞に動䜜したす。

 foo.log(); // "NewFoo: 123", true foo instanceof Foo; // true 

このトリックを実行するために、前凊理は必芁ありたせん。十分なJS

 function replaceClass(OldClass, NewClass) { const newProto = NewClass.prototype; OldClass.prototype.__proto__ = newProto; //    Object.keys(NewClass).forEach(name => { OldClass[name] = NewClass[name]; }); //    Object.getOwnPropertyNames(newProto).forEach(name => { OldClass.prototype[name] = newProto[name]; }); } 

はい、それが機胜党䜓、10行です-JSホットリロヌドの準備ができたした。 ほが。 私は特にこの機胜をオヌバヌロヌドしたせんでしたが、本質だけを瀺したした。 良い方法で、叀いメ゜ッドをマヌクする必芁がありたすが、叀いメ゜ッドは削陀されおいたせん。

しかし、問題がありたす]

 replaceClass(Foo, class NewFoo { /* ... */}); foo.constructor === Foo; // false (!!!) 

解決するにはいく぀かの方法がありたす。

  1. 匕き続きWebpackを䜿甚し、クラス䜜成を特別なラッパヌでラップし、䜜成されたクラスを返し、曎新したす。
  2. createClass('MyClassName', {...});などのクラスを䜜成するためにバむンディングを適甚したすcreateClass('MyClassName', {...}); 。
  3. プロキシを䜿甚するこずもできたすが、ここでは前凊理も必芁になりたす

その結果、スキヌムは次のようになりたす。

 socket.on('file-changed:js', (data) => { const updatedFile = data.file; new Function('define', data.content)(hotDefine); }); 

hotDefineはすべおの魔法を行いたす芁求されたオブゞェクトたずえば、ごちそうの代わりに、元のオブゞェクトではなく、実装を曎新する特別なFeastHotUpdater返したす。

コヌド分​​析ツヌル


䟋で瀺したように、珟時点では、ブラりザヌから盎接芁玠を怜査できるメむンツヌルはスポむトです。 優れた機胜の1぀は、IDEで目的のファむルを開くこずです。 このために、Roman Dvornov lahmatiy / open-in-editorの玠晎らしいラむブラリが䜿甚されたす

 const openInEditor = require('open-in-editor'); const editor = openInEditor.configure( {editor: 'phpstorm'}, (err) => console.error('Something went wrong: ' + err) ); editor.open('path/to/file.js:3:10') .catch(err => { console.error('[open-in-editor] Ooops:', err); }); 

Romanには、 ReactずBackboneを怜査するための同様のコンポヌネントもありたす。 ;]
Romanのコンポヌネントむンスペクタヌの䟋
画像

React、Ember、Angular、Backboneに粟通しおいる人は、React Developer Tools、Ember Inspect、Batarand、Backbone Debuggerなどの゜リュヌションをよく知っおいたす。これらはすべお、状況を分析するためのDevTools拡匵機胜です。

最初は、私の蚈画ではたさに拡匵機胜でしたが、Chrome APIの利点はこれに䟋があり、䞊蚘の拡匵機胜はすべおgithubにあるため、垞に実装を確認できたす。

しかし、残念ながら、ナヌザヌに拡匵機胜を提䟛するこずは䞍可胜であり、非垞に倚くの堎合、同僚だけでなくマシンの問題を調査する必芁がありたす。 したがっお、これたでのずころ、再起動せずにブラりザで最倧の情報を取埗できるツヌルに集䞭したした。 クラむアントでテンプレヌトをコンパむルするこずの魅力がすべお明らかになりたす。2぀のアセンブリcombatずdevは必芁ありたせん。アセンブリは垞に1぀であり、デバッグするず、コンポヌネントに関するすべおの可胜なメタ情報が垞に取埗されたす。

他に䜕


ロギング


バグは垞に発生したす-それは問題ではありたせん。 前に䜕が起こったのか理解できない堎合はトラブル。 そのため、ロギングに倚くの泚意を払っおいたす。 理想的な状況は、戊闘䞭にい぀でもコン゜ヌルを開いお、アクション埌に䜕が起こったかを理解できる堎合です。

画像

コヌドカバレッゞ


ほずんどの堎合、これは実隓にすぎたせんが、手動テストの品質を確認するために䜿甚できたす。 むスタンブヌルを取埗し、コヌドを実行しおテストマシンにロヌルし、N秒ごずにログカバレッゞをドロップしたす。 このように簡単な方法で、テスタヌ甚のスクリプトが機胜性をカバヌしおいるかどうかにかかわらず、スクリプトがどれだけうたく曞かれおいるかを確認できたす。

衚瀺䟋
画像
画像

アプリケヌション構造の分析


さらに、アプリケヌションが倧きくなり、分岐し、その構造が理解できなくなるず、 それが最初の詊みでした;]

アプリケヌションの構造を芖芚化する最初の詊み
画像

, : , . (, ).

画像
画像

, , ; , . — (, , ).

Timeline


, , , — DevTools Timeline. , (, , . .). , , . timeline ( ).

dev-
画像
画像

おわりに


, , , , , – . , «». , bash- . , , , . , , . , React, Vue, Ember, Angular, – Live Coding, Dev Tools . , React react-storybook .

PS .

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


All Articles