60frames / webpack-hot-server-middleware Goto Github PK
View Code? Open in Web Editor NEW:fire: Hot reload webpack bundles on the server
License: MIT License
:fire: Hot reload webpack bundles on the server
License: MIT License
Just tried the example - npm install && npm start yields the above output.
Tried passing it into webpack config directly (to bypass import/export) to the same result.
edit: rm -rf node_modules, npm cache clean and reinstall solved this issue. The initial install was also clean so not sure what went wrong.
We're seeing a lot of out-of-memory errors using this library.
I've looked at #29 and think this is another reason. After doing some heap traces I see that bundles remain in memory after every change. The nodejs module
object has a children array, which includes every generated bundle.
This issue has been fixed upstream in require-from-string@2, so a simple dep update should fix the issue here.
clone the repo
980 git clone https://github.com/60frames/webpack-hot-server-middleware.git
981 cd webpack-hot-server-middleware/example/
982 yarn
edit the server middleware:
module.exports = function serverRenderer({ clientStats, serverStats, foo }) {
return (req, res, next) => {
console.log("here");
res.status(200).send(`
cescoferraro in ~/go/src/github.com/cescoferraro/webpack-hot-server-middleware/example
$ yarn start
yarn start v0.22.0
$ node index.js
Server started: http://localhost:6060/
here
here
Why the server middleware get fired twice by hitting the browser only once?? I am seeing this behavior on my actual project and it breaks isomorphic-syle-loader
.
// ./build/webpack/vendor.js
module.exports = [require("./vendor"), require("./client"), require("./server")];
// hot.js
const app = require("express")();
const vendor = require('webpack')(require('./build/webpack/vendor.js'));
vendor.run(function (err, stats) {
console.log("DLL READY");
const compiler = require('webpack')(require('./build/webpack/dev.js'));
app.use(require('webpack-dev-middleware')(compiler));
app.use(require('webpack-hot-middleware')(compiler.compilers.find(compiler => compiler.name === 'client')));
app.use(require('webpack-hot-server-middleware')(compiler, {chunkName: 'server'}));
app.use(require("morgan")('combined'));
app.listen(3000, "0.0.0.0");
}
);
my webpack's client config generates some file like
let client = [
...server,
new FaviconsWebpackPlugin({
logo: './src/icon/icon.png',
prefix: 'icons/'
}),
new SWPrecacheWebpackPlugin(
{
cacheId: 'spotify',
filename: 'sw.js',
maximumFileSizeToCacheInBytes: 4194304,
minify: true,
runtimeCaching: [{
handler: 'cacheFirst',
urlPattern: /[.]mp3$/,
}],
}
),
new StatsWebpackPlugin('stats.json', {
chunkModules: true,
exclude: [/node_modules/]
}),
];
in my development locahost:3000/stats.json return my SPA html page instead of the actual json object. It work fine in production where I am just serving static files, look
I will do it on this week
According to the docs, it looks like I have to pass a webpack.config that consists of both "client" and "server". Is there any way to pass the server config only, and omit the client (client is not needed at this moment)?
new Promise((resolve, reject) => {
dev.waitUntilValid(() => resolve(true));
compiler.plugin('failed', error => reject(error));
});
This is because compiler is not passed into the example middleware
Following the Koa example, it seems some TS definitions are missing or out of sync with the lib.
Adding middleware requires any
casting, such as:
app.use(webpackHotServerMiddleware(compiler, {
createHandler: (webpackHotServerMiddleware as any).createKoaHandler,
}) as any);
... because:
webpackHotServerMiddleware
, by default, returns an Express middleware signature, not Koa.webpackHotServerMiddleware.createKoaHandler
(and probably other handlers) are lacking definitions.Hello,
I can't get react-loadable to work with this really cool package for code splitting.
Has anyone managed to do it and could suggest how to do it? Or share an example?
Thank you!
Hello,
first, thanks for webpack-hot-server-middleware
- it's been a pleasure to use so far!
Today, I ran into the following problem: My server renderer needs to regularly pull resources from a 3rd-party API, which is then used to render the application. To achieve that, I added a simple function that is called using setInterval
. Now when a new webpack build replaces the old one, I need to clear that timer again in order to 1) allow for garbage-collection of the old build 2) stop that old timer to avoid accumulating multiple versions.
I've solved the problem by allowing the serverRenderer-Module to export a dispose
function, which is called before the new build is activated. A quick & dirty implementation is here: aflatter@754a049
Is there another way to solve this without touching webpack-hot-server-middleware
? I've thought about passing in the timer logic as an option to the server renderer, but then I lose hot-reloading of that logic.
If there is no other way, I'd love to get input on a possible API that might also allow keeping state between two different builds:
// serverRenderer.js
export function serverRenderer({clientStats, serverStats, state}) {
// Before this server renderer is replaced, this function is called and has the chance to return a new state that will be passed to the next server renderer.
const replacementHandler = () => {
const {versions} = state || {}
return {versions: versions + 1}
}
// This is the actual function that handles incoming requests.
const requestHandler = (req, res, next) => {
res.status(200).send(`Hello world, I am server renderer #${state.versions}!`)
}
return {replacementHandler, requestHandler}
})
Would you accept that kind of functionality? Thanks!
The middleware seems to hang with no output when my server bundle encounters an error. Only upon exiting the process does the error trace print to stddout.
Middleware implementation is standard:
const compiler = webpack([client, server]);
app.use(
webpackDevMiddleware(compiler, {
noInfo: true,
stats: {
warnings: false,
colors: true,
timings: true
},
publicPath: client.output.publicPath
})
);
app.use(webpackHotMiddleware(compiler.compilers[0], { path: '/__hmr' }));
app.use(webpackHotServerMiddleware(compiler));
I can reproduce by throwing anywhere in the render/server bundle. Otherwise the middleware works normally. Is this a limitation or something I haven't configured correctly?
It doesn't make sense to pass in the compiler options to serverRenderer
as there is no corresponding compiler options in production. -- see #18
Prob want to do something like this instead:
// server.js
app.use(webpackHotServerMiddleware(compiler, {
serverRendererOptions: {
// Consumers can add whatever they want here.
foo: 'bar'
}
}))
// serverRenderer.js
export default (clientStats, serverStats, options) => (req, res, next) => {
console.log(clientStats); // Stats
console.log(serverStats); // Stats
console.log(options.foo); // 'bar'
}
// OR
export default (stats, options) => (req, res, next) => {
console.log(stats.client); // Stats
console.log(stats.server); // Stats
console.log(options.foo); // 'bar'
}
// OR
export default options => (req, res, next) => {
console.log(options.clientStats); // Stats
console.log(options.serverStats); // Stats
console.log(options.foo); // 'bar'
}
Coverage has dipped below 100% due to the 958d897 because the source file always exists.
I think the only way to get into the catch would be to trigger an error somewhere other than the webpack bundle although that's not particularly useful as a test so could just put some instanbul ignore comments in the catch.
It'd also be nice to look into testing source maps more seriously buy trigger an error and checking the stack trace is mapped to the source files.
Hi. I needed this PR to be able to run my new setup: Babel7 (+ TypeScript), Webpack4, React + Redux, SSR and HMR (universal). It's at https://github.com/Industrial/universal-demo
Could you please try git clone https://github.com/Industrial/universal-demo; cd universal-demo; npm i; npm run start;
and then open http://localhost:3000
?
I am getting the error
Error: The 'server' compiler must export a function in the form of `(options) => (req, res, next) => void`
at getServerRenderer (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack-hot-server-middleware/src/index.js:68:15)
at doneHandler (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack-hot-server-middleware/src/index.js:159:30)
at SyncHook.eval (eval at create (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/tapable/lib/HookCodeFactory.js:17:12), <anonymous>:9:1)
at SyncHook.lazyCompileHook [as _call] (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/tapable/lib/Hook.js:35:21)
at MultiCompiler.compiler.hooks.done.tap.stats (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack/lib/MultiCompiler.js:45:22)
at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:18:1)
at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/tapable/lib/Hook.js:35:21)
at Watching._done (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack/lib/Watching.js:99:28)
at compiler.emitRecords.err (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack/lib/Watching.js:73:19)
at Compiler.emitRecords (/home/tom/Code/Code9/JavaScript/Projects/universal-demo/node_modules/webpack/lib/Compiler.js:295:39)
I don't know what I'm doing wrong anymore :-(
Hello, I'm trying to implement this with Angular2. Everything seems to be working fine client side, but SSR is not working with "lazy-loaded" chunks Error: Cannot find module './0.server.js'
.
I tried using LimitChunkCountPlugin
but the rabbit hole seemed to be deeper. Now I looked at the MemoryFileSystem
and the file is definitely there.
Eventually I got it to work, but I had to run a build before running the server, which is weird, it seems like it needs the disk files to be there before starting, but it still uses the memory files. I know it doesn't use disk files because deleting their content doesn't change the outcome, and changes to /src
files (i.e. rebuilding) doesn't change them, however, if I delete the file from disk, it bugs out again. π
Here's the branch I'm working on https://github.com/S-Intelligent-Technologies/sit-ngx-starter/tree/fm-better-hmr
The error pops us in development when adding webpack-hot-server-middleware. Below is my express.js and config/webpack.dev-client.js.
express.js:
import express from 'express';
import webpack from 'webpack'
const expressStaticGzip = require('express-static-gzip')
import webpackHotServerMiddleware from 'webpack-hot-server-middleware';
const server = express()
import configDevClient from '../../config/webpack.dev-client'
import configDevServer from '../../config/webpack.dev-server'
import configProdClient from '../../config/webpack.prod-client'
import configProdServer from '../../config/webpack.prod-server'
const isProd = process.env.NODE_ENV === 'production';
if (!isProd) {
const compiler = webpack([configDevClient, configDevServer])
const clientCompiler = compiler.compilers[0]
const serverCompiler = compiler.compilers[1]
const webpackDevMiddleware = require('webpack-dev-middleware')(compiler, configDevClient.devServer)
const webpackHotMiddleware = require('webpack-hot-middleware')(clientCompiler, configDevClient.devServer)
server.use(webpackDevMiddleware)
server.use(webpackHotMiddleware)
server.use(webpackHotServerMiddleware(compiler))
} else {
webpack([configProdClient, configProdServer]).run((err, stats) => {
const render = require('../../build/prod.server.bundle.js').default
server.use(expressStaticGzip('dist', { enableBrotli: true }))
server.use(render());
})
}
const port = process.env.PORT || 8080
server.listen(port, () => console.log(`Server's running on http://localhost:${port}.`));
webpack.dev-client.js:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
name: 'client',
entry: {
main: [
'babel-polyfill',
'babel-runtime/regenerator',
'webpack-hot-middleware/client?reload=true',
'./src/main'
],
},
resolve: {
extensions: [".js", ".ts"] // add extensions to entry files above
},
mode: 'development',
output: {
filename: 'dev.client.bundle.js',
path: path.resolve(__dirname, '../dist')
},
devServer: {
contentBase: 'dist',
historyApiFallback: true,
overlay: true,
hot: true,
stats: {
colors: true
}
},
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'initial',
minChunks: 2
}
}
}
},
devtool: 'source-map',
module: {
rules: [
{
test: /\.js$/,
use: [
{ loader: 'babel-loader' }
],
exclude: /node_modules/
},
{
test: /\.ts$/,
use: [
{ loader: 'awesome-typescript-loader' }
],
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
{
// loader: 'style-loader'
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.sass$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader' }
]
},
{
test: /\.styl$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
{ loader: 'stylus-loader' }
]
},
{
test: /\.less$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
attrs: ['img:src']
}
}
]
},
{
test: /\.pug$/,
use: [
{ loader: 'pug-loader' }
]
},
{
test: /\.hbs$/,
use: [
{
loader: 'handlebars-loader',
query: {
inlineRequires: '/images/'
}
}
]
},
{
test: /\.(png|svg|gif|jpe?g)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name].[hash:8].[ext]'
}
}
]
},
{
test: /\.md$/,
use: [
{ loader: 'markdown-with-front-matter-loader' }
]
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({ filename: '[name].css' }),
new BundleAnalyzerPlugin({
generateStatsFile: true,
analyzerMode: 'server',
openAnalyzer: false
})
]
};
The full repo is at https://github.com/ElAnonimo/webpack4
I've fallen back to using new WriteFilePlugin()
and
app.use(
publicPath,
express.static(outputPath),
)
I.e. hosting the files from the file system manually. But I shouldn't have to do that. I noticed this PR to webpack-dev-middleware:
webpack/webpack-dev-middleware#151
So I'm curious how this package successfully hosted files if webpack-dev-middleware itself is struggling to host files from a multi-compiler.
...ps. otherwise, amazing package! I love that require-from-string
implementation, pure magic!
Hi,
In webpack-hot-server-middleware you have your serverRender
function and you set up dev and prod like this:
const express = require('express');
const path = require('path');
const app = express();
if (process.env.NODE_ENV !== 'production') {
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const webpackHotServerMiddleware = require('webpack-hot-server-middleware');
const config = require('./webpack.config.js');
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
serverSideRender: true
}));
app.use(webpackHotMiddleware(compiler.compilers.find(compiler => compiler.name === 'client')));
app.use(webpackHotServerMiddleware(compiler));
} else {
const CLIENT_ASSETS_DIR = path.join(__dirname, '../build/client');
const CLIENT_STATS_PATH = path.join(CLIENT_ASSETS_DIR, 'stats.json');
const SERVER_RENDERER_PATH = path.join(__dirname, '../build/server.js');
const serverRenderer = require(SERVER_RENDERER_PATH);
const stats = require(CLIENT_STATS_PATH);
app.use(express.static(CLIENT_ASSETS_DIR));
app.use(serverRenderer(stats));
}
Say I have a non root url like some-root
is it possible for me to call the serverRenderer function without redirecting? All I can think to do is this.
express.Router().post('/other-route', (_: Request, res: Response) => {
// do stuff
res.redirect('/');
});
Hello,
first of all, thank you for this awesome library, it's saving me.
I would like to inject data into an html file that is generated from a template, and kept in memory, by html-webpack-plugin. Data to inject could be html metas, preloaded state (it's for a react-redux app), etc.
I read that one way to do it is to access the file in memory, which requires access to the compiler:
const filename = path.join(compiler.outputPath, 'index.html')
compiler.outputFileSystem.readFile(filename, (err, result) => {
// do something
})
Is it possible the pass the compiler to the serverRenderer
function ? Or is there a better way to access webpack ouputs ?
I am having issues when adding magic comments to my dynamic import using react-reloadable, Instead of receiving "main" i get "Home" which is a loadable component.
Here is my server config.
const path = require('path');
const webpack = require('webpack');
const externals = require('./node-externals');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
module.exports = {
name: 'server',
target: 'node',
externals,
entry: './server/renderer.js',
mode: 'development',
output: {
filename: 'dev-server-bundle.js',
chunkFilename: '[name].js',
path: path.resolve(__dirname, '../build'),
libraryTarget: 'commonjs2'
},
devtool: 'inline-sourcemaps',
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /.css$/,
use: {
loader: 'css-loader',
options: {
minimize: true
}
}
},
{
test: /.scss$/,
use: [
{
loader: 'css-loader',
options: {
minimize: true
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /.(jpg|png|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '/images/[name].[ext]',
emitFile: false
}
}
]
}
]
},
plugins: [
new FriendlyErrorsWebpackPlugin(),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
]
};
- node : "v10.9.0" - webpack: "^4.16.5" - webpack-hot-server-middleware: "^0.5.0"
server/index.js
const webpack = require('webpack')
const express = require('express')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require('webpack-hot-middleware')
const webpackHotServerMiddleware = require('webpack-hot-server-middleware')
const clientConfigDev = require('../webpack/client.dev')
const serverConfigDev = require('../webpack/server.dev')
const clientConfigProd = require('../webpack/client.prod')
const serverConfigProd = require('../webpack/server.prod')
const { publicPath } = clientConfigDev.output
const outputPath = clientConfigDev.output.path
const DEV = process.env.NODE_ENV === 'development'
const app = express()
let isBuilt = false
const done = () =>
!isBuilt &&
app.listen(3000, () => {
isBuilt = true
console.log('Build Complete')
})
if (DEV) {
const compiler = webpack([clientConfigDev, serverConfigDev])
const clientCompiler = compiler.compilers[0]
const options = { publicPath, stats: { color: true } }
const devMiddleware = webpackDevMiddleware(compiler, options)
app.use(devMiddleware)
app.use(webpackHotMiddleware(clientCompiler))
app.use(webpackHotServerMiddleware(compiler))
devMiddleware.waitUntilValid(done)
} else {
webpack([clientConfigProd, serverConfigProd]).run((err, stats) => {
const clientStats = stats.toJson().children[0]
const serverRender = require('../build/server.js').default
app.use(publicPath, express.static(outputPath))
app.use(serverRender({ clientStats }))
done()
})
}
i have an issue with the development mode when i open my app in browser, it said serverRenderer is not a function, everything is okay with production mode
There is an example repository at https://github.com/vuejs/vue-hackernews-2.0 but I find it really hard to understand how webpack-hot-server-middleware would go into that. Probably some code in the hackernews example could be done with this middleware, but I'm not sure.
Also I don't get how to use Vue's JSON output (vue-ssr-client-manifest.json
and vue-ssr-server-bundle.json
instead of the server bundle JS output) with this middleware.
Could you prepare a minimal example setup on how to use this middleware with Vue.js and vue-router (isomorphic instantiation of a Vue "app", waiting for vue-router async hooks etc.) with express?
Probably it's much to ask and the existing examples are considered being enough for most users, but I have a hard time understanding the different plugins, Vue instantiation, SSR etc. Or is all the code in the hackernews example needed and webpack-hot-server-middleware wouldn't help in any way?
Thanks you - Vue's SSR is driving me a bit insane...
I did run example app. When I did some changes in the code the browser does not reload
const SERVER = require("./www/server.bundle").default;
const express = require("express");
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
// const webpackHotServerMiddleware = require('webpack-hot-server-middleware');
const app = express();
const PORT = 3000;
const compiler = webpack(require('./build/webpack/prod.js'));
app.use(webpackDevMiddleware(compiler));
app.use(webpackHotMiddleware(compiler.compilers.find(compiler => compiler.name === 'client')));
// app.use(webpackHotServerMiddleware(compiler));
app.use(SERVER);
app.listen(PORT, console.log.bind("listening at http://localhost:" + PORT));
If I uncomment the lines (webpackHotServerMiddleware itself) above, my build errors
/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack-dev-middleware/node_modules/memory-fs/lib/MemoryFileSystem.js:112
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
^
Error
at MemoryFileSystem.readFileSync (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack-dev-middleware/node_modules/memory-fs/lib/MemoryFileSystem.js:112:10)
at MultiCompiler.multiCompiler.plugin.multiStats (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack-hot-server-middleware/src/index.js:119:33)
at MultiCompiler.applyPlugins (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/tapable/lib/Tapable.js:25:14)
at MultiCompiler.<anonymous> (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/MultiCompiler.js:76:10)
at Compiler.applyPlugins (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/tapable/lib/Tapable.js:25:14)
at Watching._done (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:93:17)
at /home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:76:18
at Compiler.emitRecords (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:350:37)
at /home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:59:19
at /home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:343:11
at next (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/tapable/lib/Tapable.js:118:11)
at Compiler.<anonymous> (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/performance/SizeLimitsPlugin.js:115:3)
at Compiler.applyPluginsAsyncSeries1 (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/tapable/lib/Tapable.js:122:13)
at Compiler.afterEmit (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:340:8)
at Compiler.<anonymous> (/home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/lib/Compiler.js:335:14)
at /home/cescoferraro/code/go/src/github.com/cescoferraro/spotify/node_modules/webpack/node_modules/async/dist/async.js:356:16
My server.js:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './src/components/App';
import data from './src/testData.json';
export default options => (req, res, next) => {
res.status(200).send(`
<!doctype html>
<html>
<head>
<title>App</title>
</head>
<script>window._initialData = ${JSON.stringify(data.contests)}</script>
<body>
<div id="root">
${ReactDOMServer.renderToString(<App initialContests={data.contests}/>)}
</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
};
Hi guys!
I added this middleware to my side project. Webpack complies the assets but app crashes with Error: listen EADDRINUSE :::3000
. Port is avaible at the moment when app starts, I even changed the port. Without this middleware the app starts with no errors.
Could anyone share some thoughts what could cause the error?
environment οΌ
node 8.9
webpack 4.12
webpack-hot-server-middleware 0.5.0
error
serverRenderer is not a function
It'd be nice to run the same express tests in koa
with the koaHandler
.
Hi!
whether it is possible connect serverRendererOptions with fetched data?
app.use('/urlPath/:id',webpackHotServerMiddleware(compiler, {
serverRendererOptions: {
data: fetchedData // how to?
}
}));
like this:
app.get('/path/:id', (req, res) => {
firebaseDatabase.getData(req.params.id).then(resp => {
res.send(resp)
......
I cannot get the webpack.config.js folder to allow both entry points for client and server.
I copied the example:
module.exports = [
{
name: 'client',
target: 'web',
entry: './client.js'
...
}, {
name: 'server',
target: 'node',
entry: './server.js'
...
}
];
Which makes my code look like this:
module.exports = {
{
name: 'client',
target: 'web',
entry: './src/index.js'
}, {
name: 'server',
target: 'node',
entry: './tools/server.js'
},
output: {
path: __dirname + '/public',
publicPath: "/",
filename: 'bundle.js'
},
...
But then I get this error:
SyntaxError: /Users/ryan/Desktop/df/coding/rc/webpack.config.js: Unexpected token (33:4)
31 |
32 | module.exports = {
> 33 | {
| ^
34 | name: 'client',
35 | target: 'web',
36 | entry: './src/index.js'
On top of this: I have multiple entry points for the client side for react-hot-loader and webpack-hot-middleware, so my actual code is more like this
entry: {
client: [
'webpack-hot-middleware/client?reload=true', //note that it reloads the page if hot module reloading fails.
'react-hot-loader/patch', // RHL patch
'./src/index.js'
],
server: './tools/server.js'
},
output: {
path: __dirname + '/public',
publicPath: "/",
filename: '[name].bundle.js'
},
And this brings up tons more errors.
Essentially, how do I set up webpack config with the webpack-hot-middleware and react-hot-loader?
Is there any suggested setup for production?
In my mind, it would be something like:
app.use(webpackDevMiddleware(compiler, {
noInfo: true
}));
if (procsss.env.NODE_ENV !== 'production') {
app.use(webpackHotServerMiddleware(compiler));
} else {
app.use((req, res) => {
const stat = require(dist + '/stat.json')
const server = require(dist + '/server')
server(stat)(req, res)
});
}
app.listen(6060, () => {
console.log('Server started: http://localhost:6060/');
});
Hi!
In this repo I am trying to get a simple app working with SSR, HMR and the new Webpack 4 and Babel 7 (and TypeScript with that).
Right now I'm stuck on this error: TypeError: serverRenderer is not a function at node_modules/webpack-hot-server-middleware/src/index.js:13:3
.
Somehow my webpack compiler object is not emitting a 'done' event, and the server renderer is never fetched.
To reproduce:
git clone https://github.com/Inuldustrial/universal-demo;
cd universal-demo;
npm i;
npm run start;
You will see the complete webpack config, a successful compile and that error in the browser when you visit the page.
Thanks for your time,
Tom
TypeError: serverRenderer is not a function
at /home/ivan/projects/whsm/node_modules/webpack-hot-server-middleware/src/index.js:13:5
example - https://github.com/vasivas/whsm
When following the directions on https://github.com/60frames/webpack-hot-server-middleware/tree/master/example
I get the following:
npm ERR! missing script: start
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/jonathanleung/.npm/_logs/2017-08-20T18_41_23_018Z-debug.log
I was wondering if it would be possible to expose a reference to the compiler in the serverRenderer
middleware as you do with the stats
.
I want to access a file in the outputFS of the compiler (in memory) and use it to render the HTML of the page in the Server-Side Rendering way.
Would it be possible? I would like to know what you think about this, as I think it would bring flexibility to the serverRenderer
middleware.
I am using webpack-hot-reloading and
react-hot-server-middleware`:
app.use(require('webpack-dev-middleware')(multiCompiler, { serverSideRender: true }));
app.use(require('webpack-hot-middleware')(clientCompiler));
But my websocket calls are coming through to the middleware and I have some poor code to filter them out:
export default ({ clientStats }: { clientStats: any }) => async (req: Request, res: Response, next: any) => {
// TODO: find a better way of filtering websocket hot reloading
if (some(['sockjs', 'hot-update.json'], part => req.url.indexOf(part) > -1)) {
next();
return;
}
// render html
`);
};
Is there a better way?
By using this package, the errors from the bundles won't trigger the VSCode Debugger, and instead, they will simply get console logged.
To Reproduce : throw an Error
I am not sure why this happens, but in my otherwise unchanged setup, updating to Webpack-3.1.0 breaks this package.
[00:08:58] Error: Expected webpack compiler to contain both a 'client' and 'server' config
at webpackHotServerMiddleware (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/webpack-hot-server-middleware/src/index.js:88:15)
at addDevMiddleware (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/edge-builder/src/express/dev.js:42:14)
at Gulp.startDevServer (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/edge-builder/lib/node.commonjs.js:600:3)
at module.exports (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/orchestrator/index.js:214:10)
at Gulp.Orchestrator.start (/Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/orchestrator/index.js:134:8)
at /Users/sebastian/Workspace/sebastian-software/edge-boilerplate/node_modules/gulp/bin/gulp.js:129:20
at _combinedTickCallback (internal/process/next_tick.js:95:7)
at process._tickCallback (internal/process/next_tick.js:161:9)
at Function.Module.runMain (module.js:607:11)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
Webpack is triggered by Gulp as you can see.
This here is the initialization code:
const clientConfig = configBuilder({
target: "client",
env: "development"
})
const serverConfig = configBuilder({
target: "server",
env: "development"
})
const multiCompiler = webpack([ clientConfig, serverConfig ])
const clientCompiler = multiCompiler.compilers[0]
server.use(webpackDevMiddleware(multiCompiler, {
// required
publicPath: PUBLIC_PATH,
// display no info to console (only warnings and errors)
noInfo: true
}))
server.use(webpackHotMiddleware(clientCompiler))
// keeps serverRender updated with arg: { clientStats, outputPath }
server.use(webpackHotServerMiddleware(multiCompiler, {
serverRendererOptions: {
outputPath: CLIENT_OUTPUT
}
}))
Do you have any idea for a fix?
I am having an issue with https://github.com/supasate/connected-react-router and started debugging.
I did yarn link
and yarn link connected-react-router
, and now the middleware cannot see the symlink as a regular folder.
Great work @richardscarrott!
I dont know if people have made requests about this by now but i will try:
I am working on extensive-react-server with preconfigured setup, fully editable.
Here i am using webpack-hot-server-middleware
as a feature in development mode.
The problem is: Using custom plugins og loaders with webpack
Works fine when i use babel-loader
Crashes when i add style-loader
returing a 404 Not Found
Any way around this?
Well you donβt have any require
statement that explicitly requires yarn. So I think this is most likely a bug :-)
I don't get the error until I try to load the page:
server.jsx:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { match } from 'react-router/es6';
import { ServerRoot } from 'Root';
import configureStore from 'store';
import cheerio from 'cheerio';
module.exports = function(indexHTML) {
return function (req, res) {
var routes = require('./routes.jsx');
var store = configureStore();
var css = [];
match({
routes: routes.default,
location: req.originalUrl
}, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
var body = ReactDOMServer.renderToString(
<ServerRoot store={store} renderProps={renderProps} onInsertCss={(...styles) => {
styles.forEach(style => css.push(style._getCss()));
}}/>
);
const state = store.getState();
var $ = cheerio.load(indexHTML);
$('#server-style').html(css.join(''));
$('#redux-state').html('window.__REDUX_STATE__ = ' + JSON.stringify(state).replace(/<\/script/g, '<\\/script').replace(/<!--/g, '<\\!--') + ';');
$('#app').html('<div>' + body + '</div>');
res.set('content-type', 'text/html');
res.send($.html());
res.end();
} else {
res.status(404).send('Not found')
}
});
}
}
app.js:
...
var webpack = require('webpack');
var clientConfig = require(path.join(__dirname, '/config/webpack.config.client.js'));
var serverConfig = require(path.join(__dirname, '/config/webpack.config.server.js'));
var devServerConfig = clientConfig.devServer;
app.use(serverConfig.output.publicPath, express.static(serverConfig.output.path));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public/favicons')));
if (process.env.NODE_ENV === 'development') {
var compiler = webpack(clientConfig);
var serverCompiler = webpack([clientConfig, serverConfig]);
const webpackDevMiddlewareInstance = require('webpack-dev-middleware')(compiler, devServerConfig);
const webpackHotServerMiddlewareInstance = require('webpack-hot-server-middleware')(serverCompiler);
app.use(webpackDevMiddlewareInstance);
app.use(webpackHotServerMiddlewareInstance);
if (devServerConfig.hot) {
app.use(require('webpack-hot-middleware')(compiler, {
log: console.log,
path: '/__webpack_hmr',
heartbeat: 10000
}));
}
webpackDevMiddlewareInstance.waitUntilValid(function () {
compiler.outputFileSystem.readFile(path.join(compiler.outputPath, 'index.html'), function (err, result) {
if (err) throw err;
ready(result);
});
});
} else
ready(fs.readFileSync(path.join(__dirname, 'builds/client/index.html')));
function ready(indexHTML) {
app.use('*', require('./builds/server/server.js')(indexHTML));
...
}
I may be doing something very wrong or incorrectly since I am still relatively new to all of this.
Thanks.
This memory error is happening more often with webpack3.
I wonder if we could debounce the saving hook.
I find myself saving each file multiple times for formating reasons that dont actually matter to the result I expect to see.
<--- Last few GCs --->
439036 ms: Mark-sweep 1218.2 (1439.7) -> 1217.6 (1439.7) MB, 947.7 / 0.0 ms [allocation failure] [GC in old space requested].
439964 ms: Mark-sweep 1217.6 (1439.7) -> 1217.6 (1439.7) MB, 928.0 / 0.0 ms [allocation failure] [GC in old space requested].
440895 ms: Mark-sweep 1217.6 (1439.7) -> 1229.9 (1408.7) MB, 930.6 / 0.0 ms [last resort gc].
441901 ms: Mark-sweep 1229.9 (1408.7) -> 1245.4 (1407.7) MB, 1005.2 / 0.0 ms [last resort gc].
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x104cc3fcfb39 <JS Object>
1: DoJoin(aka DoJoin) [native array.js:~129] [pc=0xa2d363e0857] (this=0x104cc3f04381 <undefined>,w=0x16dc614e4c89 <JS Array[4429]>,x=4429,N=0x104cc3f043c1 <true>,J=0x104cc3f04411 <String[0]: >,I=0x104cc3fb46c9 <JS Function ConvertToString (SharedFunctionInfo 0x104cc3f52dc9)>)
2: Join(aka Join) [native array.js:180] [pc=0xa2d36a50492] (this=0x104cc3f04381 <undefined>,w=0x16dc614e4c89 <JS...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/Users/cesco/.nvm/versions/node/v6.10.1/bin/node]
2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/Users/cesco/.nvm/versions/node/v6.10.1/bin/node]
3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/Users/cesco/.nvm/versions/node/v6.10.1/bin/node]
4: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/Users/cesco/.nvm/versions/node/v6.10.1/bin/node]
5: v8::internal::Runtime_StringBuilderConcat(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/cesco/.nvm/versions/node/v6.10.1/bin/node]
6: 0xa2d335092a7
https://github.com/faceyspacey/react-universal-component
...took me a while but i finally finished and shipped everything as i wanted. looking forward to your thoughts.
I was getting an error from the title when I started my server and opened my browser before compilation was finished. After compilation was done, everything started to work perfectly. So it seems that webpack-dev-middleware
didn't put serving responses on hold during code compilation, despite the fact my setup was according to the docs.
What helped me was adding serverSideRender: true
to webpack-dev-middleware
, but it was not mentioned in the docs, that's why I am asking, if anyone experienced similar issue? I yes, I could create a PR to mention this in the docs.
I'm trying to get library up with koa2 server based middleware, but i end up with the error below.
/Users/prithviraju/Sites/site/node_modules/memory-fs/lib/MemoryFileSystem.js:112
throw new MemoryFileSystemError(errors.code.EISDIR, _path);
^
Error
at MemoryFileSystem.readFileSync (/Users/prithviraju/Sites/site/node_modules/memory-fs/lib/
MemoryFileSystem.js:112:10)
at MultiCompiler.multiCompiler.plugin.multiStats (/Users/prithviraju/Sites/site/node_module
s/webpack-hot-server-middleware/src/index.js:119:33)
at MultiCompiler.applyPlugins (/Users/prithviraju/Sites/site/node_modules/tapable/lib/Tapab
le.js:61:14)
I'm using koa connect library to achieve the compatibility by wrapping connect middleware, but stuck with the error. Its possibly related to #7 and because of the function signature of entry point needed (stats) => (req, res, next) => void
, not sure how to make it a koa based one, tried wrapping in koa connect, but no avail.
Please point me in some direction.
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.