vue 3和SSR的懒惰加载/代码拆分

发布于 2025-02-01 14:33:51 字数 14217 浏览 0 评论 0原文

在使用SSR时,我对VUE 3的每个路线特征的代码分割有问题。我在这里谈论这个: https://router.vuejs.s.s.s.org/guide/guide/advanced/lazy-loading。 html

我的SSR设置为:

src/router/index.js(路由器组件)

import {createRouter, createWebHistory, createMemoryHistory} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import Contact from '../views/Contact.vue';
import store from '../store'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    props: true,
  },
  {
    path: '/home',
    redirect: '/'
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
  {
    path: '/contact',
    name: 'Contact',
    component: Contact,
  }
];

const isServer = typeof window === 'undefined';
const history = isServer ? createMemoryHistory(process.env.BASE_URL) : createWebHistory(process.env.BASE_URL);
const router = createRouter({
  history,
  routes,
});

router.beforeEach((to) => {

  // redirect to login if auth required
  if (to.meta.requiresAuth && !store.state.auth.loggedIn) {
    return {name: 'Login'}
  }
})

export default router;

src/app.vue

<template>
  <MainHeader/>
  <div class="container-fluid zo-below-fixed-top" id="home">

    <div class="row">

      <div class="col-xl-12 col-xxl-9 col-xxxl-8" id="zo-main">
        <router-view/>
      </div>
    </div>
  </div>
  <MainFooter/>
</template>

<style lang="scss">
@import "@/assets/css/zueriost.scss";

</style>

<script>
import MainHeader from "./components/layout/MainHeader";
import MainFooter from "./components/layout/MainFooter";
import {useHead} from "@vueuse/head";
import {computed} from "vue";
import {useStore} from 'vuex'

export default {
  components: {MainFooter, MainHeader},
  setup() {
    const store = useStore()
    useHead({
      title: computed(() => store.state.meta.title),
    })
  },

}
</script>

src/app.js

import { createSSRApp, createApp } from 'vue';
import { createHead } from '@vueuse/head'
import App from './App.vue';

import router from './router';
import store from './store';

const head = createHead();
const isSSR = typeof window === 'undefined';

export default function buildApp() {
  const app = (isSSR ? createSSRApp(App) : createApp(App));

  app.use(router);
  app.use(store);
  app.use(head);

  return { app, router, store, head };
}

src/main-server.js(服务器条目)

import buildApp from './app';

export default (url) => new Promise((resolve, reject) => {
  const { router, app, store, head } = buildApp();

  // set server-side router's location
  router.push(url);

  router.isReady()
    .then(() => {
      const matchedComponents = router.currentRoute.value.matched;
      // no matched routes, reject with 404
      if (!matchedComponents.length) {
        return reject(new Error('404'));
      }

      // the Promise should resolve to the app instance so it can be rendered
      return resolve({ app, router, store, head });
    }).catch(() => reject);
});

src/main.js(src/main.js)( client)

import buildApp from './app';

const { app, router, store } = buildApp();

// eslint-disable-next-line no-underscore-dangle
const storeInitialState = window.INITIAL_DATA;
if (storeInitialState) {
  store.replaceState(storeInitialState);
}

router.isReady()
  .then(() => {
    app.mount('#app', true);
  });

server.js(Express Server)

/* eslint-disable no-param-reassign */
/* eslint-disable import/no-dynamic-require */
const serialize = require('serialize-javascript');
const path = require('path');
const express = require('express');
const fs = require('fs');
const { renderToString } = require('@vue/server-renderer');
const { renderHeadToString } = require('@vueuse/head');
const manifest = require('./dist/server/ssr-manifest.json');

// Create the express app.
const server = express();

// we do not know the name of app.js as when its built it has a hash name
// the manifest file contains the mapping of "app.js" to the hash file which was created
// therefore get the value from the manifest file thats located in the "dist" directory
// and use it to get the Vue App
const appPath = path.join(__dirname, './dist', 'server', manifest['app.js']);
const createApp = require(appPath).default;

const clientDistPath = './dist/client';
server.use('/img', express.static(path.join(__dirname, clientDistPath, 'img')));
server.use('/js', express.static(path.join(__dirname, clientDistPath, 'js')));
server.use('/css', express.static(path.join(__dirname, clientDistPath, 'css')));
server.use('/favicon.ico', express.static(path.join(__dirname, clientDistPath, 'favicon.ico')));

