Queremos actualizar la versión de Ember utilizada en Discourse.
Actualmente, estamos en la versión 3.15 y nos gustaría llegar a la 4.1.
Nos hemos propuesto terminar este trabajo antes de finales de este año. Tened en cuenta que este tema es una hoja de ruta, y todos los planes y estimaciones son provisionales. Este tema no está destinado a albergar discusiones significativas sobre actualizaciones o cambios concretos. Así que mantengamos la conversación aquí un poco enfocada. Las preguntas sobre cómo estas actualizaciones afectarán a vuestro sitio/plugin/tema están fuera de tema. Los cambios planificados son 100 % en el front-end (aplicación Ember).
Tendremos mucha precaución con los cambios que introduzcamos. Todos los plugins/temas oficiales se actualizarán (incluido cualquier trabajo personalizado que CDCK haya realizado para sus clientes). También enviaremos PRs para actualizar todos los plugins/temas no oficiales populares.
No os preocupéis si tenéis un plugin/tema personalizado que hayáis creado para vuestro sitio. Agregaremos advertencias de obsolescencia y crearemos los anuncios necesarios a tiempo para daros suficiente tiempo para realizar cualquier cambio necesario. También intentaremos guiaros a través de esos cambios si es necesario.
Comencemos con los objetivos. Obviamente, queremos llegar a la versión más alta disponible, pero necesitamos establecer objetivos intermedios entre ahora y nuestro destino final.
Planeamos hacer actualizaciones incrementales. En lugar de una actualización mayor a 4.1, dividiremos este trabajo en seis etapas. Cada etapa se centra en una actualización de Ember.
| Etapa | Tamaño | Actualizaciones |
|---|---|---|
| 1 | size-l | Ember 3.15 → Ember 3.16 |
| 2 | size-m | Ember 3.16 → Ember 3.25 |
| 3 | size-xl | Ember 3.25 → Ember 3.26 (Parte 1 - General) Ember 3.25 → Ember 3.26 (Parte 2 - Plantillas) Ember 3.25 → Ember 3.26 (Parte 3 - jQuery) Ember 3.25 → Ember 3.26 (Parte 4 - Trabajo de preparación de Octane) Ember 3.25 → Ember 3.26 (Parte 5 - Octane) |
| 4 | size-l | Ember 3.26 → Ember 3.27 (Parte 1 - General) Ember 3.26 → Ember 3.27 (Parte 2 - RenderTemplate) Ember 3.26 → Ember 3.27 (Parte 3 - Componentes integrados heredados) |
| 5 | size-s | Ember 3.27 → Ember 3.28 |
| 6 | size-s | Ember 3.28 → Ember 4.1 |
La elección de esas versiones específicas se basa enteramente en las obsolescencias y la cantidad de trabajo que introducen, y el riesgo implícito.
Así que desglosemos esto aún más para mayor claridad.
Obsolescencias por actualización
Etapa 1 (size-l)
Ember 3.15 → Ember 3.16
Esta actualización solo introduce una obsolescencia.
-
Usar el resolvedor de ember-CLI en lugar del resolvedor global heredado
- hasta: 4.0.0 - size-lDiscourse tiene su propio resolvedor personalizado que actualmente extiende
Ember.DefaultResolver.La solución recomendada es deshacerse de cualquier resolvedor personalizado y usar el resolvedor de Ember-CLI. Esto es más fácil decirlo que hacerlo porque tenemos bastante lógica personalizada para manejar plugins y temas.
Un compromiso que funciona es extender el resolvedor de Ember-CLI en lugar de extender
Ember.DefaultResolver.
Etapa 2 (size-m)
Ember 3.16 → Ember 3.25
Esta actualización introduce ocho obsolescencias.
-
Usar getter de Ember y verificar explícitamente por undefined
- hasta: 4.0.0 - size-sEsta es una obsolescencia simple. Solo necesitamos eliminargetWithDefaulten nuestra base de código, y solo hay unos pocos lugares donde lo usamos. -
Extensiones de prototipo de String
- hasta: 4.0.0 - size-mEsto también es un cambio simple y de bajo riesgo, pero usamos el prototipo de cadena extendido de Ember en bastantes lugares. Por una rápida comprobación, creo que tenemos menos de 100 lugares donde hacemos eso entre el núcleo y los plugins/temas.Una vez que actualicemos esos, también deberíamos evitar que Ember extienda ese prototipo con algo como esto.EXTEND_PROTOTYPES: { String: false }en nuestro archivo environment.
-
ImportarhtmlSafeyisHTMLSafedesde @ember/string
- hasta: 4.0.0 - size-mHay mucha superposición entre esto y el #7 en esta actualización, y debería ser directo y de bajo riesgo.
Etapa 3 (size-xl)
La actualización de 3.25 a 3.26 es bastante compleja. Aquí es donde hacemos la mayor parte del “recuperar terreno”. Hay dieciséis obsolescencias en total. Vamos a dividir esta actualización en cinco partes, donde solo hacemos un aumento de versión después de que se hayan manejado todas las obsolescencias.
Ember 3.25 → Ember 3.26 (Parte 1 - General)
Esta parte trata con nueve obsolescencias que son relativamente más fáciles de manejar.
-
Capacidades del Administrador de Componentes
- hasta: 4.0.0 - 
-
Capacidades del Administrador de Modificadores
- hasta: 4.0.0 - 
-
Característica opcional: application-template-wrapper
- hasta: 4.0.0 - 
-
classBinding y classNameBindings como argumentos en plantillas
- hasta: 4.0.0 - 
No hay nada que hacer aquí; no usamos esos.
-
Métodos de transición de rutas y controladores
- hasta: 5.0.0 - size-mEsta obsolescencia elimina un par de métodos de
routesycontrollers. Puede parecer un cambio complejo, pero debería ser directo. Solo necesitaríamos inyectar elRoutercomo un servicio y llamarlos desde allí en su lugar, cuando sea necesario. La parte complicada es que los usamos en muchos lugares, y todos necesitan ser actualizados. -
Política de soporte de navegador
- hasta: 4.0.0 - size-s~~Esto debería ser un cambio relativamente simple. Ember no soportará IE11 desde la 4.0 en adelante. Lo bueno aquí es que no lo hemos soportado durante mucho tiempo de todos modos. Lo único que necesitamos cambiar es dejar de transpilar para IE11 en producción.
discourse/app/assets/javascripts/discourse/config/targets.js at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHubHice algunas pruebas básicas, y este cambio nos ahorrará unos 60kb (gzip) o ~6 % de nuestros paquetes principales y de vendor en instalaciones de Ember-CLI en producción. -
{{hasBlock}} y {{hasBlockParams}}
- hasta: 4.0.0 - size-sLos usamos en un par de lugares. Esto es un cambio de nombre simple y de bajo riesgo. -
Ayudante{{with}}
- hasta: 4.0.0 - size-sRara vez usamos esto, pero aún necesita arreglarse. Solo necesitamos reemplazarlos y usar{{let}}o una combinación de{{if}}/{{else}}
Ember 3.25 → Ember 3.26 (Parte 2 - Plantillas)
Esta parte se centrará principalmente en obsolescencias que involucran plantillas .hbs. Hay tres obsolescencias en las que necesitamos concentrarnos aquí.
-
Búsqueda de respaldo de propiedades
- hasta: 4.0.0 - size-lA partir de Ember 4.0, esto ya no funcionará.
Hola, {{name}}!Si tenemos una propiedad en una plantilla, tenemos que buscarla con un
thisprevio así:Hola, {{this.name}}!Tendríamos que hacer eso con todas nuestras plantillas. Hay formas de reducir el dolor aquí. Podemos probar el ember-no-implicit-this-codemod y ver hasta dónde nos lleva.
Estoy a favor de limitar los cambios a 1 archivo por PR. Esto facilita la revisión y la reversión si algo sale mal.
-
Acceso a argumentos nombrados vía {{attrs}}
- hasta: 4.0.0 size-xlEl objeto
{{attrs}}se eliminará en Ember 4.0. El cambio en sí es muy directo, y el ejemplo de Ember es bastante bueno.Antes:
{{attrs.foo}} {{this.attrs.foo.bar}} {{deeply (nested attrs.foobar.baz)}}Después:
{{@foo}} {{@foo.bar}} {{deeply (nested @foobar.baz)}}Tendríamos que hacer esto para todas nuestras plantillas. Podemos combinar este cambio con la conversión de las plantillas a la sintaxis de corchetes angulares. Soy un gran fan de los corchetes angulares porque están mucho más cerca de la sintaxis estándar de componentes web personalizados.
Una cosa que podría acelerar nuestro progreso aquí es el ember-angle-brackets-codemod. Tendremos que experimentar con él y ver hasta dónde nos lleva. Maneja la obsolescencia y nos da una brillante sintaxis de corchetes angulares.
Similar al #1 en esta parte, también prefiero corregir y probar una plantilla por PR.
-
Argumentos posicionales de
<LinkTo>
- hasta: 4.0.0 - size-mEsta también es una obsolescencia que busca reducir la confusión. Hay algunos lugares donde usamos argumentos posicionales en link-to. Podemos corregirlos así:
Antes:
{{link-to "Sobre nosotros" "about"}} {{#link-to "about"}}Sobre nosotros{{/link-to}} {{#link-to "post" @post}}Leer {{@post.title}}...{{/link-to}}Después (con corchetes angulares):
<LinkTo @route="about">Sobre nosotros</LinkTo> <LinkTo @route="about">Sobre nosotros</LinkTo> <LinkTo @route="post" @model={{@post}}>Leer {{@post.title}}...</LinkTo>
Ember 3.25 → Ember 3.26 (Parte 3 - jQuery)
No hay mucho que pueda decir sobre esto que ya no sepáis. Las nuevas aplicaciones Ember no usan jQuery, y se eliminará en Ember 4.0.
En esta parte, nos centraremos en una obsolescencia.
-
Característica opcional: jquery-integration
- hasta: 4.0.0 - size-xlDurante los últimos años, hemos hecho un montón de progreso en reducir nuestro uso de jQuery. Aún hay lugares donde lo necesitamos, particularmente en el compositor y como dependencia para algunas bibliotecas de vendor que usamos. No quiero entrar en los detalles de este cambio aquí. En resumen, deberíamos alejarnos del uso de jQuery.
Sin embargo, me gustaría destacar que incluso si nos deshacemos de jQuery EN TODAS PARTES, aún deberíamos mantener esta opción establecida en true hasta que estemos listos para Ember 4.0. Necesitamos un plan para facilitar la transición para sitios con temas/plugins personalizados que no controlamos. En otras palabras, hagamos el trabajo pero vivamos con la advertencia de obsolescencia sobre desactivar la opción.
Ember 3.25 → Ember 3.26 (Parte 4 - Trabajo de preparación de Octane)
En esta parte, deberíamos concentrarnos en preparar nuestros archivos para Octane. Manejaremos dos obsolescencias.
-
Característica opcional: template-only-glimmer-components
- hasta: 4.0.0 - size-mEsto es un cambio simple en teoría, pero hay trabajo implícito que necesitamos hacer antes de poder activar esa opción.
Necesitamos asegurarnos de que nuestros componentes actuales solo de plantilla funcionen con la semántica de Glimmer. Hice algunas pruebas, y nuestras pruebas fallaron con esa opción activada. Aquí hay una lista de ejemplo de algunos componentes solo de plantilla que tenemos en el núcleo:
- app/templates/components/activation-email-form.hbs - app/templates/components/cancel-link.hbs - app/templates/components/categories-with-featured-topics.hbs - app/templates/components/category-name-fields.hbs - app/templates/components/color-input.hbs - app/templates/components/custom-html-container.hbs - app/templates/components/emoji-group-buttons.hbs - app/templates/components/emoji-group-sections.hbs - app/templates/components/empty-state.hbs - app/templates/components/ip-lookup.hbs - app/templates/components/modal-footer-close.hbs - app/templates/components/popup-menu.hbs - app/templates/components/reviewable-created-by-name.hbs - app/templates/components/reviewable-created-by.hbs - app/templates/components/reviewable-field-editor.hbs - app/templates/components/reviewable-field-text.hbs - app/templates/components/reviewable-field-textarea.hbs - app/templates/components/reviewable-field.hbs - app/templates/components/reviewable-flagged-post.hbs - app/templates/components/reviewable-post-header.hbs - app/templates/components/reviewable-post.hbs - app/templates/components/reviewable-scores.hbs - app/templates/components/reviewable-tags.hbs - app/templates/components/reviewable-topic-link.hbs - app/templates/components/score-value.hbs - app/templates/components/selected-posts.hbs - app/templates/components/subcategories-with-featured-topics.hbs - app/templates/components/text-overflow.hbs - app/templates/components/user-fields/confirm.hbs - app/templates/components/user-fields/dropdown.hbs - app/templates/components/user-fields/multiselect.hbs - app/templates/components/user-fields/text.hbs - app/templates/components/user-profile-avatar.hbs - app/templates/components/user-summary-users-list.hbsTambién necesitaremos verificar nuestras plantillas de Admin/tema/plugin y asegurarnos de que todo funcione antes de enviar esa opción.
De primeras, no estoy exactamente seguro de cómo encajarán nuestras plantillas
.hbrcrudas en esto. Sin embargo, @david ha estado trabajando en listas de temas basadas en Glimmer. Así que, quizás podamos deshacernos de las plantillas crudas por completo. -
Inyecciones implícitas
- hasta: 4.0.0 size-xlUsamos inyecciones implícitas en todas partes. Lo hacemos en un inicializador así:
discourse/app/assets/javascripts/discourse/app/pre-initializers/inject-discourse-objects.js at ac79c5efc61d259705eeb487ca21d0ec3c535807 · discourse/discourse · GitHubEmber se está alejando de las inyecciones implícitas. El camino preferido es convertir la mayor cantidad posible de nuestros objetos a servicios e inyectarlos explícitamente donde se necesiten. Por supuesto, puede haber algunas cosas donde un servicio no sea ideal. En esos casos, podemos buscar esos objetos directamente cuando se necesiten así:
getOwner(this).lookup('thing:main')Otra opción que tenemos (dependiendo de las implicaciones de rendimiento) es envolver las Clases de Ember con nuestra propia Clase de Discourse. Luego usaríamos nuestra Clase en toda la aplicación. Algo así como lo hacemos con la
Clase GlimmerComponent
discourse/app/assets/javascripts/discourse/app/components/glimmer.js at fa0c796baf9a7f64a3b27823b1aa4b370a74c3eb · discourse/discourse · GitHub. Esto haría que esta tarea fuera de size-l o incluso size-m.En cualquier caso, este cambio necesitará algo de reflexión.
Ember 3.25 → Ember 3.26 (Parte 5 - Octane)
Este es el tramo final de la actualización de 3.25 → Ember 3.26. Solo tendremos una obsolescencia restante en este punto, pero es una grande.
-
Edición: Classic
- hasta: 4.0.0 - size-xlAntes de cambiar nuestra versión a Octane, me gustaría dedicar tiempo a convertir nuestras Clases a Clases nativas y nuestros componentes a componentes Glimmer. Habrá un poco de dolor involucrado, pero vale la pena. El ember-native-class-codemod debería aliviar parte de ese dolor. Veremos hasta dónde nos lleva.
Hay muchas consideraciones y problemas de flujo de trabajo que tener en cuenta. Lo único que quiero destacar es que seguirá el mismo flujo que mencioné para las plantillas: corregir y probar 1 componente por PR.
Etapa 4
La actualización de Ember 3.26 → Ember 3.27 introduce doce obsolescencias. Propongo dividirlas en tres partes. Haremos el aumento de versión después de que se hayan manejado todas las obsolescencias.
Ember 3.26 → Ember 3.27 (parte 1 - General)
-
Obsolescencia de
Route#disconnectOutlet
- hasta: 4.0.0 - size-sSolo hacemos esto en un lugar. Es la
build-category-route, y debería ser directo de corregir. -
Invocar ayudantes sin argumentos y paréntesis en posiciones de argumentos nombrados
- hasta: 4.0.0 - size-sNo creo que hagamos esto en ningún lugar, pero lo confirmaré cuando llegue el momento. Esencialmente, llamar a un ayudante sin pasarle ningún argumento.
Incluso si usamos algo así, solo necesitaríamos agregar paréntesis. Así que esto:
<SomeComponent @arg={{someHelper}} />se convierte en
<SomeComponent @arg={{(someHelper)}} />nota los paréntesis alrededor de
someHelper -
Bucle de ejecución y acceso con punto a computed
- hasta: 4.0.0 - size-mUsamos
.para acceder a funcionescomputeden nuestro addondecorators. Se ven así, por ejemplo:
discourse/app/assets/javascripts/discourse-common/addon/utils/decorators.js at b05fddaa7ce3968ffc70cd8d4bf290e15d06eb11 · discourse/discourse · GitHubTambién tenemos uno suelto aquí y allá. Por lo que puedo ver, corregirlos es principalmente sobre corregir cómo los importamos.
Así que,
computed.filterdebería importarse así en su lugar.import { filter } from '@ember/object/computed';Nuestra versión del addon externo de vendor
buffered-proxyusa.para acceder a funcionescomputed; necesitaríamos actualizarlo.También usamos
.para acceder a funcionesrunen unos pocos lugares. Dicho esto, se aplica la misma corrección. Necesitamos actualizar la forma en que los importamos. Creo que los temas y plugins especialmente pueden tener bastantes lugares donde hacemos eso conrun. -
Obsolescencia del Global de Ember
- hasta: 4.0.0 - (#size ?)Emberno estará disponible en el contexto global después de la 4.0. Es difícil estimar la cantidad de trabajo/impacto aquí sin una mirada más profunda. Dicho esto, sé que @cvx ha estado haciendo un montón de trabajo para deshacerse de este patrón.
Ember 3.26 → Ember 3.27 (parte 2 - renderTemplate)
Esta parte se centrará solo en una obsolescencia.
-
Obsolescencia de
Route#renderTemplate
- hasta: 4.0.0 - size-lEn resumen, no podemos usar salidas nombradas en Ember 4.0. Así que esto no funcionará.
{{outlet "thing"}}Usamos
renderTemplateen casi 30 lugares solo en el núcleo. La actualización en sí parece bastante directa. Podemos usar{{#in-element}}y un elemento HTML vacío simple como marcador de posición para lo que solíamos renderizar en salidas nombradas.
Ember 3.26 → Ember 3.27 (parte 3 - Componentes integrados heredados)
Esta parte se centrará en componentes integrados heredados, y manejará cuatro obsolescencias.
- Importación de Componentes Integrados Heredados
- hasta: 4.0.0 - Argumentos Heredados de Componentes Integrados
- hasta: 4.0.0 - Argumentos de Atributo HTML Heredados de Componentes Integrados
- hasta: 4.0.0 - Reapertura de Componentes Integrados Heredados
- hasta: 4.0.0
No agregué tamaños a estos porque… realmente depende. Permítanme explicar.
Los componentes integrados heredados como Checkbox, TextField, TextArea, y LinkComponent se eliminarán en Ember 4.0. Los usamos en bastantes lugares, y también usamos algunos patrones obsoletos en ellos.
Ember ofrece una ruta de actualización que nos permite seguir usándolos, pero tenemos que importarlos de manera diferente. Sin embargo, no recibirán actualizaciones de Ember y permanecerán congelados. Espero que podamos deshacernos de todos ellos; sin embargo, eso podría ser un poco complejo. Este cambio necesitará más discusión cuando llegue el momento.
Etapa 5
Ember 3.27 → Ember 3.28
Esto es un size-s ya que es solo un aumento de versión. 3.28 es la última versión LTS en el ciclo de desarrollo 3.x. No introduce nuevas obsolescencias después de la 3.27, y es una buena versión para detenernos durante unas semanas mientras las cosas se estabilizan.
La LTS 3.28 está soportada hasta agosto de 2022 (tanto correcciones de errores como parches de seguridad).
Esta “pausa” tiene varios beneficios.
- Nos da más tiempo para ver si surgen problemas.
- Cuando enviemos una versión estable, debería estar en 3.28.
- Nos da tiempo para hacer cualquier anuncio que necesitemos hacer respecto a temas y plugins mantenidos por nosotros mismos.
- Nos da tiempo para asegurarnos de que la transición de jQuery a no jQuery sea lo más suave posible.
Etapa 6
Después de pasar unas semanas, finalmente podemos aumentar nuestra versión a Ember 4.
Ember 3.28 → Ember 4.1
Ahora podemos desactivar la integración opcional de jQuery como la última obsolescencia del ciclo 3.x.
Esta actualización introduce dos obsolescencias menores.
-
Obsolescencia de Ember.assign
- hasta: 5.0.0 - size-sNo usamos eso en el núcleo, pero necesitaremos verificar temas/plugins. En cualquier caso, es un cambio de nombre simple. -
Clase AutoLocation
- hasta: 5.0.0 - size-sEn teoría, solo necesitaríamos cambiar
locationType: 'auto'alocationType: 'history'en nuestro archivo de entorno de Ember, y debería funcionar simplemente.
Flujo de trabajo
Como mencioné al principio, tendremos mucho cuidado con estas actualizaciones. Probaremos/corregiremos/fijaremos todos los plugins/temas oficiales con cada actualización, y también enviaremos PRs a plugins/temas no oficiales populares.
El objetivo aquí no es ralentizar el desarrollo o crear dolores de cabeza. Así que las PRs serán estrictamente acotadas, con un cambio por PR y nada demasiado grande.
En un mundo ideal, todos los cambios ocurrirían en segundo plano sin interrumpir el trabajo de nadie más. Esta es la razón por la que planeamos mantener las PRs cortas y dulces. Además, no nos gustan mucho los patrones mixtos. Así que no queremos quedar atascados en un estado intermedio en una base por archivo. Un componente es o clásico o Glimmer, y una plantilla usa o llaves o corchetes angulares, nada intermedio.
Espero que esta hoja de ruta haya sido clara. Como mencioné al principio, esto es solo una visión general de alto nivel. Si algo no está claro, es incorrecto o no os sienta bien, por favor hágannoslo saber.