0
votes

I found nice article about "how configure .NET CORE with VUE SSR and Webpack".

Everything works nice, but when I want use lazy loading component in routes I got error.

An unhandled exception occurred while processing the request.
NodeInvocationException: Cannot find module '1.js'
Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance+<InvokeExportAsync>d__7.MoveNext()

OR (Depend what I use (resolve => require(['..)) or () => import("")

NullReferenceException: Object reference not set to an instance of an object.
Microsoft.AspNetCore.SpaServices.Prerendering.PrerenderTagHelper+<ProcessAsync>d__29.MoveNext()

__vue_ssr_bundle__:18146 Error: Cannot find module '1.js'
at Function.Module._resolveFilename (module.js:469:15)
at Function.Module._load (module.js:417:25)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at r (C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\EshopClientApp\node_modules\vue-server-renderer\build.js:8152:16)
at Function.requireEnsure [as e] (__vue_ssr_bundle__:41:25)
at component (__vue_ssr_bundle__:16228:40)
at __vue_ssr_bundle__:18015:17
at __vue_ssr_bundle__:18042:66
at Array.map (native)

I tried to debug .net spaservices code and I found where exception is throwed - in this method:

Module._resolveFilename = function(request, parent, isMain) {
  if (NativeModule.nonInternalExists(request)) {
    return request;
  }

  var resolvedModule = Module._resolveLookupPaths(request, parent);
  var id = resolvedModule[0];
  var paths = resolvedModule[1];

  // look up the filename first, since that's the cache key.
  debug('looking for %j in %j', id, paths);

  var filename = Module._findPath(request, paths, isMain);
  if (!filename) {
    var err = new Error("Cannot find module '" + request + "'");
    err.code = 'MODULE_NOT_FOUND';
    throw err;
  }
  return filename;
};

Id property above contains this value: 0.js

Paths: property above contains this array of paths

"C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\EshopClientApp\node_modules\vue-server-renderer\node_modules"
"C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\EshopClientApp\node_modules"
"C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\node_modules"
"C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\node_modules"
"C:\Projects\SmartSystem\DEV\Fibit.Bruno\node_modules"
"C:\Projects\SmartSystem\DEV\node_modules"
"C:\Projects\SmartSystem\node_modules"
"C:\Projects\node_modules"
"C:\node_modules"
"C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\node_modules"
"C:\Users\Martin\.node_modules"
"C:\Users\Martin\.node_libraries"
"C:\Program Files\nodejs\lib\node"

ERROR:

err = Error: Cannot find module '0.js' at Function.Module._resolveFilename (module.js:469:15) at Function.Module._load (module.js:417:25) at Module.require (module.js:497:17) at require (internal/module.js:20:19) at r (C:\Projects\SmartSystem\DEV\Fibit.Bruno\src\Fibit.Bruno.Web.Mvc\EshopClientApp\node_modules\vue-server-renderer\build.js:8152:16) at Function.requireEnsure [as e] (__vue_ssr_bundle__:41:25) at Object.module.exports.Object.defineProperty.value (__vue_ssr_bundle__:16233:40) at __webpack_require__ (__vue_ssr_bundle__:27:30) at Object.module.exports.Object.defineProperty.value (__vue_ssr_bundle__:10431:15) at __webpack_require__ (__vue_ssr_bundle__:27:30), request = "0.js"
err.code = 'MODULE_NOT_FOUND'

ROUTER:

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
    mode: 'history',
    routes: [
        { path: '/', component: resolve => require(['../components/Dashboard.vue'], resolve) },
        { path: '/messages', component: resolve => require(['../components/Messages.vue'], resolve) },
    ]
});

export default router;

WEBPACK config:

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');

module.exports = (env) => {
    const isDevBuild = !(env && env.prod);

    const sharedConfig = () => ({
        stats: { modules: false },
        resolve: { extensions: ['.js', '.vue'] },
        output: {
            filename: '[name].js',
            publicPath: '/dist/'
        },
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    loader: 'vue-loader',
                },
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    include: __dirname,
                    exclude: /node_modules/
                },
                { 
                    test: /\.css$/, 
                    loader: "style-loader!css-loader" 
                }
            ]
        }
    });

    const clientBundleOutputDir = '../wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig(), {
        entry: { 'main-client': './client.js' },
        output: {
            path: path.join(__dirname, clientBundleOutputDir)
        }
    });

    const serverBundleConfig = merge(sharedConfig(), {
        target: 'node',
        entry: { 'main-server': './server.js' },
        output: {
            libraryTarget: 'commonjs2',
            path: path.join(__dirname, '../wwwroot/dist')
        },
        module: {
            rules: [
                {
                    test: /\.json?$/,
                    loader: 'json-loader'
                }
            ]
        },
    });

    return [clientBundleConfig, serverBundleConfig];
}

How solve problem with lazy loading with SSR, .NET CORE and Webpack ? Do anybody have any idea ? Thanks!

2

2 Answers

0
votes
Combining the two, this is how to define an async component that will be automatically code-split by webpack:

const Foo = () => import('./Foo.vue')
Nothing needs to change in the route config, just use Foo as usual:

const router = new VueRouter({
  routes: [
    { path: '/foo', component: Foo }
  ]
})
0
votes

I recently posted a question that is similar to what you're looking for. In fact, you don't even need vue-router in this instance since you're also working on an MVC project from what I can see.

Global Vue Component Exposure via Webpack

Basically, you can 'inject' the components just like this in the instantiating file of webpack;

In this case, I used main.js as my 'startup' js

// Vue Components
Vue.component(/* webpackChunkName: "base-select" */ 'base-select', () => import('./components/base-select.vue'));

// Expose Vue globally
// https://stackguides.com/questions/45388795/uncaught-referenceerror-vue-is-not-defined-when-put-vue-setting-in-index-html
window.Vue = Vue;

However, i'm still looking for a solution regarding an asynchronous loading failure. Basically what happened was that the component will successfully load but fail at one part of the loading sequence. lol, i realised that i'm just one step ahead of you, no breakthrough yet just that you'll be able to load components just like me wants you follow the code above that is