Merge pull request #101 from nventive/dev/jela/node-js

Add node.js support
This commit is contained in:
Jérôme Laban 2019-06-14 09:33:52 -04:00 коммит произвёл GitHub
Родитель 5f955b34ba ea914bb32d
Коммит 82b2bcb679
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
28 изменённых файлов: 676 добавлений и 85 удалений

Просмотреть файл

@ -32,12 +32,18 @@ jobs:
npm install
cd $(build.sourcesdirectory)/src/Uno.Wasm.DynamicLinking.UITests
npm install
cd $(build.sourcesdirectory)/src/Uno.Wasm.Node.Sample.Runner
npm install
displayName: UI Tests npm dependencies
- powershell: .\build\build.ps1 -script build\build.cake
displayName: Build
- powershell: |
cd $(build.sourcesdirectory)/src/Uno.Wasm.Node.Sample.Runner
.\Validate.ps1
- task: CopyFiles@2
inputs:
SourceFolder: $(build.sourcesdirectory)

Просмотреть файл

@ -227,6 +227,32 @@ The parameters for the compression are as follows:
Note that the pre-compressed files are optional, and if the rewriting rules are removed or not used (because the site is served without IIS), the original files are available at their normal locations.
### Node.js support
The bootstrapper supports having a project loaded as part of a node application. To do so:
- Create a Wasm bootstrapper project, named `MyApp.Wasm`
- Create a Node.js TypeScript project in Visual Studio, named `MyApp.Runner`
- In boostrapper project, add the following :
```xml
<WasmShellDistPath>../MyApp.Runner/app</WasmShellDistPath>
<WasmShellMode>node</WasmShellMode>
```
- In the `app.ts`, add the following:
```js
require("./app/mono");
```
Run the application and the main method of the `MyApp.Wasm` will be executed.
The parameters of the node command line are provided to the app's main method, when running the app as follows:
```
node app param1 param2
```
An example of the node.js support is available in the `Uno.Wasm.Node.Sample` and `Uno.Wasm.Node.Sample.Runner.njsproj` projects.
### Support for additional JS files
Providing additional JS files is done through the inclusion of `EmbeddedResource` msbuild item files, in a project folder named `WasmScripts`.
Files are processed as embedded resources to allow for libraries to provide javascript files.

Просмотреть файл

