React и Vue без npm и сборки

  • Tutorial
Когда все начинают знакомство с React или Vue, как с двумя самыми популярными фреймворками для frontend, конечно-же все используем магические команды npm install, npm build. И только после этого папочку 'public' Мы деплоим «куда надо».

Но есть и другой (я бы назвал его извращенный) не стандартный способ, о котором многие начинающие фронтэнд разработчики даже не знают, так как они «выросли» на npm install/build.

А что, если не нужно проводить сборку, а просто вставить js код в html?




Подождите плевать мне в лицо и бросать камни с надписью 'I love node'… Мы конечно знаем, что без сборки Мы потеряем юнит тесты, скорость, да и как быть с импортом компонентов, и иерархией файлов, да и вообще спагетти код какой-то получится…

Так для чего Вам (и Нам) это и как это работает ?


На днях к нам прилетел заказ от «бизнеса» по добавлению функционала в их BPM/ERP систему, которая по-сути является сильно модифицированным Redmine. Всё это чудо делалось довольно давно и крутится на VPS сервере с кучей helper'ов микросервисов для считывания данных производства, станков и тп. Трогать ОС нельзя…

Redmine — написан на Ruby on Rails, и генерирует весь фронт на сервере. Всё взаимодействие на фронтэнде в дописанных там плагинах было через jquery. Сейчас RoR научился работать с webpack и можно прикрутить «человеческую npm», но это в последних версиях, а у нас древний Ruby и Centos 6 на котором нет последней версии ни Ruby ни рельсов. Собирать из исходников и перелопатить всё ради добавления нескольких реактивных форм как-то не хочется, поэтому Мы начали искать путь добавления React или Vue в шаблон страницы Rails просто как обычный JS без npm и сборок.
И быстро нашли, причём для обоих.

Vue без Vue npm




С Vue оказалось всё очень просто. Инициирование компонентов выглядит конечно «странно», но в целом читабельно и «писабельно».

Пример простой страницы на Vue c компонентом:
<html>
<head>
    <script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
    <title>Stranger Vue things</title>
</head>
<body>
<div id="vue-app"></div>
<script type="text/javascript">
const titleComponent = `<h1>{{ title }}</h1>`;

var app = new Vue({
    el: '#vue-app',
    template: titleComponent,
    data: function () {
        return {
            title: 'Stranger Vue things'
        };
    }
});
</script>
</body>
</html>

Размер скачиваемых браузером файлов: 371 Kb, время: 590 ms

Можно даже импортировать Vue компоненты в обычном формате .vue с использованием http-vue-loader и не создавать спагетти код. Очень удивило, что из зависимостей нужен всего один vue, что не может не радовать.

React без React npm


С Реактом всё чуть сложнее но не сильно. Для работы JSX нужно импортировать babel. Для работы с DOM, нужен react-dom. Без вышеперечисленного react не будет нормально работать. Вместо одного импорта нужно сделать три.

Пример простой страницы на React c компонентом:

<html lang="en">
<head>
  <title>React Stranger Things</title>
  <script type="application/javascript" src="https://unpkg.com/react@16.0.0/umd/react.production.min.js"></script>
  <script type="application/javascript" src="https://unpkg.com/react-dom@16.0.0/umd/react-dom.production.min.js"></script>
  <script type="application/javascript" src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>

<body>
  <div id="root"></div>

<script type="text/babel">
const rootElement = document.getElementById('root')    
class TitleComponent extends React.Component {    
    render() { 
        return (
            <h1> {this.props.title}</h1>
        );
    } 
}

function App(){
  return(
    <div>
        <TitleComponent title="React Stranger Things"/>
    </div>
  )
}

ReactDOM.render(
    <App />,
    rootElement
)
</script>
</body>
</html>

Размер скачиваемых браузером файлов: 542 Kb, время: 589 ms

Здесь в отличии от Vue не нужно писать шаблон компонента как строку, пишем всё как обычно, что довольно удобно и не вызывает никакого дискомфорта.

И кого Мы выбрали?


Если брать размер скачиваемых браузером импортов js — победитель Vue. Но это только на первый взгляд. Так как у нас было не много компонентов Мы сделали задачу на обоих. И удобнее было писать на React: нет почти никакой разницы при написании со сборкой, а в размере импортов разница не сильно значительная.

А как-же Preact ?


Preact — это «мини» версия react, которая чуть быстрее и весит всего 3 Кб. Как только я услышал о нашей задаче — первое о чём я вспомнил — preact. Открыв документацию меня ждал не приятный сюрприз: React ≠ Preact.
У preact нет JSX, написание компонентов сильно отличается от React. Учиться писать на «preact way» для нашей мини-задачи сильно избыточно и «дорого».

