1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 |
|
7 | var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
8 |
|
9 | var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
10 |
|
11 | var _keys = require('babel-runtime/core-js/object/keys');
|
12 |
|
13 | var _keys2 = _interopRequireDefault(_keys);
|
14 |
|
15 | var _path = require('path');
|
16 |
|
17 | var _fsExtra = require('fs-extra');
|
18 |
|
19 | var _url = require('url');
|
20 |
|
21 | var _path2 = require('./utils/path');
|
22 |
|
23 | var _constants = require('./constants');
|
24 |
|
25 | var _composeMiddleware = require('compose-middleware');
|
26 |
|
27 | var _express = require('express');
|
28 |
|
29 | var _serveStatic = require('serve-static');
|
30 |
|
31 | var _serveStatic2 = _interopRequireDefault(_serveStatic);
|
32 |
|
33 | var _serveFavicon = require('serve-favicon');
|
34 |
|
35 | var _serveFavicon2 = _interopRequireDefault(_serveFavicon);
|
36 |
|
37 | var _compression = require('compression');
|
38 |
|
39 | var _compression2 = _interopRequireDefault(_compression);
|
40 |
|
41 | var _ssr = require('./middlewares/ssr');
|
42 |
|
43 | var _ssr2 = _interopRequireDefault(_ssr);
|
44 |
|
45 | var _koaError = require('./middlewares/koa-error');
|
46 |
|
47 | var _koaError2 = _interopRequireDefault(_koaError);
|
48 |
|
49 | var _expressError = require('./middlewares/express-error');
|
50 |
|
51 | var _expressError2 = _interopRequireDefault(_expressError);
|
52 |
|
53 | var _static = require('./middlewares/static');
|
54 |
|
55 | var _static2 = _interopRequireDefault(_static);
|
56 |
|
57 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | const INTERNAL_MIDDLEWARE = {
|
66 | TRAILING_SLASH: 'trailing-slash',
|
67 | STATIC: 'static',
|
68 | SERVICE_WORKER: 'service-worker',
|
69 | FAVICON: 'favicon',
|
70 | COMPRESSION: 'compression',
|
71 | SSR: 'ssr',
|
72 | ERROR: 'error'
|
73 | };
|
74 |
|
75 | const ALL_MIDDLEWARES = (0, _keys2.default)(INTERNAL_MIDDLEWARE).map(key => INTERNAL_MIDDLEWARE[key]);
|
76 |
|
77 | class MiddlewareComposer {
|
78 | constructor(core) {
|
79 | this.core = core;
|
80 | this.cwd = core.cwd;
|
81 | this.config = core.config;
|
82 | this.isProd = core.isProd;
|
83 | this.internalMiddlewares = [];
|
84 | }
|
85 |
|
86 | add(middleware, head = false) {
|
87 | if (typeof middleware !== 'function') {
|
88 | throw new Error('Middleware must be a function.');
|
89 | }
|
90 | if (head) {
|
91 | this.internalMiddlewares.unshift(middleware);
|
92 | } else {
|
93 | this.internalMiddlewares.push(middleware);
|
94 | }
|
95 | }
|
96 |
|
97 | reset(config) {
|
98 | this.config = config;
|
99 | this.internalMiddlewares = [];
|
100 | }
|
101 |
|
102 | |
103 |
|
104 |
|
105 |
|
106 | setup() {
|
107 | if (this.config.build && this.config.build.compress) {
|
108 |
|
109 | this.add((0, _compression2.default)());
|
110 | }
|
111 |
|
112 | let faviconPath = _path.posix.join(this.cwd, _constants.ASSETS_DIRNAME_IN_DIST, 'img/icons/favicon.ico');
|
113 | this.add((0, _serveFavicon2.default)(faviconPath));
|
114 | }
|
115 |
|
116 | |
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | koa(selectedMiddlewares = ALL_MIDDLEWARES) {
|
124 | var _this = this;
|
125 |
|
126 | if (!Array.isArray(selectedMiddlewares)) {
|
127 | selectedMiddlewares = [selectedMiddlewares];
|
128 | }
|
129 |
|
130 | const composeKoa = require('koa-compose');
|
131 | const c2k = require('koa-connect');
|
132 | const mount = require('koa-mount');
|
133 | const koaStatic = require('koa-static');
|
134 | const send = require('koa-send');
|
135 |
|
136 | let { router: { base }, build: { ssr, publicPath }, serviceWorker, errorHandler } = this.config;
|
137 | base = (0, _path2.removeTrailingSlash)(base || '/');
|
138 |
|
139 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.COMPRESSION)) {
|
140 |
|
141 | this.add((0, _compression2.default)());
|
142 | }
|
143 |
|
144 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.FAVICON)) {
|
145 |
|
146 | let faviconPath = _path.posix.join(this.cwd, _constants.ASSETS_DIRNAME_IN_DIST, 'img/icons/favicon.ico');
|
147 | if ((0, _fsExtra.existsSync)(faviconPath)) {
|
148 | this.add((0, _serveFavicon2.default)(faviconPath));
|
149 | }
|
150 | }
|
151 |
|
152 |
|
153 | this.internalMiddlewares = this.internalMiddlewares.map(c2k);
|
154 |
|
155 |
|
156 | this.add((() => {
|
157 | var _ref = (0, _asyncToGenerator3.default)(function* (ctx, next) {
|
158 | ctx.status = 200;
|
159 | yield next();
|
160 | });
|
161 |
|
162 | return function (_x, _x2) {
|
163 | return _ref.apply(this, arguments);
|
164 | };
|
165 | })(), true);
|
166 |
|
167 |
|
168 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.ERROR)) {
|
169 | this.add((0, _koaError2.default)(errorHandler), true);
|
170 | }
|
171 |
|
172 |
|
173 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.TRAILING_SLASH)) {
|
174 | this.add((() => {
|
175 | var _ref2 = (0, _asyncToGenerator3.default)(function* (ctx, next) {
|
176 | if (base === ctx.path) {
|
177 | ctx.redirect(`${ctx.path}/${ctx.search}`);
|
178 | } else {
|
179 | yield next();
|
180 | }
|
181 | });
|
182 |
|
183 | return function (_x3, _x4) {
|
184 | return _ref2.apply(this, arguments);
|
185 | };
|
186 | })());
|
187 | }
|
188 |
|
189 | if (ssr) {
|
190 | |
191 |
|
192 |
|
193 |
|
194 |
|
195 | if (this.isProd && !(0, _path2.isFromCDN)(publicPath)) {
|
196 |
|
197 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.STATIC)) {
|
198 |
|
199 | this.add(mount(_path.posix.join(publicPath, _constants.ASSETS_DIRNAME_IN_DIST), koaStatic((0, _path.join)(this.cwd, _constants.ASSETS_DIRNAME_IN_DIST))));
|
200 | }
|
201 |
|
202 |
|
203 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.SERVICE_WORKER) && serviceWorker && serviceWorker.swDest) {
|
204 | let swFiles = [(0, _path.basename)(serviceWorker.swDest), 'sw-register.js'].map(f => _path.posix.join(publicPath, f));
|
205 | this.add((() => {
|
206 | var _ref3 = (0, _asyncToGenerator3.default)(function* (ctx, next) {
|
207 | let done = false;
|
208 | if (swFiles.includes(ctx.path)) {
|
209 |
|
210 | ctx.set('Cache-Control', 'private, no-cache, no-store');
|
211 | done = yield send(ctx, ctx.path.substring(publicPath.length), {
|
212 | root: _this.cwd
|
213 | });
|
214 | }
|
215 | if (!done) {
|
216 | yield next();
|
217 | }
|
218 | });
|
219 |
|
220 | return function (_x5, _x6) {
|
221 | return _ref3.apply(this, arguments);
|
222 | };
|
223 | })());
|
224 | }
|
225 | }
|
226 |
|
227 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.SSR)) {
|
228 | this.add(c2k((0, _ssr2.default)(this.core)));
|
229 | }
|
230 | }
|
231 |
|
232 | return composeKoa(this.internalMiddlewares);
|
233 | }
|
234 |
|
235 | |
236 |
|
237 |
|
238 |
|
239 |
|
240 |
|
241 | express(selectedMiddlewares = ALL_MIDDLEWARES) {
|
242 | if (!Array.isArray(selectedMiddlewares)) {
|
243 | selectedMiddlewares = [selectedMiddlewares];
|
244 | }
|
245 |
|
246 | let expressRouter = _express.Router;
|
247 | let { router: { base }, build: { ssr, publicPath }, serviceWorker, errorHandler } = this.config;
|
248 | base = (0, _path2.removeTrailingSlash)(base || '/');
|
249 |
|
250 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.COMPRESSION)) {
|
251 |
|
252 | this.add((0, _compression2.default)());
|
253 | }
|
254 |
|
255 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.FAVICON)) {
|
256 |
|
257 | let faviconPath = _path.posix.join(this.cwd, _constants.ASSETS_DIRNAME_IN_DIST, 'img/icons/favicon.ico');
|
258 | this.add((0, _serveFavicon2.default)(faviconPath));
|
259 | }
|
260 |
|
261 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.TRAILING_SLASH)) {
|
262 |
|
263 | let rootRouter = expressRouter();
|
264 | rootRouter.get(base, (req, res, next) => {
|
265 | let url = (0, _url.parse)(req.url);
|
266 | if (!url.pathname.endsWith('/')) {
|
267 | res.redirect(301, url.pathname + '/' + (url.search || ''));
|
268 | } else {
|
269 | next();
|
270 | }
|
271 | });
|
272 | this.add(rootRouter, true);
|
273 | }
|
274 |
|
275 | if (ssr) {
|
276 | |
277 |
|
278 |
|
279 |
|
280 |
|
281 | if (this.isProd && !(0, _path2.isFromCDN)(publicPath)) {
|
282 |
|
283 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.STATIC)) {
|
284 | let staticRouter = expressRouter();
|
285 | staticRouter.get(_path.posix.join(publicPath, _constants.ASSETS_DIRNAME_IN_DIST, '*'), (0, _static2.default)(publicPath));
|
286 | this.add(staticRouter);
|
287 |
|
288 | this.add((0, _serveStatic2.default)(this.cwd, {
|
289 | cacheControl: false,
|
290 | etag: false
|
291 | }));
|
292 | }
|
293 |
|
294 |
|
295 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.SERVICE_WORKER)) {
|
296 | if (serviceWorker && serviceWorker.swDest) {
|
297 | let swFiles = [(0, _path.basename)(serviceWorker.swDest), 'sw-register.js'].map(f => _path.posix.join(publicPath, f));
|
298 | let swRouter = expressRouter();
|
299 | swRouter.get(swFiles, (0, _static2.default)(publicPath));
|
300 | this.add(swRouter);
|
301 |
|
302 | this.add((0, _serveStatic2.default)(this.cwd, {
|
303 | etag: false
|
304 | }));
|
305 | }
|
306 | }
|
307 | }
|
308 |
|
309 |
|
310 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.SSR)) {
|
311 | this.add((0, _ssr2.default)(this.core));
|
312 | }
|
313 | }
|
314 |
|
315 |
|
316 | if (selectedMiddlewares.includes(INTERNAL_MIDDLEWARE.ERROR)) {
|
317 | this.add((0, _expressError2.default)(errorHandler));
|
318 | }
|
319 |
|
320 | return (0, _composeMiddleware.compose)(this.internalMiddlewares);
|
321 | }
|
322 | }
|
323 | exports.default = MiddlewareComposer;
|
324 | module.exports = exports['default']; |
\ | No newline at end of file |