Компоненты vaz-маршрутизатора с отложенной загрузкой не работают с SSR - PullRequest
4 голосов
/ 03 октября 2019

У меня есть две разные точки входа для server.js и client.js (я использую vue-server-renderer и laravel-mix) - (мои server.js и client.js выглядят в точности так, как описано здесь - spatie / laravel-сервер-рендеринг и если я делаю статический экспорт import Test from '../views/Test', он работает ..

Если я пытаюсь импортировать маршрут без отложенной загрузки, SSR работает:

import Test from "../views/Test";

export const routes = [{
    path: '/my-route',
    name: "Test",  
    component: Test,
}]

Но если я попытаюсь выполнить отложенную загрузку, произойдет сбой в SSR:

export const routes = [{
    path: '/my-route',
    name: "Test"
    component: () => import('../views/Test.vue'),
}]

Не удается найти модуль './js/chunks/server/0.js?id=c3384f174123f0848451'

Для () => import('../views/Home.vue), client.js работает, не работает только server.js.


My server.js:

import renderVueComponentToString from 'vue-server-renderer/basic';
import app from './app';
import {router} from './router/index';

new Promise((resolve, reject) => {
    router.push(context.url);
    router.onReady(() => {
        resolve(app);
    }, reject);
})
    .then(app => {
        renderVueComponentToString(app, (err, res) => {
            if (err) throw new Error(err);

            dispatch(res);
        });
    });

Полная ошибка:

Команда "/ usr / bin / node /home/vagrant/Code/project/storage/app/ssr/1228cfee3f79dc5949bd898950384e53.js"Код выхода: 1 (общая ошибка)

Рабочий каталог: / home / vagrant / Код / project / public Вывод:

================ Ошибка вывода: ================ internal / modules / cjs / loader.js: 628 бросить ошибку;^

Ошибка: не удается найти модуль './js/chunks/server/0.js?id=c3384f174123f0848451'


Обновление

Я думаю, что у меня есть идея, почему это происходит (я могу ошибаться):

export const routes = [{
     path: '/', 
     name: "Home", 
     component: () => import('../views/Home')
}]

с этим кодом, я получаю ошибку:

Ошибка: Не удается найти модуль './js/chunks/server/0.js?id=c3384f174123f0848451'

Команда "/ usr / bin / node / home / vagrant / Code / project / storage / app / ssr/717358e60bfd52035a1e58256cdfbba0.js "не удалось. Код выхода: 1 (общая ошибка) Рабочий каталог: / home / vagrant / Код / project / public Вывод: ================ Ошибка вывода: ================ internal / modules / cjs / loader.js: 628 throw err;^ Ошибка: не удается найти модуль './js/chunks/server/0.js?id=c3384f174123f0848451'

Посмотрите на пути: в моем скомпилированном файле (который находится на public/js) яесть эта строка:

var chunk = require("./js/chunks/server/" + ({}[chunkId]||chunkId) + ".js?id=" + {"0":"c3384f174123f0848451"}[chunkId] + "");

Это похоже на относительный путь. Однако файл на самом деле выполняется в соответствии с тем, что я указал в config/ssr.php - 'temp_path' => storage_path('app/ssr') - поэтому он не может найти путь.

Однако даже я изменяю temp_path на public_path(), чтобы он могнайдите фрагмент из ./js/chunks/server/ (то есть public/js/chunks/server/0.js), он по-прежнему выдает ту же ошибку. Несмотря на то, что путь_схемы SSR отличается.

Команда "/ usr / bin / node /home/vagrant/Code/project/public/3560d8d101faa4bdef316054b14873cc.js" не выполнена. Код выхода: 1 (общая ошибка) Рабочий каталог: / home / vagrant / Код / project / public Вывод: ================ Ошибка вывода: ================ internal / modules / cjs / loader.js: 628 throw err;^ Ошибка: не удается найти модуль './js/chunks/server/0.js?id=c3384f174123f0848451'

Также, если я console.log(_dirname) в renderVueComponentToString(), он возвращает меня' / '

Ответы [ 2 ]

1 голос
/ 09 октября 2019

Я решил, теперь это работает с SSR и разделением кода только на стороне клиента - если у вас есть идея получше, я все еще уши.

Я использовал spatie / laravel-серверный рендеринг , и его довольно легко настроить.

Вот мое решение (и мои изменения в рендеринге spatie / laravel-server-side):

Я узнал об отделении пакетов от комментария charlesBochet , однако вместо 2x webpack.mix.js файлов я использовал один.

  • package.json
"scripts": {
    // concurrently is just for building them asynchronously 
    "dev-all": "concurrently \"npm --section=server run dev\" \"npm --section=client run dev\"  --kill-others-on-fail",

    // can also build them separately if you wish
    "dev-client": "npm --section=client run dev",
    "dev-server": "npm --section=server run dev"
     ...
}
  • webpack.mix.js
if (process.env.npm_config_section === 'server') {
    mix.js('resources/js/app-server.js', 'public/js')
        .webpackConfig({
            target: 'node',

            // Prevent code-splitting for server-build
            plugins: [
                new webpack.optimize.LimitChunkCountPlugin({
                    maxChunks: 1,
                })
            ],
        })
        // merge manifest is a package for merging manifests,
        // otherwise they'll get overwritten by each other
        // https://github.com/kabbouchi/laravel-mix-merge-manifest
        .mergeManifest()
        .version();

} else if (process.env.npm_config_section === 'client') {
    mix.js('resources/js/app-client.js', 'public/js')
        .webpackConfig({
            target: 'web',
            output: {
                chunkFilename: 'js/chunks/[name].js?id=[chunkhash]',
                publicPath: '/',
            },
        })
        .mergeManifest()
        .version();

    // Only build css with the client build, server build only needs
    // the html and not the css
    mix.sass('resources/sass/app.scss', 'public/css')
} else {
    console.log(
        '\x1b[41m%s\x1b[0m',
        'Provide correct --section argument to build command: server, client'
    );
    throw new Error('Provide correct --section argument to build command!')
}
  • app-server.js - должен дождаться готовности маршрутизатора
new Promise((resolve, reject) => {
    router.push(context.url);
    router.onReady(() => {
        resolve(app);
    }, reject);
})
    .then(app => {
        renderVueComponentToString(app, (err, res) => {
            if (err) throw new Error(err);
            dispatch(res);
        });
    });
  • app-client.js
router.onReady(function() {
    app.$mount('#app');
})
  • и, наконец, разделение кода файла маршрутизатора работает для app-client.js
export const routes = [
{
    path: '/',
    name: "Home",
    component: () => import('../views/Home.vue')
},
0 голосов
/ 07 октября 2019

Не знаю, откуда возникла проблема, но вы должны прочитать это:

Обратите внимание, что по-прежнему необходимо использовать router.onReady на сервере и клиенте, прежде чем вернуться/ монтирование приложения, поскольку маршрутизатор должен заранее разрешить компоненты асинхронного маршрута, чтобы должным образом вызывать перехваты компонентов ... Vue SSR, маршрутизация и разделение кода

Так что вместо

app.$mount('#app');

Попробуйте

router.onReady(() => {
  app.$mount('#app')
})

Надеюсь, это поможет.

...