alidcast / rogue.js Goto Github PK
View Code? Open in Web Editor NEWThe "nearly invisible" way to server-render React applications
License: MIT License
The "nearly invisible" way to server-render React applications
License: MIT License
start
scriptnextjs /examples
folder provides a great starting point if anyone wants to help with this
Though I'm thinking so many examples aren't needed since Rogue is much simpler (It's basically just React and React Router 4!).
I'll soon create a starter template and I think that will be much more useful than examples; but I'll still leave this issue here in case anyone encounters it and wants to contribute/discuss
hi,
0.1.9 build results in the following error
ReferenceError: SERVER is not defined
at Object.<anonymous> (.../node_modules/rogue/scripts/dev.js:16:31)
at Module._compile (internal/modules/cjs/loader.js:702:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:713:10)
at Module.load (internal/modules/cjs/loader.js:612:32)
at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
at Function.Module._load (internal/modules/cjs/loader.js:543:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:744:10)
at startup (internal/bootstrap/node.js:238:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:572:3)
0.1.6 is OK
thanks,
tinto
We need to decide on getInitialProps` usage:
getInitialProps
be called during client navigation? #18getInitialProps
align with expectations based on its name? If not, we should consider our own method #42In order to get point 1 & 2 I'm thinking we would need to wrap Router component so that we can handle getInitialProps per page on the client...though that still leaves open behavior for Providers/Hocs that aren't nested in Routes
For now I'm considering changing name since it seems to be simplest path forward
There are two ways we can go with Rogue. The Nextjs route, where the build setup and ssr setup are together, or Afterjs route, where they are separate and you can use any build system (.e. Razzlejs)
The reason I'm considering the second option, is that I've run into a few problems with Parcel; and I'm supposed to be focused on building an app I'm working on, so would like to get back to that asap
If we make a Rogue app independent of build setup, then anyone can start using Rogue now using Razzle and not have to wait till the rogue-parcel-srr build setup is far enough along to push an app to production; and later it should be easy to exchange Razzle for a Rogue-Parcel setup fsor faster build times
I'll also note that, @DeMoorJasper, a core team member of Parcel, recently released Blazingly (https://github.com/DeMoorJasper/blazingly), an experimental repo testing Parcel for SSR. I think I'd be awesome if we could work together towards a common solution. If he'd consider putting the framework specific bit aside, I could see Blazingly turning into a Razzlejs alternative that any application, such as Rogue, can run on top of.
You guys have showed interested in project so cc'ing you to get your thoughts
@alexparish @peter-mouland @ctrlplusb @nyl-auster
can i import style.css/scss in App.js file?
bundle.js:39 Uncaught Error: Cannot find module 'core-js/modules/es6.typed.array-buffer'
at newRequire (VM152 bundle.js:39)
at localRequire (VM152 bundle.js:54)
at Object.parcelRequire.1 (VM152 bundle.js:109)
at newRequire (VM152 bundle.js:48)
at parcelRequire.1 (VM152 bundle.js:80)
at VM152 bundle.js:106
We shouldn't call it on client side mount side that will cause a props mismatch. But it should still be called on client navigation, i.e. for redirects to work.
In order to make this happen I'm thinking will need to wrap the router Link
component (which I'd rather not do), unless there's a way to hook up to its events; gotta look into this
Hey, I've been checking out your project and I've been having some trouble integrating it into my React application which needs SSR. Essentially what happens is that I get the following error when I run npm run dev
:
C:\Users\lukec\Documents\git\the-jade-podium\node_modules\@roguejs\app\dist\server.js:165
constructor(App, { bundleUrl }) {
^
TypeError: Cannot destructure property `bundleUrl` of 'undefined' or 'null'.
at new App (C:\Users\lukec\Documents\git\the-jade-podium\node_modules\@roguejs\app\dist\server.js:165:16)
at Module../src/server.js (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\src\server.js:9:1)
at __webpack_require__ (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:682:1)
at fn (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:59:1)
at Module../src/index.js (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\src\index.js:1:1)
at __webpack_require__ (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:682:1)
at fn (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:59:1)
at Object.0 (C:\Users\lukec\Documents\git\the-jade-podium\build\server.js:1704:18)
at __webpack_require__ (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:682:1)
at module.exports../build/assets.json.module.exports.client.js (C:\Users\lukec\Documents\git\the-jade-podium\build\webpack:\webpack\bootstrap:749:1)
I modified my code to be similar to what you have for the with-razzle example. Here is my package.json:
{
"name": "the-jade-podium",
"version": "0.1.0",
"private": true,
"dependencies": {
"@roguejs/app": "^0.6.8",
"razzle": "^2.2.0",
"react-bulma-components": "^1.5.0",
"react-typography": "^0.16.13",
"typeface-cabin-condensed": "0.0.54",
"typeface-patua-one": "0.0.54",
"typography": "^0.16.17",
"typography-theme-funston": "^0.15.10",
"babel-polyfill": "^6.26.0"
},
"scripts": {
"dev": "razzle start"
}
}
client.js
import { hydrate } from '@roguejs/app'
import App from './App'
hydrate(App)
index.js
import http from 'http'
import app from './server'
const server = http.createServer(app.render)
let currentApp = app
server.listen(process.env.PORT || 3000, error => {
if (error) {
console.log(error)
}
console.log('๐ started')
})
if (module.hot) {
console.log('โ
Server-side HMR Enabled!')
module.hot.accept('./server', () => {
console.log('๐ HMR Reloading `./server`...')
server.removeListener('request', currentApp)
const newApp = require('./server').default
server.on('request', newApp)
currentApp = newApp
})
}
server.js
import Rogue from '@roguejs/app/server'
import { Helmet } from 'react-helmet'
import serveStatic from 'serve-static'
import App from './App'
const publicDir = process.env.RAZZLE_PUBLIC_DIR
const bundleUrl = require(process.env.RAZZLE_ASSETS_MANIFEST).client.js
const app = new Rogue({
Helmet,
App,
bundleUrl
})
app.preuse(serveStatic(publicDir))
export default app
and my App.js
import React, { Component } from 'react';
import './App.css';
import 'react-bulma-components/dist/react-bulma-components.min.css';
import { Columns } from 'react-bulma-components';
import NavBar from './components/NavBar';
import Banner from './components/Banner';
import Typography from 'typography';
import funstonTheme from 'typography-theme-funston';
import logo from './assets/images/logo.png';
const typography = new Typography(funstonTheme);
typography.injectStyles();
class App extends Component {
render() {
return (
<div className="App">
<NavBar/>
<Banner/>
</div>
);
}
}
export default App;
Do you have any idea what I could be doing wrong?
It would be great if Rogue could be used as part of a larger Express app. Thanks for considering!
Hello here !
when running "npm run dev" i get the following message :
( mac OS Sierra 10.12.6, npm 6.1.0 )
> [email protected] dev /Applications/MAMP/htdocs/TEST/roguetest
> rogue
Unknown script "undefined".
Perhaps you need to update renso?
My package.json:
{
"name": "roguetest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "rogue",
"build": "rogue build",
"start": "rogue start"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-router-dom": "^4.3.1",
"rogue": "^0.1.1"
}
}
see what they're using in App.js file and add the SSR solution for it in server.js so that it works out of the box just like css preprocessors
It would be very useful to be able to access the parsed route params in getInitialProps
to load a particular resource using the url params as identifiers.
For example, when navigating to /users/:name
:
export default class App extends React.Component {
static async getInitialProps({ params }) {
const user = await fetchUserByName(params.name)
return { user }
}
// ...
}
I couldn't find a way to do this without parsing req.url
manually.
This tweet by @gaearon made me reconsider it https://twitter.com/dan_abramov/status/1021548632619790336
And now I'm realizing it that doing so in Rogue.js is unnecessary since we're just initializing App.js in the server (and not pages, anymore)
Sorry, not an issue. Just want to sing your praise on the work you are doing here. Amazing stuff. ๐
Can I still use this even I don't use Apollo GraphQL? Im using React Router 4 to manage my routes and I would like to explore doing SSR.
Cheers!
Hey @mkay581 are you still using the rogue
npm name? I couldn't find any repo for it but did see that you published a package under it.
If you're not using it, are you willing to give it away? I'm creating a SSR framework for React, with the tagline that it's "quick and invisible" so I'd love to use that name.
I didn't know how else to reach you, so if you see this let me know, thanks!
I really like emotion's logo.
Not sure how hard this would be to pull off, but I'd be super cool to have a logo that shows the upper body of semi-invisible female with a rogue outfit that partially displays a react logo
I'm also open to any ideas
If anyone is interested in contributing this, let me know
credit & link to your work will be given in readme
Can one of the examples be of importing this into an electron app. Please.
[email protected] dev /Applications/MAMP/htdocs/TEST/roguetest
rogue devfs.js:948
binding.stat(pathModule._makeLong(path));
^Error: ENOENT: no such file or directory, stat '/Applications/MAMP/htdocs/TEST/roguetest/public'
at Object.fs.statSync (fs.js:948:11)
at /Applications/MAMP/htdocs/TEST/roguetest/node_modules/graceful-fs/polyfills.js:297:22
at getStats (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/fs-extra/lib/copy-sync/copy-sync.js:42:14)
at startCopy (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/fs-extra/lib/copy-sync/copy-sync.js:37:10)
at copySync (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/fs-extra/lib/copy-sync/copy-sync.js:32:10)
at prepBuild (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/rogue/src/bundler/index.js:55:3)
at bundler (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/rogue/src/bundler/index.js:61:3)
at Object. (/Applications/MAMP/htdocs/TEST/roguetest/node_modules/rogue/scripts/dev.js:21:23)
at Module._compile (module.js:635:30)
at Object.Module._extensions..js (module.js:646:10)
What do you think about using prettier @alidcastano ?
Seems a good way of avoiding debates about code style.
Right now any data returned from getInitialProps
will be passed to the App.js
component. That component can then delegate the data to each page component.
Obviously, this isn't ideal as each getInitialProps
should operate in a black box.
Some ideas for handling this correctly:
loadable-components
does and pass data from server to window
object and the render component with appropriate data (this seems like the way to go)However, I don't know to what extent this is worth the hassle. If you're using Apollo, you don't really need to fetch data from getInitialProps
(right??). So it's only useful for plugin hocs
(e.g. Apollo, Redux, etc) to server render their own data (which would be passed to App.js anyway) and to handle route middleware in the server (which doesn't return any data).
So going to leave it as it is for now but posting my thoughts here for reference
First need to resolve #42
getIntialProps is only called in server now to bootstrap App.js with server logic
This method can be extracted at compile from the client bundle using a babel plugin. This would prevent unnecessary server code from being included in client bundle without relying on tree-shaking
I am running rogue.js version 0.6.10 and still getting this issue for bundle.js. Mentioned in #20.
I am also new to SSR and I don't know if I figured out what is the right purpose for this bundle. Should it be compiled client side (client.js) script for usage when continuing with an app on the browser side after initial server render?
razzle example uses some client.js script so I don't know, because when I build the app via @roguejs/cli the bundle.js contains ES5 version of server.js code, but that may be the error and because of it I got confused.
Thanks for answer.
Keep up the great work. Rogue.js will be awesome.
so much for #2 :(
right now we're walking tree checking for two switch statements
The idea was that you'd have a layout and a page
However, with React Router 4, layouts are declared inside the same route as a page
E.g. rather than this
<Route path="login|register" component={AuthLayout} />
You do this:
<Route path="login" render:{() => <AuthLayout><Login /><AuthLayout>} />
So we can likely remove condition where we look for two switch statements, and just continue walking tree until we find non-servevable components 5 levels apart
How would it be like to write custom plugins for rogue?
I'd like to support JSS to use Material-UI and it seems that only rogue-made hocs would work.
As I could see from their code, the hocs are simple and I could implement another one myself.
My question is: would that work? Because from what I could see from the docs it wouldn't.
Thanks for the awesome work!
Referring our discussions in this issue #37
Github repo to reproduce:
https://github.com/rayandrews/reproduce-rogue-behavior
what's the different?
cc: @alidcastano
I'm getting the following error when running the with-razzle example:
Warning: render(): Calling ReactDOM.render() to hydrate server-rendered markup will stop working in React v17. Replace the ReactDOM.render() call with ReactDOM.hydrate() if you want React to attach to the server HTML.
From what I can tell, the error seems to occur because window.__SSR_DATA__
is an empty object initially, which causes render
to be called. As I understand it, hydrate
should be called initially, followed by render
going forward on the client.
Would it be reasonable to tweak this similar to the approach Next took?
An example of how to add rogue to a default create-react-app would be great
Spent all day yesterday trying to get to the bottom of bundling issues... first an unexpected token import
then an undefined module 'react'
error.
I was using the package via a linked module, so then I randomly tried downloading the actual package and it worked, jesus
So problem seems to be the Parcel treats linked modules differently than downloaded ones (parcel-bundler/parcel#1617)... geezzz, I guess that's why people don't like too much magic but still I think Parcel's going to be great
Anyway, I ended up going back to es5 code and using React.createElement
rather than JSX and now, no bundling needed!
Wow, everythings so simple now
I hate fighting with bundling issues, such a waste of time
Opening this issue as a reminder of why I made this decision, and so I can send anyone that asks over here
Cheers
I like the idea of zero configuration while being able to eject (like create-react-app)
Just not sure if for SSR it's more problems than it's worth.
E.g. if I contionally take over server.js, need a way for user to still start app manually for testing
I'm running into very odd behavior using the with-razzle example. The Razzle app runs and reloads as expected prior to adding Rogue and I'm wondering if anyone else is seeing this behavior or not.
Steps to reproduce:
Create new Razzle app
create-razzle-app with-razzle
cd with-razzle
Start the app, make a change to Home.js
, then verify the app is built and reloads as expected
Install Rogue using specific version to match with-razzle example
yarn add @roguejs/[email protected]
Overwrite contents of local server.js
, index.js
, client.js
, and App.js
files with content from with-razzle example directory files
Start the app, make a change to App.js
, then verify the app is built and reloads as expected
โ success server compiled in 141ms
โ success client compiled in 165ms
๐ HMR Reloading `./server`...
[HMR] Updated modules:
[HMR] - ./src/App.js
[HMR] - ./src/server.js
[HMR] Update applied.
โ success client compiled in 564ms
Error displayed in the console:
Warning: Text content did not match. Server: "Roguejs with Razzle" Client: "Roguejs with Razzle!"
Browser still shows old content, but view source and JS bundle show the updated content
Upgrade @rogue/app to 0.6.11
Start the app, make a change to App.js
, then verify the app is built and reloads as expected
โ success server compiled in 750ms
โ success client compiled in 671ms
๐ HMR Reloading `./server`...
[HMR] Updated modules:
[HMR] - ./src/App.js
[HMR] - ./src/server.js
[HMR] Update applied.
โ success client compiled in 933ms
Browser shows the change quickly, then reverts to the content as it was prior to the change. Also, the 'text content did not match' message is back in the console.
View page source and JS bundle both have content matching the source
"dependencies": {
"@roguejs/app": "0.6.11",
"express": "4.16.3",
"razzle": "2.2.0",
"react": "16.4.1",
"react-dom": "16.4.1",
"react-router-dom": "4.3.1"
}
OS: Windows 10
Node: 8.11.3
Yarn: 1.5.1
In the example with razzle
when started, it does not open the browser automatically with the project executed
Right now we walk component tree and call getInitialProps per component
The problem for redux is that getInitialProps is called before App/Page components, so its doing nothing for ssr the store
Few ideas:
I guess it goes back to #42 - if pages don't need to query server data nor handle redirects what do pages need getInitialProps
for?
Hi there,
I was wondering if it would be possible to have a route protected by some server-side authentication.
Simplest example:
Most importantly, the data (including layout / content of the page) cannot be transmitted unless the client has successfully authenticated. I was hoping to use import
and have the server only return the component if the user is authenticated but don't know how to hook into this tool (or if it is possible).
Thanks in advance!
Hello !
Here is what i tried for now, but this is not server side rendered :
And here is my App.js
https://github.com/nyl-auster/roguepress/blob/7956588023c0524533e172f54e1159284be4fb50/src/App.js
Any suggestions ? Will be glad to complete README about this point :)
Is there any way to passing value of getInitialProps to suitable component props like Next.js or After.js?
Thank you!
Hi!
I'm giving rogue a trial with typescript.
I'm just using the example setup but exchanged the App.js with a App.tsx.
It's not hot-reloading and when i change the text in the divs i get the folowing error:
bundle.js:sourcemap:5721 Warning: Text content did not match. Server: "Welcome to Rogue.js test!" Client: "Welcome to Rogue.js!"...
What gives? Did i miss something?
When you do a 'npm run build' it be great if the files had checksums for cache busting (like webpack does). Otherwise you will still need to something like grunt to do that.
related to #66
loadable-components seems like the way to go
Sometimes bundle.js contains src/App.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.