Quando as estruturas JavaScript desaparecerão?

O autor do material, cuja tradução publicamos hoje, um desenvolvedor web, diz que tenta revisar regularmente o conjunto de ferramentas que usa. Ele faz isso para entender se pode ficar sem alguns deles, resolvendo suas tarefas habituais. Ele recentemente decidiu realizar um experimento e criar um aplicativo front-end sofisticado sem usar estruturas JavaScript.

O que é uma estrutura?


Se você tentar definir uma estrutura JavaScript sem entrar em detalhes, é uma ferramenta que pode ser usada para desenvolver aplicativos da web complexos, em particular aplicativos de página única (SPA).

Antigamente, esses aplicativos eram criados com base nos recursos do JavaScript puro e na biblioteca jQuery. Porém, com a crescente complexidade dos aplicativos front-end, começaram a aparecer as ferramentas correspondentes que facilitam a vida dos programadores. Por exemplo, esses são React, Angular e Vue.

As estruturas que são populares atualmente têm algumas semelhanças em comum. Portanto, a maioria das estruturas e bibliotecas de front-end, relativamente falando, do Vue ao React, oferece ao desenvolvedor uma certa combinação dos seguintes recursos:

  • Sincronização do estado e apresentação visual do aplicativo.
  • Encaminhamento
  • Sistema de modelo.
  • Componentes adequados para reutilização.

As estruturas são necessárias para um desenvolvedor moderno?


A resposta para a pergunta colocada no título desta seção depende de como você se relaciona com a idéia da “necessidade” de estruturas. Estou certo de que muitos podem dizer que as estruturas de front-end não são necessárias no kit de ferramentas para desenvolvedores da Web e nunca foram necessárias. Embora seja indiscutível que essas são ferramentas muito úteis.

Na verdade, nossa pergunta pode ser reformulada da seguinte maneira: “Os frameworks são um pouco de uma“ biblioteca jQuery moderna ”? É possível resolver os problemas a que se destinam, por outros meios, por exemplo, aqueles que apareceram à disposição dos programadores durante o desenvolvimento das APIs do navegador? ”


jQuery

De fato, não é fácil responder a essa pergunta, mas podemos dizer que o desenvolvimento de JavaScript, tecnologias para trabalhar com componentes da Web e ferramentas para construção de projetos tornou o desenvolvimento do SPA sem o uso de estruturas mais fácil do que nunca.

Para explorar essa idéia, desenvolvi um aplicativo de uma página usando apenas JavaScript, componentes padrão da Web e o empacotador de pacotes. No processo, encontrei alguns problemas e dificuldades, olhando para os quais você claramente começa a ver os pontos fortes das estruturas JS modernas.

Ao mesmo tempo, assim que lidei com os obstáculos iniciais, fiquei surpreso com a facilidade de criar um aplicativo de uma página em JavaScript puro.

Visão Geral da Aplicação Experimental


A aplicação em questão é bastante simples. É uma coleção eletrônica de receitas e permite ao usuário criar, visualizar e editar receitas. Além disso, o usuário pode marcar receitas, indicando que ele gosta delas, e também pode filtrar e excluir entradas.


Homepage do aplicativo


Página de registro de receita

Componentes da 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/pt439824/


All Articles