Английскую версию данного поста я написал еще в мае и опубликовал ее в багтрекере проекта 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
Для модуля JavaScriptEngineSwitcher.V8 необходимы сборки
msvcp120.dll
иmsvcr120.dll
из распространяемых пакетов Visual C++ для Visual Studio 2013.
Начиная с версии 2.2.0 нативные сборки модуля JavaScriptEngineSwitcher.V8 зависят от сборки
msvcp140.dll
из распространяемого пакета Visual C++ для Visual Studio 2015.Пакет 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 приводит к ошибкам.
После установки пакетов
JavaScriptEngineSwitcher.V8.Native.*
необходимо вручную скопировать нативные сборки в каталог приложения, потому что это рекомендуется авторами ClearScript.
После установки этих пакетов не нужно выполнять каких-либо дополнительных действий, и это является основным преимуществом JavaScriptEngineSwitcher.V8. Установка нативных сборок производится с помощью следующих средств:
- Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например,
JavaScriptEngineSwitcher.V8.Native.win-x64.props
) - Для веб-сайтов ASP.NET 4.X используются скрипты PowerShell (например,
Install.ps1
иUninstall.ps1
). - Для приложений .NET Core и веб-приложений ASP.NET Core используется механизм, основанный на каталогах
runtimes
и идентификаторах сред выполнения (RID).
В версии JavaScriptEngineSwitcher.V8 для .NET 4.X нативные сборки загружаются из нестандартных каталогов. В данном случае, нативные сборки расположены в подкаталогах
x86
иx64
каталогаbin\[Debug|Release]
(для веб-приложений и сайтов просто каталогbin
).- Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например,
Для 64-разрядной версии Windows достаточно установить только пакет JavaScriptEngineSwitcher.V8.Native.win-x64.
.NET-приложения, ASP.NET веб-приложения и сайты в 64-разрядной версии Windows могут выполняться не только 64-битных процессах, но и в 32-битных. Для корректной работы JavaScriptEngineSwitcher.V8 в 32-битном процессе необходимо установить пакет JavaScriptEngineSwitcher.V8.Native.win-x86. Если вы не знаете в каком процессе будет выполняться ваше приложение или веб-сайт, то установите оба пакета.
ChakraCore
Для корректной работы модуля 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.Пакет 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.
После установки пакетов
JavaScriptEngineSwitcher.ChakraCore.Native.*
необходимо вручную скопировать нативные сборки в каталогbin
.
После установки этих пакетов не нужно выполнять каких-либо дополнительных действий, и это является основным преимуществом JavaScriptEngineSwitcher.ChakraCore. Установка нативных сборок производится с помощью следующих средств:
- Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например,
JavaScriptEngineSwitcher.ChakraCore.Native.win-x64.props
). - Для веб-сайтов ASP.NET 4.X используются скрипты PowerShell (например,
Install.ps1
иUninstall.ps1
). - Для приложений .NET Core и веб-приложений ASP.NET Core используется механизм, основанный на каталогах
runtimes
и идентификаторах сред выполнения (RID).
В версии JavaScriptEngineSwitcher.ChakraCore для .NET 4.X переопределяются стандартные пути для поиска нативных сборок. В данном случае, нативные сборки расположены в подкаталогах
x86
,x64
иarm
каталогаbin\[Debug|Release]
(для веб-приложений и сайтов просто каталогbin
).- Для приложений .NET 4.X и веб-приложений ASP.NET 4.X используются скрипты MSBuild (например,
Для 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. Также не стоит забывать про документацию и багтрекер.