prerender-spa-plugin icon indicating copy to clipboard operation
prerender-spa-plugin copied to clipboard

Webpack not building 100% when renderAfterDocumentEvent is defined

Open alexis-regnaud opened this issue 7 years ago • 4 comments

Hey,

I Use VueJs + webpack encore (Symfony 3). I would use the prerender-spa-plugin but when I defined a renderAfterDocumentEvent option, my npm run dev building is blocked at 95% emitting.

image

If I remove the renderAfterDocumentEvent option, the running has 100% but pages html are empty :

index.html : image

This is my webpackconfig.js :

// webpack.config.js
const Encore = require('@symfony/webpack-encore');
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const PrerenderSpaPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSpaPlugin.PuppeteerRenderer
//const JSDOMRenderer = require('@prerenderer/renderer-jsdom')

Encore
// the project directory where all compiled assets will be stored
    .setOutputPath('web/build/')
    // the public path used by the web server to access the previous directory
    .setPublicPath('/')

    /**Loader**/
    .addLoader({ test: /\.js$/, loader: 'babel-loader?cacheDirectory', include: [/node_modules\/foundation-sites/]})
    .addLoader({ test: /\.js$/, loader: 'babel-loader?cacheDirectory', include: [/node_modules\/vuex-cache/]})
    .addLoader({
        test: /\.js$/,
        enforce: 'pre',
        loader: 'eslint-loader',
        exclude: /node_modules/,
        options: {
            fix: true,
            emitWarning: true
       }
   })
    .addLoader({
        test: /\.modernizrrc\.js$/,
        loader: 'webpack-modernizr-loader',
        exclude: /node_modules/,
    })
    /** Add entry **/
    // will create public/build/app.js and public/build/app.css
    .addEntry('polyfill', ["babel-polyfill"])
    .addEntry('entrypoint', './assets/vue/entrypoint.js')
    //Style
    .addStyleEntry('app_style',[
        './assets/scss/app.scss'
    ])
    /***************/

    // allow legacy applications to use $/jQuery as a global variable
    .autoProvidejQuery()

    // enable source maps during development
    .enableSourceMaps(!Encore.isProduction())

    // empty the outputPath dir before each build
    .cleanupOutputBeforeBuild()

    // create hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

    // allow sass/scss files to be processed
    .enableSassLoader(function(sassOptions) {}, {
        resolveUrlLoader: false
    })

    // to enable vue
    .enableVueLoader()
    .enablePostCssLoader((options) => {
        options.config = {
            path: './postcss.config.js'
        };
    })

    /** Add plugin **/
    .addPlugin(
        new HtmlWebpackPlugin({
            title: 'PRODUCTION prerender-spa-plugin',
            template: path.resolve(__dirname, './app/Resources/views/front/other.html'),
            filename: path.resolve(__dirname, './web/build/index.html')
        })
    )
    .addPlugin(
        new PrerenderSpaPlugin({
            staticDir: path.join(__dirname, 'web/build'),
            routes: [ '/', '/about', '/contact' ],
            renderer: new Renderer({
                inject: {
                    foo: 'bar'
                },
               /* headless: false, */ 
                renderAfterDocumentEvent: 'render-event'
            }),
            renderAfterElementExists: '#app-vue'
        })
    )
/***************/
;

let config = Encore.getWebpackConfig();

if(Encore.isProduction()){
    /*** Uglify accept ES6 ****/
    // Remove the old version first
    config.plugins = config.plugins.filter(
        plugin => !(plugin instanceof webpack.optimize.UglifyJsPlugin)
    );
    // Add the new one
    config.plugins.push(new UglifyJsPlugin({
        cache: true,
        parallel: true
    }));
    /*********************/
}
/* global __dirname */
config.resolve.alias = {
    assets: path.resolve(__dirname, './web/assets'),
    modernizr$: path.resolve(__dirname, "./.modernizrrc.js"),
    vue$: 'vue/dist/vue.esm.js'
};
module.exports = config;

alexis-regnaud avatar Nov 07 '18 09:11 alexis-regnaud

After testing, the blocked statu is only in dev build, in a prod build 100% are emitting.. In my proccess will not be a blocking problem because the prerender will be only in prod build.

But I have always a issu, my compiled assets are in a build folder (.js and .css) but actualy in the index.html the link is : <script type="text/javascript" src="/entrypoint.1429cc83.js"></script> Instead of : <script type="text/javascript" src="/build/entrypoint.1429cc83.js"></script>

I tried to change .setPublicPath('/') in .setPublicPath('/build') or .setPublicPath('/build/') but the building again blocked to 95% ..

alexis-regnaud avatar Nov 07 '18 09:11 alexis-regnaud

I have the same problem that I was build the official example, which is always blocked and shows "98% after emitting PrerenderSPAPlugin". When I removed the renderAfterDocumentEvent, it worked.

light0x00 avatar Aug 07 '19 03:08 light0x00

It stays at 98% cos PrerenderSPAPlugin is waiting for DocumentEvent to fire but it's not firing. It will actually keep waiting forever, so try figure out why DocumentEvent is not firing and you have your way!

ajayidavid99 avatar May 31 '20 20:05 ajayidavid99

you should move document.dispatchEvent(new Event('render-event')) to root. like this: let app = new Vue({ el: '#app', router, render: h => h(App), mounted() { // You'll need this for renderAfterDocumentEvent. setTimeout(() => { document.dispatchEvent(new Event('render-event')); }, 5000); }, });

luoshenxia avatar Apr 13 '21 13:04 luoshenxia