preactjs / preact-cli

😺 Your next Preact PWA starts in 30 seconds.
MIT License
4.69k stars 375 forks source link

Custom render-html-plugin method #844

Open cortopy opened 5 years ago

cortopy commented 5 years ago

Do you want to request a feature or report a bug? Request a feature

What is the current behaviour? Preact-cli uses its own html-render-plugin and it's very difficult to extend. For example, in L54 it seems like the prerender method can be customised. But how does one get to pass the configuration for it?

If the current behaviour is a bug, please provide the steps to reproduce.

What is the expected behaviour?

If this is a feature request, what is motivation or use case for changing the behaviour?

I would like to be able to extend render-html-plugin for my own purposes like:

Please mention other relevant information.

I would like to start a discussion on which would be the best way to accomplish this. Would a PR that aims to do the following look good?

Please paste the results of preact info here.

cortopy commented 5 years ago

Ah!! I've just realised something like this is already discussed in https://github.com/preactjs/preact-cli/pull/839

prateekbh commented 5 years ago

Hi! Yes, the cases u listed seems like valid use cases. The approach also seems fine.

alternative plugins can also be initialized in preact.config.js, in which case render-html-plugin is not used

Is the only part i am not sure about as the setting in the the template.html are the key to the performance promised by preact-cli

cortopy commented 5 years ago

Hi! Yes, the cases u listed seems like valid use cases. The approach also seems fine.

alternative plugins can also be initialized in preact.config.js, in which case render-html-plugin is not used

Is the only part i am not sure about as the setting in the the template.html are the key to the performance promised by preact-cli

That would be the ultimate case when a developer knows what s/he is doing and prefers using her/his own prerender plugin. In this proposal, if nothing is provided in the config in regards to prerendering, then all the defaults are used, so users should not experience anything different to what preact-cli does now. This shouldn't be a breaking change

kenny-f commented 4 years ago

I've just run into this problem too. It would be nice to have an escape hatch for customising the prerender.

I managed to find a solution after reading the preact-cli source code and coming up with an elaborate workaround that doesn't involve forking the repo.

I'll detail the workaround here for other people running into the same issues. The problem I was trying to solve was that there was a FOUC when using material-ui because their styles were not being inlined, but this could easily be the case for styled-components, emotion etc.

// index.js - export a function to use later
import { ServerStyleSheets } from '@material-ui/core/styles';
import renderToString from 'preact-render-to-string';

export const createCss = () => {
    const sheets = new ServerStyleSheets();

    renderToString(
        sheets.collect(<App />)
    );

    return sheets.toString();
};

create a plugin by creating a preact.config.js file so that we can add a function to the HtmlWebpackPlugin

const { resolve } = require('path');

const createServerStyleSheets = (env) => () => {
    if (!env.ssr) {
        let entry = resolve(env.dest, './ssr-build/ssr-bundle.js');

        return require(entry).createCss();
    }
};

export default (config, env, helpers) => {
    const createCss = createServerStyleSheets(env);

    const plugins = helpers.getPluginsByName(config, 'HtmlWebpackPlugin');
    plugins.forEach((p) => {
        p.plugin.options.css = createCss;
    });
};

Create a template.html which is a copy of the default preact-cli one except with the extra line of injected inline styles where we call the function we attached in the custom plugin.

    <style id="jss-server-side"><%= htmlWebpackPlugin.options.css() %></style>

This took me a while to figure out. It would be great if there was a way to do this with a config option.

developit commented 4 years ago

I created a solution for styled-components that adds support for stylesheet SSR in preact-cli, and doesn't really require any special configuration or tweaks (aside from defining an SSR constant that we should probably have added in core anyway).

You can check it out here: https://gist.github.com/developit/23fc4995c3b2c07bd8ff3f916565bb03