Skip to content

chore: monaco-editor 0.30.1 → 0.55.1#182

Open
OlegKopeykin wants to merge 8 commits into
Pr-Mex:masterfrom
OlegKopeykin:chore/monaco-upgrade
Open

chore: monaco-editor 0.30.1 → 0.55.1#182
OlegKopeykin wants to merge 8 commits into
Pr-Mex:masterfrom
OlegKopeykin:chore/monaco-upgrade

Conversation

@OlegKopeykin

Copy link
Copy Markdown
Contributor

Апгрейд monaco-editor с 0.30.1 до 0.55.1 (текущий latest stable) с сохранением работоспособности в встроенном WebKit 1С:Предприятие.

Как сделано — 5 кластерных шагов (по одному коммиту, каждый проверен в реальной 1С)

Шаг Версия Ключевое
1. 0.32.1 esbuild-loader target es2015 на monaco + воркеры (понижает ?./class fields); полифилы queueMicrotask/ResizeObserver/matchMedia.addEventListener; CI-гейт es-check es2019
2 → 0.34.1 services/languagelanguages/language; +арг MonarchTokenizer; IWorkspaceTextEdit.edittextEdit; полифил Array.flat/flatMap
3 → 0.45.0 свой NLS-пайплайн (localize2, вендоренный ru.json) вместо monaco-editor-nls; diff-навигация goToDiff/getLineChanges; стабы globalThis/WeakRef/ClipboardItem
4 → 0.52.2 lightbulb enum; IOpenerService напрямую; инлайн воркеров (asyncChunks:false); срез RegExp-флага d; суппрессор Canceled
5 → 0.55.1 ESM-only переупаковка (alias на esm-вход); полифилы replaceAll/at/matchAll; lookbehind (?<=) → консумирующая группа; colorDecorators:false

Совместимость с 1С — без полифилов не оживает

Движок 1С лишён: globalThis, queueMicrotask, ResizeObserver, WeakRef, flat/flatMap, replaceAll, matchAll, at, fromEntries, allSettled, matchMedia.addEventListener, ClipboardItem, lookbehind (?<=), RegExp-флаг d.
Полифилы — в src/polyfills.ts (main) и в баннере tools/loaders/compile.js (у blob-воркера свой глобальный контекст). esbuild транспилирует только синтаксис — рантайм-методы полифилятся вручную.

Публичный API интеграции с 1С — НЕ изменён

src/types/public-api.d.ts не тронут. Все window.*-экспорты целы (VanessaEditor, VanessaTabs, VanessaDiffEditor, VanessaGherkinProvider, createVanessa*, dispose*, useVanessaDebugger). Единственное изменение public-методов — canNavigate()/previous()/next() в diff-редакторе переписаны на новый API monaco с идентичными сигнатурами.

Дополнительно в этой ветке

Обновление dev-зависимостей (коммит chore: обновить dev-зависимости в lock): patch/minor в пределах semver — webpack 5.107.2, webpack-cli 7.0.3, webpack-dev-server 5.2.5, ts-loader 9.6.0, terser-webpack-plugin 5.6.1. Только build-тулинг, в production-бандл не попадает. Мажоры (typescript 6, chai 6, mocha 11, standard 17) отложены как breaking.

Уборка мёртвых хвостов после апгрейда (коммит chore: убрать мёртвые хвосты…), по результатам аудита кода на monaco 0.55.1:

  • удалён мёртвый no-op replace-strings патч "(.*)$','d'" (строки нет в monaco 0.55.1 — в 0.55 findSectionHeaders строит флаг иначе);
  • убрано AMD-наследие loadMessageBundle/config из NLS-шима (0 использований);
  • убран рудиментарный 4-й аргумент tokenize(…, 0) (в 0.55 сигнатура 3-арговая) и неиспользуемый debug-хелпер logTokens();
  • удалён закомментированный мёртвый блок в emitEventTo1C.