@ -39,6 +39,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.DynamicLinking", "
EndProject
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Uno.Wasm.DynamicLinking.UITests", "Uno.Wasm.DynamicLinking.UITests\Uno.Wasm.DynamicLinking.UITests.njsproj", "{4A68C463-ADB6-48FB-BC22-F52A97F2FDBE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Wasm.Node.Sample", "Uno.Wasm.Node.Sample\Uno.Wasm.Node.Sample.csproj", "{B98B35A0-181C-4151-9671-6B9D207D40A6}"
EndProject
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "Uno.Wasm.Node.Sample.Runner", "Uno.Wasm.Node.Sample.Runner\Uno.Wasm.Node.Sample.Runner.njsproj", "{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB}"
ProjectSection(ProjectDependencies) = postProject
{B98B35A0-181C-4151-9671-6B9D207D40A6} = {B98B35A0-181C-4151-9671-6B9D207D40A6}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -97,6 +104,14 @@ Global
{4A68C463-ADB6-48FB-BC22-F52A97F2FDBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A68C463-ADB6-48FB-BC22-F52A97F2FDBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A68C463-ADB6-48FB-BC22-F52A97F2FDBE}.Release|Any CPU.Build.0 = Release|Any CPU
{B98B35A0-181C-4151-9671-6B9D207D40A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B98B35A0-181C-4151-9671-6B9D207D40A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B98B35A0-181C-4151-9671-6B9D207D40A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B98B35A0-181C-4151-9671-6B9D207D40A6}.Release|Any CPU.Build.0 = Release|Any CPU
{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -113,6 +128,8 @@ Global
{B4C15C47-85E2-444E-B9F3-D970E35601A9} = {BA079449-9703-42D1-9B7B-B534C2D1DB88}
{8CF49D1D-ED83-41AE-B2D5-1F8B1EBB4BE6} = {35E84E5F-1C9B-4168-8333-216B456C12DF}
{4A68C463-ADB6-48FB-BC22-F52A97F2FDBE} = {BA079449-9703-42D1-9B7B-B534C2D1DB88}
{B98B35A0-181C-4151-9671-6B9D207D40A6} = {35E84E5F-1C9B-4168-8333-216B456C12DF}
{A5FB0E0F-0B2C-451A-9642-E371DE7AFCBB} = {35E84E5F-1C9B-4168-8333-216B456C12DF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FA350FE9-9316-4846-8145-356F9A0ACBC7}

Просмотреть файл

@ -0,0 +1,28 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
//
// This file is based on the work from https://github.com/praeclarum/Ooui
//
namespace Uno.Wasm.Bootstrap
{
internal enum ShellMode
{
Browser,
Node,
}
}

Просмотреть файл

@ -47,6 +47,7 @@ namespace Uno.Wasm.Bootstrap
private string[] _additionalStyles;
private List<AssemblyDefinition> _referencedAssemblyDefinitions;
private RuntimeExecutionMode _runtimeExecutionMode;
private ShellMode _shellMode;
[Microsoft.Build.Framework.Required]
public string CurrentProjectPath { get; set; }
@ -55,7 +56,7 @@ namespace Uno.Wasm.Bootstrap
public string Assembly { get; set; }
[Microsoft.Build.Framework.Required]
public string OutputPath { get; set; }
public string DistPath { get; set; }
[Microsoft.Build.Framework.Required]
public string IntermediateOutputPath { get; set; }
@ -83,6 +84,9 @@ namespace Uno.Wasm.Bootstrap
[Microsoft.Build.Framework.Required]
public string IndexHtmlPath { get; set; }
[Required]
public string WasmShellMode { get; set; }
[Microsoft.Build.Framework.Required]
public string MonoRuntimeExecutionMode { get; set; }
@ -133,7 +137,7 @@ namespace Uno.Wasm.Bootstrap
// Debugger.Launch();
ParseRuntimeExecutionMode();
ParseProperties();
GetBcl();
CreateDist();
CopyContent();
@ -146,6 +150,7 @@ namespace Uno.Wasm.Bootstrap
GenerateHtml();
CleanupDist();
GenerateConfig();
MergeConfig();
TouchServiceWorker();
TryCompressDist();
@ -539,16 +544,10 @@ namespace Uno.Wasm.Bootstrap
}
}
private void ParseRuntimeExecutionMode()
private void ParseProperties()
{
if (Enum.TryParse<RuntimeExecutionMode>(MonoRuntimeExecutionMode, out _runtimeExecutionMode))
{
Log.LogMessage(MessageImportance.Low, $"MonoRuntimeExecutionMode={MonoRuntimeExecutionMode}");
}
else
{
throw new NotSupportedException($"The MonoRuntimeExecutionMode {MonoRuntimeExecutionMode} is not supported");
}
ParseEnumProperty(nameof(WasmShellMode), WasmShellMode, out _shellMode);
ParseEnumProperty(nameof(MonoRuntimeExecutionMode), MonoRuntimeExecutionMode, out _runtimeExecutionMode);
}
private void BuildReferencedAssembliesList()
@ -646,8 +645,7 @@ namespace Uno.Wasm.Bootstrap
private void CreateDist()
{
var outputPath = Path.GetFullPath(OutputPath);
_distPath = Path.Combine(outputPath, "dist");
_distPath = Path.GetFullPath(DistPath);
_managedPath = Path.Combine(_distPath, "managed");
Directory.CreateDirectory(_managedPath);
}
@ -864,6 +862,45 @@ namespace Uno.Wasm.Bootstrap
}
}
private void MergeConfig()
{
if(_shellMode == ShellMode.Node)
{
var tempFile = Path.GetTempFileName();
try
{
var monoJsPath = Path.Combine(_distPath, "mono.js");
using (var fs = new StreamWriter(tempFile))
{
fs.Write(File.ReadAllText(Path.Combine(_distPath, "mono-config.js")));
fs.Write(File.ReadAllText(Path.Combine(_distPath, "uno-config.js")));
fs.Write(File.ReadAllText(Path.Combine(_distPath, "uno-bootstrap.js")));
fs.Write(File.ReadAllText(monoJsPath));
}
File.Delete(monoJsPath);
File.Move(tempFile, monoJsPath);
Log.LogMessage($"Merged config files with mono.js");
}
finally
{
try
{
if (File.Exists(tempFile))
{
File.Delete(tempFile);
}
}
catch(Exception e)
{
Console.WriteLine($"Failed to delete temporary file: {e}");
}
}
}
}
private IEnumerable<string> GetPWACacheableFiles()
=> from file in Directory.EnumerateFiles(_distPath, "*.*", SearchOption.AllDirectories)
where !file.EndsWith("web.config", StringComparison.OrdinalIgnoreCase)
@ -925,6 +962,11 @@ namespace Uno.Wasm.Bootstrap
private void GenerateHtml()
{
if (_shellMode != ShellMode.Browser)
{
return;
}
var htmlPath = Path.Combine(_distPath, "index.html");
using (var w = new StreamWriter(htmlPath, false, new UTF8Encoding(false)))
@ -947,13 +989,12 @@ namespace Uno.Wasm.Bootstrap
Log.LogMessage($"HTML {htmlPath}");
}
}
}
private void GeneratePrefetchHeaderContent(StringBuilder extraBuilder)
{
if (GeneratePrefetchHeaders)
if (_shellMode == ShellMode.Browser && GeneratePrefetchHeaders)
{
extraBuilder.AppendLine($"<link rel=\"prefetch\" href=\"mono.wasm\" />");
@ -967,6 +1008,11 @@ namespace Uno.Wasm.Bootstrap
private void GeneratePWAContent(StringBuilder extraBuilder)
{
if (_shellMode != ShellMode.Browser)
{
return;
}
if (!string.IsNullOrWhiteSpace(PWAManifestFile))
{
var manifestDocument = JObject.Parse(File.ReadAllText(PWAManifestFile));
@ -993,5 +1039,17 @@ namespace Uno.Wasm.Bootstrap
}
}
}
private void ParseEnumProperty<TEnum>(string name, string stringValue, out TEnum value) where TEnum : struct
{
if (Enum.TryParse<TEnum>(stringValue, true, out value))
{
Log.LogMessage(MessageImportance.Low, $"{name}={value}");
}
else
{
throw new NotSupportedException($"The {name} {value} is not supported");
}
}
}
}

