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

Please Upgrade to Core 3 #138

Open
Grandizer opened this issue Sep 25, 2019 · 19 comments
Open

Please Upgrade to Core 3 #138

Grandizer opened this issue Sep 25, 2019 · 19 comments

Comments

@Grandizer
Copy link

I am attempting to upgrade my app to Core 3 and am running into this issue.

@kiran94
Copy link

kiran94 commented Sep 25, 2019

+1, We are also experiencing this issue

@JoshDiDuca
Copy link

Core 3 has removed HMR.

@Grandizer
Copy link
Author

So there is no workaround?

@JoshDiDuca
Copy link

JoshDiDuca commented Sep 25, 2019

Not at this time, I believe Microsoft is expecting the community to pick up these packages. Very frustrating, if you ask me.

@poganytamas
Copy link

Very frustrating, if you ask me.
Not just frustrating, it is a shame to kill such important feature. For me it is a deal breaker to upgrade to 3.0, staying at 2.2 :(

@poganytamas
Copy link

Even if UseWebpackDevMiddleware is obsolate today, not deprecated, it doesn't work. I upgraded to 3.0, and the __webpack_hmr endpoint does nothing. No updates, nor heartbeats. Sad :( Staying at .net core 2.2.

@UseMuse
Copy link

UseMuse commented Oct 16, 2019

@Grandizer , @kiran94 , @JoshDiDuca , @poganytamastsys
I managed to upgrade the project to asp core 3 while maintaining a hot reload using Westwind.AspnetCore.LiveReload , because hot reload from asp core 2.2 under asp core 3 stopped working https://github.com/UseMuse/aspnetcore-Vue-starter
clone and run from under the box
made a pull request

@poganytamas
Copy link

@UseMuse This is a great start having HMR back. My only concern is that instead of using chunks, it rebuilds the whole main.js, therefore reloading the whole page.

@rjgotten
Copy link

@Grandizer , @kiran94 , @JoshDiDuca , @poganytamastsys, @UseMuse
I managed to upgrade the project to asp core 3 while maintaining a hot reload

No, you didn't. WestWind.AspNetCore.LiveReload reloads the entire page whenever any single file it monitors is changed. That is cold reloading, not hot reloading in the normal sense of module replacement within a running page.

@hhuseyinpay
Copy link

Is there any progress? @MarkPieszak

@oslotboom
Copy link

oslotboom commented Dec 22, 2019

(Updated 20191229) I converted my 2.2 project based on this template to 3.1. It took about two days of toiling, so I'm posting what I did for possible benefit to others. It does not have hot or cold reloading, but the package.json has been modified to always rebuild the files in the wwwroot/dist folder on project build. Sorry about the formatting of the code sections - I could not get it to work as desired.

  1. Make all the updates as outlined in the 2.2 > 3.0 conversion guide. Afterwards, review the 3.0 > 3.1 guide 2.2 to 3.0 , 3.0 to 3.1

This requires numerous changes to startup.cs. As others have noted, the hot reloading is deleted from the new DLLs.
See my new startup.cs below. Note that it contains extras not needed in a basic project.

`using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Vue2Spa
{
public class Startup
{
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; set; }
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Environment = env;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Lots of other project-specific stuff here
services.AddControllersWithViews(); //I don't know if this is needed
}

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            //UseWebpackDevMiddleware DELETED in 3.0
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");

            endpoints.MapFallbackToController(
                action: "Index",
                controller: "Home");
        });
    }
}

}`

Program.cs
`using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Vue2Spa
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

}`

  1. (Optional) Convert to use Microsoft.AspnetCore.SpaServices.Extensions. The official template for Angular (when you create a new Angular web site in VS 2019) uses Microsoft.AspnetCore.SpaServices.Extensions. Reference For info see [Announcement] Obsoleting Microsoft.AspNetCore.SpaServices and Microsoft.AspNetCore.NodeServices dotnet/aspnetcore#12890
    a. Install Microsoft.AspnetCore.SpaServices.Extensions via NuGet
    b. Modify *.csproj to match the approach used in the Angular template. I included my entire file for reference, but of course you'll need to sample what applies to your project. Note that the target Name="DebugEnsureNodeEnv" is new and needed to construct updated single file components when a build occurs.

For some unexplainable reason a section is being shown as code, you'll need to decode it with and online html decoder to show the < and > characters correctly.

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<SpaRoot>ClientApp&lt;/SpaRoot>
<Dist>wwwroot\dist&lt;/Dist>
<DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules**</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.4.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" />
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
</ItemGroup>

<ItemGroup>
<!-- Files not to show in IDE -->
<None Remove="yarn.lock" />
<!-- Don't publish the SPA source files, but do show them in the project files list -->
<Content Remove="$(SpaRoot)" />
<None Remove="$(SpaRoot)
" />
<None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules**" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TaskManagers\TaskManagers.csproj" />
</ItemGroup>

<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec Command="node -e &quot;console.log('NPM Installing dependencies...')&quot;" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install --ignore-scripts" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />

&lt;!-- Include the newly-built files in the publish output --&gt;
&lt;ItemGroup&gt;
  &lt;DistFiles Include="$(Dist)**; $(SpaRoot)dist\**" /&gt;
  &lt;ResolvedFileToPublish Include="@(DistFiles-&gt;'%(FullPath)')" Exclude="@(ResolvedFileToPublish)"&gt;
    &lt;RelativePath&gt;%(DistFiles.Identity)&lt;/RelativePath&gt;
    &lt;CopyToPublishDirectory&gt;PreserveNewest&lt;/CopyToPublishDirectory&gt;
    &lt;!-- I don't know if the next line is needed --&gt;
    &lt;!-- &lt;ExcludeFromSingleFile&gt;true&lt;/ExcludeFromSingleFile&gt; --&gt;
  &lt;/ResolvedFileToPublish&gt;
&lt;/ItemGroup&gt;

</Target>

</Project>

  1. webpack.config.js
    ExtractTextPlugIn needs to be replaced with MiniCssExtractPlugin. Reference https://github.com/webpack-contrib/mini-css-extract-plugin

npm install --save-dev mini-css-extract-plugin

Delete
const ExtractTextPlugin = require('extract-text-webpack-plugin')
Add
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

Delete
const extractCSS = new ExtractTextPlugin('site.css')
Add
const extractCSS = new MiniCssExtractPlugin('site.css')

Update rule for css
Old
module: {
rules: [
{ test: /.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader' }) },
New
rules: [
{ test: /.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : [MiniCssExtractPlugin.loader, 'css-loader'] },

  1. webpack.config.vendor.js
    Update similar to webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = () => {
const extractCSS = new MiniCssExtractPlugin('vendor.css')

module: {
  rules: [
    { test: /\.css(\?|$)/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }
  1. The main.js.map files were not being correctly generated. (File was very small, and debugging in Chrome did not work). main.js.map was correctly generated when I added devtool: false, in webpack.config.js
    return [{ mode: isDevBuild ? 'development' : 'production', devtool: false, // IMPORTANT: without this statement, the source map is not correctly built using SourceMapDevToolPlugin

6, (Optional) Update to use FontAwesome 5.
a. In Visual Studio, Solution Explorer, Project file listing, Dependencies, npm: uninstall all existing fortawesome items

b. Install the latest npm packages
$ npm i --save @fortawesome/fontawesome-svg-core
$ npm i --save @fortawesome/free-solid-svg-icons
$ npm i --save @fortawesome/free-brands-svg-icons
$ npm i --save @fortawesome/free-regular-svg-icons
$ npm i --save @fortawesome/vue-fontawesome

c. Modify icons.js to use the new standards. The code sample shows individual icons being added. The new version has a tree-shaking feature which I didn't fully understand, but may allow you to just link to the library.
Reference
https://github.com/FortAwesome/vue-fontawesome/blob/master/UPGRADING.md
https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4
`import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'

//These commands import libraries. It is not known if "tree-shaking" will remove the unused icons so that only used icons are included
import { fas } from '@fortawesome/free-solid-svg-icons'
import { faBrands } from '@fortawesome/free-brands-svg-icons'

//The following commands import specific icons
import { faFontAwesome } from '@fortawesome/free-brands-svg-icons/faFontAwesome'
import { faMicrosoft } from '@fortawesome/free-brands-svg-icons/faMicrosoft'
import { faVuejs } from '@fortawesome/free-brands-svg-icons/faVuejs'

library.add(faFontAwesome, faMicrosoft, faVuejs)

import { faHome } from '@fortawesome/free-solid-svg-icons/faHome'
import { faList } from '@fortawesome/free-solid-svg-icons/faList'
import { faGraduationCap } from '@fortawesome/free-solid-svg-icons/faGraduationCap'
import { faSpinner } from '@fortawesome/free-solid-svg-icons/faSpinner'
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'
import { faCog } from '@fortawesome/free-solid-svg-icons/faCog'
import { faCheckSquare } from '@fortawesome/free-solid-svg-icons/faCheckSquare'
import { faTimesCircle } from '@fortawesome/free-solid-svg-icons/faTimesCircle'
import { faCheck } from '@fortawesome/free-solid-svg-icons/faCheck'
import { faAngleUp } from '@fortawesome/free-solid-svg-icons/faAngleUp'

library.add(faHome, faList, faGraduationCap, faSpinner, faExclamationTriangle, faCog, faCheckSquare, faTimesCircle, faCheck, faAngleUp )

export {
FontAwesomeIcon
}
`

  1. package.json
    The main change to get the single file components to update on build is
    "install": "npm run build-vendor:dev && npm run build:dev"
    I updated the version number of numerous packages. The babel update is definitely needed, and fontawesome updates may be needed. I don't know if the other updates are needed, but they don't do any harm.

{
"name": "aspnetcore-vuejs",
"description": "ASP.NET Core & VueJS Starter project",
"author": "Mark Pieszak",
"repository": {
"url": "https://github.com/MarkPieszak/aspnetcore-Vue-starter"
},
"license": "MIT",
"scripts": {
"dev": "cross-env ASPNETCORE_ENVIRONMENT=Development NODE_ENV=development dotnet run",
"build": "npm run build-vendor:prod && npm run build:prod",
"build:prod": "cross-env NODE_ENV=production webpack --progress --hide-modules",
"build:dev": "cross-env NODE_ENV=development webpack --config webpack.config.js --progress",
"build-vendor:prod": "cross-env NODE_ENV=production webpack --config webpack.config.vendor.js --progress",
"build-vendor:dev": "cross-env NODE_ENV=development webpack --config webpack.config.vendor.js --progress",
"lint": "eslint -c ./.eslintrc.js ClientApp//*.js ClientApp//.vue ClientApp/**/.json webpack*.js",
"install": "npm run build-vendor:dev && npm run build:dev"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-brands-svg-icons": "^5.12.0",
"@fortawesome/free-regular-svg-icons": "^5.12.0",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/vue-fontawesome": "^0.1.9",
"axios": "^0.15.3",
"core-js": "^2.5.3",
"element-ui": "^2.4.4",
"vue": "^2.6.11",
"vue-router": "^3.1.3",
"vue-server-renderer": "^2.6.11",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.1.2",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"aspnet-webpack": "^2.0.3",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.26.0",
"bootstrap": "^4.0.0",
"cross-env": "^3.2.4",
"css-loader": "^0.26.4",
"eslint": "^4.18.2",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-html": "^4.0.2",
"eslint-plugin-import": "^2.9.0",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-promise": "^3.7.0",
"eslint-plugin-standard": "^3.0.1",
"event-source-polyfill": "0.0.7",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^0.9.0",
"font-awesome": "^4.7.0",
"jquery": "^2.2.4",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.8.2",
"optimize-css-assets-webpack-plugin": "^1.3.2",
"popper.js": "^1.14.1",
"sass-loader": "^4.1.1",
"style-loader": "^0.13.2",
"url-loader": "^0.5.9",
"vue-loader": "^14.2.2",
"webpack": "^4.41.4",
"webpack-cli": "^3.3.10",
"webpack-dev-middleware": "^3.7.2",
"webpack-hot-middleware": "^2.25.0"
}
}

  1. After these changes, a project build will launch a full run of npm, which will update the single file components. As an alternative, you can change the install script item in package.json to remove the npm run and manually rebuild the single file components. Of course, this is not hot reloading. But it does allow development work to proceed.

For manual rebuilding: At a powershell command prompt at the root of the project, Run the following to update main.js and main.js.map
$ npm build:dev
To update vendor.js, vendor.css and vendor-manifest.json, run
$ npm build-vendor:dev

@Nordes
Copy link
Contributor

Nordes commented Dec 27, 2019

Actually, there's a way to make the hot-reload works. It require to use the spa.UseProxyToSpaDevelopmentServer("http://localhost:8080"); line under the app.UseSpa(...=> { //somewhere here

I did it on my current VueJS starter (different repository than this using picnic css instead of bootstrap). However, it requires you normally to start the VueJS project using WebPack outside of Visual Studio using let's say webpack-dev-server. The proxy will link between your webpack port (http...8080) and your webapp on port 5000/5001. That being said, if you start your application using HTTPS in development, it will fails since the certificate used in your application is not valid and the Spa-PROXY will not like it (So far I've seen no option to do skip that validation). You could still share the same SSL certificate (pfx, etc.) and make it work using SSL locally. Personally, I've removed the HTTPS for local and use HTTP + Proxy using webpack-dev-server.

In order to avoid running the webpack-dev-server everytime, you could lazilly start a BackgroundService in C#. The caveat with that is that if you push the Stop/Restart button in the IDE it kills the C# application, but does not terminate properly the sub-process tree (current bug: dotnet/aspnetcore#5204). If you use the ctrl-c in order to stop your application, it works like a charm.

update: Issue dotnet/aspnetcore#5204 was fixed today 31st of jan. 2020 🎉

@AdamJamesNaylor
Copy link

+1 I'm also looking to use this template but keen to start from a net core 3.0/3.1 base.

@sksallaj82
Copy link

sksallaj82 commented Mar 19, 2020

@Nordes the problem with that approach is to completely leave the MVC Razor pages completely. Which I wouldn't agree with. With SPA, trying to handle requests and things over the network is WAY more complex than it needs to be, and that complexity grows quickly. Some people won't be up for that. When using MVC views, I have very simple configs to handle auths, and there are nice Authorize decorators I use to wrap each view, to go completely JS in that manner would be a huge pain for me and other devs who wants to have nicer options of turning it off.

However, I do agree with you that developing a SPA is very easy, and it includes hot-reloading. In my case, I derailed a bit away from this GitHub project's template. First, I began using Vue-CLI as it abstracts away a lot of Vue stuff from webpack. In fact, I favor this approach than straight-up using webpack because the Vue-CLI config brings in a lot of things to aid in your Vue development that you would have had to otherwise set up in your webpack. Take a look at a vue.config.js file and compare that to what you see in webpack.config.js setting up Vue, you'll know straight away which is simpler.

Vue-CLI creates a lot of files that you'd need to set up a location for. In order to get what I had working with Razor, I needed to create two separate environments in launchSettings. One is to use the Vue-CLI dev server - without controllers, and the other is to use IIS Express with controllers set up.

It was a bit messy because I took the generated index.html that Vue-cli created (it brings in the js and CSS that Vue-CLI bundled and compiled). I converted it into a string, sanitized it as much as I could, and then dumped it into my index.cshtml.

When I have time, I'll take the template from this github project, and convert it the same way I did with my project, and I'll add it to my github repo.

@poganytamas
Copy link

Any news upgrading this template to 3.x with hmr?

@bryandam
Copy link

bryandam commented Aug 4, 2020

I've been trying to get HMR working in our .Net Core 3.1+Vue project that was based on an earlier version of this starter template.

It would appear that UseWebpackDevMiddleware isn't gone, it's just moved into the Microsoft.AspNetCore.SpaServices.Extensions nuget package. I downloaded the current code, added that package, added "options => options.EnableEndpointRouting = false" to the services.AddMvc constructor in Startup.cs, updated the project to 3.1 and everything compiled. Any changes I make appear to trigger webpack to recompile. The only thing that doesn't seem to work is that the browser doesn't automatically refresh but if I refresh manually I see the changes. I'm going to try and see if that's fixable but even so it's better than a full recompile of our .NET project.

@sksallaj82
Copy link

sksallaj82 commented Aug 5, 2020

You can use my forked repo if you want. It works on ASP Core 3.1. It's a bit hacky because I glued the VUE-CLI to MVC. You can see how hacky it is when you see that I basically did a straight-up html injection of the generated index.html outputted by VUE-CLI into an MVC view cshtml file. Because I'm using VUE-CLI, there are no webpack dependencies. And yes, hot-reload works using the VUE-CLI dev server. I tried my best to give instructions on how it works and how to configure it to your liking because I wanted it to be as flexible as possible. It is also being used in my client's production environment.

If you want, you could turn off ever using MVC, meaning no controllers or views. I needed it as the project I was working on had server-side security features I needed to implement.

I should probably break up the code to reflect that, how to have it work with MVC and how to make it work just by using the VUE-CLI

https://github.com/sksallaj82/aspnetcore-Vue-starter

@Luiz-Monad
Copy link

Luiz-Monad commented Feb 22, 2021

I happened to drop by parachute here when I was trying to find an easier way for the aspnet-core to run JS code "directly", iow, I want to call functions in JS, and needed some kind of bi-directional interop layer.

I guess I'm going to keep using 2 Webpacks, one to server-side render, and the other to client-side render, and some unwieldy bunch of crap code that taps into Webpack's internals and do some shenanigans.

You can control both "instances" of webpack running in the same node, and do some hacks when they are running.
The code to start them is something like this:

warning: contains javascript

Click to expand!
const path = require('path');
const webpack = require('webpack');
const Module = require('module');

const fs = require('fs');

const outputStats = (logger, err, stats) => {
    if (err) {
        logger.error(err)
        return true;
    }
    const info = stats.toJson('verbose');
    (info.errors || []).forEach(logger.error.bind(logger));
    (info.warnings || []).forEach(logger.warn.bind(logger));
    logger.log(stats.toString({
        colors: true
    }));
    return false;
};

const parentModule = module;
const exec = (code, loaderContext) => {
    const { resource, context } = loaderContext;
    const module = new Module(resource, parentModule);
    module.paths = Module._nodeModulePaths(context);
    module.filename = resource;
    module._compile(code, resource);
    return module.exports;
}

module.exports = (options, loaderContext) => {
    const logger = loaderContext.getLogger('SSR')
    return new Promise((resolve, reject) => {
        logger.log('SSR: Compiling ...');

        const configSSR = path.join(__dirname, options.config);
        loaderContext.addDependency(configSSR);
        const webpackConf = require(configSSR);
        const finalConf = webpackConf(options.baseConfig());
        const outputPath = finalConf.output.path;

        const serverCompiler = webpack(finalConf);
        serverCompiler.run((err, stats) => {

            if (outputStats(logger, err, stats)) {
                reject(new Error('Webpack failed.'));
                return;
            }

            const assets = stats.compilation.assets;
            const fileDeps = stats.compilation.fileDependencies;
            const ctxDeps = stats.compilation.contextDependencies;
            const entry = stats.compilation.entrypoints.keys().next().value;
            const asset = Object.keys(assets).reduce((_, a) => a.startsWith(entry) ? a : null);
            fs.readFile(path.join(outputPath, asset), (err, content) => {

                if (err) {
                    reject(new Error(`Webpack couldn\'t find the "${asset}" file.`));
                    return;
                }
    
                let modl;
                try {
                    modl = exec(content.toString('utf8'), loaderContext);
                } catch (err) {
                    reject(new Error(`Failure compiling "${entry}": ${err}`));
                    return;
                }
                
                let output;
                try {
                    output = modl[Object.keys(modl)[0]]();
                } catch (err) {
                    reject(new Error(`Failure running "${entry}": ${err}`))
                    return;
                }

                const emitFile = files => {
                
                    if (!files || !files[0]) {
                        resolve({
                            code: output,
                            dependencies: fileDeps,
                            contextDependencies: ctxDeps,
                            cacheable: true,
                        })
                        logger.log('SSR: Done');
                        return;
                    }

                    const file = files[0];                    
                    fs.readFile(path.join(outputPath, file), (err, content) => {

                        loaderContext.emitFile(file, content);
                        
                        if (err) {
                            reject(new Error(`Webpack couldn\'t find the "${file}" file.`));
                            return;
                        }

                        emitFile(files.splice(1));

                    });
                };

                const extras = Object.keys(assets).filter((a) => !a.startsWith(entry));
                emitFile(extras);

            });

        });

    });

};

The only thing that saved me the effort of having to fix this crap was https://fable.io/
As my code is F#, I can just run it directly inside node, and don't actually need the interop layer.

I was just doing this experiment on getting rid of webpack, I guess I won't then.

At least Blazor is supposed to implement packing and bundling, then all they need to actually do, if they are that committed to support Blazor is to write something that converts Javascript to C#, this would be immensely useful.
(not in that specific case I have, I would need to convert C# to F#, but that's another project of mine, lets call it "transposing", as in music)
My company is specialized in that kind of thing, source-source conversion, I could do that kind of thing, and make JS->C# compilation, I only need some small financial investment to start it, if someone needs it, that be.

I'm not going to migrate to Blazer for that, heck, I'll write my own webpacker in F#, its easier.
How hard could it be, Accorn parser to AST, some treeshaking, babelifying and then some terser library, who needs all those chunk separation complexity anyway, its just a matter of adding some tags to the code and doing tree deforestation, as they call it.

@Luiz-Monad
Copy link

Found this https://github.com/Taritsyn/JavaScriptEngineSwitcher/
Looks like a good replacement for this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests