-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebpack.dev.js
133 lines (122 loc) · 4.84 KB
/
webpack.dev.js
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
require('dotenv').config()
const cookieParser = require('cookie-parser')
const dayjs = require('dayjs')
const decache = require('decache')
const { merge } = require('webpack-merge')
const path = require('path')
const { parse } = require('set-cookie-parser')
const { WebpackManifestPlugin } = require('webpack-manifest-plugin')
let indexFilepath = path.resolve(__dirname, 'dist/server/index.js')
if (!indexFilepath.startsWith('/')) {
// need for Windows.
indexFilepath = 'file:///' + indexFilepath
}
const remoteHost = process.env[`REMOTE_HOST`]
module.exports = (env, argv) => {
const [server, app] = require('./webpack.config')(env, argv)
server.devServer = {
client: {
progress: true,
},
devMiddleware: {
index: true,
serverSideRender: true,
writeToDisk() {
return true
},
},
host: 'localhost',
liveReload: true,
onListening(devServer) {
devServer.compiler.compilers
.find(({ name }) => name === 'server')
.hooks.afterCompile.tap('DecacheIndex', () => decache(indexFilepath))
},
setupMiddlewares(middlewares, devServer) {
devServer.app.use(cookieParser())
middlewares.push(async (req, res) => {
// adapt between express Request/Response and Lambda.
const originalUrl = req.originalUrl
const indexOfQuery = originalUrl.indexOf('?')
const event = {
rawPath: req.path,
rawQueryString: indexOfQuery >= 0 ? req.originalUrl.substring(indexOfQuery + 1) : '',
queryStringParameters: req.query,
cookies: Object.entries(req.cookies || {}).map(([key, value]) => `${key}=${value}`),
headers: {
'x-forwarded-for': req.ip,
},
requestContext: {
timeEpoch: dayjs().valueOf(),
},
}
// stub the global awslambda. our handler only uses two things so shouldn't be too bad.
globalThis.awslambda = {
streamifyResponse(f) {
return f
},
HttpResponseStream: {
from(proxiedRes, { statusCode, headers, cookies }) {
// the _ is actually identical to res, so it doesn't matter which we use.
res.status(statusCode)
for (const [k, v] of Object.entries(headers)) {
res.append(k, v)
}
// AWS Lambda response's Cookies contains the entries that are Set-Cookie values such as:
// sid=1245; Secure; HttpOnly; SameSite=Lax.
// we'll use set-cookie-parse to parse them into something express can use.
const cookieMap = parse(cookies, { map: true })
Object.entries(cookieMap).forEach(([name, cookie]) =>
res.cookie(name, cookie.value, {
expires: cookie.expires,
httpOnly: cookie.httpOnly,
path: cookie.path,
sameSite: 'lax',
secure: cookie.secure,
})
)
return proxiedRes
},
},
}
import(indexFilepath).then(async ({ handler }) => await handler(event, res))
})
return middlewares
},
port: 3000,
proxy: {
'/images': {
changeOrigin: true,
target: remoteHost,
},
'/videos': {
changeOrigin: true,
target: remoteHost,
},
},
server: 'https',
static: {
directory: path.join(__dirname, 'public'),
serveIndex: false,
},
watchFiles: {
paths: ['./src/**/*', './public/**/*'],
options: {
usePolling: false,
},
},
}
return [
server,
merge(app, {
plugins: [
new WebpackManifestPlugin({
// we cannot have the default app config write to dist/server because of output.clean == true, which
// will clean the dist/server and dist/app in determined order.
fileName: '../server/manifest.json',
basePath: '/',
}),
],
}),
]
}