Vue-Code-Formatierung in VSCode

Mit .vue-Dateien und Visiual Studio Code hatte ich oft Probleme, nun aber endlich eine Konfiguration gefunden, die sowohl Javascript- wie auch HTML-Segmente automatisch überprüft und formatiert. Als Plugins kommen dabei ESLint und Vetur zum Einsatz, meine settings.json sieht folgendermaßen aus:

{
  "git.autofetch": true,
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    {
      "language": "vue",
      "autoFix": true
    },
    {
      "language": "html",
      "autoFix": true
    },
    {
      "language": "javascript",
      "autoFix": true
    },
  ]
}

Problem ist nun, dass das HTML nicht eingerückt wird, wenn ich die Vue-Standardeinstellungen verwende. Um dies zu beheben, wechsele ich in der .eslintrc im Extends-Teil von plugin:vue/essential auf plugin:vue/recommended:

module.exports = {
  root: true,
  env: {
    node: true
  },
  'extends': [
    'plugin:vue/recommended',
    'standard'
  ],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
  },
  parserOptions: {
    parser: 'babel-eslint'
  }
}

Ggf. müssen hier noch Pakete installiert werden. Die Extension standard sorgt dafür, dass simplere Javascript-Regeln wie Einrückungen automatisch vorgenommen werden.

Dies ist ein sehr viel strengerer Linter, der viele Fehlerquellen ausschließt, aber auch einige subjektive Entscheidungen trifft. Dass HTML-Tags immer mehrzeilig werden, sobald mehr als ein Attribut definiert wird, finde ich gewöhnungsbedürftig. Dass hingegen die Standardeigenschaften einer Vue-Komponente immer konsistent sortiert werden, weiß zu gefallen.

Datenbeschaffung in Vue-Router-Views vereinfachen

created und watch

Ein typisches Vue-Router-Szenario: Daten müssen initialisiert und bei Routen-Updates zurückgesetzt und geladen werden, da die Komponente nicht neu erzeugt sondern nur intern aktualisiert wird.

data () {
  return {
    user: null,
    loading: true
  }
},
created () {
  this.fetchData()
},
watch: {
  '$route': 'fetchData'
},
methods: {
  async fetchData () {
    this.loading = true
    this.user = await this.$network.getUser(this.$route.params.userId)
    this.loading = false
  }
}

Watchers und immediate: true

Die Dopplung in created und watch kann durch einen Watcher mit der Eigenschaft immediate eliminiert werden:

watch: {
  '$route': {
    handler: 'fetchData',
    immediate: true
  }
}

Neuladen statt Updaten

Zudem kann man ein Neu-Rendern der Komponente bei Routen-Änderung erzwingen, um die Unübersichtlichkeit und das Fehlerpotential eines Updates zu vermeiden.

data () {
  return {
    user: null,
    loading: true
  }
},
async created () {
  this.loading = true
  this.user = await this.$network.getUser(this.$route.params.userId)
  this.loading = false
}

Hierfür muss im Template, welches den Router-View einfügt, einfach ein Key übergeben werden, der idealerweise die gesamte URL darstellt:

<router-view :key="$route.fullPath" />

Pakyows Ansatz für Views in Web-Applikationen

Auch wenn die Vertreter der Client-Seite den Kampf um die Frage, wo Views künftiger Web-Applikationen gerendert werden, schon lange gewonnen haben, so bleiben doch einige Diskussionspunkte offen. Was wird aus Suchmaschinen, Javascript-Verweigerern und den Nutzern von schwacher Hardware oder alter Browser? Der Schritt zur Client-Side-Web-Application ist an Konsequenzen geknüpft, die nicht jeder in Kauf nehmen möchte. Ich halte immer die Augen nach Projekten offen, die das Rendern sowohl auf Server als auch Client mit möglichst wenig Overhead ermöglichen. weiterlesen

Javascript: Klick außerhalb eines Bereiches

Folgendes Beispiel überwacht ein Dokument auf einen beliebigen Klick, außer wenn dieser in einem bestimmten Element (.container) liegt:

$(document).on 'click', (ev) ->
    if $('.container').has(ev.target).length == 0
      # ...

