Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a way for goober to async render #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Added a way for goober to async render
  • Loading branch information
cristianbote committed Jul 16, 2020
commit ca9c58ed014f209c8a991500129a2d380763b516
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 13,8 @@
"scripts": {
"start": "snowpack dev",
"build": "snowpack build",
"format": "prettier --write \"src/**/*.{js,jsx}\"",
"lint": "prettier --check \"src/**/*.{js,jsx}\"",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
"lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\"",
"test": "jest",
"build:server": "webpack --config ./server/webpack.config.js"
},
Expand Down
37 changes: 20 additions & 17 deletions server/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 2,9 @@ import Koa from 'koa';
import serve from 'koa-static';
import { h } from 'preact';
import renderToString from 'preact-render-to-string';
import { extractCss, setPragma } from 'goober';
import { setPragma } from 'goober';
import App from '../src/App';
import { mainGlobalStyles } from '../src/styles/main';
import { setupStylesCollector } from '../src/styles/styles-collector';

setPragma(h);

Expand All @@ -18,29 18,32 @@ const app = new Koa();
const webpackManifest = require(ASSETS_MANIFEST_PATH);
const mainJs = webpackManifest.main.js;

app.use(serve(STATIC_ASSETS_PATH, {
index: 'NO_INDEX_FILE_ALLOWED.html',
})); // serve the static assets generated by snowpack build
app.use(
serve(STATIC_ASSETS_PATH, {
index: 'NO_INDEX_FILE_ALLOWED.html',
}),
); // serve the static assets generated by snowpack build

app.use(async (ctx) => {
// need to be called for every request
mainGlobalStyles();
const style = { data: '' };

// Setup the current request with a styles collector
setupStylesCollector(style);

const markup = renderToString(<App name="SSR" />);

// simulate asynchronous rendering, for example, maybe we are using react-apollo `renderToStringWithData()`
// Because goober use a single "sheet" for SSR, this will not work properly.
// Only the first finished request will get the style from extractCss();
await (async () => {
return new Promise(resolve => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 3000)
})
}, 3000);
});
})();

const style = extractCss();

console.log({style})
console.log({ style });

ctx.body = `
<html>
Expand All @@ -50,16 53,16 @@ app.use(async (ctx) => {
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Web site created using create-snowpack-app" />
<title>SSR - Snowpack preact</title>
<style>${style}</style>
<style>${style.data}</style>
</head>
<body>
<div id="root">${markup}</div>
<script defer src="${mainJs}"></script>
</body>
</html>
`
})
`;
});

app.listen(8001, () => {
console.log('Koa server listening on port 8001')
console.log('Koa server listening on port 8001');
});
38 changes: 21 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,27 1,31 @@
import { h } from 'preact';
import { h, Fragment } from 'preact';
import logo from './logo.png';
import * as classes from './styles/app';
import { GlobalStyles } from './styles/main';

const App: preact.FunctionComponent<{ name: string }> = ({ name = '' }) => {
console.log('Welcome,', name);

return (
<div className={classes.App()}>
<header className={classes.AppHeader()}>
<img src={logo} className={classes.AppLogo()} alt="logo" />
<p>
Edit <code>src/App.jsx</code> and save to reload.
</p>
<p>Welcome to Snowpack Preact TypeScript starter!</p>
<div className={classes.Content()}>
<pre className={classes.Pre()}>
<code>$ yarn install</code>
<br />
<code>$ yarn start</code>
</pre>
</div>
</header>
</div>
<Fragment>
<GlobalStyles />
<div className={classes.App()}>
<header className={classes.AppHeader()}>
<img src={logo} className={classes.AppLogo()} alt="logo" />
<p>
Edit <code>src/App.jsx</code> and save to reload.
</p>
<p>Welcome to Snowpack Preact TypeScript starter!</p>
<div className={classes.Content()}>
<pre className={classes.Pre()}>
<code>$ yarn install</code>
<br />
<code>$ yarn start</code>
</pre>
</div>
</header>
</div>
</Fragment>
);
};

Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 6,4 @@ test('renders learn preact link', () => {
const { getByText } = render(<App name="preact" />);
const linkElement = getByText(/learn preact/i);
expect(linkElement).toBeInTheDocument();
});
});
4 changes: 1 addition & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 2,10 @@ import { h, render } from 'preact';
import { setPragma } from 'goober';
import 'preact/devtools';
import App from './App.js';
import { mainGlobalStyles } from './styles/main';

// Setup goober to use preact jsx pragma
setPragma(h);

const container = document.getElementById('root') as HTMLElement;

mainGlobalStyles();
render(<App name={"John Doe"} />, container);
render(<App name={'John Doe'} />, container);
2 changes: 1 addition & 1 deletion src/styles/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
import { css } from 'goober';
import { css } from './styles-collector';

export const App = (): string => css`
text-align: center;
Expand Down
32 changes: 18 additions & 14 deletions src/styles/main.ts
Original file line number Diff line number Diff line change
@@ -1,16 1,20 @@
import { glob } from 'goober';
import { glob } from './styles-collector';