// handle all routes in our application
server.get('*', async (req, res) => {
  const { app, store, head } = await createApp(req);

  let appContent = await renderToString(app);
  const { headTags, htmlAttrs, bodyAttrs } = renderHeadToString(head);

  const renderState = `
    <script>
      window.INITIAL_DATA = ${serialize(store.state)}
    </script>`;

  fs.readFile(path.join(__dirname, clientDistPath, 'index.html'), (err, html) => {
    if (err) {
      throw err;
    }

    appContent = `<div id="app">${appContent}</div>`;

    html = html.toString()
      .replace('<div id="app"></div>', `${appContent}`)
      .replace('</head>', `${headTags}${renderState}</head>`);
    res.setHeader('Content-Type', 'text/html');
    res.send(html);
  });
});

const port = process.env.PORT || 8080;
server.listen(port, () => {
  console.log(`You can navigate to http://localhost:${port}`);
});

package.json

{
  "name": "ssr_vue_3",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "startcsr": "vue-cli-service serve",
    "buildcsr": "vue-cli-service build",
    "build": "rm -rf ./dist && npm run build:client && npm run build:server",
    "build:client": "vue-cli-service build --dest dist/client",
    "build:server": "cross-env SSR=1 vue-cli-service build --dest dist/server",
    "start": "node server.js",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vue/server-renderer": "^3.2.33",
    "@vueuse/head": "^0.7.6",
    "axios": "^0.27.2",
    "core-js": "^3.6.5",
    "cross-env": "^7.0.2",
    "express": "^4.17.1",
    "node-fetch": "^2.6.1",
    "serialize-javascript": "^5.0.1",
    "vue": "^3.0.0",
    "vue-axios": "^3.4.1",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0",
    "vue3-cookies": "^1.0.6"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-airbnb": "^5.0.2",
    "@vue/test-utils": "^2.0.0-0",
    "babel-eslint": "^10.1.0",
    "cross-env": "^7.0.2",
    "eslint": "^6.8.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-vue": "^7.0.0",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "typescript": "~3.9.3",
    "vue-jest": "^5.0.0-0",
    "webpack-manifest-plugin": "^2.2.0",
    "webpack-node-externals": "^2.5.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {
      "max-len": [
        2,
        300,
        4,
        {
          "ignoreUrls": true
        }
      ]
    },
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/unit/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ],
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
    "transform": {
      "^.+\\.vue$": "vue-jest"
    }
  }
}

vue.config.js

const ManifestPlugin = require('webpack-manifest-plugin');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  devServer: {
    overlay: {
      warnings: false,
      errors: false,
    },
  },
  chainWebpack: (webpackConfig) => {
    webpackConfig.module.rule('vue').uses.delete('cache-loader');
    webpackConfig.module.rule('js').uses.delete('cache-loader');
    webpackConfig.module.rule('ts').uses.delete('cache-loader');
    webpackConfig.module.rule('tsx').uses.delete('cache-loader');

    if (!process.env.SSR) {
      // This is required for repl.it to play nicely with the Dev Server
      webpackConfig.devServer.disableHostCheck(true);

      webpackConfig.entry('app').clear().add('./src/main.js');
      return;
    }

    webpackConfig.entry('app').clear().add('./src/main-server.js');

    webpackConfig.target('node');
    webpackConfig.output.libraryTarget('commonjs2');

    webpackConfig.plugin('manifest').use(new ManifestPlugin({ fileName: 'ssr-manifest.json' }));

    webpackConfig.externals(nodeExternals({ allowlist: /\.(css|vue)$/ }));

    webpackConfig.optimization.splitChunks(false).minimize(false);

    webpackConfig.plugins.delete('hmr');
    webpackConfig.plugins.delete('preload');
    webpackConfig.plugins.delete('prefetch');
    webpackConfig.plugins.delete('progress');
    webpackConfig.plugins.delete('friendly-errors');

    // console.log(webpackConfig.toConfig())
  },
};

现在,此设置工作就像魅力一样。 中的DOC中,

但是,如果我尝试将懒惰的加载/代码介绍给此,例如VUE 3: SRC/Router/index.js

import {createRouter, createWebHistory, createMemoryHistory} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import Contact from '../views/Contact.vue';
import store from '../store'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    props: true,
  },
  {
    path: '/home',
    redirect: '/'
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
  },
  {
    path: '/contact',
    name: 'Contact',
    component: () => import(/* webpackChunkName: "contact" */ '../views/Contact.vue'),
  }
];

const isServer = typeof window === 'undefined';
const history = isServer ? createMemoryHistory(process.env.BASE_URL) : createWebHistory(process.env.BASE_URL);
const router = createRouter({
  history,
  routes,
});

