• Как программно инвалидировать SSR кеш в NextJS?

    @dimuska139 Автор вопроса
    Backend developer
    В общем, сам решил вопрос. У cacheable-response можно в параметре cache указать свой экземпляр Keyv, передав в конструктор класса нужный store. Соответственно, если передать туда @keyv/redis, то кеш будет храниться в Redis. При желании можно просто из Redis удалять нужный ключ и все - вот и инвалидация.
    Может немного неправильно объяснил, так что вот код моего server.js:
    const express = require('express');
    const next = require('next');
    const redirects = require("./redirects");
    const cacheableResponse = require('cacheable-response');
    const port = parseInt(process.env.PORT, 10) || 3001;
    const dev = process.env.NODE_ENV !== 'production';
    const app = next({ dev });
    const KeyvRedis = require('@keyv/redis');
    const Keyv = require('keyv');
    
    const handle = app.getRequestHandler();
    
    const keyvRedis = new KeyvRedis('redis://127.0.0.1:6399'); // TODO: Get from dotenv
    
    const ssrCache = cacheableResponse({
        ttl: 1000 * 60 * 120, // 2 hours
        get: async ({ req, res, pagePath, queryParams }) => ({
            data: await app.renderToHTML(req, res, pagePath, queryParams)
        }),
        cache: new Keyv({ store: keyvRedis }),
        send: ({ data, res }) => res.send(data)
    });
    
    
    app.prepare().then(() => {
        const server = express();
    
        redirects.forEach(({ from, to, type = 301, method = 'get' }) => {
            server[method](from, (req, res) => {
                res.redirect(type, to)
            })
        });
    
        server.use((req, res, next) => {
            res.append('Set-Cookie', "HttpOnly;Secure;SameSite=Strict");
            next();
        });
    
        server.get('/posts/:slug', (req, res) => {
            const queryParams = { slug: req.params.slug };
            const pagePath = '/post';
            return ssrCache({
                req,
                res,
                pagePath,
                queryParams
            });
        });
    
        server.get('/', (req, res) => {
            const pagePath = '/';
            return ssrCache({
                req,
                res,
                pagePath
            });
        });
    
        server.all('*', (req, res) => {
            //console.dir(req.url);
            return handle(req, res)
        });
    
        server.listen(port, err => {
            if (err) throw err;
            console.log(`> Ready on http://localhost:${port}`)
        })
    });
    Ответ написан
    Комментировать
  • На каких этапах стоит комитить код?

    DevMan
    @DevMan
    есть простое правило: больше коммитов, меньше конфликтов.

    это не значит, что нужно коммитить каждую минуту. это значит что как только вы написали законченный код, даже если это фрагмент другой задачи, его стоит коммитить.
    Ответ написан
    4 комментария
  • Как правильно запустить сайты на nodejs?

    @McBernar
    Да, запускайте ноду под каждый проект и разводите через nginx.
    pm2 вам в помощь для запуска и логов.

    Лучше фреймворк. Зачем делать то, что уже сделано?
    Ответ написан
    7 комментариев
  • Как сделать маску для input-телефона с помощью чистого JavaScript, без использования JQuery и плагинов?

    joeberetta
    @joeberetta Куратор тега JavaScript
    Читай: https://epdf.pub/google-for-dummies.html
    Хреново у вас с гуглом
    Ответ написан
    Комментировать
  • Как задать лимит contenteditable div, чтобы после обрезки фокус был в конце последнего символа?

    dmtrbskkv
    @dmtrbskkv Автор вопроса
    Кодим и декодим, а иногда кино смотрим
    Нашел ответ в интернетах:
    <p id="p">Example: <i>italic</i> and <b>bold</b></p>
    
    From <input id="start" type="number" value=1> – To <input id="end" type="number" value=4>
    <button id="button">Click to select</button>


    let range = new Range();
    
        range.setStart(p, start.value);
        range.setEnd(p, end.value);
    
        // применим выделение, объясняется далее
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(range);
    Ответ написан
    Комментировать
  • Как навесить обработчик внутри iframe После Динамической загрузки Iframe?

    sinneren
    @sinneren Автор вопроса
    1. mutation observer
    2. увидеть в нем addedNodes с фреймом
    3. навесить обработчик на контент фрейма как обычно
    Ответ написан
    Комментировать
  • Конфликт формы обратной связи с vendor.min.js?

    Kozack
    @Kozack Куратор тега JavaScript
    Thinking about a11y
    Никаких "конфликтов" у вас там нет.
    Когда вендоры подключены, всё корректно работает. Форма отправляется. Это можно посмотреть в отладчике браузера.

    Когда есть вендоры — все скрипты работают. И форма отправляется посредством ajax на mail.php. А тот возвращает ошибку 404. На сайте не предусмотрена обработка ошибок, вот вам и кажется что "ничего не происходит".

    Когда вы отключаете вендоры, скрипты ломаются, и уже ничего не перехватывает обработку формы. И форма отправляется по старинке, но уже по другому адресу — order.php который показывает сообщение об успехе.
    Ответ написан
    1 комментарий
  • Как запустить webpack-dev-server на nodejs и express?

    Alexsandrrh
    @Alexsandrrh
    Мне тут интересно.
    Привет! Для Node.js + Express есть webpack-dev-middleware и webpack-hot-middleware. Они сделаны для того чтобы в виде сервера был Express, а не webpack-dev-server.
    https://madole.github.io/blog/2015/08/26/setting-u...
    Ответ написан
    Комментировать
  • Как организовать mixin по айдишникам?

    delphinpro
    @delphinpro Куратор тега Sass
    frontend developer
    Кто же вас заставлял создавать кучу однотипных переменных, если для этого существуют массивы? Или, в терминологии sass - мапы.

    $colors: {
      1: #333,
      5: #111,
      100: #222,
    }
    
    @each $index, $color in $colors {
      #var#{$index} {
        color: $color;
      }
    }
    Ответ написан
    3 комментария
  • Когда использовать useCallback, useMemo и useEffect?

    @LEXA_JA
    useEffect - это хук, который позволяет использовать сайд эффект. В классах его аналогом было использование componentDidMount, componentDidUpdate и componentWillUnmount. В нем можно делать подписки, отправлять запросы управлять анимацией и т. д.
    const [data, setData] = useState(null);
    
    useEffect(() => {
      const controller = new AbortController()
      fetchData(controller.signal).then(setData)
    
      return () => controller.abort()
    }, [fetchData, setData])


    useCallback и useMemo предназначены для оптимизации. useCallback получает на функцию и массив аргументов, и возвращает одну и туже функцию, до тех пор, пока аргументы не изменились. useMemo отличается тем, что он возвращает не саму функцию, а результат её выполнения. По большому счету они являются взаимозаменямыми.
    Таким образом, useMemo используется для сохранения результатов тяжёлых вычислений, например обработка массива.
    const data = useMemo(() => array.map(mapper).filter(predicate).reduce(reducer), [array])

    А useCallback используется, когда важна постоянность ссылок на функцию. Например, когда мы передаём ссылку в компонент, который использует React.PureComponent или React.memo, или, когда функция используется в качестве аргумента в других хуках
    const handler = useCallback(() => {
      // что-то сделать 
    }, [])
    
    useEffect(() => {
      handler(value)
      // если не использовать useCallback, эффект будет срабатывать постоянно 
    }, [handler, value])
    Ответ написан
    1 комментарий
  • Почему код скрывает только первый блок в списке?

    joeberetta
    @joeberetta Куратор тега JavaScript
    Читай: https://epdf.pub/google-for-dummies.html
    document.querySelectorAll('.quest1').forEach(quest => quest.style.display = 'none');
    document.querySelectorAll('.quest2').forEach(quest => quest.style.display = 'none');
    Ответ написан
    3 комментария
  • Автоматически увеличивающаяся строка поиска, когда текст заполнил её полностью. Как создать?

    zkrvndm
    @zkrvndm
    Архитектор решений
    Для описанных целей существует плагин autosize.
    Ответ написан
    Комментировать
  • Как удалить все данные с сервера без возможности восстановления?

    @alex1478
    Способ надёжнее простого dd по ssh:
    mkdir /target
    mount none -t tmpfs -o size=1G /target/
    debootstrap stable /target/ https://deb.debian.org/debian/
    echo "Killer_system" > /target/etc/debian_chroot
    chroot /target
    mount none -t proc /proc/
    mount none -t sysfs /sys/
    mount none -t devtmpfs /dev/
    mount none -t devpts /dev/pts/
    apt install openssh-server
    echo "Port 11122" >> /etc/ssh/sshd_config
    echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
    /etc/init.d/ssh start
    passwd root

    Теперь подключаетесь к ssh, запущенному из озу:
    ssh root@<IP> -p 11122
    Передёргиваем диск:
    echo 1 > /sys/block/sda/device/delete
    for i in /sys/class/scsi_host/host?/scan ; do echo "- - -" > $i ; done

    Теперь sda станет sdb
    dd if=/dev/urandom of=/dev/sdb bs=4096
    В конце работы:
    echo b > /proc/sysrq-trigger
    Это перезапустит сервак, но он конечно уже не загрузится.

    В отличии от предыдущего способа, мы 100% сможем дождаться завершения работы dd
    Ответ написан
    18 комментариев
  • Как организовать передача состояния из react в svg?

    rockon404
    @rockon404 Куратор тега React
    Frontend Developer
    Лучше создавать спрайт и добавлять его в документ, а иконки забирать по id.
    Компонент на примере Styled Components:
    import React from 'react';
    import styled from 'styled-components';
    
    const SVG = styled.svg`
      display: inline-block;
      vertical-align: middle;
    `;
    
    const Icon = ({ name, ...props }) {
      if (!name) {
        throw new Error('Unknown icon name!');
      }
      return (
        <SVG {...props}>
          <use xlinkHref={`#icon-${name}`} />
        </SVG>
      );
    }
    
    export default Icon;


    Cтилизованая иконка c разными состояниями:
    import React from 'react';
    import styled from 'styled-components';
    import { Icon } from './components';
    
    const StyledIcon = styled(Icon)`
      fill: ${props => props.state.fill};
    `;
    
    const Example = ({ iconState }) => <StyledSVG name="profile" state={iconState} />;
    
    export default Example;


    Styled Components, тут лишь для примера. Подобные компоненты легко реализуются и без использования этой библиотеки.
    Ответ написан
    2 комментария
  • Как восстановить глобальный метод после теста в Jest?

    yakimchuk-ry
    @yakimchuk-ry Автор вопроса
    Нашел ответ чисто случайно. Каждый файл тестов запускается в Jest в отдельном контексте VM, поэтому мутация глобальных переменных работает только в рамках файла, поэтому это НЕ проблема, это никак не влияет на тесты вне текущего файла.
    Ответ написан
    Комментировать
  • Как перенаправить данные из API через Node.js в React-приложение?

    maxilamb
    @maxilamb
    Frontend developer, lover of all new

    1. Как получить данные через node.js


    2. используй express.js
      app.get('/api/v1/bitcoin', function (req, res) {
      //запрос coinmarketcap 
      .then(response => res.json(response))
      .catch(() => res.send("Ops something went wrong"))
      })



    3. в package.json пропиши прокси к локальному node.js серверу

    Ответ написан
    1 комментарий
  • Soket.io каждые 50 секунд, открывает соединение заново в чем проблема?

    IDONTSUDO
    @IDONTSUDO Автор вопроса
    ЧСВ программистов идет в комплекте с первой IDE.
    сделал, вот так. И не переподключается, на удивление. Я не знаю почему, но оно работает как надо.

    import io from "socket.io-client";
    import { isAuthenticated} from "../Api/Auth"
    
    
    const jwt = isAuthenticated().token
    
    const socket = io.connect('http://localhost:4001', 
      { query: {token: jwt} 
    })
    
    
    export const testSoket = () => {
        socket.on("news")
        socket.on('disconnect', function(){});
    }
    Ответ написан
    Комментировать
  • Как собрать приложение JS приложение с помощью Electron вместе с БД?

    MvcBox
    @MvcBox
    Software Engineer [C/C++/JS(for Node.js)/etc]
    Код для Electron.js приложений после билда хранится в asar архиве.
    Вы не должны упаковывать свою базу в этот архив.
    Базу можно создавать, к примеру, рядом с исполняемым файлом приложения.
    Удалите db.sqlite3 из списка files, а в своем приложении укажите следующий путь к базе:
    `${process.execPath}/db.sqlite3`
    Ответ написан
    Комментировать
  • С чего начать изучение webgl, чтобы сделать так?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Вся суть таких анимаций - много заранее заготовленных кадров, которые мы по очереди показываем. Чем больше кадров - тем плавнее анимация. Они могут быть в отдельных картинках или по много кадров в одной. На вашем сайте все это еще поделили - каждая часть бутылочки имеет свою последовательность кадров:
    Спойлер
    1ersu-v8gwpy6mxqyagwggfny0k.png

    Каких-то конкретных преимуществ этого подхода по сравнению с одним кадром на все я не вижу. Использовать ли для этого WebGL? Ну можно. Точно также, как и обычный canvas. Как выводить картинки на него вы легко загуглите, остается только посчитать координаты расположения кадров в картинке (по идее дизайнер должен их там аккуратно по сеточке расставлять) и выводить их по очереди.

    P.S.: По идее можно отрендерить видео и вместо ручного переключения кадров проматывать его в разные стороны с разной скоростью в зависимости от скролла. Но на практике что-то не видно, чтобы это массово делали, обычно используют именно отдельные кадры.
    Ответ написан
    1 комментарий
  • Какой самый универсальный инструмент для работы с анимацией и графикой на js?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Вы хотите, чтоб у вас всё было, и вам за это ничё не было.
    Но так не может быть.

    Любой, даже супер навороченный фреймворк, это, как минимум, увеличение размера страницы и потребления памяти. Если у вас простая задача, типа нарисовать 7 красных линий, то это можно сделать на нативном JS, без фреймворков.

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

    А вот когда есть повторные задания, очень похожие на предыдущие, вот тогда уже имеет смысл что-то, что упростит решение типовых задач, автоматизирует его. Но что мешает скопировать свой предыдущий код и чуть модифицировать его?
    Ответ написан
    1 комментарий