Почему TeqFW использует только ES-модули?

от автора

Ни у кого не получится показать другому то, что тот не хочет или не может увидеть. Объяснять и показывать нужно только тем, кто а) может понять, б) хочет понять. В этой публикации я демонстрирую пару своих документов для LLM, которые предписывают «силиконовым«, какими правилами им следует руководствоваться при создании кода для моей платформы. «Силиконовым» можно впаривать любую дичь — они всеядные (могут понять) и покладистые (согласны понять). За это мы их и любим!

Кому интересно, что за инструкции — прошу под кат. Кто хочет сразу получить ответ на вопрос в заголовке — могут задать его (и множество других) соответствующему преднастроенному GPT-чату. Кто не хочет ни того, ни другого — в вашей ленте есть ещё куча других, более интересных публикаций.

Введение

Я пришёл к выводу, что инструкции для LLM нужно делить на две части:

  • промпт: короткий документ (до 500 токенов), используется в качестве стартера для начала диалога;

  • эмбеддинг: более обширный документ (до 4К токенов), который подшивается в базу знаний соответствующего LLM-агента.

Промпт

По сути, этот документ — свод правил, которые должны быть понятны разработчику сеньорского уровня. Нужно помнить, что из любого правила всегда бывают исключения, но правила существуют именно для того, чтобы ими руководствоваться в большинстве случаев. Категоричность тона промпта компенсируется повышенным раздолбайством аудитории (LLM), являющимся следствием её вероятностной природы.

# **Правила генерации ES-модулей в TeqFW**  LLM **должна строго следовать этим правилам** при генерации кода. **Отклонения недопустимы**.  ## **1. Только ES-модули (ESM)**  - **Единственный допустимый формат — ES-модули**. - Запрещены: CommonJS (`require()`, `module.exports`), UMD, AMD, IIFE и другие форматы. - **Нельзя использовать `require()`, `module.exports`, `export =`, `__dirname`, `import()` внутри   условий (`if`, `try`, `switch`)**. - Взаимодействие с модулями других форматов возможно **только в runtime-режиме**.  ## **2. Изоляция модулей**  - Модуль выполняется **автономно**, доступ к содержимому только через `export`. - **Не использовать глобальные объекты** (`globalThis`, `window`, `document`).  ## **3. Жёсткий контроль API**  - Экспортируемые сущности **неизменяемы** (использовать `Object.freeze()`, `const`). - **Запрещено изменять API после загрузки**.  ## **4. Явные зависимости**  - Все зависимости **передаются явно** через аргументы функций или классов. - Запрещены **статические и динамические импорты** (`import()`).  ## **5. Запрещены побочные эффекты при импорте**  - Импорт **не должен вызывать выполнение кода** (логирование, таймеры, сетевые запросы, изменение глобальных объектов   или хранилищ).  ## **6. Отсутствие внутреннего состояния**  - **Запрещены изменяемые глобальные переменные**. - Состояние должно передаваться в функции или классы извне.  ---  **LLM должна соблюдать эти правила и разъяснять несоответствия.**

Эмбеддинг

Это документ уровня мидла — в нём более подробно и более доступно, с примерами, объясняются те же самые концепции, что и в предыдущем документе. При прочтении держите в уме, что это документ для LLM, а не для людей (можете испытать дискомфорт при прочтении).