router.beforeEach((to) => {

  // redirect to login if auth required
  if (to.meta.requiresAuth && !store.state.auth.loggedIn) {
    return {name: 'Login'}
  }
})

export default router;

NPM运行式构建 - 现在会创建多个JS文件,而不是仅仅是常规应用程序。 (某人).js。它还创建了称为联系人的JS文件。(somehash).js及其周围。(somehash).js 看起来像这样:

“

但是,我无法直接调用这些组件。当我这样做时,Express Server会以以下输出(个人路径编辑)崩溃:

You can navigate to http://localhost:8080
[Vue Router warn]: Path "/" was passed with params but they will be ignored. Use a named route alongside params instead.
[Vue Router warn]: Path "/about" was passed with params but they will be ignored. Use a named route alongside params instead.
[Vue Router warn]: uncaught error during route navigation:
Error: Cannot find module './js/about.0feb3705.js'
Require stack:
- (personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js
- (personalpath)\Projects\zueriost_vue\server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Function.requireEnsure [as e] ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:46:25)
    at component ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:3328:32)
    at extractComponentsGuards ((personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:2012:40)
    at (personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:3133:22
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '(personalpath)\\Projects\\zueriost_vue\\dist\\server\\js\\app.85883f58.js',
    '(personalpath)\\Projects\\zueriost_vue\\server.js'
  ]
}
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: Cannot find module './js/about.0feb3705.js'
Require stack:
- (personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js
- (personalpath)\Projects\zueriost_vue\server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Function.requireEnsure [as e] ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:46:25)
    at component ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:3328:32)
    at extractComponentsGuards ((personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:2012:40)
    at (personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:3133:22
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '(personalpath)\\Projects\\zueriost_vue\\dist\\server\\js\\app.85883f58.js',
    '(personalpath)\\Projects\\zueriost_vue\\server.js'
  ]
}

似乎他找不到可以在服务器端加载的模块,但是我不知道为什么以及如何修复此问题或在哪里搜索。如何将模块加载到服务器端?欢迎任何输入/线索。

I have a problem regarding the code splitting per route feature of Vue 3 while using SSR. I am talking about this one right here:
https://router.vuejs.org/guide/advanced/lazy-loading.html

My SSR setup is the following:

src/router/index.js (Router Component)

import {createRouter, createWebHistory, createMemoryHistory} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import Contact from '../views/Contact.vue';
import store from '../store'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    props: true,
  },
  {
    path: '/home',
    redirect: '/'
  },
  {
    path: '/about',
    name: 'About',
    component: About,
  },
  {
    path: '/contact',
    name: 'Contact',
    component: Contact,
  }
];

const isServer = typeof window === 'undefined';
const history = isServer ? createMemoryHistory(process.env.BASE_URL) : createWebHistory(process.env.BASE_URL);
const router = createRouter({
  history,
  routes,
});

router.beforeEach((to) => {

  // redirect to login if auth required
  if (to.meta.requiresAuth && !store.state.auth.loggedIn) {
    return {name: 'Login'}
  }
})

export default router;

src/App.vue

<template>
  <MainHeader/>
  <div class="container-fluid zo-below-fixed-top" id="home">

    <div class="row">

      <div class="col-xl-12 col-xxl-9 col-xxxl-8" id="zo-main">
        <router-view/>
      </div>
    </div>
  </div>
  <MainFooter/>
</template>

<style lang="scss">
@import "@/assets/css/zueriost.scss";

</style>

<script>
import MainHeader from "./components/layout/MainHeader";
import MainFooter from "./components/layout/MainFooter";
import {useHead} from "@vueuse/head";
import {computed} from "vue";
import {useStore} from 'vuex'

export default {
  components: {MainFooter, MainHeader},
  setup() {
    const store = useStore()
    useHead({
      title: computed(() => store.state.meta.title),
    })
  },

}
</script>

src/app.js

import { createSSRApp, createApp } from 'vue';
import { createHead } from '@vueuse/head'
import App from './App.vue';

import router from './router';
import store from './store';

const head = createHead();
const isSSR = typeof window === 'undefined';

export default function buildApp() {
  const app = (isSSR ? createSSRApp(App) : createApp(App));

  app.use(router);
  app.use(store);
  app.use(head);

  return { app, router, store, head };
}

src/main-server.js (Server Entry)

import buildApp from './app';