Это костыль! Ударьте его им же


Мы знаем, что это костыль. Но иногда приходится выдумывать подобные решения исходя из задач. В нормальной ситуации разработки frontend использование в таком варианте фреймворков страшный костыль и конечно совсем не рекомендуется.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 44

    0
    А почему бы не компилировать jsx в IDE?
      –1
      Можно сделать полностью сборку в bundle.js через тот-же npm build и импортировать его в html страницу. Но как подключать root компонент? Через window.onload и тп. Проблема в том, что в таком виде нужно продумывать подключение root компонентов в зависимости от загрузки dom.
        0

        Выставляете наружу из бандла метод initialize, в который пробрасываете корневой элемент для рендеринга.

      +10
      Вот уже и выросло поколение, которое считает работу бандлера (по сути не являющуюся чем-то более интересным, чем поиск/замена/склейка строк или узлов AST) магией, и восторгающееся тем, что бандлер, оказывается, не обязателен.

      Мы потеряем юнит тесты

      Не потеряете.

      скорость

      Не потеряете. Или для вас будет открытием то, что минифицировать и оптимизировать тоже можно без бандлера?

      да и как быть с импортом компонентов

      Не надо с ними «быть», во всех уважающих себя браузерах импорты уже работают нативно. Ну и еще немного можно эту работу расширить через вот это.

      да и вообще спагетти код какой-то получится…

      Подождите, вы серьезно считаете модульный код с импортами и экспортами «спагетти»? А монолитную функцию на 50 000 строк — я так полагаю, нет?
        +6
        Работа бабела на лету никак не повлияет на скорость? НУОК.
          +1

          Вместо babel можно взять buble, он будет поменьше весить, чем babel-standalone.

            +3
            Работа бабеля никак не зависит от наличия или отсутствия бандлера. Ничего не мешает прогонять проект через бабель без бандлера.
            0
            Я вот все знаю, но выбираю webpack :) Почему? Просто в этом случае разработка приложения на том же vue можно распихать нормально по файлам компонентам и нормально туда сюда это все импортировать. И это становится не такой болью как обычно.
              0
              Не потеряете. Или для вас будет открытием то, что минифицировать и оптимизировать тоже можно без бандлера?

              Без бандлера — можно, а вот без этапа сборки вообще — не получится.

              +2

              Вместо JSX можно использовать template strings при помощи пакета htm:


              import htm from 'https://unpkg.com/htm?module'
              const html = htm.bind(React.createElement);
              
              function Component({name}) {
                return html`
                  <div>${name}</div>
                `;
              }
                0
                Спасибо, что написали! Тоже хотел про него написать когда писал про Preact, но вылетело из головы )
                0
                У preact нет JSX

                Как это нет, если даже на главной странице пример с JSX?

                  0

                  Думаю, имеется ввиду, что нет компилятора jsx

                    0
                    Верно, там пример через комплиятор, без компилятора там рекомендуют использовать htm.
                      0

                      Он же через тот же самый babel компилируется.

                  +3
                  Размер скачиваемых браузером файлов: 542 Kb, время: 589 ms

                  Вы считаете это нормальным для вывода 3 слов в теге h1?

                    +1
                    Конечно нет, для этого оно и показано ) Использовать так react и vue костыль для очень узких задач, как и описано в выводах.
                      –1

                      Для каких задач?

                    0
                    тоже активно использую такой способ.
                    шаблоны удобно писать в теге скрипт:
                    <sc*ript type="text/x-template" id="product-options">....</scr*ipt>

                        Vue.component('product-options', {
                            template: '#product-options'
                        }
                      0
                      Все неплохо, до тех пор когда нужно будет поставить либу, и тут окажется что для половины либ прямого способа нет.
                        0

                        Через unpkg.com можно подключить любой npm-пакет (если он опубликован в основном репозитории, конечно же).

                          0

                          Не получится. Т.к. импорты надо переписывать. https://habr.com/ru/post/474672/ я поступил так.

                            0

                            Там же есть экспериментальная фича ?module, которая переписывает все статические импорты чтобы те работали. Обратите внимание, что она тут и используется...

                              0

                              Да, но допустим он размотает import Foo from 'foo' в const Foo = window.Foo или как он там это делает, но файл то кто будет грузить? Я руками? В index.html все все все прописывать? А что если это зависимость зависимости и тд?

                                0

                                Насколько я понял, он размотает import Foo from 'foo' во что-то вроде import Foo from 'foo@1.2.3?module'. А грузить это будет браузер.

                                  0

                                  Так а скрипт то сам как будет грузиться? Он какой то добавочный код подсунет чтоб тег script приземлить на страницу? По-моему он дальше чем текстовая замена не идет и в рантайме ничего не делает особого.

                                    0

                                    Зачем добавочный код и тэг script? Какую проблему вы сейчас пытаетесь решить?

                                      0

                                      Физически код зависимости как попадет на страницу? Вот вы например запросили пакет с A, прописали его:


                                      <script type="application/javascript" src="https://unpkg.com/a@1.0.0/a.production.min.js"></script>


                                      А он в свою очередь потянет еще что-то. Не все ж пакеты как реакт несут в себе полную сборку, некоторые еще что-то требуют. И далее по цепочке. Как это разруливать?

                                        0

                                        Браузер увидит конструкцию "import ..." и загрузит зависимости. Зачем тут ещё какой-то дополнительный код и динамически формируемый тэг script?

                                          0

                                          wipe я был не прав, Unpkg все перепишет https://unpkg.com/next-redux-wrapper@4.0.1/es6/index.js?module, но реакт распространяется как UMD, он несовместим с import=module: https://unpkg.com/react@16.12.0?module и привет… следовательно любой другой пакет потенциально может так отпасть, следовательно нет никакой уверенности (((


                                          Вы читали статью мою, которую я выше кинул? Там все это описано.


                                          Статью спасает что топ левел реакт как скрипт прописан...

                                            0

                                            Вы вообще читаете что вам пишут?


                                            Во-первых, да, в режиме ?module unpkg именно что перепишет все зависимости так, чтобы они смогли нормально загрузиться.


                                            Во-вторых, UMD — это формат самодостаточного бандла, готового к подключению на страницу тэгом script

                                              0

                                              Да, читаю, я отредактировал коммент, вы правы, а я нет (по части переписывания путей)


                                              Во-вторых, UMD — это формат самодостаточного бандла, готового к подключению на страницу тэгом script

                                              Это не так. UMD — обертка, она может иметь прописанные package identifiers и обращения к global scope в качестве фоллбэка.


                                              UMD не равно bundle со всеми зависимостями. Реакт же не отрезолвился вообще https://unpkg.com/react@16.12.0?module (ссылка сгенеренная Unpkg). А Вы читаете, что вам пишут? )))

                                                0

                                                Реакт не отрезолвился потому что он поставляется в формате UMD, а не es6 module


                                                Но у него и импортов-то нет

                                                  0

                                                  Я и говорю, повезло. А может и не повезти. Я регулярно встречаю странные поставки без ES6 и в UMD без бандла...


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

                                                    0

                                                    Исторически именно прямое подключение библиотек на страницу было основным сценарием использования, так что все легаси-библиотеки подключить через unpkg проще чем собрать в бандл.


                                                    А потому я сомневаюсь, что невезение будет частым.

                        0
                        Стоп, подождите. А как насчет react-rails?
                          0
                          Для него нужен свежий Rails и Ruby, а у нас нельзя было трогать ОС и всё что внутри.
                            0
                            Если я не ошибаюсь, то мы использовали react-rails на третьей версии RoR. Или у вас все было еще хуже?
                          0
                          Меня умиляет неадекватность этого сравнения.

                          Добавили для реакта преобразователь — сразу реакт почемуто стал удобнее.
                          Давайте для Vue тоже подгрузим такой же конвертер? Тоже станет удобнее, тогда можно будет более легкую версию фреймворка грузить, без компилятора шаблонов.
                          Учитывая, что кроме отрисовки компонентов и значений переменных в реакте больше ничего нет и надо грузить кучу библиотек(как ранее в коментах предложили, «для удобства»), это тоже не имеет значения?
                            0

                            А как насчет использования библиотек? ;)
                            Я дальше пошел и преобразования в воркер засунул: https://habr.com/ru/post/474672/

                              0
                              Интересное решение, спасибо, что поделились.
                                0

                                Спасибо! Удивительно насколько различается кол-во пришедших читать пост, подача — важно )))

                              0

                              Кажется, вы боретесь с проблемой, которой нет. Собрать бандл на любом фреймворке (React, Preact, Vue, Svelte) и интегрировать его в любой сайт нет никакой сложности.


                              На реакте вполне можно писать без JSX, и не нужно будет тащить babel в рантайм.


                              Рекомендую приглядется к Svelte, он для написание разных виджетов и частей страниц очень неплохо подходит (за счет почти отсутствия рантайма)

                                0
                                К Svelte Мы не только присмотрелись, но и пробовали его в продакте Про Svelte

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое