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

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 opened this issue Jan 9, 2023 · 2 comments

Comments

@YataoZhang
Copy link

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.

@WinfredWang
Copy link

same issue

@ReySun
Copy link

ReySun commented Jul 14, 2023

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants