Skip to content

SSR with webpack5, run renderToString() report "cannot find module ''../js/xxx.js" when use import() to lazy load components in router configs. #12924

Open
@YataoZhang

Description

@YataoZhang

Version

2.7.14

Reproduction link

github.com

Steps to reproduce

step 1: write a simple vue-router use cases:

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

Vue.use(VueRouter);

export default function () {
    const router = new VueRouter({
        mode: 'history',
        base: '/',
        routes: [
            {
                path: '/',
                redirect: '/index'
            }, {
                path: '/index',
                component: () => import(
                    /* webpackChunkName: "index" */
                    '@/pages/index.vue'
                )
            }, {
                path: '/about',
                component: () => import(
                    /* webpackChunkName: "about" */
                    '@/pages/about.vue'
                )
            }],
    });
    return router;
}

Step 2: configuration vue.config.js for server bundle of SSR Mode:

const { defineConfig } = require('@vue/cli-service')
const nodeExternals = require('webpack-node-externals');
const VueSSRServerPlugin = require('vue-server-renderer/server-plugin');

module.exports = defineConfig({
  productionSourceMap: false,
  css: {
    extract: false,
  },
  transpileDependencies: true,
  configureWebpack: {
    entry: '@/enter-server.js',
    target: 'node',
    output: {
      library: {
        type: 'commonjs2'
      },
      libraryTarget: 'commonjs2',
    },
    externals: nodeExternals({
      allowlist: [/\.css$/],
    }),
    optimization: {
      splitChunks: { chunks: 'all' },
    },
    plugins: [
      new VueSSRServerPlugin(),
    ],
  }
})

Step 3: write a render test case:

const { createBundleRenderer } = require('vue-server-renderer');
const serverBundle = require('./dist/vue-ssr-server-bundle.json');
const createRenderer = (bundle, options = {}) => {
    return createBundleRenderer(bundle, Object.assign(options, {
        runInNewContext: false
    }));
};
let renderer = createRenderer(serverBundle);
const ctx = {
    route: { path: '/index' },
};
renderer.renderToString(ctx, (err, html) => {
    if (err) {
        return console.log(err);
    }
    console.log(html);
});

What is expected?

run command: npm run build, and it will emit some errors:

[vue-router] Failed to resolve async component default: Error: Cannot find module '../js/index.5c9c2de1.js'

What is actually happening?

In Webpack5, when the output.target is "node". it will use the installChunk(require("../" + __webpack_require__.u(chunkId))); to load the all async modules. and "vue-server-renderer/server-plugin" will put all modules in .json file.

The reason it on the "../". while renderToString() was executed.
cause cannot resolve and async components bundle with prefix ”.../“ in evaluateModule().


finally, i am apologize for my pool english.

Activity

WinfredWang

WinfredWang commented on Jun 8, 2023

@WinfredWang

same issue

ReySun

ReySun commented on Jul 14, 2023

@ReySun

try add specific filename to webpack.output, like this:

output: {
      libraryTarget: "commonjs2",
      filename: "server-bundle.js",
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @WinfredWang@YataoZhang@ReySun

        Issue actions

          SSR with webpack5, run renderToString() report "cannot find module ''../js/xxx.js" when use import() to lazy load components in router configs. · Issue #12924 · vuejs/vue