Проверка

  • npm run buildci — зелёный (webpack 5.107.2).
  • es-check es2019 dist/*.js — чисто (0 ?./??/class fields; пропускает наш ES2018 \p{L}).
  • mocha 46/46 в Chrome и под эмуляцией движка 1С.
  • Автотест VAEditorSample в реальной 1С 8.3.27 — 46/46 на КАЖДОМ из 5 шагов.
  • Полная цепочка Vanessa: редактор → инъекция в vanessa-automationvanessa-automation.epf (19.6 МБ) компилируется.
  • Бонус-коммит: обновлены dev-зависимости в lock (webpack 5.107.2, ts-loader 9.6.0 и т.д.).

Публичные breaking changes (нас не задели):
- IEncodedLineTokens binary format изменён (поддержка strikethrough)
- IDiffEditor.getDomNode() → getContainerDomNode()
- InlayHint.text → InlayHint.label, InlayHintList API

Внутренние breaking changes:
- StaticServices удалён → StandaloneServices с DI API
- createTokenizationSupport() удалён → new MonarchTokenizer(...)
- editor/common/modes → editor/common/languages (TokenizationRegistry, ITokenizationSupport)
- modeService → languageService (ILanguageService в editor/common/services/language)
- IStandaloneThemeService теперь через DI вместо statics

Bundler-changes 0.31:
- ESBuild + новый синтаксис (optional chaining, rest params)
- worker-файлы содержат локальную `function localize(...)`

src/main.ts:
- StaticServices.standaloneThemeService.get()
  → StandaloneServices.get(IStandaloneThemeService)

src/vanessa-tabs.ts:
- StaticServices.modelService.get()
  → StandaloneServices.get(IModelService)
- Импорт IModelService из editor/common/services/model

src/languages/turbo-gherkin/provider.ts:
- createTokenizationSupport(modeSvc, themeSvc, id, lexer)
  → new MonarchTokenizer(languageService, themeSvc, id, lexer)
- StaticServices.modeService.get() → StandaloneServices.get(ILanguageService)
- import 'editor/common/modes' → 'editor/common/languages'

tools/loaders/monacoNls.js:
- regex localize-патчера: /localize\(/g → /(?<!function )localize\(/g
- В 0.31 worker-файлы содержат локальную `function localize(key, ...)` —
  без негативного lookbehind loader патчил объявление функции
  и генерировал невалидный JS: `function localize('vs/...', key, ...)`

webpack.config.js:
- Удалён dead патч `let __insane_func` — переменной больше не существует
  в ESM-коде (insane sanitizer заменён на DOMPurify уже несколько версий
  назад). grep по node_modules/monaco-editor/esm/ — 0 совпадений.
- Патч `secondary: [CtrlCmd | KeyI] → secondary: null` остаётся: переехал
  из findController.js в suggestController.js, regex matches /esm/.+\.js$ —
  патч продолжает применяться.

Этот PR требует webpack 5 (см. PR 1: chore/webpack-5). Monaco 0.32
использует современный JS-синтаксис в worker-файлах, который webpack 4
не парсит без babel.

- InlayHint API — inline-аннотации (показать значение <Контрагент>
  рядом с placeholder'ом). Подробнее: см. отдельную исследовательскую
  ветку про адаптацию для Vanessa Automation.
- Strikethrough в IEncodedLineTokens — для disabled/deprecated шагов.

Build: `npm run buildci` exit 0, monaco-editor@0.32.1 в bundle.
NLS-патч работает: vs/editor/* строки присутствуют в dist/app.js.
StaticServices полностью удалён из src/, заменён на StandaloneServices.
Шаг 1/5 апгрейда monaco. Версия monaco не меняется
(0.32.1) — закрываем блокеры синтаксиса/рантайма ДО прыжков по версиям.
Подтверждено автотестом в реальной 1С 8.3.27: mocha 46/46, 0 ошибок.

Синтаксис (esbuild-loader target es2015 на node_modules/monaco-editor/esm,
+ воркеры через child compiler наследуют rule):
  №1 ?. (ES2020) и №2 class fields (ES2022) из esbuild-сборки monaco >=0.31 —
  WebKit 1С их не парсит (SyntaxError всего бандла). Порядок use:
  replace-strings -> esbuild.

Рантайм-полифилы (src/polyfills.ts, импорт ПЕРВЫМ в main и autotest):
  №3 queueMicrotask (Safari 12.1) — зовётся при загрузке бандла
     (AsyncIterableObject.EMPTY); + префикс в blob-воркер (compile.js).
  №4 ResizeObserver (Safari 13.1, @juggle) — monaco >=0.32 убрал guard в
     ElementSizeObserver, а у нас automaticLayout:true.
  №5 MediaQueryList.addEventListener (Safari 14) — НАЙДЕН диагностикой в 1С:
     monaco зовёт matchMedia(q).addEventListener("change") при создании
     сервисов на StandaloneServices.get(), это убивало app.js до
     VanessaGherkinProvider (зависание автотеста). В движке 1С только legacy
     addListener, причём глобальный конструктор MediaQueryList не выставлен —
     поэтому патчим прототип через инстанс matchMedia() + обёртка.

CI-гейт es-check es2019 (ловит ES2020+; пропускает наш ES2018 \p{L}-regex,
есть и в рабочем master 0.30.1). Проверено: build зелёный; es-check es2019 чист
(3 бандла + 5 blob-воркеров); mocha 46/46 в Chrome и под эмуляцией старого
движка; автотест в 1С 8.3.27 — 46/46.
Шаг 2/5 апгрейда monaco. Подтверждено автотестом в
1С 8.3.27: mocha 46/46, 0 ошибок.

Миграция API 0.32→0.34:
- ILanguageService: import 'common/services/language' → 'common/languages/language'
  (старый путь удалён в 0.34).
- MonarchTokenizer: добавлен 5-й арг конструктора _configurationService —
  передаём StandaloneServices.get(IConfigurationService). НЕ undefined:
  конструктор сразу зовёт _configurationService.getValue()/onDidChange().
- IWorkspaceTextEdit: поле edit → textEdit (+ обязательный versionId) в
  quickfix code-action (provider.ts).

Совместимость с движком 1С (≈Safari 11.x — проба capabilities из 1С):
- NLS: monaco ≥0.34 vs/base/common/platform.js зовёт nls.getConfiguredDefaultLocale(),
  которого нет в monaco-editor-nls@2.0.0 → TypeError убивал бандл. Добавлен
  экспорт (returns undefined) через replace-strings. Полноценный свой NLS-шим —
  шаг 3 (0.45, localize2).
- Array.prototype.flat/flatMap (ES2019, Safari 12.0): движок 1С их лишён, а
  monaco ≥0.34 зовёт xs.map(...).flat() при создании редактора → TypeError в
  beforeAll-хуках (createMultipleDoneError, 6 падений). Полифил в src/polyfills.ts.

Гейты: build зелёный · es-check es2019 чист · mocha 46/46 в Chrome и под
калиброванной эмуляцией движка 1С · автотест в 1С 8.3.27 → 46/46.
Шаг 3/5 апгрейда monaco. Подтверждено автотестом в
1С 8.3.27: mocha 46/46, 0 ошибок.

Свой NLS-пайплайн (заменяет monaco-editor-nls@2.0.0, который не годится с 0.45):
- src/nls/nls.js — шим (localize/localize2/getConfiguredDefaultLocale/setLocaleData).
  localize2 (ILocalizedString {value,original}) — стена NLS №1, появилась в 0.45.
- src/nls/locale/ru.json — вендоренные locale-данные (RU). Прочие локали при
  необходимости добавляются в эту папку.
- monacoNls-лоадер дописывает путь и в call-sites localize2( (не только localize().
- webpack: NormalModuleReplacementPlugin -> наш шим; зависимость monaco-editor-nls
  и её replace-strings-rule удалены.

Миграция API 0.34→0.45:
- IDiffNavigator / createDiffNavigator удалены. Навигация по диффам — через
  IStandaloneDiffEditor.goToDiff('next'|'previous') и getLineChanges()
  (vanessa-diff-editor.ts).

Совместимость с движком 1С (≈Safari 11.x) — рантайм-полифилы (esbuild их не
делает; в blob-воркере СВОЙ контекст — продублированы в compile.js):
- globalThis (Safari 12.1): monaco ≥0.45 ссылается на голый globalThis при загрузке.
- WeakRef / FinalizationRegistry (Safari 14.1): monaco использует в _attachModel
  (создание модели) → ReferenceError убивал editor.create(). Стабы (сильная ссылка
  / no-op — теряется лишь GC-оптимизация).
- ClipboardItem + navigator.clipboard (Safari 13.1): monaco на WebKit-пути
  (installWebKitWriteTextWorkaround) зовёт их СРАЗУ при создании сервиса. Стаб
  ClipboardItem гасит переданный promise (иначе Canceled-reject каскадит в mocha).

Гейты: build зелёный · es-check es2019 чист · mocha 46/46 в Chrome и под
эмуляцией движка 1С (Safari-UA + удаление отсутствующих API) · 1С 8.3.27 → 46/46.
Шаг 4/5 апгрейда monaco. Подтверждено автотестом в
1С 8.3.27: mocha 46/46, 0 ошибок (sync-XHR-маяк).

Миграция API 0.45→0.52:
- lightbulb.enabled: boolean → ShowLightbulbIconMode ('off'|'onCode'|'on');
  передаём 'onCode' (vanessa-editor.ts).
- getContribution('editor.contrib.hover') стал lazy → null до первого ховера.
  Перехват кликов по ссылкам теперь берёт IOpenerService напрямую из
  StandaloneServices (тот же singleton) и оборачивает open ОДИН раз
  (повторная обёртка общего сервиса = бесконечная рекурсия). actions.ts.
- NLS-стена №2: vs/nls реэкспортит getNLSLanguage/getNLSMessages из
  nls.messages.js (читают globalThis._VSCODE_NLS_*). Добавлены в наш шим
  (возвращают undefined; call-sites localize/localize2 остались в source-форме,
  поэтому шим+monacoNls работают как раньше).

Сборка/совместимость:
- Воркеры: monaco 0.52 дробит worker через import(); blob-воркер не догружает
  под-чанки → asyncChunks:false (+ LimitChunkCountPlugin) в child compiler
  инлайнят всё в один блоб (compile.js). Без этого — "Multiple chunks emit ...
  app.worker.js".
- RegExp флаг 'd' (hasIndices, Safari 15): findSectionHeaders.js top-level
  new RegExp(...,'d') → "Invalid flags" в WebKit 1С при загрузке. Срезаем 'd'
  через replace-strings (единственный 'd'/'v'-regex; .indices нужен лишь
  MARK:-заголовкам, в gherkin их нет).
- CancellationError (name 'Canceled'): monaco реджектит pending-промисы при
  dispose/отмене (штатно, сам игнорит). Необработанный reject в 1С каскадил —
  гасим именно Canceled в polyfills.ts (capture, до mocha).

Гейты: build зелёный · es-check es2019 чист · mocha 46/46 в Chrome и под
эмуляцией движка 1С · автотест в 1С 8.3.27 → 46/46.
Шаг 5/5 (финал) апгрейда monaco. 0.55.1 — текущий latest.
Подтверждено автотестом в 1С 8.3.27: mocha 46/46, 0 ошибок (sync-XHR).

ESM-переупаковка пакета (0.53 выпилил AMD):
- package.json "exports" мапит require→min/vs/editor/editor.main.js (AMD,
  webpack не парсит), import→esm. Наш TS компилится в commonjs (require) →
  bare `import * as monaco from "monaco-editor"` тянул AMD-min. Алиас
  monaco-editor$ → esm/vs/editor/editor.main.js (resolve.alias, webpack.config.js).

Рантайм-полифилы (движок 1С ≈ Safari 11.x; monaco 0.55 использует свободно):
- String.prototype.replaceAll (Safari 13.1) — getCSS при загрузке.
- Array/String.prototype.at (Safari 15.4) — listCodeEditors().at() в mainContainer.
- String.prototype.matchAll (Safari 13) — r.matchAll(e).
- + проактивно Object.fromEntries / Promise.allSettled. Все продублированы в
  blob-воркере (compile.js).

RegExp-несовместимости WebKit 1С (правки в monaco через replace-strings):
- Флаг 'd' (hasIndices, Safari 15): editorOptions `new RegExp(inputRegex,'d')`
  → срезаем 'd'. (Глобальную обёртку RegExp НЕ делаем — она реконструирует
  regex через .source и ломает именованные группы (?<name>), которые движок 1С
  как раз поддерживает.)
- Lookbehind (?<=) (Safari 16.4): defaultDocumentColorsComputer
  initialValidationRegex — raw-литерал, движок 1С читает (?<= как невалидную
  named-group → "invalid group specifier name" при require модуля. Меняем
  lookbehind на консумирующую группу (?:...). (linesOperations использует
  BackwardsCompatibleRegExp с try/catch — graceful, правка не нужна.)
- colorDecorators:false + defaultColorDecorators:'never' в обоих редакторах
  (color-декорации в gherkin не нужны).

Воркеры: monaco 0.55 как 0.52 — asyncChunks:false инлайнит worker в 1 блоб.

Гейты: build зелёный · es-check es2019 чист · mocha 46/46 в Chrome и под
эмуляцией движка 1С (Safari-UA + удаление отсутствующих API) · 1С 8.3.27 → 46/46.
npm update — только пины package-lock.json (диапазоны ^ не менялись):
- webpack 5.107.1 → 5.107.2
- webpack-cli 7.0.2 → 7.0.3
- webpack-dev-server 5.2.4 → 5.2.5
- ts-loader 9.5.7 → 9.6.0
- terser-webpack-plugin 5.6.0 → 5.6.1

Все — dev/build-тулинг, в production-бандл не попадают. Проверено: build
зелёный (webpack 5.107.2), es-check es2019 чист, mocha 46/46 (Chrome +
эмуляция движка 1С). Мажоры (typescript 6, chai 6, mocha 11, standard 17)
отложены — breaking. monaco-editor на 0.55.1 (latest stable).
Удалены остатки, подтверждённые аудитом как мёртвые на monaco 0.55.1:
- webpack.config.js: мёртвый no-op replace-strings патч "(.*)$','d'" —
  строка не встречается в monaco 0.55.1 (в 0.55 findSectionHeaders строит
  флаг иначе). Патч "new RegExp(inputRegex,'d')" остаётся — он живой.
- src/nls/nls.js: убраны AMD-наследие loadMessageBundle/config — 0
  использований в monaco 0.55.1 и в нашем коде.
- src/languages/turbo-gherkin/provider.ts: убран рудиментарный 4-й арг
  tokenize(...,0) (в 0.55 сигнатура 3-арговая); удалён неиспользуемый
  debug-хелпер logTokens().
- src/common.ts: удалён закомментированный мёртвый блок в emitEventTo1C.

Публичный API 1С не затронут. Проверено: build зелёный, es-check es2019
чист, mocha 46/46 (Chrome + эмуляция движка 1С).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant