Рубрики
Без рубрики

Cloudpress – Часть 2: CMX, удобный вариант JSX!

Мы посмотрим на две новые технологии: CMX и Graphqldatabaseloader!. Теги с помощью TypeyScript, WebDev, Node, JavaScript.

Предыдущий

В моей предыдущей статье я говорил о CloudPress, новой системе управления контентом, на которой я работал на прошлом году. Я говорил о архитектуре плагина и как работает система. Сегодня я буду введен вам пару новых технологий, которые я реализовал в прошлой неделе.

CMX – это спин jsx. Их синтаксис по существу одинаково, с одним ключевым отличием: в CMX значения оцениваются как данные JSON; И не выражения JavaScript.

Пример CMX страницы будет выглядеть так:


  
{/* this is a comment*/}

Который будет выводить HTML ниже:

Если вы не знакомы с JSX, вам могут быть интересно, Документ и CustomComponent не являются стандартными элементами HTML. Так что они?

И мой ответ будет, что они на заказ Компоненты . Они являются объектами реагирования, которые зарегистрированы в системе плагинами. Они действуют точно так же, как шорткоды в WordPress. Хотя они вписываются с HTML более естественно на мой взгляд.

Компоненты имеют доступ к системе через GraphQL, и они могут запросить данные или выполнять действия, вызывая мутации. Это дает разработчикам плагина очень мощный инструмент для взаимодействия с системой. Они также изоморфны и должны представлены на сервере точно так, как они представляют в браузере.

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

Другая технология, которую я закончил вчера, это Graphqldatabaseloader , который является кешинговым погрузчиком, построенным на вершине Типрм Это складывает набор различных запросов базы данных в единственный запрос.

Если вы посмотрите на Facebook Data-Loader Библиотека, вы увидите проблему по явлению: это слишком общее. Как вы видите в примере ниже:

const userLoader = new DataLoader(keys => myBatchGetUsers(keys));
userLoader.load(1)
  .then(user => userLoader.load(user.invitedByID))
  .then(invitedBy => console.log(`User 1 was invited by ${invitedBy}`));

Он может загружать только предметы по идентификаторам, что хорошо и хорошо, но она строго ограничивает нас в нашем случае использования.

Например: если вы используете его с помощью GraphQL и базой данных SQL (что это ситуация, которую многие окажутся в), она не позволяет вам оптимизировать ваши запросы столько, сколько вы обычно сможете. (Используя что-то вроде Присоединиться к монстру Например)

Использование Graphqlresollishinfo Параметр, предоставленный для резольдентов GraphQL, можно использовать его, чтобы получить именно необходимые данные. Не больше, не меньше. Выбор оператора может выбрать именно то, что было запрошено и вернуть его. Тем не менее, с DataLoader Facebook вы просто не можете использовать эту информацию, из-за кэширования (подумайте, что произойдет, если входящий запрос хотел поле И это не было в кэше) и тысячу других причин.

Еще одним ограничением является это: что, если запрос хотел нажать на поле, кроме удостоверения личности? Слизняка возможно?

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

Graphqldatabaseloader это база данных и graphql -ware. Он складывает все запросы базы данных, полученные от всех источников (думают: Resharders graphql, промежуточное программное обеспечение KOA, что угодно) во время одного цикла петли события в единый запрос базы данных и кэшируют результаты на вершине этого.

Например, с запросом, таким как этот:

query {
  user1: node(id: "VXNlcjox") {
    __typename
    id
    ...UserFragment
  }
  hello_world: node(id: "UGFnZTox") {
    __typename
    id
    ...PageFragment
  }
  test2: lookupPageBySlug(slug: "test2") {
    __typename
    id
    content
    ...PageFragment
  }
}
fragment PageFragment on Page {
  title
  excerpt
  slug
  author {
   name
  }
}
fragment UserFragment on User {
  name
  username
  email
}

3 Различные запросы GraphQl приведут именно 1 запрос баз данных, один, который будет Выберите именно необходимые поля:

SELECT
        "Page0"."id" AS "Page0_id",
        "Page0"."title" AS "Page0_title",
        "Page0"."slug" AS "Page0_slug",
        "Page0"."content" AS "Page0_content",
        "Page0"."excerpt" AS "Page0_excerpt",
        "Page0_author"."name" AS "Page0_author_name",
        "User1"."id" AS "User1_id",
        "User1"."name" AS "User1_name",
        "User1"."username" AS "User1_username",
        "User1"."email" AS "User1_email",
        "Page2"."id" AS "Page2_id",
        "Page2"."title" AS "Page2_title",
        "Page2"."slug" AS "Page2_slug",
        "Page2"."excerpt" AS "Page2_excerpt",
        "Page2_author"."name" AS "Page2_author_name",
        "74d5c2aed587be81c9d67117dc60afd8" AS "Page0_KEY",
        "bdeac7ffad7e49ac60b1ab6c123e4f85" AS "User1_KEY",
        "d81c9566475e497a46b39e00d0826e3c" AS "Page2_KEY" 
    FROM
        "page" "Page",
        "user" "User",
        "page" "Page" 
    LEFT JOIN
        "page" "Page0" 
            ON (
                "Page0"."slug"=$1
            )  
    LEFT JOIN
        "user" "Page0_author" 
            ON "Page0_author"."id"="Page0"."authorId"  
    LEFT JOIN
        "user" "User1" 
            ON (
                "User1"."id"=$2
            )  
    LEFT JOIN
        "page" "Page2" 
            ON (
                "Page2"."id"=$3
            )  
    LEFT JOIN
        "user" "Page2_author" 
            ON "Page2_author"."id"="Page2"."authorId"

И вернуть результаты:

{
  "data": {
    "user1": {
      "__typename": "User",
      "id": "VXNlcjox",
      "name": "Abdullah",
      "username": "voodooattack",
      "email": "voodooattack@hotmail.com"
    },
    "hello_world": {
      "__typename": "Page",
      "id": "UGFnZTox",
      "title": "Welcome to CloudPress!",
      "excerpt": "test",
      "slug": "hello-world",
      "author": {
        "name": "Abdullah"
      }
    },
    "test2": {
      "__typename": "Page",
      "id": "UGFnZToy",
      "content": "\n  
\n \n \n {/* this is a comment*/}\n \n
\n
", "title": "test 2", "excerpt": "", "slug": "test2", "author": { "name": "Abdullah" } } } }

Часть, которую я хочу, чтобы вы заметили, это часть запроса:

"74d5c2aed587be81c9d67117dc60afd8" AS "Page0_KEY",
"bdeac7ffad7e49ac60b1ab6c123e4f85" AS "User1_KEY",
"d81c9566475e497a46b39e00d0826e3c" AS "Page2_KEY"

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

/**
 * Load a model from the database.
 * @param where Query conditions.
 * @param {GraphQLResolveInfo} info GraphQL resolver information argument.
 * @param {IModelInfo} modelInfo The model type to load.
 * @returns {Promise}
 */
async load(where: any, info: GraphQLResolveInfo, modelInfo: IModelInfo): Promise {
  const fields = graphqlFields(info);
  const hash = crypto.createHash('md5');
  const key = hash.update(JSON.stringify({ where, fields })).digest().toString('hex');
  if (key in this._cache)
    return this._cache[key];
  ...

Если HASH CHERESH найден в таблице кэша, кэшированное значение возвращается.

И я почти забыл упомянуть, что каждый HTTP-запрос получает свой Graphqldatabaseloader. Таким образом, не происходит никаких столкновений или утечек между сеансами пользователей. Это все!

Редактировать: Это теперь доступно как автономный пакет на NPM: Тип-погрузчик

В этой серии я надеюсь обсудить больше технических аспектов проекта и сталкиваюсь с проблемами. Я также попробую пост регулярные обновления, планы на будущее, и неоднократно и бесстыдно умоляющие людей, чтобы способствовать проекту. Если вы заинтересованы в содействии (я действительно мог бы использовать помощь), не стесняйтесь обращаться ко мне здесь или на Twitter Отказ

До скорого!

Оригинал: “https://dev.to/voodooattack/cloudpresspart-2-cmx-the-user-friendly-variant-of-jsx-boo”