Три сосны: MSIE, V8 и ChakraCore


Английскую версию данного поста я написал еще в мае и опубликовал ее в багтрекере проекта ReactJS.NET. Изначально я не планировал переводить данный пост на русский язык, но в понедельник я увидел программу 13-й встречи MskDotNet Community, и решил, что такой перевод был бы полезен сообществу


Для лучшего понимания материала изложенного в посте, я немного расскажу о ReactJS.NET и JavaScript Engine Switcher. ReactJS.NET – это .NET-библиотека, которая производит компиляцию JSX-кода в JS-код. Данная библиотека не является .NET-портом библиотеки React (по аналогии c Less.js и dotless). При создании ReactJS.NET использован совершенно другой подход: JS-код библиотеки React запускается из .NET с помощью JS-движка. Роль этого JS-движка, как раз и выполняет библиотека JavaScript Engine Switcher. JavaScript Engine Switcher определяет унифицированный интерфейс доступа к базовым возможностям популярных JS-движков (MSIE JavaScript Engine for .Net, Microsoft ClearScript.V8, Jurassic, Jint и ChakraCore) и позволяет быстро переключить вашу библиотеку или приложение на использование другого JS-движка (при условии, что ваш JS-код совместим со стандартом ECMAScript 5).


Когда я проектировал JavaScript Engine Switcher, то предполагал, что разработчики библиотек в своих пакетах будут ссылаться только на JavaScriptEngineSwitcher.Core и оставят пользователям библиотек возможность выбора наиболее подходящей им реализации JS-движка. Именно такой подход я использую в своем проекте Bundle Transformer. Но автор ReactJS.NET пошел другим путем: пакет React.Core в своем списке зависимостей уже содержит несколько предустановленных модулей JavaScript Engine Switcher: MSIE, V8 и ChakraCore. Во время инициализации библиотеки производятся последовательные попытки создать экземпляр одного из вышеперечисленных движков и первый успешно созданный движок становится движком по умолчанию.


Стоит отметить, что это поведение можно переопределить и самому выбрать наиболее подходящий движок. Для этого нужно зарегистрировать JS-движки перед инициализацией ReactJS.NET. В ASP.NET 4.X инициализация ReactJS.NET обычно производится в файле App_Start/ReactConfig.cs (благодаря атрибуту [assembly: WebActivatorEx.PreApplicationStartMethod(…)] содержимое этого файла запускается раньше кода, определенного в методе Application_Start из файла Global.asax), а в ASP.NET Core для этих целей используется файл Startup.cs. Кроме того, если при регистрации указать имя JS-движка по умолчанию, то выбор подходящего движка пройдет по упрощенной схеме.

Подобный подход удобен для пользователей библиотеки, потому что позволяет использовать ReactJS.NET прямо из коробки (без необходимости регистрировать JS-движки вручную). Но у такого подхода есть один существенный недостаток — процесс выбора JS-движка непрозрачен. Зачастую пользователи не знают какой в данный момент используется JS-движок, а некоторые даже не знают о существовании JavaScript Engine Switcher. Недостаток информации приводит к ошибкам и заблуждениям, которые сначала появляются в багтрекере в виде советов, а затем в виде постов в блогах. Заблуждения имеют свойство распространяться с большей скоростью, чем верная информация. В какой-то момент, этот процесс выходит из под контроля и наступает необходимость написать пост подобный этому.


За последние полгода мне часто приходилось общаться с пользователями ReactJS.NET по поводу ошибок, которые возникают из-за JavaScript Engine Switcher. В 80% случаев это были не ошибки, а просто неправильное использование библиотеки, вызванное заблуждениями о том, как она работает. В этом посте я рассмотрю большую часть из этих заблуждений.


MSIE


Для корректной работы модуля JavaScriptEngineSwitcher.Msie достаточно, чтобы на компьютере был установлен Internet Explorer.


