Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot-reload using webpack 5 #162

Merged
merged 35 commits into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
546ffbe
bootstrap alternative modules dependency provider
mpm-os Oct 27, 2023
267fe0c
attempt to set modules provider
mpm-os Oct 27, 2023
e6b5e06
working, refactor is needed
mpm-os Oct 30, 2023
bd6c4b5
fix encoding
mpm-os Oct 30, 2023
f7e8c05
fix encondings
mpm-os Oct 30, 2023
cbfa588
fix encoding
mpm-os Oct 30, 2023
4f4b01a
fix encoding
mpm-os Oct 30, 2023
a4b9158
fix encoding
mpm-os Oct 30, 2023
e15e563
more changes to hot reload
mpm-os Oct 31, 2023
92f0af0
Code cleanup
mpm-os Nov 1, 2023
ba0e3b4
webpack config
mpm-os Nov 1, 2023
6c165c4
remove file
mpm-os Nov 1, 2023
e1db8a5
Applies code review suggestions
mpm-os Nov 2, 2023
0102b7a
Bump versions
alvesmiguel1 Nov 2, 2023
4fce445
Bump ViewGenerator
alvesmiguel1 Nov 2, 2023
6d81313
Bump ViewGenerator
alvesmiguel1 Nov 13, 2023
6d6b390
Make dependencies provider readonly
alvesmiguel1 Nov 13, 2023
713802d
Fixed example
alvesmiguel1 Nov 13, 2023
367f442
Simplified example
alvesmiguel1 Nov 13, 2023
37ab8b2
Fixed images usage in examples
alvesmiguel1 Nov 13, 2023
f2cd1c8
Fixed ViewGenerator
alvesmiguel1 Nov 13, 2023
5b86d0a
Fixed WPF build
alvesmiguel1 Nov 13, 2023
cb50b33
Fixed build
alvesmiguel1 Nov 13, 2023
024a7bb
Fixed build
alvesmiguel1 Nov 13, 2023
b939010
Fixed script
alvesmiguel1 Nov 13, 2023
e5159f5
Tentative tests fix
alvesmiguel1 Nov 13, 2023
3601f20
Fixed tests
alvesmiguel1 Nov 13, 2023
09b1773
Tentative tests fix
alvesmiguel1 Dec 5, 2023
36bf792
Tentative fix for tests
alvesmiguel1 Dec 5, 2023
316fced
Code review refactor
alvesmiguel1 Dec 11, 2023
c702e9e
CR
alvesmiguel1 Dec 11, 2023
5fc575f
Update FileDependenciesProvider.cs
alvesmiguel1 Dec 11, 2023
af57090
Update Tests.ReactView.csproj
alvesmiguel1 Dec 11, 2023
3fdebc6
Merge branch 'master' into chore/hot-reload-fixes
alvesmiguel1 Dec 11, 2023
ce94001
Merge branch 'master' into chore/hot-reload-fixes
alvesmiguel1 Dec 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ Sample.Avalonia/Generated/
Sample.Avalonia/node_modules/
**/*.DS_Store
**/*.idea
**/RunWebpackDevServer.sh
**/RunWebpackDevServer.bat
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Platforms>x64;ARM64</Platforms>
<AssemblyVersion>2.0.0.0</AssemblyVersion>
<FileVersion>2.0.0.0</FileVersion>
<Version>2.117.1</Version>
<Version>2.117.2</Version>
<Authors>OutSystems</Authors>
<Product>ReactView</Product>
<Copyright>Copyright © OutSystems 2023</Copyright>
Expand Down
6 changes: 3 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@

<PackageVersion Include="WebViewControl-Avalonia" Version="$(WebViewVersion)" />
<PackageVersion Include="WebViewControl-Avalonia-ARM64" Version="$(WebViewVersion)" />

<PackageVersion Include="WebViewControl-WPF" Version="$(WebViewVersion)" />
<PackageVersion Include="WebViewControl-WPF-ARM64" Version="$(WebViewVersion)" />

<PackageVersion Include="ViewGenerator" Version="1.0.330" />
<PackageVersion Include="ViewGenerator" Version="1.1.22" />
<PackageVersion Include="ViewGeneratorCore" Version="1.0.229" />

<PackageVersion Include="NLog" Version="4.6.2" />
Expand All @@ -35,6 +35,6 @@
<PackageVersion Include="nunit" Version="3.12.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />

</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions ReactViewControl.Avalonia/ReactViewControl.Avalonia.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
<Compile Include="..\ReactViewControl\ViewModuleContainer.cs" Link="ViewModuleContainer.cs" />
<Compile Include="..\ReactViewControl\ViewModuleExtensions.cs" Link="ViewModuleExtensions.cs" />
<Compile Include="..\ReactViewControl\StringExtensions.cs" Link="StringExtensions.cs" />
<Compile Include="..\ReactViewControl\IModuleDependenciesProviderFactory.cs" Link="IModuleDependenciesProviderFactory.cs" />
<Compile Include="..\ReactViewControl\ModuleDependenciesProviderFactory.cs" Link="ModuleDependenciesProviderFactory.cs" />
<Compile Include="..\ReactViewControl\IModuleDependenciesProvider.cs" Link="IModuleDependenciesProvider.cs" />
<Compile Include="..\ReactViewControl\FileDependenciesProvider.cs" Link="FileDependenciesProvider.cs" />
</ItemGroup>

<ItemGroup>
Expand Down
47 changes: 47 additions & 0 deletions ReactViewControl/FileDependenciesProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.IO;
using System.Linq;
using WebViewControl;

namespace ReactViewControl {
internal class FileDependenciesProvider : IModuleDependenciesProvider {

private const string JsEntryFileExtension = ".js.entry";
private const string CssEntryFileExtension = ".css.entry";

private readonly string sourcePath;

public FileDependenciesProvider(string sourcePath) {
this.sourcePath = sourcePath;

DependencyJsSourcesCache = new Lazy<string[]>(() => GetDependenciesFromEntriesFile(JsEntryFileExtension));
CssSourcesCache = new Lazy<string[]>(() => GetDependenciesFromEntriesFile(CssEntryFileExtension));
}

public string[] GetCssDependencies() => CssSourcesCache.Value;

public string[] GetJsDependencies() => DependencyJsSourcesCache.Value;

private Lazy<string[]> DependencyJsSourcesCache { get; }
private Lazy<string[]> CssSourcesCache { get; }

private string[] GetDependenciesFromEntriesFile(string extension) {
var entriesFilePath = Path.Combine(Path.GetDirectoryName(sourcePath), Path.GetFileNameWithoutExtension(sourcePath) + extension);
var resource = entriesFilePath.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);

using (var stream = GetResourceStream(resource)) {
if (stream != null) {
using (var reader = new StreamReader(stream)) {
var allEntries = reader.ReadToEnd();
if (!string.IsNullOrEmpty(allEntries)) {
return allEntries.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
}
}
}
}
return Array.Empty<string>();
}

private Stream GetResourceStream(string[] resource) => ResourcesManager.TryGetResourceWithFullPath(resource.First(), resource);
}
}
2 changes: 0 additions & 2 deletions ReactViewControl/IChildViewHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ public interface IChildViewHost {
bool AddChildView(IViewModule childView, string frameName);

ReactView Host { get; }

bool IsHotReloadEnabled { get; }
}
}
7 changes: 7 additions & 0 deletions ReactViewControl/IModuleDependenciesProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ReactViewControl {
public interface IModuleDependenciesProvider {
string[] GetCssDependencies();

string[] GetJsDependencies();
}
}
6 changes: 6 additions & 0 deletions ReactViewControl/IModuleDependenciesProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ReactViewControl;

public interface IModuleDependenciesProviderFactory {

IModuleDependenciesProvider CreateModuleDependenciesProvider(string sourcePath);
}
5 changes: 2 additions & 3 deletions ReactViewControl/IViewModule.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;

namespace ReactViewControl {

Expand Down Expand Up @@ -37,4 +36,4 @@ public interface IViewModule {

ReactView Host { get; }
}
}
}
14 changes: 14 additions & 0 deletions ReactViewControl/ModuleDependenciesProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace ReactViewControl;

public class ModuleDependenciesProviderFactory : IModuleDependenciesProviderFactory {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public sealed class


public static IModuleDependenciesProviderFactory Instance { get; private set; } = new ModuleDependenciesProviderFactory();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public static IModuleDependenciesProviderFactory Instance { get; set; } = new ModuleDependenciesProviderFactory();


public static void SetInstance(IModuleDependenciesProviderFactory factory) {
Instance = factory;
}
Comment on lines +7 to +9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove


public virtual IModuleDependenciesProvider CreateModuleDependenciesProvider(string sourcePath) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public IModuleDependenciesProvider CreateModuleDependenciesProvider(string sourcePath) {

return new FileDependenciesProvider(sourcePath);
}
}
10 changes: 5 additions & 5 deletions ReactViewControl/ReactView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public abstract partial class ReactView : IDisposable {

private static ReactViewRender CreateReactViewInstance(ReactViewFactory factory) {
ReactViewRender InnerCreateView() {
var view = new ReactViewRender(factory.DefaultStyleSheet, () => factory.InitializePlugins(), factory.EnableViewPreload, factory.EnableDebugMode, factory.DevServerURI);
var view = new ReactViewRender(factory.DefaultStyleSheet, () => factory.InitializePlugins(), factory.EnableViewPreload, factory.EnableDebugMode);
if (factory.ShowDeveloperTools) {
view.ShowDeveloperTools();
}
Expand Down Expand Up @@ -118,8 +118,8 @@ public T WithPlugin<T>() {
}

/// <summary>
/// Enables or disables debug mode.
/// In debug mode the webview developer tools becomes available pressing F12 and the webview shows an error message at the top with the error details
/// Enables or disables debug mode.
/// In debug mode the webview developer tools becomes available pressing F12 and the webview shows an error message at the top with the error details
/// when a resource fails to load.
/// </summary>
public bool EnableDebugMode { get => View.EnableDebugMode; set => View.EnableDebugMode = value; }
Expand Down Expand Up @@ -176,7 +176,7 @@ public event CustomResourceRequestedEventHandler CustomResourceRequested {
}

/// <summary>
/// Handle external resource requests.
/// Handle external resource requests.
/// Call <see cref="ResourceHandler.BeginAsyncResponse"/> to handle the request in an async way.
/// </summary>
public event ResourceRequestedEventHandler ExternalResourceRequested {
Expand Down Expand Up @@ -222,7 +222,7 @@ public void CloseDeveloperTools() {
/// <summary>
/// Number of preloaded views that are mantained in cache for each view.
/// Components with different property values are stored in different cache entries.
/// Defaults to 6.
/// Defaults to 6.
/// </summary>
public static int PreloadedCacheEntriesSize { get; set; } = 6;

Expand Down
7 changes: 1 addition & 6 deletions ReactViewControl/ReactViewFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,5 @@ public class ReactViewFactory {
/// The view is cached and preloaded. First render occurs earlier.
/// </summary>
public virtual bool EnableViewPreload => true;

/// <summary>
/// Webpack dev server url. Setting this value will enable hot reload. eg: new Uri("http://localhost:8080")
/// </summary>
public virtual Uri DevServerURI => null;
}
}
}
41 changes: 14 additions & 27 deletions ReactViewControl/ReactViewRender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using WebViewControl;
using Xilium.CefGlue;
using Xilium.CefGlue;

namespace ReactViewControl {

Expand Down Expand Up @@ -36,7 +36,7 @@ internal partial class ReactViewRender : IChildViewHost, IDisposable {
private ResourceUrl defaultStyleSheet;
private bool isInputDisabled; // used primarly to control the intention to disable input (before the browser is ready)

public ReactViewRender(ResourceUrl defaultStyleSheet, Func<IViewModule[]> initializePlugins, bool preloadWebView, bool enableDebugMode, Uri devServerUri = null) {
public ReactViewRender(ResourceUrl defaultStyleSheet, Func<IViewModule[]> initializePlugins, bool preloadWebView, bool enableDebugMode) {
UserCallingAssembly = GetUserCallingMethod().ReflectedType.Assembly;

// must useSharedDomain for the local storage to be shared
Expand All @@ -53,7 +53,6 @@ public ReactViewRender(ResourceUrl defaultStyleSheet, Func<IViewModule[]> initia
DefaultStyleSheet = defaultStyleSheet;
PluginsFactory = initializePlugins;
EnableDebugMode = enableDebugMode;
DevServerUri = devServerUri;

GetOrCreateFrame(FrameInfo.MainViewFrameName); // creates the main frame

Expand Down Expand Up @@ -90,11 +89,6 @@ public ReactViewRender(ResourceUrl defaultStyleSheet, Func<IViewModule[]> initia

public ReactView Host { get; set; }

/// <summary>
/// True when hot reload is enabled.
/// </summary>
public bool IsHotReloadEnabled => DevServerUri != null;

public bool IsDisposing => WebView.IsDisposing;

/// <summary>
Expand All @@ -108,8 +102,8 @@ public ReactViewRender(ResourceUrl defaultStyleSheet, Func<IViewModule[]> initia
public bool IsMainComponentLoaded => Frames.TryGetValue(FrameInfo.MainViewFrameName, out var frame) && frame.LoadStatus >= LoadStatus.ComponentLoading;

/// <summary>
/// Enables or disables debug mode.
/// In debug mode the webview developer tools becomes available pressing F12 and the webview shows an error message at the top with the error details
/// Enables or disables debug mode.
/// In debug mode the webview developer tools becomes available pressing F12 and the webview shows an error message at the top with the error details
/// when a resource fails to load.
/// </summary>
public bool EnableDebugMode {
Expand All @@ -125,11 +119,6 @@ public bool EnableDebugMode {
}
}

/// <summary>
/// Gets webpack dev server url.
/// </summary>
public Uri DevServerUri { get; }

/// <summary>
/// Gets or sets the webview zoom percentage (1 = 100%)
/// </summary>
Expand Down Expand Up @@ -165,7 +154,7 @@ public event ResourceLoadFailedEventHandler ResourceLoadFailed {
public event ResourceRequestedEventHandler EmbeddedResourceRequested;

/// <summary>
/// Handle external resource requests.
/// Handle external resource requests.
/// Call <see cref="ResourceHandler.BeginAsyncResponse"/> to handle the request in an async way.
/// </summary>
public event ResourceRequestedEventHandler ExternalResourceRequested;
Expand Down Expand Up @@ -370,7 +359,7 @@ public void RemoveCustomResourceRequestedHandler(string frameName, CustomResourc
}

/// <summary>
/// Gets the view loaded on the specified frame. If none it will create a view of the specified
/// Gets the view loaded on the specified frame. If none it will create a view of the specified
/// instance and bind it to the frame.
/// </summary>
/// <param name="frameName"></param>
Expand Down Expand Up @@ -407,7 +396,7 @@ public bool AddChildView(IViewModule childView, string frameName) {
}

/// <summary>
/// Binds the coponent to the specified frame.
/// Binds the component to the specified frame.
/// </summary>
/// <param name="component"></param>
/// <param name="frame"></param>
Expand Down Expand Up @@ -550,18 +539,16 @@ private void UnregisterNativeObject(IViewModule module, FrameInfo frame) {
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private string ToFullUrl(string url) {
private string ToFullUrl(string url) {
if (url.OrdinalContains(Uri.SchemeDelimiter)) {
return url;
} else if (url.OrdinalStartsWith(ResourceUrl.PathSeparator)) {
if (IsHotReloadEnabled) {
return new Uri(DevServerUri, url).ToString();
} else {
return new ResourceUrl(ResourceUrl.EmbeddedScheme, url).ToString();
}
} else {
return new ResourceUrl(UserCallingAssembly, url).ToString();
}

if (url.OrdinalStartsWith(ResourceUrl.PathSeparator)) {
return new ResourceUrl(ResourceUrl.EmbeddedScheme, url).ToString();
}

return new ResourceUrl(UserCallingAssembly, url).ToString();
}

/// <summary>
Expand Down
Loading
Loading