Пробросить window и document в Vue при запуске через терминал NodeJS

В nodejs запускаю webpack, сервер polka (minimal express.js) и далее экземпляр Vue. Один компонент ругается на отсутствие window и document. Как в Nodejs можно создать эти глобальные переменные? Вроде есть пакеты (JSDOM например) которые позволяют создавать DOM. Пробовал через DefinePlugin в конфигурации WEBPACK делать глобальную переменную, но Vue не видит ее...

build.js

const fs = require('fs'),
    path = require('path'),
    polka = require('polka')
    vueSR = require('vue-server-renderer');

let renderer;

const app = polka();
require('./ssr/setup-dev-server.js')(app, {
    render(bundle) {
        renderer = vueSR.createBundleRenderer(bundle);
        renderer.renderToString().then(html => {
            fs.writeFileSync("./ssr/cache/"+process.argv[2]+".tmp", JSON.stringify(html))
        }).catch((e) => {
            console.log(e)
            fs.appendFileSync("./ssr/logs/errors.log", `\n${e.toString()}`)
            fs.writeFileSync("./ssr/cache/"+process.argv[2]+".tmp", '')
        })
    },
});

setup-dev-server

/* eslint-disable no-console */
const path = require('path'),
    webpack = require('webpack'),
    MFS = require('memory-fs');

const serverConfig = require('./webpack/webpack-server');

module.exports = (app, opts) => {
    const
        serverCompiler = webpack(serverConfig),
        mfs = new MFS(),
        serverBundlePath = path.join(serverConfig.output.path, 'vue-ssr-server-bundle.json');

    serverCompiler.outputFileSystem = mfs;

    serverCompiler.run((err, stats) => {
        if (err) throw err;
/*        stats = stats.toJson();
        stats.errors.forEach(err => console.error(err));
        stats.warnings.forEach(err => console.warn(err));*/
        opts.render(JSON.parse(mfs.readFileSync(serverBundlePath, 'utf-8')));
    });
};

webpack-server.js

const path = require('path'),
    { createConfig } = require('./webpack-base.js'),
    { DefinePlugin } = require('webpack'),
    VueSSRServerPlugin = require('vue-server-renderer/server-plugin');

const baseConfig = createConfig('server');

const serverConfig = Object.assign({}, baseConfig, {
    target: 'node',
    entry: './ssr/entry/server.js',
    output: {
        ...baseConfig.output,
        libraryTarget: 'commonjs2',
        filename: 'server-bundle.js',
        path: path.resolve(process.cwd(), 'dist/server'),
    },
    externals: Object.keys(require('../../../../package.json').dependencies),
    plugins: (baseConfig.plugins || []).concat([
        new DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
            window: 'undefined',
        }),
        new VueSSRServerPlugin(),
    ]),
});

serverConfig.module.rules = (baseConfig.module.rules || []).concat([
    {
        test: /\.(styl(us)?|css|less|sass|scss|sss)$/,
        loader: 'null-loader',
    },
]);

module.exports = serverConfig;

webpack-base.js

const path = require('path'),
    { VueLoaderPlugin } = require('vue-loader');

exports.createConfig = (runtimeEnv) => {
    const vueLoader = {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {},
    };

    const config = {
        devtool: false,
        mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
        output: {
            publicPath: '/dist/',
            filename: '[name].[chunkhash:8].js',
            chunkFilename: '[name].[chunkhash:8].js',
        },
        module: {
            rules: [

                // source files

                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    // needed for vue-loader to correctly import modules' components
                    exclude: file => /node_modules/.test(file) && !/\.vue\.js/.test(file),
                },
                vueLoader
            ],
        },
        resolve: {
            extensions: ['.js', '.vue', '.json'],
            modules: [
                'node_modules',
                process.cwd(),
            ],
        },
        performance: {
            hints: process.env.NODE_ENV === 'production' ? 'warning' : false,
        },
        plugins: [
            new VueLoaderPlugin(),
        ],
        stats: {
            all: false,
            colors: true,
            errors: true,
            hash: true,
            timings: true,
            version: true,
        }
    };

    if (process.env.NODE_ENV === 'development') {
        vueLoader.options.cacheDirectory = path.resolve(process.cwd(), 'node_modules/.cache/vue-loader-cache');
        vueLoader.options.cacheIdentifier = runtimeEnv;
    }

    return config;
};

server.js

import createApp from './app';

export default context => {
    return createApp(context);
};

Ответы (1 шт):

Автор решения: Денис Григоров

Решение: Помог пакет browser-env. В месте создания экземпляра сервера, нужно вызывать метод require('browser-env')(); Тогда появится полноценный виртуальный DOM и плагины, использующие DOM заработают

→ Ссылка