ssr.js
3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const express = require('express');
const vm = require('vm');
const fs = require('fs');
const path = require('path');
const MemoryFs = require('memory-fs');
const nativeModule = require('module');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const clientConfig = require('../build/webpack.client.conf');
const serverConfig = require('../build/webpack.server.conf');
const bundlePath = path.join(serverConfig.output.path, serverConfig.output.filename);
const manifestPath = path.join(clientConfig.output.path, '../../manifest.json');
const isDev = process.env.NODE_ENV === 'development' || !process.env.NODE_ENV;
let manifestProd;
if (!isDev) {
manifestProd = require(manifestPath);
}
const getModuleFromString = (bundle, filename) => {
const m = { exports: {} };
const wrapper = nativeModule.wrap(bundle);
const script = new vm.Script(wrapper, {
filename,
displayErrors: true,
});
const result = script.runInThisContext();
result.call(m.exports, m.exports, require, m);
return m;
}
exports.devServer = (cb) => {
const app = express();
let bundle, manifest;
let resolve;
let realyPromise = new Promise(r => {
resolve = r;
});
let ready = (...args) => {
resolve();
cb(...args);
};
if (isDev) {
const webpack = require('webpack');
clientConfig.entry.app = ['./build/client-hot.js', clientConfig.entry.app];
clientConfig.output.publicPath = '//127.0.0.1:6012/';
clientConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
);
const clientCompiler = webpack(clientConfig);
devMiddleware = webpackDevMiddleware(clientCompiler, {
publicPath: clientConfig.output.publicPath,
quiet: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
});
app.use(devMiddleware);
clientCompiler.plugin('done', stats => {
stats = stats.toJson();
stats.errors.forEach(error => console.log(error));
stats.warnings.forEach(warning => console.log(warning));
if (stats.errors.length) {
return;
}
try {
manifest = JSON.parse(devMiddleware.fileSystem.readFileSync(manifestPath, 'utf-8'));
} catch (e) {
console.error('manifest load failure!');
}
if (bundle) {
ready({bundle, manifest});
}
});
hotMiddleware = webpackHotMiddleware(clientCompiler, { heartbeat: 5000 });
app.use(hotMiddleware);
const mfs = new MemoryFs();
const serverCompiler = webpack(serverConfig);
serverCompiler.outputFileSystem = mfs;
serverCompiler.watch({}, (err, stats) => {
if (err) throw err;
const info = stats.toJson();
if (stats.hasErrors()) {
console.log('错误');
console.error(info.errors);
}
if (stats.hasWarnings()) {
console.log('警告');
console.warn(info.warnings);
}
const bundleSource = mfs.readFileSync(bundlePath, 'utf8');
const m = getModuleFromString(bundleSource, 'server-entry.js');
bundle = m.exports;
if (manifest) {
ready({bundle, manifest});
}
});
} else {
const bundleSource = fs.readFileSync(bundlePath, 'utf8');
const m = getModuleFromString(bundleSource, 'server-entry.js');
ready({ bundle: m.exports, manifest: manifestProd});
}
app.listen(6012, () => {
console.log('static server is started');
});
return realyPromise;
}