На данный момент, большинство JS-библиотек написано на ECMAScript 5 (библиотека React также не является исключением). Полная поддержка стандарта ECMAScript 5 появилась в Internet Explorer только начиная с 9-й версии, когда был выпущен новый JavaScript-движок — Chakra.


Если вы запустите ReactJS.NET в связке с модулем JavaScriptEngineSwitcher.Msie на компьютере, на котором установлен Internet Explorer 8 или ниже, то получите ошибку наподобие этой:


Object doesn't support this property or method

Поэтому, всегда следует использовать JavaScriptEngineSwitcher.Msie только на компьютерах, на которых установлен Internet Explorer 9+ или Microsoft Edge. В идеале на компьютере разработчика и продакшн-сервере должна быть установлена одна и та же версия браузера.


Если у вас нет возможности установить на сервере современную версию браузера, то начните использовать модуль JavaScriptEngineSwitcher.ChakraCore.


V8


  1. Для модуля JavaScriptEngineSwitcher.V8 необходимы сборки msvcp120.dll и msvcr120.dll из распространяемых пакетов Visual C++ для Visual Studio 2013.


    Начиная с версии 2.2.0 нативные сборки модуля JavaScriptEngineSwitcher.V8 зависят от сборки msvcp140.dll из распространяемого пакета Visual C++ для Visual Studio 2015.

  2. Пакет JavaScriptEngineSwitcher.V8 больше не содержит нативных сборок, и поэтому в дополнение к нему вам необходимо установить пакет ClearScript.V8.


    Действительно, начиная с версии 2.1.0 пакет JavaScriptEngineSwitcher.V8 не содержит нативных сборок для Windows, но эти сборки никуда не пропали, а были перемещены в отдельные пакеты: JavaScriptEngineSwitcher.V8.Native.win-x86 и JavaScriptEngineSwitcher.V8.Native.win-x64. Поэтому вам не нужно устанавливать пакет ClearScript.V8, который не имеет никакого отношения к JavaScript Engine Switcher. Вообще, использование пакета ClearScript.V8 вместе с JavaScriptEngineSwitcher.V8 приводит к ошибкам.

  3. После установки пакетов JavaScriptEngineSwitcher.V8.Native.* необходимо вручную скопировать нативные сборки в каталог приложения, потому что это рекомендуется авторами ClearScript.


    После установки этих пакетов не нужно выполнять каких-либо дополнительных действий, и это является основным преимуществом JavaScriptEngineSwitcher.V8. Установка нативных сборок производится с помощью следующих средств:


    1. Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например, JavaScriptEngineSwitcher.V8.Native.win-x64.props)
    2. Для веб-сайтов ASP.NET 4.X используются скрипты PowerShell (например, Install.ps1 и Uninstall.ps1).
    3. Для приложений .NET Core и веб-приложений ASP.NET Core используется механизм, основанный на каталогах runtimes и идентификаторах сред выполнения (RID).

    В версии JavaScriptEngineSwitcher.V8 для .NET 4.X нативные сборки загружаются из нестандартных каталогов. В данном случае, нативные сборки расположены в подкаталогах x86 и x64 каталога bin\[Debug|Release] (для веб-приложений и сайтов просто каталог bin).

  4. Для 64-разрядной версии Windows достаточно установить только пакет JavaScriptEngineSwitcher.V8.Native.win-x64.


    .NET-приложения, ASP.NET веб-приложения и сайты в 64-разрядной версии Windows могут выполняться не только 64-битных процессах, но и в 32-битных. Для корректной работы JavaScriptEngineSwitcher.V8 в 32-битном процессе необходимо установить пакет JavaScriptEngineSwitcher.V8.Native.win-x86. Если вы не знаете в каком процессе будет выполняться ваше приложение или веб-сайт, то установите оба пакета.


ChakraCore


  1. Для корректной работы модуля JavaScriptEngineSwitcher.ChakraCore в ОС Windows необходимы сборки msvcp120.dll и msvcr120.dll из распространяемых пакетов Visual C++ для Visual Studio 2013.


    Начиная с версии 2.1.0 нативные сборки модуля JavaScriptEngineSwitcher.ChakraCore для Windows зависят от сборки msvcp140.dll из распространяемого пакета Visual C++ для Visual Studio 2015.

  2. Пакет JavaScriptEngineSwitcher.ChakraCore больше не содержит нативных сборок, и поэтому в дополнение к нему вам нужно установить пакет Microsoft.ChakraCore.


    Действительно, начиная с версии 2.1.0 пакет JavaScriptEngineSwitcher.ChakraCore не содержит нативных сборок, но эти сборки никуда не пропали, а были перемещены в отдельные пакеты: JavaScriptEngineSwitcher.ChakraCore.Native.win-x86 и JavaScriptEngineSwitcher.ChakraCore.Native.win-x64. Поэтому вам не нужно устанавливать пакет Microsoft.ChakraCore, который не имеет никакого отношения к JavaScript Engine Switcher.


    В дополнение к этим двум пакетам также доступны еще три пакета:


    • JavaScriptEngineSwitcher.ChakraCore.Native.win8-arm содержит нативную сборку для ARM-версий Windows. Данный пакет совместим только с .NET Core и .NET Framework 4.5.
    • JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64 содержит нативную сборку для 64-разрядных дистрибутивов Linux, основанных на Debian (Debian, Ubuntu и Linux Mint). Данный пакет совместим только с .NET Core.
    • JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64 содержит нативную сборку для 64-разрядных версий OS X. Требует установки библиотеки ICU4C. Данный пакет совместим только с .NET Core.

    Если вы используете какой-то другой дистрибутив Linux, то вы можете собрать библиотеку ChakraCore с помощью следующих инструкций из официального репозитория. Только вместо последней версии исходного кода ChakraCore, вам нужно использовать версию, которая поддерживается модулем JavaScriptEngineSwitcher.ChakraCore.

  3. После установки пакетов JavaScriptEngineSwitcher.ChakraCore.Native.* необходимо вручную скопировать нативные сборки в каталог bin.


    После установки этих пакетов не нужно выполнять каких-либо дополнительных действий, и это является основным преимуществом JavaScriptEngineSwitcher.ChakraCore. Установка нативных сборок производится с помощью следующих средств:


    1. Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например, JavaScriptEngineSwitcher.ChakraCore.Native.win-x64.props).
    2. Для веб-сайтов ASP.NET 4.X используются скрипты PowerShell (например, Install.ps1 и Uninstall.ps1).
    3. Для приложений .NET Core и веб-приложений ASP.NET Core используется механизм, основанный на каталогах runtimes и идентификаторах сред выполнения (RID).

    В версии JavaScriptEngineSwitcher.ChakraCore для .NET 4.X переопределяются стандартные пути для поиска нативных сборок. В данном случае, нативные сборки расположены в подкаталогах x86, x64 и arm каталога bin\[Debug|Release] (для веб-приложений и сайтов просто каталог bin).

  4. Для 64-разрядной версии Windows достаточно установить только пакет JavaScriptEngineSwitcher.ChakraCore.Native.win-x64.


    .NET приложения, ASP.NET веб-приложения и сайты в 64-разрядной Windows могут выполняться не только в 64-битных процессах, но и в 32-битных. Для корректной работы модуля JavaScriptEngineSwitcher.ChakraCore в 32-битном процессе нужно установить пакет JavaScriptEngineSwitcher.ChakraCore.Native.win-x86. Если вы не знаете в каком процессе будет выполняться ваше приложение или веб-сайт, тогда устанавливайте оба пакета.


P.S.: Чтобы избежать подобных заблуждений в будущем, я рекомендую вам хотя бы бегло читать разделы «Release Notes» обновляемых NuGet пакетов. В случае, когда проблемы уже возникли, читайте CHANGELOG.md или раздел «Releases» в репозитории проекта на GitHub. Также не стоит забывать про документацию и багтрекер.

Комментарии (0)