export default (url) => new Promise((resolve, reject) => {
  const { router, app, store, head } = buildApp();

  // set server-side router's location
  router.push(url);

  router.isReady()
    .then(() => {
      const matchedComponents = router.currentRoute.value.matched;
      // no matched routes, reject with 404
      if (!matchedComponents.length) {
        return reject(new Error('404'));
      }

      // the Promise should resolve to the app instance so it can be rendered
      return resolve({ app, router, store, head });
    }).catch(() => reject);
});

src/main.js (Client Entry)

import buildApp from './app';

const { app, router, store } = buildApp();

// eslint-disable-next-line no-underscore-dangle
const storeInitialState = window.INITIAL_DATA;
if (storeInitialState) {
  store.replaceState(storeInitialState);
}

router.isReady()
  .then(() => {
    app.mount('#app', true);
  });

server.js (Express Server)

/* eslint-disable no-param-reassign */
/* eslint-disable import/no-dynamic-require */
const serialize = require('serialize-javascript');
const path = require('path');
const express = require('express');
const fs = require('fs');
const { renderToString } = require('@vue/server-renderer');
const { renderHeadToString } = require('@vueuse/head');
const manifest = require('./dist/server/ssr-manifest.json');

// Create the express app.
const server = express();

// we do not know the name of app.js as when its built it has a hash name
// the manifest file contains the mapping of "app.js" to the hash file which was created
// therefore get the value from the manifest file thats located in the "dist" directory
// and use it to get the Vue App
const appPath = path.join(__dirname, './dist', 'server', manifest['app.js']);
const createApp = require(appPath).default;

const clientDistPath = './dist/client';
server.use('/img', express.static(path.join(__dirname, clientDistPath, 'img')));
server.use('/js', express.static(path.join(__dirname, clientDistPath, 'js')));
server.use('/css', express.static(path.join(__dirname, clientDistPath, 'css')));
server.use('/favicon.ico', express.static(path.join(__dirname, clientDistPath, 'favicon.ico')));

// handle all routes in our application
server.get('*', async (req, res) => {
  const { app, store, head } = await createApp(req);

  let appContent = await renderToString(app);
  const { headTags, htmlAttrs, bodyAttrs } = renderHeadToString(head);

  const renderState = `
    <script>
      window.INITIAL_DATA = ${serialize(store.state)}
    </script>`;

  fs.readFile(path.join(__dirname, clientDistPath, 'index.html'), (err, html) => {
    if (err) {
      throw err;
    }

    appContent = `<div id="app">${appContent}</div>`;

    html = html.toString()
      .replace('<div id="app"></div>', `${appContent}`)
      .replace('</head>', `${headTags}${renderState}</head>`);
    res.setHeader('Content-Type', 'text/html');
    res.send(html);
  });
});

const port = process.env.PORT || 8080;
server.listen(port, () => {
  console.log(`You can navigate to http://localhost:${port}`);
});

package.json

{
  "name": "ssr_vue_3",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "startcsr": "vue-cli-service serve",
    "buildcsr": "vue-cli-service build",
    "build": "rm -rf ./dist && npm run build:client && npm run build:server",
    "build:client": "vue-cli-service build --dest dist/client",
    "build:server": "cross-env SSR=1 vue-cli-service build --dest dist/server",
    "start": "node server.js",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@vue/server-renderer": "^3.2.33",
    "@vueuse/head": "^0.7.6",
    "axios": "^0.27.2",
    "core-js": "^3.6.5",
    "cross-env": "^7.0.2",
    "express": "^4.17.1",
    "node-fetch": "^2.6.1",
    "serialize-javascript": "^5.0.1",
    "vue": "^3.0.0",
    "vue-axios": "^3.4.1",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0",
    "vue3-cookies": "^1.0.6"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-unit-jest": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "@vue/eslint-config-airbnb": "^5.0.2",
    "@vue/test-utils": "^2.0.0-0",
    "babel-eslint": "^10.1.0",
    "cross-env": "^7.0.2",
    "eslint": "^6.8.0",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-vue": "^7.0.0",
    "sass": "^1.26.5",
    "sass-loader": "^8.0.2",
    "typescript": "~3.9.3",
    "vue-jest": "^5.0.0-0",
    "webpack-manifest-plugin": "^2.2.0",
    "webpack-node-externals": "^2.5.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {
      "max-len": [
        2,
        300,
        4,
        {
          "ignoreUrls": true
        }
      ]
    },
    "overrides": [
      {
        "files": [
          "**/__tests__/*.{j,t}s?(x)",
          "**/tests/unit/**/*.spec.{j,t}s?(x)"
        ],
        "env": {
          "jest": true
        }
      }
    ]
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ],
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
    "transform": {
      "^.+\\.vue
quot;: "vue-jest"
    }
  }
}

vue.config.js

const ManifestPlugin = require('webpack-manifest-plugin');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  devServer: {
    overlay: {
      warnings: false,
      errors: false,
    },
  },
  chainWebpack: (webpackConfig) => {
    webpackConfig.module.rule('vue').uses.delete('cache-loader');
    webpackConfig.module.rule('js').uses.delete('cache-loader');
    webpackConfig.module.rule('ts').uses.delete('cache-loader');
    webpackConfig.module.rule('tsx').uses.delete('cache-loader');

    if (!process.env.SSR) {
      // This is required for repl.it to play nicely with the Dev Server
      webpackConfig.devServer.disableHostCheck(true);

      webpackConfig.entry('app').clear().add('./src/main.js');
      return;
    }

    webpackConfig.entry('app').clear().add('./src/main-server.js');

    webpackConfig.target('node');
    webpackConfig.output.libraryTarget('commonjs2');

    webpackConfig.plugin('manifest').use(new ManifestPlugin({ fileName: 'ssr-manifest.json' }));

    webpackConfig.externals(nodeExternals({ allowlist: /\.(css|vue)$/ }));

    webpackConfig.optimization.splitChunks(false).minimize(false);

    webpackConfig.plugins.delete('hmr');
    webpackConfig.plugins.delete('preload');
    webpackConfig.plugins.delete('prefetch');
    webpackConfig.plugins.delete('progress');
    webpackConfig.plugins.delete('friendly-errors');

    // console.log(webpackConfig.toConfig())
  },
};

Now, this setup works like a charm. However, if I try to introduce lazy loading/codesplitting into this, like in the doc of Vue 3:

src/router/index.js

import {createRouter, createWebHistory, createMemoryHistory} from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';
import Contact from '../views/Contact.vue';
import store from '../store'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    props: true,
  },
  {
    path: '/home',
    redirect: '/'
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
  },
  {
    path: '/contact',
    name: 'Contact',
    component: () => import(/* webpackChunkName: "contact" */ '../views/Contact.vue'),
  }
];

const isServer = typeof window === 'undefined';
const history = isServer ? createMemoryHistory(process.env.BASE_URL) : createWebHistory(process.env.BASE_URL);
const router = createRouter({
  history,
  routes,
});

router.beforeEach((to) => {

  // redirect to login if auth required
  if (to.meta.requiresAuth && !store.state.auth.loggedIn) {
    return {name: 'Login'}
  }
})

export default router;

The npm-run-build-command now creates multiple JS-Files instead of just the regular app.(somehash).js. It creates also the JS-files called contact.(somehash).js and about.(somehash).js
It looks like this:

dist folder when npm run build

However, I cannot call these components directly per Route. When I do so, the express server crashes with the following output (personalpath edited out):

You can navigate to http://localhost:8080
[Vue Router warn]: Path "/" was passed with params but they will be ignored. Use a named route alongside params instead.
[Vue Router warn]: Path "/about" was passed with params but they will be ignored. Use a named route alongside params instead.
[Vue Router warn]: uncaught error during route navigation:
Error: Cannot find module './js/about.0feb3705.js'
Require stack:
- (personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js
- (personalpath)\Projects\zueriost_vue\server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Function.requireEnsure [as e] ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:46:25)
    at component ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:3328:32)
    at extractComponentsGuards ((personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:2012:40)
    at (personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:3133:22
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '(personalpath)\\Projects\\zueriost_vue\\dist\\server\\js\\app.85883f58.js',
    '(personalpath)\\Projects\\zueriost_vue\\server.js'
  ]
}
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: Cannot find module './js/about.0feb3705.js'
Require stack:
- (personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js
- (personalpath)\Projects\zueriost_vue\server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Function.requireEnsure [as e] ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:46:25)
    at component ((personalpath)\Projects\zueriost_vue\dist\server\js\app.85883f58.js:3328:32)
    at extractComponentsGuards ((personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:2012:40)
    at (personalpath)\Projects\zueriost_vue\node_modules\vue-router\dist\vue-router.cjs.js:3133:22
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '(personalpath)\\Projects\\zueriost_vue\\dist\\server\\js\\app.85883f58.js',
    '(personalpath)\\Projects\\zueriost_vue\\server.js'
  ]
}

It seems like he cannot find the module to load on the server side, but I have no idea why and how to fix this or where to search. How to I load the modules on the server side? Any input/clues would be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文