Quand les frameworks JavaScript vont-ils disparaître?

L'auteur du matériel, dont nous publions aujourd'hui la traduction, développeur Web, dit qu'il essaie de revoir régulièrement l'ensemble des outils qu'il utilise. Il le fait pour comprendre s'il peut se passer de certains d'entre eux en résolvant ses tâches habituelles. Il a récemment décidé de mener une expérience et de créer une application frontale sophistiquée sans utiliser de frameworks JavaScript.

Qu'est-ce qu'un cadre?


Si vous essayez de définir un framework JavaScript sans entrer dans les détails, il s'avère que c'est un outil qui peut être utilisé pour développer des applications Web complexes, en particulier des applications à page unique (SPA).

Autrefois, ces applications étaient construites sur la base des capacités de JavaScript pur et de la bibliothèque jQuery. Mais, avec la complexité croissante des applications frontales, des outils correspondants ont commencé à apparaître qui facilitent la vie des programmeurs. Par exemple, ce sont React, Angular et Vue.

Les cadres qui sont populaires de nos jours ont des similitudes en commun. Ainsi, la plupart des frameworks et bibliothèques frontaux, relativement parlant, de Vue à React, offrent au développeur une certaine combinaison des fonctionnalités suivantes:

  • Synchronisation de l'état et présentation visuelle de l'application.
  • Acheminement
  • Système de modèles.
  • Composants pouvant être réutilisés.

Les frameworks sont-ils nécessaires pour un développeur moderne?


La réponse à la question posée dans le titre de cette section dépend de la manière dont vous vous reliez à l'idée de la «nécessité» des cadres. Je suis sûr que beaucoup peuvent dire que les frameworks frontaux ne sont pas nécessaires dans la boîte à outils du développeur Web et n'ont jamais été nécessaires. Bien qu'il soit incontestable que ce sont des outils très utiles.

En fait, notre question peut être reformulée comme suit: «Les frameworks sont-ils un peu une« bibliothèque jQuery moderne »? Est-il possible de résoudre les problèmes auxquels ils sont destinés, par d'autres moyens, par exemple, ceux qui sont apparus à la disposition des programmeurs lors du développement des API de navigateur? »


jQuery

En fait, cette question n'est pas facile à répondre, mais nous pouvons dire que le développement de JavaScript, des technologies pour travailler avec des composants Web et des outils pour construire des projets a rendu le développement de SPA sans utiliser de frameworks plus facile que jamais.

Afin d'explorer cette idée, j'ai développé une application d'une page utilisant uniquement JavaScript, des composants Web standard et le bundle Parcel. Au cours du processus, j'ai rencontré des problèmes et des difficultés, dont vous commencez particulièrement à voir clairement les points forts des frameworks JS modernes.

En même temps, dès que j'ai surmonté les obstacles initiaux, j'ai été surpris de la facilité avec laquelle il est possible de créer une application d'une page en JavaScript pur.

Présentation de l'application expérimentale


L'application en question est assez simple. Il s'agit d'une collection électronique de recettes et permet à l'utilisateur de créer, afficher et modifier des recettes. L'utilisateur, en plus, peut marquer des recettes, indiquant qu'il les aime, et peut également filtrer et supprimer des entrées.


Page d'accueil de l'application


Page d'enregistrement de recette

Composants Web


- — . , , HTMLElement ( HTMLParagraphElement, ) .

, - , , connectedCallback, disconnectedCallback, attributeChangedCallback.

recipe-item, .

import template from './recipe.html'
import DATA_SERVICE from '../../utils/data'
export default class Recipe extends HTMLElement {
  constructor () {
    //   DOM,    recipe  DATA_SERVICE()
    super()
    this._shadowRoot = this.attachShadow({ mode: 'open' })
    this._recipe = null
    this.ds = new DATA_SERVICE()
  }
  connectedCallback () {
    //    html-  
    this._shadowRoot.innerHTML = template
    //   delete   
    this._shadowRoot
      .querySelector('.delete')
      .addEventListener('click', () => this._delete())
  }
  _render (title) {
    //      ,   
    this._shadowRoot.querySelector('.recipe-title').innerHTML = title
    this._shadowRoot.querySelector('.favorite').innerHTML = this._recipe
      .favorite
      ? 'Unfavorite'
      : 'Favorite'
  }
  _delete () {
    //       
    try {
      await this.ds.deleteRecipe(this._recipe.id)
    } catch (e) {
      console.error(e)
      alert(
        'Sorry, there was a problem deleting the recipe. Please, try again.'
      )
    }
  }
  get recipe () {
    //   
    return this._recipe
  }
  set recipe (recipe = {}) {
    //   ,   render
    this._recipe = recipe
    this._render(this._recipe.title)
  }
}

