© 2021 WebHive

Как пересобрать ckeditor5 в виде ES5 модуля

Столкнулся с проблемой — нужно воткнуть в Rails приложение ckeditor5 через стандартный рельсовый sprockets. Ничего не предвещало подвоха, но неожиданно казалось бы нехитрая задача превратилась в проблему.

Ранее у меня уже был опыт работы с Ckeditor и даже с 5-й версией и даже в рельсовом-же приложении поэтому не ожидал подвоха. Более того — в development режиме всё прекрасно работало. Проблемы начались при попытке задеплоить код на сервер. При сборке ассетов вылетала ошибка NoMethodError: undefined method `start_with?' for nil:NilClass.

Кто виноват?

Как оказалось виновником проблемы был uglifier, который в свою очередь как оказалось принципиально не работает с ES6. Несмотря на то, что формально он ES6 поддерживает через т. н. harmony режим, который включается как:

# надо заменить в environment/production.rb
config.assets.js_compressor = :uglifier
# на
config.assets.js_compressor = Uglifier.new(harmony: true)

Но видимо в случае с ckeditor5 это не прокатывает.

Что делать?

Возникла идея транслировать код ckeditor5 из ES6 в ES6. Для этого были выкачаны исходники. Вот отсюда https://github.com/ckeditor/ckeditor5-build-classic

Далее было обнаружено, что для сборки используется webpack, что вселило некоторую надежду. Ну и после нехитрого гугления и ряда эспериментов я получил требуемый результат:

В webpack.config.js нужно добавить примерно следующее:

// entry заменяем на
  entry: [
    require.resolve( 'regenerator-runtime/runtime.js' ),
    path.resolve( __dirname, 'src', 'ckeditor.js' ),
  ],
       ...
// в rules добавляем
  rules: [
    {
       test: /\.js$/,
       use: [
            {
                loader: 'babel-loader',
                options: {
                    presets: [ require( 'babel-preset-env' ) ]
                }
            }
        ]
    },

Ну и нужно добавить в package.json

"dependencies": {
  "babel-core": "^6.26.3",
  "babel-loader": "^7.1.4",
  "babel-preset-env": "^1.7.0",
  "regenerator-runtime": "^0.11.1"
}

После этого запускаем сборку

$ npm run create-entry-file && npm run build-ckeditor

И получаем в папке./build готовую сборку

Минусы

Метод конечно не безупречен и имеет существенный недостаток — полученный файл имеет вдвое больший размер (861 Кб vs 439 Кб).

Итого

Если есть возможность то конечно лучше его избегать, тем более, что ES6 шагает по планете и много чем поддерживается. Но если возможности нет, то в качестве эрзац варианта вполне подойдёт. В особенности я думаю будет полезен в древних рельсовых проектах, в которые ещё пытаются вдохнуть жизнь используя современные «свистелки и перделки» для фронтенда.

Комментарии