オープンソースの冒険:エピソード23:Imba


別のImba 1アプリをImba 2に移植しましょう.
アプリは非常に簡単ですが、1つのコンポーネントを持っており、json-stringify-pretty-compactパッケージにすべてのロジックをoutsource.
それについての最も興味深い部分は、インテグレーションテストのためのサイプレスを使用しているので、次のポストではまた、Imba 2バージョンのセットアップをサイプレス統合テストしようとします.

ここでアクションで見ることができます Imbaの1アプリ。印旛


let stringify = require("json-stringify-pretty-compact")

tag App
  def setup
    @maxlen = 80
    @indent = 2
    @text = JSON.stringify({hello: "world"})
    @error = null

  def prettify
    try
      let indent = parseInt(@indent)
      let json = JSON.parse(@text)
      let spaces = Array.from({length: indent+1}).join(" ")
      @text = stringify(json, {maxLength: @maxlen, indent: spaces})
    catch e
      @error = e

  def clear_error
    @error = null

  def upload(event)
    let file = event.native:target:files[0]
    return unless file
    let reader = FileReader.new

    reader:onload = do |event|
      @text = event:target:result
      @error = nil
      Imba.commit
    reader.read-as-text(file)

  def render
    <self>
      <header>
        "JSON Beautifier"
      <textarea[@text] rows=10 :input.clear_error>
      if @error
        <div.error>
          @error
      <div.controls>
        <input#file type="file" :change.upload>
        <label for="indent">
          "Indent"
        <input#indent[@indent] type="number" min=0>
        <label for="maxlen">
          "Max row length"
        <input#maxlen[@maxlen] type="number" min=0>
        <button :click.prettify>
          "Prettify"

Imba.mount <App>

Imbaの1アプリ。SCSS


@import 'normalize-scss';
@include normalize();

.App {
  display: flex;
  flex-direction: column;
  align-items: center;

  header {
    font-size: 64px;
    text-align: center;
  }

  textarea {
    min-width: 50vw;
    margin-bottom: 10px;
  }

  .controls {
    display: grid;
    grid-row-gap: 5px;
    margin: auto;

    label { grid-column: 1; }
    input { grid-column: 2; }
    button { grid-column: 2; }
  }

  .error {
    background-color: #fcc;
    min-width: 50vw;
    padding: 5px;
    border: 1px solid #800;
  }
}

Imba 2アプリ。印旛


import stringify from "json-stringify-pretty-compact"

tag app
  prop maxlen = 80
  prop indent = 2
  prop text = JSON.stringify({hello: "world"})
  prop error

  def prettify
    try
      let json = JSON.parse(text)
      let spaces = Array.from({length: parseInt(indent)+1}).join(" ")
      text = stringify(json, {maxLength: parseInt(maxlen), indent: spaces})
    catch e
      error = ""+e
    imba.commit()

  def clear_error
    error = null

  def upload(event)
    let file = event.target.files[0]
    return unless file
    let reader = new FileReader

    reader.onload = do |event|
      text = event.target.result
      error = nil
      imba.commit()
    reader.readAsText(file)

  <self>
    <header>
      "JSON Beautifier"
    <textarea bind=text rows=10 :input.clear_error>
    if error
      <div.error>
        error
    <div.controls>
      <input#file type="file" :change.upload>
      <label for="indent">
        "Indent"
      <input#indent bind=indent type="number" min=0>
      <label for="maxlen">
        "Max row length"
      <input#maxlen bind=maxlen type="number" min=0>
      <button :click.prettify>
        "Prettify"

  css
    display: flex
    flex-direction: column
    align-items: center
    ff: sans

    header
      font-size: 64px
      text-align: center

    textarea
      min-width: 50vw
      margin-bottom: 10px

    .controls
      display: grid
      grid-row-gap: 5px
      margin: auto

      label
        grid-column: 1
      input, button
        grid-column: 2

    .error
      background-color: #fcc
      min-width: 50vw
      padding: 5px
      border: 1px solid #800

imba.mount <app>
これは非常に簡単な翻訳です.
IMPBA 2はErrorオブジェクトを出力に直接入れたくないので、StringErrorに変換する必要があります.
それ以外は、マイナーな構文変更です.
ところで、どんな枠組みでもlabel for問題に対して良い解決策を提供することになるでしょうか.たった今、彼らは本質的にグローバルスコープIDを使用します.

ソースコード


ソースコードは です.
また、imba2-json-beautifier repository .

ライブバージョンはこちら 今度来る


次のエピソードでは、このアプリにサイプレステストを追加しようとします.