Просмотреть файл

@ -30,7 +30,14 @@ var Module = {
// There's no way to get the filename from mono.js right now.
// so we just hardcode it.
const wasmUrl = config.mono_wasm_runtime || "mono.wasm";
if (typeof WebAssembly.instantiateStreaming === 'function') {
if (ENVIRONMENT_IS_NODE) {
return WebAssembly
.instantiate(getBinary(), imports)
.then(results => {
successCallback(results.instance);
});
} else if (typeof WebAssembly.instantiateStreaming === 'function') {
App.fetchWithProgress(
wasmUrl,
loaded => App.reportProgressWasmLoading(loaded))
@ -88,6 +95,8 @@ var MonoRuntime = {
this.invoke_method = Module.cwrap("mono_wasm_invoke_method", "number", ["number", "number", "number"]);
this.mono_string_get_utf8 = Module.cwrap("mono_wasm_string_get_utf8", "number", ["number"]);
this.mono_string = Module.cwrap("mono_wasm_string_from_js", "number", ["string"]);
this.mono_wasm_obj_array_new = Module.cwrap("mono_wasm_obj_array_new", "number", ["number"]);
this.mono_wasm_obj_array_set = Module.cwrap("mono_wasm_obj_array_set", null, ["number", "number", "number"]);
},
conv_string: function (mono_obj) {
@ -140,8 +149,16 @@ var App = {
try {
App.attachDebuggerHotkey(config.file_list);
MonoRuntime.init();
BINDING.bindings_lazy_init();
BINDING.call_static_method(config.uno_main, []);
if (ENVIRONMENT_IS_NODE) {
var mainMethod = BINDING.resolve_method_fqn(config.uno_main);
var array = BINDING.js_array_to_mono_array(process.argv);
MonoRuntime.call_method(mainMethod, null, [array]);
}
else {
BINDING.call_static_method(config.uno_main, []);
}
} catch (e) {
console.error(e);
}
@ -303,20 +320,41 @@ var App = {
asset = asset.replace("/managed/", `/${config.uno_remote_managedpath}/`);
if (!config.enable_debugging) {
// Assembly fetch streaming is disabled during debug, it seems to
// interfere with the ability for mono or the chrome debugger to
// initialize the debugging session properly. Streaming in debug is
// not particularly interesting, so we can skip it.
if (ENVIRONMENT_IS_NODE) {
var fs = require('fs');
const assemblyName = asset.substring(asset.lastIndexOf("/") + 1);
if (config.assemblies_with_size.hasOwnProperty(assemblyName)) {
return this
.fetchWithProgress(asset, (loaded, adding) => this.reportAssemblyLoading(adding));
console.log('Loading... ' + asset);
var binary = fs.readFileSync(asset);
var resolve_func2 = function (resolve, reject) {
resolve(new Uint8Array(binary));
};
var resolve_func1 = function (resolve, reject) {
var response = {
ok: true,
url: asset,
arrayBuffer: function () {
return new Promise(resolve_func2);
}
};
resolve(response);
};
return new Promise(resolve_func1);
} else {
if (!config.enable_debugging) {
// Assembly fetch streaming is disabled during debug, it seems to
// interfere with the ability for mono or the chrome debugger to
// initialize the debugging session properly. Streaming in debug is
// not particularly interesting, so we can skip it.
const assemblyName = asset.substring(asset.lastIndexOf("/") + 1);
if (config.assemblies_with_size.hasOwnProperty(assemblyName)) {
return this
.fetchWithProgress(asset, (loaded, adding) => this.reportAssemblyLoading(adding));
}
}
else {
return fetch(asset);
}
}
else {
return fetch(asset);
}
},
@ -338,29 +376,37 @@ var App = {
++pending;
if (config.enable_debugging) console.log(`Loading dependency (${dependency})`);
require(
[dependency],
instance => {
let processDependency = instance => {
// If the module is built on emscripten, intercept its loading.
if (instance && instance.HEAP8 !== undefined) {
// If the module is built on emscripten, intercept its loading.
if (instance && instance.HEAP8 !== undefined) {
const existingInitializer = instance.onRuntimeInitialized;
const existingInitializer = instance.onRuntimeInitialized;
if (config.enable_debugging) console.log(`Waiting for dependency (${dependency}) initialization`);
if (config.enable_debugging) console.log(`Waiting for dependency (${dependency}) initialization`);
instance.onRuntimeInitialized = () => {
checkDone(dependency);
if (existingInitializer)
existingInitializer();
};
}
else {
instance.onRuntimeInitialized = () => {
checkDone(dependency);
}
if (existingInitializer)
existingInitializer();
};
}
);
else {
checkDone(dependency);
}
};
if (ENVIRONMENT_IS_NODE) {
dependency = './' + dependency;
processDependency(require(dependency));
}
else {
require(
[dependency],
processDependency
);
}
});
}
else {
@ -374,41 +420,43 @@ var App = {
attachDebuggerHotkey: function (loadAssemblyUrls) {
//
// Imported from https://github.com/aspnet/Blazor/tree/release/0.7.0
//
// History:
// 2019-01-14: Adjustments to make the debugger helper compatible with Uno.Bootstrap.
//
if (ENVIRONMENT_IS_WEB) {
//
// Imported from https://github.com/aspnet/Blazor/tree/release/0.7.0
//
// History:
// 2019-01-14: Adjustments to make the debugger helper compatible with Uno.Bootstrap.
//
App.currentBrowserIsChrome = window.chrome
&& navigator.userAgent.indexOf("Edge") < 0; // Edge pretends to be Chrome
App.currentBrowserIsChrome = window.chrome
&& navigator.userAgent.indexOf("Edge") < 0; // Edge pretends to be Chrome
hasReferencedPdbs = loadAssemblyUrls
.some(function (url) { return /\.pdb$/.test(url); });
hasReferencedPdbs = loadAssemblyUrls
.some(function (url) { return /\.pdb$/.test(url); });
// Use the combination shift+alt+D because it isn't used by the major browsers
// for anything else by default
const altKeyName = navigator.platform.match(/^Mac/i) ? "Cmd" : "Alt";
// Use the combination shift+alt+D because it isn't used by the major browsers
// for anything else by default
const altKeyName = navigator.platform.match(/^Mac/i) ? "Cmd" : "Alt";
if (App.hasDebuggingEnabled()) {
console.info(`Debugging hotkey: Shift+${altKeyName}+D (when application has focus)`);
}
// Even if debugging isn't enabled, we register the hotkey so we can report why it's not enabled
document.addEventListener("keydown", function (evt) {
if (evt.shiftKey && (evt.metaKey || evt.altKey) && evt.code === "KeyD") {
if (!hasReferencedPdbs) {
console.error("Cannot start debugging, because the application was not compiled with debugging enabled.");
}
else if (!App.currentBrowserIsChrome) {
console.error("Currently, only Chrome is supported for debugging.");
}
else {
App.launchDebugger();
}
if (App.hasDebuggingEnabled()) {
console.info(`Debugging hotkey: Shift+${altKeyName}+D (when application has focus)`);
}
});
// Even if debugging isn't enabled, we register the hotkey so we can report why it's not enabled
document.addEventListener("keydown", function (evt) {
if (evt.shiftKey && (evt.metaKey || evt.altKey) && evt.code === "KeyD") {
if (!hasReferencedPdbs) {
console.error("Cannot start debugging, because the application was not compiled with debugging enabled.");
}
else if (!App.currentBrowserIsChrome) {
console.error("Currently, only Chrome is supported for debugging.");
}
else {
App.launchDebugger();
}
}
});
}
},
launchDebugger: function () {
@ -441,12 +489,15 @@ if (config.dynamicLibraries) {
Module.dynamicLibraries = config.dynamicLibraries;
}
document.addEventListener("DOMContentLoaded", () => App.preInit());
if (ENVIRONMENT_IS_WEB) {
if (config.enable_pwa && 'serviceWorker' in navigator) {
console.log('Registering service worker now');
navigator.serviceWorker.register('/service-worker.js')
.then(function () {
console.log('Service Worker Registered');
});
document.addEventListener("DOMContentLoaded", () => App.preInit());
if (config.enable_pwa && 'serviceWorker' in navigator) {
console.log('Registering service worker now');
navigator.serviceWorker.register('/service-worker.js')
.then(function () {
console.log('Service Worker Registered');
});
}
}

Просмотреть файл

@ -9,6 +9,7 @@
<WasmShellIndexHtmlPath Condition="!Exists('$(_packageBinaryPath)')">$(MSBuildThisFileDirectory)../Templates/index.html</WasmShellIndexHtmlPath>
<WasmShellIndexHtmlPath Condition="Exists('$(_packageBinaryPath)') and '$(WasmShellIndexHtmlPath)'==''">$(MSBuildThisFileDirectory)../tools/templates/index.html</WasmShellIndexHtmlPath>
<WasmShellMode Condition="'$(WasmShellMode)'==''">browser</WasmShellMode>
<MonoWasmRuntimeConfiguration Condition="'$(MonoWasmRuntimeConfiguration)'==''">release</MonoWasmRuntimeConfiguration>
<MonoRuntimeDebuggerEnabled Condition="'$(MonoRuntimeDebuggerEnabled)'==''">false</MonoRuntimeDebuggerEnabled>
<WasmShellILLinkerEnabled Condition="'$(WasmShellILLinkerEnabled)'==''">true</WasmShellILLinkerEnabled>
@ -102,6 +103,11 @@
Condition="'%(Extension)' == '.dll'" />
</ItemGroup>
<PropertyGroup>
<!-- Defined here because OutputPath is defined late -->
<WasmShellDistPath Condition="'$(WasmShellDistPath)'==''">$(OutputPath)/dist</WasmShellDistPath>
</PropertyGroup>
<UnoInstallSDKTask_v0
MonoWasmSDKUri="$(MonoWasmSDKUri)"
MonoWasmAOTSDKUri="$(MonoWasmAOTSDKUri)"
@ -119,9 +125,10 @@
<ShellTask_v0
CurrentProjectPath="$(MSBuildProjectDirectory)"
Assembly="$(IntermediateOutputPath)$(TargetFileName)"
OutputPath="$(OutputPath)"
DistPath="$(WasmShellDistPath)"
IntermediateOutputPath="$(ProjectDir)$(IntermediateOutputPath)"
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
WasmShellMode="$(WasmShellMode)"
MonoWasmSDKPath="$(_UnoMonoSdkPath)"
PackagerBinPath="$(_UnoMonoPackagerBinPath)"
UseFileIntegrity="$(WashShellUseFileIntegrity)"

Просмотреть файл

@ -6,6 +6,10 @@
"author": {
"name": ""
},
"scripts": {
"build": "tsc --build",
"clean": "tsc --build --clean"
},
"devDependencies": {
"@types/node": "^8.0.14"
},

1
src/Uno.Wasm.Node.Sample.Runner/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
app

Просмотреть файл

@ -0,0 +1,3 @@
# Uno.Wasm.Node.Sample.Runner

Просмотреть файл

@ -0,0 +1,82 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Name>Uno.Wasm.Node.Sample.Runner</Name>
<RootNamespace>Uno.Wasm.Node.Sample.Runner</RootNamespace>
<TypeScriptToolsVersion>3.5</TypeScriptToolsVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>a5fb0e0f-0b2c-451a-9642-e371de7afcbb</ProjectGuid>
<ProjectHome>.</ProjectHome>
<StartupFile>app.ts</StartupFile>
<StartWebBrowser>False</StartWebBrowser>
<SearchPath>
</SearchPath>
<WorkingDirectory>.</WorkingDirectory>
<OutputPath>.</OutputPath>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
<EnableTypeScript>true</EnableTypeScript>
<StartWebBrowser>false</StartWebBrowser>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<None Include="app.ts" />
<Content Include="package.json" />
<Content Include="README.md" />
<Content Include="tsconfig.json" />
</ItemGroup>
<!-- Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them. -->
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" Condition="Exists('$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets')" />
<Target Name="Restore" />
<Target Name="Publish" />
<Target Name="Pack" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>0</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:48022/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>True</UseCustomServer>
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}" User="">
<WebProjectProperties>
<StartPageUrl>
</StartPageUrl>
<StartAction>CurrentPage</StartAction>
<AspNetDebugging>True</AspNetDebugging>
<SilverlightDebugging>False</SilverlightDebugging>
<NativeDebugging>False</NativeDebugging>
<SQLDebugging>False</SQLDebugging>
<ExternalProgram>
</ExternalProgram>
<StartExternalURL>
</StartExternalURL>
<StartCmdLineArguments>
</StartCmdLineArguments>
<StartWorkingDirectory>
</StartWorkingDirectory>
<EnableENC>False</EnableENC>
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>

Просмотреть файл

@ -0,0 +1,13 @@
$testParameters = 'test1; test2'
$appOutput = node app test1 test2
echo "App output: "
echo $appOutput
$result = $appOutput | Select-String -Pattern $testParameters -CaseSensitive -SimpleMatch
if(!$result){
throw "Unable to find $($testParameters) in app output";
}

Просмотреть файл

@ -0,0 +1,2 @@
global.Module = require("./app/mono");
//# sourceMappingURL=app.js.map

Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"app.js","sourceRoot":"","sources":["app.ts"],"names":[],"mappings":"AAAM,MAAO,CAAC,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC"}

Просмотреть файл

@ -0,0 +1 @@
(<any>global).Module = require("./app/mono");

20
src/Uno.Wasm.Node.Sample.Runner/package-lock.json сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,20 @@
{
"name": "uno.wasm.node.sample.runner",
"version": "0.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "8.10.49",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.49.tgz",
"integrity": "sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w==",
"dev": true
},
"typescript": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz",
"integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==",
"dev": true
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
{
"name": "uno.wasm.node.sample.runner",
"version": "0.0.0",
"description": "Uno.Wasm.Node.Sample.Runner",
"main": "app.js",
"author": {
"name": ""
},
"scripts": {
"build": "tsc --build",
"clean": "tsc --build --clean"
},
"devDependencies": {
"@types/node": "^8.0.14",
"typescript": "^3.2.2"
}
}

Просмотреть файл

@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"lib": ["es6"],
"sourceMap": true
},
"exclude": [
"node_modules"
]
}

Двоичные данные
src/Uno.Wasm.Node.Sample/Content/LockScreenLogo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Просмотреть файл

@ -0,0 +1,4 @@
<linker>
<assembly fullname="Uno.Wasm.Node.Sample">
</assembly>
</linker>

Просмотреть файл

@ -0,0 +1,36 @@
// ******************************************************************
// Copyright <20> 2015-2018 nventive inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// ******************************************************************
using System;
using WebAssembly;
namespace Uno.Wasm.Sample
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Mono Runtime Mode: " + Environment.GetEnvironmentVariable("UNO_BOOTSTRAP_MONO_RUNTIME_MODE"));
Console.WriteLine($"Arguments: " + string.Join("; ", args));
var i = 42;
var now = DateTime.Now.ToString();
Console.WriteLine($"Main! {i} {now}");
Runtime.InvokeJS($"console.log('Done with main')", out var result);
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System.Runtime.CompilerServices;
namespace WebAssembly
{
internal sealed class Runtime
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern string InvokeJS(string str, out int exceptional_result);
}
}

Просмотреть файл

@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<MonoRuntimeDebuggerEnabled Condition="'$(Configuration)'=='Debug'">true</MonoRuntimeDebuggerEnabled>
<WasmShellDistPath>../Uno.Wasm.Node.Sample.Runner/app</WasmShellDistPath>
<WasmShellMode>node</WasmShellMode>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="System.Collections.Immutable" Version="1.4.0" />
</ItemGroup>
<Import Project="..\Uno.Wasm.Bootstrap\build\Uno.Wasm.Bootstrap.targets" />
<ItemGroup>
<None Include="WasmScripts\**\*.js" />
<None Include="WasmCSS\**\*.css" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="WasmScripts\**\*.js" />
<EmbeddedResource Include="WasmCSS\**\*.css" />
</ItemGroup>
<ItemGroup>
<WasmShellMonoEnvironment Include="MONO_GC_PARAMS" Value="soft-heap-limit=512m,nursery-size=64m,evacuation-threshold=66,major=marksweep" />
<WasmShellMonoEnvironment Include="MONO_LOG_LEVEL" Value="debug" />
<WasmShellMonoEnvironment Include="MONO_LOG_MASK" Value="gc" />
</ItemGroup>
<ItemGroup>
<LinkerDescriptor Include="LinkerConfig.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Uno.Wasm.Bootstrap\Uno.Wasm.Bootstrap.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<UndefineProperties>TargetFramework</UndefineProperties>
</ProjectReference>
<ProjectReference Include="..\Uno.Wasm.Bootstrap.Cli\Uno.Wasm.Bootstrap.Cli.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<UndefineProperties>TargetFramework</UndefineProperties>
</ProjectReference>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,53 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

Просмотреть файл

@ -0,0 +1 @@
console.log("Additional test module");

Просмотреть файл

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
<system.webServer>
<!-- Disable compression as we're doing it throuh pre-compressed files -->
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
<staticContent>
<remove fileExtension=".dll" />
<remove fileExtension=".wasm" />
<remove fileExtension=".woff" />
<remove fileExtension=".woff2" />
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />
<mimeMap fileExtension=".clr" mimeType="application/octet-stream" />
<mimeMap fileExtension=".pdb" mimeType="application/octet-stream" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
<!-- Required for PWAs -->
<mimeMap fileExtension=".json" mimeType="application/octet-stream" />
</staticContent>
<rewrite>
<rules>
<rule name="Lookup for pre-compressed brotli file" stopProcessing="true">
<match url="(.*)$"/>
<conditions>
<!-- Match brotli requests -->
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<!-- Match all but pre-compressed files -->
<add input="{REQUEST_URI}" pattern="^(?!/_compressed_br/)(.*)$" />
<!-- Check if the pre-compressed file exists on the disk -->
<add input="{DOCUMENT_ROOT}/_compressed_br/{C:0}" matchType="IsFile" negate="false" />
</conditions>
<action type="Rewrite" url="/_compressed_br{C:0}" />
</rule>
<rule name="Lookup for pre-compressed gzip file" stopProcessing="true">
<match url="(.*)$"/>
<conditions>
<!-- Match gzip requests -->
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<!-- Match all but pre-compressed files -->
<add input="{REQUEST_URI}" pattern="^(?!/_compressed_gz/)(.*)$" />
<!-- Check if the pre-compressed file exists on the disk -->
<add input="{DOCUMENT_ROOT}/_compressed_gz/{C:0}" matchType="IsFile" negate="false" />
</conditions>
<action type="Rewrite" url="/_compressed_gz{C:0}" />
</rule>
</rules>
<outboundRules>
<rule name="Adjust content encoding for gzip pre-compressed files" enabled="true" stopProcessing="true">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern="" />
<conditions>
<add input="{REQUEST_URI}" pattern="/_compressed_gz/.*$" />
</conditions>
<action type="Rewrite" value="gzip"/>
</rule>
<rule name="Adjust content encoding for brotli pre-compressed files" enabled="true" stopProcessing="true">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern="" />
<conditions>
<add input="{REQUEST_URI}" pattern="/_compressed_br/.*$" />
</conditions>
<action type="Rewrite" value="br"/>
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

Просмотреть файл

@ -1,4 +1,6 @@
const puppeteer = require('puppeteer');
import { settings } from "cluster";
const puppeteer = require('puppeteer');
const path = require("path");
(async () => {
@ -45,3 +47,7 @@ function delay(time) {
setTimeout(resolve, time)
});
}
function keepAlive() {
setTimeout(keepAlive, 1000);
}

Просмотреть файл

@ -6,6 +6,10 @@
"author": {
"name": ""
},
"scripts": {
"build": "tsc --build",
"clean": "tsc --build --clean"
},
"devDependencies": {
"@types/node": "^8.0.14"
},