Dies ist beispielsweise hilfreich um ein Popup oder Dropdown-Menü schließen möchte, wenn der Nutzer „irgendwo“ außer auf das Widget selbst klickt.

Coffeescript nur nach Änderung kompilieren

Mein Build- und Entwicklungshilfe-Script für Node-Projekte kann bereits das Wesentliche: Coffeescript kompilieren, Tests ausführen, einen Server starten und beenden sowie das Dateisystem überwachen, um die anderen Aufgaben nach jedem Speichern automatisch auszuführen. Die schnell geschriebene Build-Task kompilierte bisher jede Coffeescript-Datei, die sie finden konnte. Um nach dem Speichern möglichst schnell Testergebnisse zu erhalten, sollte nur neu gebaut werden, was sich auch geändert hat. weiterlesen

Bash-Build-Script mit Desktop-Nachrichten und Dateiüberwachung

Ich habe mich die letzte Zeit viel mit Grunt herumgeschlagen. Grunt ist ein umfangreiches und mächtiges Build-Werkzeug für Node, dennoch hatte ich stets das Gefühl, dass die Konfiguration umständlicher als der wirkliche Nutzen ist. Ich habe daher mit einem Build-Script auf Bash-Basis begonnen, welches vom Nutzer spezifizierte Aufgaben nacheinander ausführt. Diese frühe Version unterstützt Coffeescript-Kompilierung, Testausführung und Dateisystemüberwachung, welche die anderen Tasks bei jeder Änderung automatisch ausführt. Nach dem Speichern bekommt man so stets die direkte Rückmeldung, ob die Unittests erfolgreich waren. weiterlesen

Node-Coding-Style: Vergleich zwischen Node FS und NPM

Noch immer führt die Suche nach einem Coding-Style für Node.js ins Leere. Da man sich für ein gleichmäßiges Code-Bild auch ohne offizielle Vorgabe Richtlinien schaffen muss, habe ich hier einen Vergleich zweier wesentlicher Module vorgenommen: Nodes integriertes FS und das unangefochtene Paketwerkzeug NPM.

Ich betrachte für mich derzeit relevante Punkte, wie etwa:

  • Einrückung
  • if-Statements
  • Stringausdrücke
  • Variablendeklaration
  • Semikolons

Mein Fazit: Den einen Node-Coding-Style gibt es nicht. Selbst die beiden Kernmodule weisen elementare Unterschiede auf. Den eigenen Stil muss man sich nach wie vor selbst zusammensuchen.

Eine Alternative: In Coffeescript ist der Code-Style Teil der Syntax, was konsistenten Code begünstigt.
weiterlesen

Current Working Directory in Node

Nutzt man verschiedene Node-Applikationen, die sich gegenseitig aufrufen, kann dies zu Problemen mit relativen Pfaden führen. Ein require('./...'); schlägt schnell fehl, wenn Programm A Programm B im eigenen Arbeitsverzeichnis ausführt. B kann das CWD ändern, etwa von einer Datei im Rootverzeichnis:

// in B/app.js
process.chdir(__dirname);
// oder in B/sub/file.js
process.chdir(__dirname + '/../');

Ist kein Aprilscherz. Dafür wählt Youtube endlich seinen Gewinner:

[youtube clip_id=“H542nLTTbu0″]

Live-Unittest-Entwicklungsumgebung für Node

Und wieder mal mehr Zeit in die Arbeitsvorbereitung als in die eigentliche Arbeit gesteckt. Eigentlich wollte ich in einem bestehenden Node-Projekt auch mit Coffee-Script arbeiten können. Herausgekommen ist eine Entwicklungsumgebung, in der man jede auf Node basierende Sprache wie eben Coffee- oder auch Type-Script verwenden kann, eine die Änderungen in Echtzeit deployt, die Unittests ausführt und eventuelle Fehler via Desktop-Benachrichtigung anzeigt. Das Ganze funktioniert unabhängig vom verwendeten Editor bzw. verwendeter IDE. Wer in Sublime Text noch Strg+B drückt, macht es sich zu kompliziert… weiterlesen