window.customElements.define('recipe-item', Recipe)


. , , .

, , npm- Vanilla JS Router. , API History, , - 100 . , - , (route guard).

import './components/error/error'
import content404 from './components/404/404.html'
import DATA_SERVICE from './utils/data'
const ds = new DATA_SERVICE()
//  ,  SPA
const $el = document.getElementById('app')

//  
const home = async () => {
  await import('./components/recipe/recipe')
  await import('./components/recipe-list/recipe-list')
  await import('./components/modal/modal.js')
  $el.innerHTML = `<recipe-list></recipe-list>`
}

const create = async () => {
  await import('./components/create-recipe/create-recipe')
  $el.innerHTML = `<create-recipe></create-recipe>`
}

const edit = async () => {
  await import('./components/edit-recipe/edit-recipe')
  $el.innerHTML = `<edit-recipe></edit-recipe>`
}

const error404 = async () => {
  $el.innerHTML = content404
}

//     
//    id     
const routes = {
  '/': home,
  '/create': create,
  '/error': error404,
  '/edit': async function (params) {
    const id = params.get('id')
    const recipe = await ds.getRecipe(id)
    await edit()
    $el.querySelector('edit-recipe').recipe = recipe
  }
}

//   onpopstate    URL    
//       -   /error
window.onpopstate = async () => {
  const url = new URL(
    window.location.pathname + window.location.search,
    window.location.origin
  )
  if (routes[window.location.pathname]) {
    await routes[window.location.pathname](url.searchParams)
  } else routes['/error']()
}
//     
let onNavItemClick = async pathName => {
  const url = new URL(pathName, window.location.origin)
  const params = url.searchParams
  if (routes[url.pathname]) {
    window.history.pushState({}, pathName, window.location.origin + pathName)
    await routes[url.pathname](params)
  } else {
    window.history.pushState({}, '404', window.location.origin + '/404')
    routes['/error']()
  }
}

//        
;(async () => {
  const url = new URL(
    window.location.pathname + window.location.search,
    window.location.origin
  )
  if (routes[window.location.pathname]) {
    await routes[window.location.pathname](url.searchParams)
  } else routes['/error']()
})()

//     onNavItemClick()
const router = {
  onNavItemClick,
  routes
}
export { router }

, . , , , — .

JS


, , . , JS-.



-, , , , . , - Fronteers Conference 2011. . . , HTML- , .


-. , — skatejs ssr web-component-tester. . , -, .



querySelector()

- , , . Angular .

, — . , , , .

▍ Shadow DOM


Shadow DOM. . — , . , , , , , - . , . , , .

▍ DOM


Angular React , DOM. , . Angular University: «Angular DOM, , HTML- ».

Angular, , jQuery, DOM. , HTML-, , DOM, . , HTML-. Virtual DOM , , .

JS . .



-, JS, ( «») , , . , , , Angular-.


Angular-


,


- CLI, , , . , , -. , , , , , , .


, , . . — . , , , , , . , , , , DOM. .

, React Angular, , . . , - React shouldUpdate() onPush Angular.


— . , . . , , , . , .


Parcel. , , Webpack, , , , , Parcel , .

React, Vue Angular . «». , React «», Vue — « ».

Stencil Polymer? , , , , - , . , . , -.

, SPA - . , , , .

?


, - , , « ». , , , , , , . , , , , .

, — , , . « » . , , . , , , -.

, , , , , , , . — . , , , . — , -, , jQuery, .


, - . - , . , , - , .

- . , , , .

! -, ?

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


All Articles