export const mainGlobalStyles = (): void => glob`
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
export const GlobalStyles = (): null => {
glob`
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}`;
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
`;
return null;
};
23 changes: 23 additions & 0 deletions src/styles/styles-collector.ts
Original file line number Diff line number Diff line change
@@ -0,0 1,23 @@
import { css as originalCss, glob as originalGlob } from 'goober';

let context: Object;

export const setupStylesCollector = (ctx: Object) => {
context = ctx;
};

export const css = (tag: TemplateStringsArray | string, ...props: any[]) => {
if (context) {
return originalCss.bind({ target: context })(tag, ...props);
}

return originalCss(tag, ...props);
};

export const glob = (tag: TemplateStringsArray | string, ...props: any[]) => {
if (context) {
return originalGlob.bind({ target: context })(tag, ...props);
}

return originalGlob(tag, ...props);
};
8 changes: 4 additions & 4 deletions src/types/import.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 7,8 @@ interface ImportMeta {
env: Record<string, any>;
}

declare module "preact/devtools" {
declare module 'preact/devtools' {
// Empty. This module initializes the React Developer Tools integration
export = preactDevTools;
// when imported.
}
export = preactDevTools;
// when imported.
}
2 changes: 1 addition & 1 deletion src/types/static.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 29,4 @@ declare module '*.png' {
declare module '*.webp' {
const ref: string;
export default ref;
}
}
52 changes: 0 additions & 52 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3068,23 3068,6 @@ copy-webpack-plugin@^6.0.1:
serialize-javascript "^3.1.0"
webpack-sources "^1.4.3"

copy-webpack-plugin@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz#2b3d2bfc6861b96432a65f0149720adbd902040b"
integrity sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q 9yPRu7MtYFPt GBOXRav9lvIINifTQ1vSCs eA==
dependencies:
cacache "^15.0.4"
fast-glob "^3.2.4"
find-cache-dir "^3.3.1"
glob-parent "^5.1.1"
globby "^11.0.1"
loader-utils "^2.0.0"
normalize-path "^3.0.0"
p-limit "^3.0.1"
schema-utils "^2.7.0"
serialize-javascript "^4.0.0"
webpack-sources "^1.4.3"

core-js-compat@^3.6.2:
version "3.6.5"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c"
Expand Down Expand Up @@ -4299,18 4282,6 @@ fast-glob@^3.1.1, fast-glob@^3.2.2:
micromatch "^4.0.2"
picomatch "^2.2.1"

fast-glob@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3"
integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.0"
merge2 "^1.3.0"
micromatch "^4.0.2"
picomatch "^2.2.1"

fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
Expand Down Expand Up @@ -7057,13 7028,6 @@ p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0:
dependencies:
p-try "^2.0.0"

p-limit@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.1.tgz#584784ac0722d1aed09f19f90ed2999af6ce2839"
integrity sha512-mw/p92EyOzl2MhauKodw54Rx5ZK4624rNfgNaBguFZkHzyUG9WsDzFF5/yQVEJinbJDdP4jEfMN uBquiGnaLg==
dependencies:
p-try "^2.0.0"

p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
Expand Down Expand Up @@ -8503,13 8467,6 @@ serialize-javascript@^3.1.0:
dependencies:
randombytes "^2.1.0"

serialize-javascript@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa"
integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==
dependencies:
randombytes "^2.1.0"

set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
Expand Down Expand Up @@ -9600,15 9557,6 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha1-2pN/emLiH wf0Y1Js1wpNQZ6bHI=

url-loader@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.0.tgz#c7d6b0d6b0fccd51ab3ffc58a78d32b8d89a7be2"
integrity sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m RyM5N3mLx5BqJKccgxJS W3kqw==
dependencies:
loader-utils "^2.0.0"
mime-types "^2.1.26"
schema-utils "^2.6.5"

url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
Expand Down