Cómo configurar TinyMCE en su aplicación Rails usando Webpack

La popularidad de utilizar Webpack para gestionar sus activos en Rails está aumentando constantemente. Comenzar es realmente sencillo. Si está iniciando una nueva aplicación, simplemente ejecute rails new my_app --webpacky Rails se encargará del resto.

Gracias a la gema del paquete web, agregar Webpack a su aplicación existente también es bastante sencillo. Agrega la gema a su Gemfile, empaqueta y finalmente instala webpacker:

gem 'webpacker', '~> 3.5'bundlebundle exec rails webpacker:install

Esto es bastante dulce. Ahora todo lo que necesita hacer es vincular su paquete de JavaScript y el CSS importado en el encabezado de su application.html.haml:

Una vez hecho esto, estará listo para escribir su código JavaScript moderno y hacer uso de todas las excelentes bibliotecas que existen.

¿Qué es tinyMCE?

TinyMCE es un editor de texto enriquecido en la nube. En pocas palabras, es como Word que se puede implementar en su aplicación.

El proyecto en el que estoy trabajando lo usa para permitir que los administradores editen el contenido de la página principal. Gracias a TinyMCE, no es necesario crear una interfaz de administración separada para ese propósito. Pero el uso del editor puede ser mucho más versátil. Piense, por ejemplo, en lo que Wordpress o Evernote le permiten hacer gracias a sus herramientas integradas.

Uso a través de CDN

Originalmente implementamos el editor a través de CDN (por ejemplo, vinculando el script en el encabezado de nuestro application.html.haml) de esta manera:

!!!%html %head %meta ...  %title ...  = csrf_meta_tags
 %script{src: '//cloud.tinymce.com/stable/tinymce.min.js?apiKey=gexncjni90zx3qf0m5rr7kl8l40wd5yuly2xjza0g3kwrljt'} = stylesheet_link_tag 'application', media: 'all' = javascript_include_tag 'application' %body 

Esto requirió agregar un archivo con nuestra función personalizada en formato app/assets/javascript/tinyMce.js. Tenga en cuenta que también estamos usando jQuery.

$( document ).on('turbolinks:load', function() {
 tinyMCE.init({ selector: 'textarea.tinymce', // some other settings, like height, language, // order of buttons on your toolbar etc. plugins: [ 'table', 'lists' // whatever plugins you want to add ] });});

Además de eso, tuvimos que incluir un archivo de traducción (que no es necesario si está usando inglés en su aplicación). Para que todo se muestre correctamente en producción, también deberá obtener una clave API gratuita de Tiny Cloud.

Webpack y tinyMCE

Todo funcionó muy bien durante un par de meses, pero decidimos que era hora de la transición hacia Webpack.

Se supone que Webpack te hace la vida más fácil y, junto con el hilo, te permite concentrarte en las cosas importantes. Supongamos que desea utilizar el paquete A. Sucede que el paquete A se basa en los paquetes B y C. Y el paquete B depende de D, E y F. En lugar de pasar horas averiguando cuáles son las dependencias e instalarlas todas individualmente, ¿qué lo que quiere es decir yarn add package-Ay que se lo resuelva Y este es casi el caso.

Esta transición en lo que respecta a tinyMCE fue mucho más dolorosa de lo que debería haber sido. Y por eso decidí escribir este post. Espero que le ahorre a alguien algo de tiempo y frustración.

Si anteriormente había implementado tinyMCE a través de CDN , le gustaría deshacerse de algunas cosas para comenzar a limpiar. Quite el enlace del script de application.html.haml. Luego, comente el contenido del tinyMce.jsarchivo (y el archivo de idioma si está usando uno). También decidí deshacerme de la dependencia de jQuery (en nuestro caso significaba eliminar gem 'jquery-rails'del Gemfile y app/assets/javascripts/application.jseliminar //= require jqueryy reemplazar //= require jquery_ujscon //= require rails-ujs).

Nota: Proceda con precaución si tiene más bibliotecas externas en su proyecto que dependen de jQuery (por ejemplo, Bootstrap o Select2). En última instancia, su objetivo probablemente sería moverlos todos a Webpack, pero cuanto más grande sea el proyecto, más compleja podría ser la tarea, así que téngalo en cuenta. Nada le impide mantener su implementación tradicional paralela a la de Webpack. En ese caso, aún recomendaría comentarlo para el momento de la implementación de tinyMCE.

Todos estos pasos asegurarán que las cosas que implementaremos a partir de ahora funcionen y que la implementación anterior no funcione como una alternativa.

Paso 1. Si desea utilizar jQuery a través del paquete web

Agregar jQuery a través de Webpack es tan simple como ejecutar yarn add jqueryy agregar el siguiente código a config/webpack/environment.js:

const { environment } = require('@rails/webpacker')const webpack = require('webpack')environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }))module.exports = environment

Paso 2. Obtenga el paquete tinyMCE

Eso también es bastante sencillo: ejecutar yarn add tinymce.

Luego crea un nuevo archivo donde colocaremos nuestra función. Terminé app/javascript/vendor/tinyMce.jscon el siguiente contenido:

import tinymce from 'tinymce/tinymce';import 'tinymce/themes/modern/theme';import 'tinymce/plugins/table';import 'tinymce/plugins/lists';
function tinyMce() { tinymce.init({ selector: 'textarea.tinymce',
 // some other settings, like height, language, // order of buttons on your toolbar etc.
 plugins: [ 'table', 'lists' ] });}
// if you're using a language file, you can place its content here
export { tinyMce };

Paso 3. Importe todo al application.js

Podemos importar nuestra función así:

import { tinyMce } from "../vendor/tinyMce";

y luego llamarlo:

document.addEventListener(“turbolinks:load”, function () { tinyMce(); });

Como puede ver, también reemplazamos el código jQuery con ES6.

Paso 4. Haga que la piel tinyMCE funcione

Si ejecuta su webpack-dev-servery rails s, se sorprenderá al ver que su editor de texto no está allí. Una mirada en la consola y verá el siguiente error:

Esto se debe a que tinyMCE no funcionará sin una máscara, y extraerlo a través de Webpack requiere su importación explícita. Podemos hacer esto incluyendo esta línea en nuestro tinyMce.jsarchivo, justo después de las otras declaraciones de importación. La ruta es relativa a la node_modulescarpeta:

import ‘tinymce/skins/lightgray/skin.min.css’;

At this point you should have your editor working.

But… if you look into the console, you might be disappointed to see that you are still getting 2 errors:

Don’t despair! There is an easy fix. Just add skin: false to your function tinyMce() config and it should do the trick. This will prevent the default files from loading.

Congrats! You just got your tinyMCE up and running!