-
-
Notifications
You must be signed in to change notification settings - Fork 383
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
Get CSS and JS for requested chunk at server itself #343
Comments
I'll simplify my query. I'm able to make SSR work using "loadable-components". When the app loads in the browser, it's the main bundle which inserts the requested route's chunk in DOM, as I'm not able to get the requested chunk on server. This works fine but I need to get requested route's chunk's JS+CSS file on server side itself. How can we do that?
This only gives me |
@Rid Anyways, ignore. I found in some article saying that this lib behaves in same manner as in my post. So, using react-loadable for my purpose. |
@aseem2625 you should not use react-loadable, but anyway if it fits your needs, stick with it. |
@aseem2625 did you tag me in by a mistake? I'm not the maintainer of this project. We're using it in https://github.com/wellyshen/react-cool-starter |
Yeh, right @Rid. Actually, you referenced it in the wrong issue, so I tagged you. So, I just wanted to tell that this is not issue with setting up SSR with @neoziro I'm not sure why shouldn't use My requirement was to have chunk JS/CSS info available at the server only. But it's being available at browser side. So, wanted to reduce the latency. I was able to make chunking perfectly working with |
@aseem2625 react-loadable have issue tab closed and only merge PR that modifies docs. The project is literally dead. It is not compatible with new features coming into React and not compatible with last versions of webpack. But yeah you could use it if you want. |
@neoziro Hi there! Thanks for this package. scriptTags <script id="__LOADABLE_REQUIRED_CHUNKS__" type="application/json">[]</script>
<script async data-chunk="app" src="/build/runtime.js"></script>
<script async data-chunk="app" src="/build/app-chunk.js"></script> linkTags <link data-chunk="app" rel="preload" as="script" href="/build/runtime.js">
<link data-chunk="app" rel="preload" as="style" href="/build/app.css">
<link data-chunk="app" rel="preload" as="script" href="/build/app-chunk.js"> styleTags <link data-chunk="app" rel="stylesheet" href="/build/app.css"> Also, I have two entry points: app for client and node for ssr. SSR result code is correct but doesn`t content js and css links on chunks. const extractor = new ChunkExtractor({ statsFile, entrypoints: ['app'] });
const nodeExtractor = new ChunkExtractor({ statsFile: nodeStatsFile, entrypoints: ['node'] });
const App = nodeExtractor.requireEntrypoint('node');
const rContext = { ...routerContext, ...RC };
const jsx = extractor.collectChunks(
React.createElement(App, {
userAgent : req && req.headers['user-agent'],
url,
data,
routerContext: rContext,
}),
);
const scriptTags = extractor.getScriptTags();
... In webpack: ...
externals: [
'@loadable/component',
nodeExternals({
whitelist : [/\.(?!(?:jsx?|json)$).{1,5}$/i],
modulesFromFile: true,
}),
],
... And @theKashey your |
You have to use |
@theKashey thanks for a quick answer. I use nodeExtractor only to get App component. But without it, I have the same issue. |
Server code emits "chunk-name" of the used component and |
All my chunks has ...
"react-eq-posts-list": [
"react-eq-posts-list.css",
"react-eq-posts-list-chunk.js"
],
...
"assets": [
...
{
"name": "react-eq-posts-list-chunk.js",
"size": 78703,
"chunks": [
"react-eq-posts-list"
],
"chunkNames": [
"react-eq-posts-list"
]
},
{
"name": "react-eq-posts-list.css",
"size": 8635,
"chunks": [
"react-eq-posts-list"
],
"chunkNames": [
"react-eq-posts-list"
]
},
...
]
... But I have no one chunk. |
🤷♂️ I'm afraid it's not solvable without example. |
Thanks for the idea. Result:[
'react-eq-shape-overlay',
'react-eq-menu',
'react-eq-gallery',
'react-eq-notifications-notify',
'react-eq-notifications',
'react-eq-theme-paper',
'react-eq-posts-filter-calendar',
'react-eq-cart-button',
'react-eq-theme-paper-header-large',
'react-eq-weather',
'react-eq-tags',
'react-eq-ui-feature',
'react-eq-theme-paper-footer-content',
'react-eq-theme-paper-auth-info',
'react-eq-posts-list',
'react-eq-social-share',
'react-eq-card',
'react-eq-special-block',
'react-eq-comments'
] usedStyles can find that:[
"app.css"
"react-eq-card.css"
"react-eq-comments.css"
"react-eq-events~react-eq-events-form.css"
"react-eq-gallery.css"
"react-eq-notifications.css"
"react-eq-places~react-eq-places-form.css"
"react-eq-posts-list.css"
"react-eq-posts-list~react-eq-posts-preview.css"
"react-eq-posts-list~react-eq-posts-single.css"
"react-eq-posts-list~react-eq-posts-single~react-eq-posts-theme-form.css"
"react-eq-posts-preview.css"
"react-eq-shape-overlay.css"
"react-eq-shop-routes.css"
"react-eq-social-share.css"
"react-eq-tags.css"
"react-eq-theme-paper-header-default~react-eq-theme-paper-header-large.css"
"react-eq-theme-paper-header-large.css"
"react-eq-theme-paper-news-aside.css"
"react-eq-theme-paper.css"
"react-eq-ui-feature.css"
] I will try to understand how this package work and what happens with |
I found it! Wrong wayconst getExt = (url, { routerContext: RC, ...data }, routerContext, req) => {
const extractor = new ChunkExtractor({ statsFile, entrypoints: ['app'] });
const nodeExtractor = new ChunkExtractor({ statsFile: nodeStatsFile, entrypoints: ['node'] });
const App = nodeExtractor.requireEntrypoint('node');
const jsx = extractor.collectChunks(React.createElement(App, params));
const scriptTags = extractor.getScriptTags();
const linkTags = extractor.getLinkTags();
const styleTags = extractor.getStyleTags();
return { jsx, scriptTags, linkTags, styleTags };
};
const renderWithStream = (params) => {
const { jsx, ...ext } = getExt(params);
const htmlStream = ReactDOMServer.renderToNodeStream(jsx);
...
return { htmlStream, ...ext };
};
const render = (params) => {
const { jsx, ...ext } = getExt(params);
const html = ReactDOMServer.renderToString(jsx);
...
return { html, ...ext };
} IMPORTANT use const renderStatic = (params) => {
const { jsx, extractor } = getExt(params);
const html = ReactDOMServer.renderToString(jsx); // <--- IMPORTANT before use extractor.get
const scriptTags = extractor.getScriptTags();
const linkTags = extractor.getLinkTags();
const styleTags = extractor.getStyleTags();
return { html, scriptTags, linkTags, styleTags };
} Can I ask why it is so important? How @aseem2625 maybe it is will be useful for you. |
Ok. So |
No |
Wow i ran into the same issue that is fixed by #343 (comment). Never thought that |
i am still wondering how extractor works with ReactDOMServer? |
When a route is requested from server, I need to find all the required style and bundle required for that route.
This gives me script and style tags for
base
andvendor
bundle. BUT the requested chunk's JS and CSS are not included here. It's thisbase.js
bundle when loaded on browser makes request to corresponding chunk.How we can achieve that in such a way that loadableReady includes that chunk's JS and CSS as well for that loadableReady( ofcourse on client)?
I can do the same in
react-loadable
This gives me the required chunk's JS and CSS but the limitation is it doesn't include
base
andvendor
bundle's JS/CSSand hence, opposite to
loadable-components
, Loadable.preloadReady won't includemain
andvendor
bundle's CSS and JS to load.So, for
react-loadable
, I've to implement loading vendor and base bundle before chunk's JS/CSS. But not sure how to know the chunk in case ofloadable-components
while at serverNote: I'm having only one entry point for JS
base
. style for base's CSS are extracted usingmini-css-extract
plugin. And vendor is split using webpack'sSplitchunks
.The text was updated successfully, but these errors were encountered: