-
-
Notifications
You must be signed in to change notification settings - Fork 376
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
Access memoryfs files #88
Comments
You can access the filesystem directly through the
edit: oops, apparently "You should not access |
@sunyang713, does the link @grrowl posted above answer your question? So you'd need to rewrite the request. |
Not quite @SpaceK33z, rewriting requests alone doesn't achieve what I need, because I would still need to access the memoryFs. I also posted in the issue that grrowl linked (no response yet). I've pasted below
|
@sunyang713, could you tell me why you need to rewrite the request to |
Thanks for the response @SpaceK33z . I want to be very clear about my use case, so this response is pretty long. I would be very happy to see if there's a nicer, /cleaner/ way to do this that the community has established, but at the time I hadn't found one, and I haven't found one since. I do use html-webpack-plugin. I use it to add a hash after my javascript builds. At the same time, I use server-side rendering with react. I need to render some initial content, AFTER the server is running and . . .
<%= "\<% if (content) { %\>" %>
<div id="root"><%= "\<%- content %\>" %></div>
<%= "\<% } else { %\>" %>
. . . At the bottom of the file, the correct . . .
<% if (content) { %>
<div id="root"><%- content %></div>
<% } else { %>
. . . So I've generated a template from a template, and I will then use this to server-render like so: app.set('view engine', 'ejs')
. . .
// on 200
res.render('index.ejs', appInjections()) where
And ... except it doesn't - here is the problem. In prod, I would build all of my javascript files before running my server. The document lives in the filesystem and is easily accessed using the static-middleware provided by express. But in devo, I use webpack-dev-middleware which means all files are served from memory. This also means that the generated // the return value of a new function renderApp()
ejs.render(getDocument(), { content }) where function getDocument() {
const memoryFs = compiler.outputFileSystem // 'compiler' is the webpack compiler
return memoryFs.readFileSync('index.ejs', 'utf8')
} In prod it looks like this: import fs from 'fs'
import path from 'path'
export default function getDocument() {
return fs.readFileSync('index.ejs', 'utf8')
} and the response command is changed to: // on 200
res.send(renderApp()) I would like for |
Thanks @sunyang713 for sharing your solution. I stumbled upon this inconvenient issue myself too with a pretty similar tech stack. In my case, I have a single-page app (SPA) with client-side routing and URLs like /login, /invite, /item/123, and the root / of course. To provide a boring use case, if a user bookmarks the /item/123 and browses to it later on, the URL needs to work. The express server should response the request /item/123 with index.html in a manner identical to the requests /, /login, and /invite. Their routing is then made on the client. However, in prod env this is easy as you showed but not so in dev env where I use the webpack-dev-middleware. The server-side code should have a file access to the webpacked index.html, then to be able to serve it for any valid URL the user throws at the server. Fortunately in my case the solution was simple. Because my index.html is completely static in the first place, I am able to serve it without messing with webpack's temporary files. I lose the benefits of html uglification and other webpack feats but in dev environment that is ok. For a reference, the server-side catch-all route for the SPA then becomes:
I hope this comment to expand the perspective and further describe the issue. |
@axelpale, can't you do something like this: var webpackMiddleware = require("webpack-dev-middleware");
var historyApiFallback = require("connect-history-api-fallback");
var instance = webpackMiddleware(...);
app.use(instance);
app.use(historyApiFallback());
app.use(instance); Note that using |
@SpaceK33z Interesting! The first |
I tried to do something like @SpaceK33z 's comment but the express server does not respond. const express = require('express');
const path = require('path');
const app = express();
const historyApiFallback = require('connect-history-api-fallback');
if (process.env.NODE_ENV !== 'production') {
const webpackMiddleware = require('webpack-dev-middleware');
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
const webpackInstance = webpackMiddleware(webpack(webpackConfig));
app.use(webpackInstance);
app.use(historyApiFallback);
app.use(webpackInstance);
} else {
app.use(express.static('dist'));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
})
}
app.listen(process.env.PORT || 3050, () => console.log('Listening...')); I can't access react routes using browserHistory. It only works if i use hashHistory. |
@eduardoleal were you able to resolve this? |
Oops, you need to pass |
Yes, @anthonator!
|
Closing as there seems to be a good resolution here. If anyone would like to add this to the documentation, please open a PR 😄 |
There really needs to be a more intuitive solution. Adding the instance twice seems really hacky. Is there a good reason that there isn't an equivalent historyApiFallback option in webpack-dev-middleware? This seems like a really common use case that deserves a setting. |
Also, could there be performance concerns with adding webpack twice? |
@robbyemmert it looks like you may be new to Github, so please do note that it's a best practice to edit a previous comment to add more info, rather than posting a comment shortly after a previously posted comment. I'm not sure you're fully understanding the solutions provided in this thread, as neither of the latest examples "add webpack" . Regardless, there's a new feature in |
Hi, so I know that this middleware automatically handles the serving of all assets from memory. However, is there a way to let express use this memoryFs for other middleware as well? So that I can, for example, use
res.render('myfile.ext')
wheremyfile.ext
is also in the webpack-dev memoryFs?The text was updated successfully, but these errors were encountered: