修理 Ghost 中文輸入法的 BUG

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或從新修改使用,但須要註明來源。 署名 4.0 國際 (CC BY 4.0)html

本文做者: 蘇洋node

建立時間: 2020年01月19日 統計字數: 6643字 閱讀時間: 14分鐘閱讀 本文連接: soulteary.com/2020/01/19/…mysql


修理 Ghost 中文輸入法的 BUG

去年的時候,我曾寫過一篇文章 《 將 Ghost 遷移 Hugo 背後的事 》 裏面描述了Ghost 當前對於非英文用戶的主要問題。git

其中最使人詬病的即是編輯器對於 CJK 三種語言輸入法「吃字」 BUG 的問題,這個問題影響 Ghost 從 2.x 到如今的 3.x 版本。產生問題的緣由是,核心編輯器組件 0.11.1 - 0.12.x 版本中對於輸入法事件沒有進行邏輯覆蓋,維護者和 Ghost 官方時至今日依舊沒有作出任何變動,無論用戶提了多少「IME BUG」的求助和 PR 。github

最近有項目須要一個文檔編輯器,因而考慮「修理修理」它,看看能不能用起來。web

關於這個持續了兩年的BUG

  • 2018 年的時候,有人提交了 PR github.com/bustle/mobi… ,使用 event.isIME() 方法了問題修正,可是受到了非標準實現的質疑,後續這個問題便被掛了兩年之久。
  • 2019 年底,又有人提交了新的 PR github.com/TryGhost/mo…,使用 event.isComposing() 方法進行問題修正,可是不知道是單純由於 CI 測試未經過,仍是帶有客戶羣歧視,這個 PR 也被擱置了。

前置準備

本文依賴一些軟件或前置知識,若是不是很瞭解,能夠參考以往的文章。sql

  • 須要 Docker、docker-compose
  • 可選 traefik

Traefik 的使用

Traefik 的具體使用,能夠參考以往的文章,好比:使用服務發現改善開發體驗更完善的 Docker + Traefik 使用方案 等,更多內容,能夠翻看歷史內容的標籤,這裏不過多贅述。docker

本文只須要關注編排文件中的 labelsnetworks 字段配置就足夠啦。對不一樣容器服務的 networks 字段,聲明包含相同的內容,則可讓不一樣應用所處於的網絡一致。數據庫

networks:
  - traefik
複製代碼

好比上面的聲明,會讓容器服務都處於名爲 traefik 的網絡環境中。npm

早期的修正方案

去年年初的時候,忍不了這個 BUG 的時候,我在官方主倉庫一個 IME BUG 的 ISSUE 裏,我提了一個解決方案,告訴你們把當時的 Ghost 項目的 package.json 中的 @tryghost/mobiledoc-kit 替換爲 @bugfix/mobiledoc-kit ,而後從新構建資源就能解決問題,時至今日這條評論還能收到一些點贊。

github.com/TryGhost/Gh…

早先的解決方案

可是到去年下半年的時候,這個方案便因爲官方設計變動而失效了,並且這樣作也不利於後續跟進官方 bugfix 的版本,太笨重不夠靈活。

當前的修正方案

要解決的問題主要是在客戶端運行的腳本,治標又治本的方案是對於有問題的腳本進行 patch ,而後從新構建項目,讓頁面加載新的腳本資源便可。

可是官方編譯項目設計的很是不環保不綠色,項目拆分設計不是十分合理,構建腳本 tricks和硬編碼巨多,使用 grunt 搭配 git submoudle 很是不利於 debug。並且要全局安裝一堆構建工具,還須要鎖定 Node 運行版本在老版本,編譯效率更是慢到使人髮指(Mac Book Pro 2019 i9 2.4GHz 編譯感受時間巨慢長)...

爲了不後續浪費更多時間在折騰項目架構的問題上,這裏考慮將定製軟件的容器編譯環境,交由性能更高的服務器進行編譯,並抽取編譯產物對每一個版本的 Ghost 進行資源替換,來解決這個陳年 BUG。

我把這個方案上傳到了 GitHub:github.com/soulteary/y…,方便你進行進一步定製改造,若是有必要的話,能夠持續跟進幾個版本的官方更新。

下面來聊聊方案的詳細內容。

定製構建鏡像生成「補丁」

官方編輯器補丁文件,我上傳到了 GitHub,能夠自取。構建環境踩坑過程不表,下面是構建容器的 Dockerfile:

FROM node:12-alpine
LABEL maintainer="soulteary@gmail.com"
 
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8
ENV LC_ALL=en_US.UTF-8

RUN echo '' > /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/main"         >> /etc/apk/repositories && \
    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.10/community"    >> /etc/apk/repositories && \
    echo "Asia/Shanghai" > /etc/timezone

RUN apk update && apk add git && \
    yarn global add knex-migrator grunt-cli ember-cli bower

COPY patches/mobiledoc-kit/event-manager.js /patches/mobiledoc-kit/event-manager.js

RUN git clone https://github.com/TryGhost/mobiledoc-kit.git /mobiledoc-kit && \
    cd /mobiledoc-kit && \
    git checkout 3b0f375d32f7183a4eee9cce5373ebabeb249165 && \
    cp /patches/mobiledoc-kit/event-manager.js /mobiledoc-kit/src/js/editor/event-manager.js && \
    yarn && \
    cp -r /mobiledoc-kit/dist /patches/mobiledoc-kit/dist && \
    rm -rf /mobiledoc-kit

RUN git clone --recurse-submodules https://github.com/TryGhost/Ghost.git /Ghost && \
    cd /Ghost && \
    git checkout 3.3.0 && \
    yarn setup

RUN rm -rf /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/dist && \
    cp -r /patches/mobiledoc-kit/dist /Ghost/core/client/node_modules/\@tryghost/mobiledoc-kit/

WORKDIR /Ghost

RUN grunt prod

EXPOSE 2368

CMD ["npm", "start"]
複製代碼

執行 docker build -t soulteary/ghost:3.3.0 ,若是是本地構建,泡杯茶休息會,大概十分鐘左右鏡像就行了。固然,你也能夠執行 docker pull soulteary/ghost:3.3.0 直接獲取已經構建好的鏡像。

接着,建立一個 docker-compose.assets.yml 用於提取構建鏡像中的靜態資源。

version: '3'
services:

  build-ghost-assets:
    image: soulteary/ghost:3.3.0
    container_name: ghost-assets
    volumes:
      - ./patches/ghost-assets/loop.js:/Ghost/index.js
複製代碼

因爲拷貝資源的鏡像必須在拷貝的時候存活,而 Ghost 啓動必須配置數據庫,否則就報錯退出,因此這裏建立一個 HTTP Server 來解決問題。

const http = require("http");

const server = http.createServer(function(req, res) {
  res.writeHead(200);
  res.end("Hold on for sync assets");
});

server.listen(2368);
複製代碼

將下面的命令保存爲 sync-assets.sh,執行以後,項目目錄中就會出現 3.3.0 版本 Ghost 的編輯器靜態資源補丁了。

#!/usr/bin/env bash 
docker-compose -f docker-compose.assets.yml down && docker-compose -f docker-compose.assets.yml up -d

rm -rf docker-assets && mkdir -p docker-assets

docker cp ghost-assets:/Ghost/core/built ./docker-assets/built
docker cp ghost-assets:/Ghost/core/server/web/admin/views ./docker-assets/admin-views

docker-compose -f docker-compose.assets.yml down
複製代碼

驗證方案效果

想要驗證補丁效果,能夠本地啓動一套 Ghost,首先建立一個 docker-compose.db.yml 啓動本地數據庫。

version: '2'
services:

  db:
    image: mysql:5.7
    container_name: ghost-db
    networks:
      - traefik
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ghost
    volumes:
      - ./localdb:/var/lib/mysql

networks:
  traefik:
    external: true
複製代碼

等待日誌中出現 ready for connections.表示數據庫就緒了:

ghost-db | 2020-01-18T17:24:04.154079Z 0 [Note] Event Scheduler: Loaded 0 events
ghost-db | 2020-01-18T17:24:04.154348Z 0 [Note] mysqld: ready for connections.
ghost-db | Version: '5.7.28'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
複製代碼

接着建立 docker-compose.yml 並輸入下面的內容:

version: "3.6"

services:

  www-ghost-local:
    image: ghost:3.3.0
    expose:
      - 2368
    environment:
      url: https://soulteary.io
      database__client: mysql
      database__connection__host: ghost-db
      database__connection__user: root
      database__connection__password: ghost
      database__connection__database: ghost
      NODE_ENV: production
    volumes:
      - ./docker-assets/built:/var/lib/ghost/versions/3.3.0/core/built:ro
      - ./docker-assets/admin-views:/var/lib/ghost/current/core/server/web/admin/views:ro
      - ./config.production.json:/var/lib/ghost/config.production.json:ro
      - ./content/adapters:/var/lib/ghost/versions/3.3.0/content/adapters
      - ./content/apps:/var/lib/ghost/versions/3.3.0/content/apps
      - ./content/images:/var/lib/ghost/versions/3.3.0/content/images
      - ./content/logs:/var/lib/ghost/content/logs
      - ./content/settings:/var/lib/ghost/versions/3.3.0/content/settings
    extra_hosts:
      - "soulteary.io:127.0.0.1"
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.port=2368"
      - "traefik.frontend.rule=Host:soulteary.io"
      - "traefik.frontend.entryPoints=https,http"

networks:
  traefik:
    external: true
複製代碼

使用 docker-compose up 啓動應用,等待應用啓動就緒:

www-ghost-local_1  | [2020-01-18 17:25:10] INFO Ghost is running in production...
www-ghost-local_1  | [2020-01-18 17:25:10] INFO Your site is now available on https://soulteary.io/
www-ghost-local_1  | [2020-01-18 17:25:10] INFO Ctrl+C to shut down
www-ghost-local_1  | [2020-01-18 17:25:10] INFO Ghost boot 9.472s
複製代碼

打開Ghost 的管理後臺

訪問 http://soulteary.io/ghost 進行項目的初始化,設置管理員帳號後,隨手建立一篇文章就能進行測試啦。

一切都正常了

最後

作開源軟件不易,可是若是目的不僅是簡單作作營銷PR,拉一些流量。而是想造福、方便更多人,讓社區生態更好,那麼就應該擺出開放包容的姿態,適當謙虛接受社區批評和建議,況且你們都幫你寫好了代碼,只要點一下 Merge 按鈕就行了。

--EOF


我如今有一個小小的折騰羣,裏面彙集了一些喜歡折騰的小夥伴。

在不發廣告的狀況下,咱們在裏面會一塊兒聊聊軟件、HomeLab、編程上的一些問題,也會在羣裏不按期的分享一些技術沙龍的資料。

喜歡折騰的小夥伴歡迎掃碼添加好友。(請註明來源和目的,不然不會經過審覈)

關於折騰羣入羣的那些事

相關文章
相關標籤/搜索