## Детализация правил генерации ES-модулей в TeqFW  ### 1. **Только ES-модули (ESM)**  TeqFW использует исключительно **ES-модули (ESM)** для генерации кода. Это означает, что **любые другие форматы, такие как CommonJS, UMD, AMD, IIFE, не поддерживаются**.  #### 🔹 **Почему это важно?**  - **ESM** является стандартом для модульности в JavaScript и гарантирует предсказуемость и совместимость. - **Использование `require()`**, **`module.exports`**, и **`export =`** из CommonJS **не допускается**. Модули на основе   этих подходов не могут быть использованы в TeqFW.  #### 🔹 **Пример плохой практики**:  ```js // Плохая практика - CommonJS const fs = require('fs'); module.exports = function readFile() {     fs.readFileSync('file.txt'); }; ```  #### 🔹 **Как работать с модулями других форматов?**  - Взаимодействие с модулями других форматов, например, **CommonJS**, возможно только в **runtime-режиме**, при этом   изоляция и совместимость с ESM сохраняются. Например, для таких адаптеров должны использоваться **фабричные функции   или мосты**.  ### 2. **Изоляция модулей**  В TeqFW **каждый модуль изолирован**, и его код не может влиять на глобальную область. Доступ к коду модуля осуществляется только через экспортированные сущности.  #### 🔹 **Почему это важно?**  - Изоляция модулей обеспечивает **безопасность** и **детерминированность**. Модули не могут случайно изменить глобальные   объекты (`globalThis`, `window`, `document`), что защищает от неожиданных побочных эффектов.  #### 🔹 **Пример хорошей практики**:  ```js // Правильная практика: модуль работает с экспортированными сущностями export const myFunction = () => {}; ```  ### 3. **Жёсткий контроль API**  Все экспортируемые сущности должны быть **неизменяемыми** (используйте `Object.freeze()` или `const`). После загрузки модуля API не должно изменяться.  #### 🔹 **Почему это важно?**  - **Жёсткий контроль API** предотвращает нежелательные изменения, обеспечивая стабильность взаимодействий с внешним   кодом.  #### 🔹 **Пример хорошей практики**:  ```js const API = Object.freeze({     process: () => console.log('Processing...') }); export default API; ```  ### 4. **Явные зависимости**  Все зависимости должны передаваться **явно** (например, через аргументы конструктора или фабричной функции). Запрещены * *статические и динамические импорты** внутри модуля.  #### 🔹 **Почему это важно?**  - Явное передача зависимостей помогает контролировать, какие библиотеки или функции используются внутри модуля, а также   избегать неявных связей и сложных для отладки ошибок.  #### 🔹 **Пример хорошей практики**:  ```js export default function createService({logger, fs}) {     return {         log: logger.log,         readFile: fs.readFileSync     }; } ```  #### 🔹 **Запрещённые практики**:  ```js // Плохая практика: использование динамического импорта без явного контроля export default async function loadLibrary() {     const lib = await import('./some-lib.js');     return lib.process(); } ```  ### 5. **Запрещены побочные эффекты при импорте**  При импорте модулей не должно происходить **выполнения побочных эффектов**, таких как логирование, запуск таймеров, сетевые запросы или изменения глобальных объектов.  #### 🔹 **Почему это важно?**  - Это позволяет избежать нежелательных изменений в среде выполнения при простом импорте модуля, что улучшает   предсказуемость кода и безопасность.  #### 🔹 **Пример плохой практики**:  ```js // Плохая практика - запуск таймеров при импорте import './someModule.js'; // запускает setTimeout ```  #### 🔹 **Пример хорошей практики**:  ```js // Правильная практика: побочные эффекты должны происходить только при явном вызове import {startTimer} from './timer.js';  startTimer(); ```  ### 6. **Отсутствие внутреннего состояния**  Модули не должны хранить **изменяемое внутреннее состояние**. Все данные должны передаваться в функции или классы извне.  #### 🔹 **Почему это важно?**  - Это упрощает тестирование и позволяет избежать неожиданных побочных эффектов, связанных с изменениями состояния внутри   модуля.  #### 🔹 **Пример плохой практики**:  ```js // Плохая практика: использование глобальных переменных внутри модуля let counter = 0; counter++; ```  #### 🔹 **Пример хорошей практики**:  ```js // Правильная практика: состояние передаётся извне export default function increment(counter) {     return counter + 1; } ```  ---  **LLM должна строго следовать этим правилам и разъяснять несоответствия**, если пользователь запрашивает несовместимый с ESM код. В таких случаях модель обязана предложить корректное решение, соответствующее принципам TeqFW.

Заключение

В комментариях к своей предыдущей статье я сформулировал вот такую мысль (спасибо коллеге @Per_Ardua за правильный вопрос):

Вы просто начинаете мыслить в тех же категориях, что и среда исполнения, а не среда написания.

Эти инструкции и эта публикация родились из попытки разобраться, а с какой, собственно, средой исполнения я имею дело, и что в этой среде для меня является принципиально важным?

Я ответил сам себе на эти вопросы и оформил их в виде инструкций для LLM. Но публикую я свои ответы не для того, чтобы вы их критиковали или оспаривали. Вы, конечно, можете делать и то, и другое, но… основное назначение этих документов — быть предупреждением:

Не надо пытаться пробовать Tequila Framework, если вы не согласны с изложенным здесь — вам она точно не понравится.

Если же кто-то решится попробовать — лучше обратитесь напрямую ко мне (контакты найдёте хоть на том же Хабре). Я помогу вам стартануть с проектом, чтобы вы избежали головной боли. Хотя… кто пил текилу, тот знает — если как следует принять, то головной боли на следующее утро не избежать.

Всем добра и вайб-кодинга!! 🧂🥃🍋‍🟩


ссылка на оригинал статьи https://habr.com/ru/articles/892942/