question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ssrBuild with async Vue3 components / routes , trouble with import to require conversion in built files.

See original GitHub issue

Describe the bug

I’ve been spending some time with the mostly undocumented ssrBuild feature of Vite + Vue3, so this might not actually be a bug but working as intended and i might be doing something wrong.

I am trying to run the ssrBuild with a router that defines some async components as below:

export default function (type) {
  const routerHistory = type === 'client' ? createWebHistory() : createMemoryHistory();
  
  return createRouter({
    history: routerHistory,
    routes: [
      { path: '/', component: Home, props: true },
      { path: '/a', component: () => import('./components/PageA.vue'), props: true },
      { path: '/b', component: () => import('./components/PageB.vue'), props: true },
    ]
  });
}

However, once i built my entry files with ssrBuild it converts the router part in the entry file to:

function createRouter$1(type) {
  const routerHistory = type === "client" ? createWebHistory() : createMemoryHistory();
  return createRouter({
    history: routerHistory,
    routes: [
      {path: "/", component: script$2, props: true},
      {path: "/a", component: () => Promise.resolve().then(function() {
        return require("./PageA.161ddab2.js");
      }).default, props: true},
      {path: "/b", component: () => Promise.resolve().then(function() {
        return require("./PageB.f65a13cd.js");
      }).default, props: true}
    ]
  });
}

The problem here is how the requires are defined:

 return require("./PageA.161ddab2.js");

The above code does end up not being able to find the component. If i manually go into the built files and add a .default behind this, the code works fine and my pages load / hydrate correctly.

 return require("./PageA.161ddab2.js").default;

since the exported pages all have default exports, this seems to be logical. E.g. in PageA:

"use strict";
var renderer = require("@vue/server-renderer");
var script = {
  name: "PageA",
  props: {
    msg: String
  },
  data() {
    return {
      randomNumber: 0,
      initialized: false,
      count: 0
    };
  }
};
function ssrRender(_ctx, _push, _parent, _attrs, $props, $setup, $data, $options) {
  _push(`<h1${renderer.ssrRenderAttrs(_attrs)}>I AM PAGE A</h1>`);
}
script.ssrRender = ssrRender;
script.__file = "src/components/PageA.vue";
exports.default = script;

Is this actually a bug with vite where it should be adding the .default to the required components? Am I doing something wrong here and should i define my imports differently? Happy to provide additional info if needed.

System Info

  • required vite version: ^1.0.0-rc.4
  • required Operating System: win10 with WSL1
  • required Node version: v14.7.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:19 (10 by maintainers)

github_iconTop GitHub Comments

2reactions
posvacommented, Sep 2, 2020

Thanks, well for some reason the generated module is missing the __esModule property so we don’t get the default.

@underfin I think there might be a bug in the transpilation on SSR: shouldn’t the dynamic import output a require(...).default? Or add the __esModule property? Checking for default in the resolved import should work but I’m not sure if it would break in some scenarios

1reaction
tbgsecommented, Oct 24, 2020

@underfin it seems like a fix was merged in rollup https://github.com/rollup/rollup/pull/3822

EDIT: it seems to work as expected now by installing the latest version of rollup and adding

    rollupOutputOptions: {
      namespaceToStringTag: true
    }

to the build config. Would it be possible to update the rollup dependency for vite?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't use async components in vue3 when using SSR
import renderer from '@vue/server-renderer'; import createApp from './main.js'; const {app, router, store} = createApp(context, true); router.
Read more >
Async Components - Vue 3 Migration Guide
Guide on migrating from Vue 2 to Vue 3.
Read more >
Lazy Load Components in Vue with defineAsyncComponent
Using Vue 3's defineAsyncComponent feature lets us lazy load components. This means that they're only loaded from the server when they're ...
Read more >
Vue 3 Server Side Rendering (SSR)
The vue 3 server renderer provides the API to convert a Vue App ... that dont need to run in Node; An ssr-manifest.json...
Read more >
Recommended - SlideShare
For production: after running vite build , a manifest.json file will ... Named Imports It's possible to only import parts of the modules ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found