- PVSM.RU - https://www.pvsm.ru -

Заблуждения о JavaScript Engine Switcher 2.X

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

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

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

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

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

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

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

MSIE

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

На данный момент, большинство JS-библиотек написано на ECMAScript 5 (библиотека React [5] также не является исключением). Полная поддержка стандарта 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 [23].

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

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

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

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

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

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

    В версии JavaScriptEngineSwitcher.V8 для .NET 4.X нативные сборки загружаются из нестандартных каталогов [37]. В данном случае, нативные сборки расположены в подкаталогах 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 [38].

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

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

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

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

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

    Если вы используете какой-то другой дистрибутив Linux, то вы можете собрать библиотеку ChakraCore с помощью следующих инструкций из официального репозитория [46]. Только вместо последней версии исходного кода 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 [47]).
    2. Для веб-сайтов ASP.NET 4.X используются скрипты PowerShell (например, Install.ps1 [48] и Uninstall.ps1 [49]).
    3. Для приложений .NET Core и веб-приложений ASP.NET Core используется механизм, основанный на каталогах runtimes и идентификаторах сред выполнения (RID) [36].

    В версии JavaScriptEngineSwitcher.ChakraCore для .NET 4.X переопределяются стандартные пути для поиска [50] нативных сборок. В данном случае, нативные сборки расположены в подкаталогах 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 [51] или раздел «Releases» [52] в репозитории проекта на GitHub. Также не стоит забывать про документацию [53] и багтрекер [54].

Автор: Taritsyn

Источник [55]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/265014

Ссылки в тексте:

[1] Английскую версию данного поста: https://github.com/reactjs/React.NET/issues/409

[2] 13-й встречи MskDotNet Community: https://mskdotnet.timepad.ru/event/586426/

[3] ReactJS.NET: https://github.com/reactjs/React.NET

[4] JavaScript Engine Switcher: https://github.com/Taritsyn/JavaScriptEngineSwitcher

[5] React: https://facebook.github.io/react/

[6] Less.js: https://github.com/less/less.js

[7] dotless: http://www.dotlesscss.org/

[8] MSIE JavaScript Engine for .Net: https://github.com/Taritsyn/MsieJavaScriptEngine

[9] Microsoft ClearScript.V8: https://github.com/Microsoft/ClearScript

[10] Jurassic: https://github.com/paulbartrum/jurassic

[11] Jint: https://github.com/sebastienros/jint

[12] ChakraCore: https://github.com/Microsoft/ChakraCore

[13] JavaScriptEngineSwitcher.Core: http://www.nuget.org/packages/JavaScriptEngineSwitcher.Core

[14] Bundle Transformer: https://github.com/Taritsyn/BundleTransformer

[15] React.Core: https://www.nuget.org/packages/React.Core/

[16] MSIE: https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/JS-Engine-Switcher:-MSIE

[17] V8: https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/JS-Engine-Switcher:-V8

[18] ChakraCore: https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/JS-Engine-Switcher:-ChakraCore

[19] попытки создать экземпляр одного из вышеперечисленных движков: https://github.com/reactjs/React.NET/blob/2752d9d66ea7a9cffefb2748a02e20695e90de30/src/React.Core/JavaScriptEngineFactory.cs#L261-L285

[20] зарегистрировать JS-движки: https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/Registration-of-JS-engines

[21] по упрощенной схеме: https://github.com/reactjs/React.NET/blob/2752d9d66ea7a9cffefb2748a02e20695e90de30/src/React.Core/JavaScriptEngineFactory.cs#L245-L259

[22] постов в блогах: https://pilpag.blogspot.ru/2017/03/reactjsnet-30-and-error-object-doesnt.html

[23] распространяемых пакетов Visual C++ для Visual Studio 2013: https://www.microsoft.com/en-us/download/details.aspx?id=40784

[24] версии 2.2.0: https://github.com/Taritsyn/JavaScriptEngineSwitcher/releases/tag/v2.2.0

[25] распространяемого пакета Visual C++ для Visual Studio 2015: https://www.microsoft.com/en-us/download/details.aspx?id=53840

[26] JavaScriptEngineSwitcher.V8: https://www.nuget.org/packages/JavaScriptEngineSwitcher.V8/

[27] ClearScript.V8: https://www.nuget.org/packages/ClearScript.V8/

[28] версии 2.1.0: https://github.com/Taritsyn/JavaScriptEngineSwitcher/releases/tag/v2.1.0

[29] JavaScriptEngineSwitcher.V8.Native.win-x86: https://www.nuget.org/packages/JavaScriptEngineSwitcher.V8.Native.win-x86/

[30] JavaScriptEngineSwitcher.V8.Native.win-x64: https://www.nuget.org/packages/JavaScriptEngineSwitcher.V8.Native.win-x64/

[31] ошибкам: https://github.com/Taritsyn/JavaScriptEngineSwitcher/issues/29

[32] это рекомендуется авторами ClearScript: https://microsoft.github.io/ClearScript/Details/Build.html

[33] JavaScriptEngineSwitcher.V8.Native.win-x64.props: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.V8.Native.win-x64/build/JavaScriptEngineSwitcher.V8.Native.win-x64.props

[34] Install.ps1: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.V8.Native.win-x64/tools/Install.ps1

[35] Uninstall.ps1: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.V8.Native.win-x64/tools/Uninstall.ps1

[36] идентификаторах сред выполнения (RID): https://docs.microsoft.com/ru-ru/dotnet/core/rid-catalog

[37] загружаются из нестандартных каталогов: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/src/JavaScriptEngineSwitcher.V8/AssemblyResolver.cs#L30-L67

[38] распространяемых пакетов Visual C++ для Visual Studio 2013: http://www.microsoft.com/en-us/download/details.aspx?id=40784

[39] JavaScriptEngineSwitcher.ChakraCore: https://www.nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore/

[40] Microsoft.ChakraCore: https://www.nuget.org/packages/Microsoft.ChakraCore/

[41] JavaScriptEngineSwitcher.ChakraCore.Native.win-x86: https://www.nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore.Native.win-x86/

[42] JavaScriptEngineSwitcher.ChakraCore.Native.win-x64: https://www.nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore.Native.win-x64/

[43] JavaScriptEngineSwitcher.ChakraCore.Native.win8-arm: http://nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore.Native.win8-arm

[44] JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64: http://nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore.Native.debian-x64

[45] JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64: http://nuget.org/packages/JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64

[46] инструкций из официального репозитория: https://github.com/Microsoft/ChakraCore/wiki/Building-ChakraCore#linux

[47] JavaScriptEngineSwitcher.ChakraCore.Native.win-x64.props: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.ChakraCore.Native.win-x64/build/JavaScriptEngineSwitcher.ChakraCore.Native.win-x64.props

[48] Install.ps1: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.ChakraCore.Native.win-x64/tools/Install.ps1

[49] Uninstall.ps1: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/NuGet/JavaScriptEngineSwitcher.ChakraCore.Native.win-x64/tools/Uninstall.ps1

[50] переопределяются стандартные пути для поиска: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/src/JavaScriptEngineSwitcher.ChakraCore/AssemblyResolver.cs#L34-L72

[51] CHANGELOG.md: https://github.com/Taritsyn/JavaScriptEngineSwitcher/blob/master/CHANGELOG.md

[52] «Releases»: https://github.com/Taritsyn/JavaScriptEngineSwitcher/releases

[53] документацию: https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki

[54] багтрекер: https://github.com/Taritsyn/JavaScriptEngineSwitcher/issues

[55] Источник: https://habrahabr.ru/post/339440/