Skip to content

Commit 9b7fb2c

Browse files
committed
feat(server): 延迟 404 的请求直到编译结束(使得编译副产物可以被请求到)
1 parent 02c26de commit 9b7fb2c

File tree

2 files changed

+115
-65
lines changed

2 files changed

+115
-65
lines changed

lib/commands/server.js

Lines changed: 82 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -167,76 +167,103 @@ exports.run = function (options) {
167167
var cacheId = sysPath.join(projectName, requestUrlNoVer);
168168
var middleware = middlewareCache[cacheId];
169169

170+
// 准备生成 middleware
170171
if (!middleware) {
171172
var project = Manager.getProject(projectCwd, { cache: false });
172173

173174
if (project.check()) {
174-
compiler = project.getServerCompiler(function (config) {
175-
var nextConfig = extend({}, config);
175+
(function () {
176176

177-
// entry 应该是个空对象, 这样如果没有找到请求对应的 entry, 就不会编译全部入口
178-
nextConfig.entry = {};
179-
180-
// 将 webpack entry 设置为当前请求的资源
181-
Object.keys(config.entry).map(function (entryKey) {
182-
var entryItem = config.entry[entryKey];
183-
184-
var isRequestingEntry = false,
185-
entryPath = '';
186-
187-
if (Array.isArray(entryItem)) {
188-
entryPath = entryItem[entryItem.length - 1];
189-
} else {
190-
entryPath = entryItem;
191-
}
192-
193-
// 将入口的 .scss/.less 后缀替换为.css
194-
var cssReg = new RegExp('\\' + config.entryExtNames.css.join('|\\'));
195-
entryPath = entryPath.replace(cssReg, '.css');
196-
197-
// 如果是 ykit 处理过的样式文件,将其变为正常的请求路径(../.ykit_cache/main/index.css.js => main/index.css)
198-
if (entryPath.indexOf('.css.js') && entryPath.indexOf('.ykit_cache/') > 1) {
199-
entryPath = entryPath.split('.ykit_cache/')[1].replace('.css.js', '.css');
200-
}
201-
202-
// 判断所请求的资源是否在入口配置中
203-
if (sysPath.normalize(entryPath) === sysPath.normalize(requestUrl)) {
204-
isRequestingEntry = true;
205-
} else if (sysPath.normalize(entryPath) === sysPath.normalize(requestUrlNoVer)) {
206-
req.url = req.url.replace(/@[\d\w]+(?=\.\w+$)/, '');
207-
isRequestingEntry = true;
208-
}
209-
210-
if (isRequestingEntry) {
211-
nextConfig.entry = _defineProperty({}, entryKey, entryItem);
212-
}
177+
var nextConfig = void 0;
178+
compiler = project.getServerCompiler(function (config) {
179+
nextConfig = extend({}, config);
180+
181+
// entry 应该是个空对象, 这样如果没有找到请求对应的 entry, 就不会编译全部入口
182+
nextConfig.entry = {};
183+
184+
// 将 webpack entry 设置为当前请求的资源
185+
Object.keys(config.entry).map(function (entryKey) {
186+
var entryItem = config.entry[entryKey];
187+
188+
var isRequestingEntry = false,
189+
entryPath = '';
190+
191+
if (Array.isArray(entryItem)) {
192+
entryPath = entryItem[entryItem.length - 1];
193+
} else {
194+
entryPath = entryItem;
195+
}
196+
197+
// 将入口的 .scss/.less 后缀替换为.css
198+
var cssReg = new RegExp('\\' + config.entryExtNames.css.join('|\\'));
199+
entryPath = entryPath.replace(cssReg, '.css');
200+
201+
// 如果是 ykit 处理过的样式文件,将其变为正常的请求路径(../.ykit_cache/main/index.css.js => main/index.css)
202+
if (entryPath.indexOf('.css.js') && entryPath.indexOf('.ykit_cache/') > 1) {
203+
entryPath = entryPath.split('.ykit_cache/')[1].replace('.css.js', '.css');
204+
}
205+
206+
// 判断所请求的资源是否在入口配置中
207+
if (sysPath.normalize(entryPath) === sysPath.normalize(requestUrl)) {
208+
isRequestingEntry = true;
209+
} else if (sysPath.normalize(entryPath) === sysPath.normalize(requestUrlNoVer)) {
210+
req.url = req.url.replace(/@[\d\w]+(?=\.\w+$)/, '');
211+
isRequestingEntry = true;
212+
}
213+
214+
if (isRequestingEntry) {
215+
nextConfig.entry = _defineProperty({}, entryKey, entryItem);
216+
}
217+
});
218+
219+
nextConfig.plugins.push(require('../plugins/progressBarPlugin.js'));
220+
nextConfig.plugins.push(require('../plugins/compileInfoPlugin.js'));
221+
222+
return nextConfig;
213223
});
214224

215-
nextConfig.plugins.push(require('../plugins/progressBarPlugin.js'));
216-
nextConfig.plugins.push(require('../plugins/compileInfoPlugin.js'));
217-
218-
return nextConfig;
219-
});
220-
221-
compiler.watch({}, function (err) {
222-
if (err) {
223-
error(err);
225+
// 如果没找到该资源,在整个编译过程结束后再返回
226+
if (Object.keys(nextConfig.entry).length === 0) {
227+
setTimeout(function () {
228+
promiseCache[projectName] ? Promise.all(promiseCache[projectName]).then(function () {
229+
next();
230+
}) : null;
231+
}, 1000);
224232
} else {
225-
middlewareCache[cacheId] = req.url;
226-
next();
233+
(function () {
234+
// 生成该请求的 promiseCache
235+
var resolve = null;
236+
var requestPromise = new Promise(function (res) {
237+
resolve = res;
238+
});
239+
240+
if (!promiseCache[projectName]) {
241+
promiseCache[projectName] = [requestPromise];
242+
} else {
243+
promiseCache[projectName].push(requestPromise);
244+
}
245+
246+
compiler.watch({}, function (err) {
247+
if (err) {
248+
error(err);
249+
} else {
250+
middlewareCache[cacheId] = req.url;
251+
next();
252+
}
253+
resolve();
254+
});
255+
})();
227256
}
228-
});
229257

230-
// 检测config文件变化
231-
watchConfig(project, middleware, cacheId);
258+
// 检测config文件变化
259+
watchConfig(project, middleware, cacheId);
260+
})();
232261
} else {
233262
next();
234263
}
235264
} else {
236265
req.url = middleware;
237-
setTimeout(function () {
238-
next();
239-
}, 300);
266+
next();
240267
}
241268
})();
242269
} else {

src/commands/server.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,15 @@ exports.run = (options) => {
163163
const cacheId = sysPath.join(projectName, requestUrlNoVer);
164164
let middleware = middlewareCache[cacheId];
165165

166+
// 准备生成 middleware
166167
if (!middleware) {
167168
let project = Manager.getProject(projectCwd, { cache: false });
168169

169170
if (project.check()) {
171+
172+
let nextConfig;
170173
compiler = project.getServerCompiler(function (config) {
171-
let nextConfig = extend({}, config);
174+
nextConfig = extend({}, config);
172175

173176
// entry 应该是个空对象, 这样如果没有找到请求对应的 entry, 就不会编译全部入口
174177
nextConfig.entry = {};
@@ -216,14 +219,36 @@ exports.run = (options) => {
216219
return nextConfig;
217220
});
218221

219-
compiler.watch({}, (err) => {
220-
if(err) {
221-
error(err);
222+
// 如果没找到该资源,在整个编译过程结束后再返回
223+
if(Object.keys(nextConfig.entry).length === 0) {
224+
setTimeout(() => {
225+
promiseCache[projectName] ? Promise.all(promiseCache[projectName]).then(() => {
226+
next();
227+
}) : null;
228+
}, 1000);
229+
} else {
230+
// 生成该请求的 promiseCache
231+
let resolve = null;
232+
const requestPromise = new Promise((res) => {
233+
resolve = res;
234+
});
235+
236+
if (!promiseCache[projectName]) {
237+
promiseCache[projectName] = [requestPromise];
222238
} else {
223-
middlewareCache[cacheId] = req.url;
224-
next();
239+
promiseCache[projectName].push(requestPromise);
225240
}
226-
});
241+
242+
compiler.watch({}, (err) => {
243+
if(err) {
244+
error(err);
245+
} else {
246+
middlewareCache[cacheId] = req.url;
247+
next();
248+
}
249+
resolve();
250+
});
251+
}
227252

228253
// 检测config文件变化
229254
watchConfig(project, middleware, cacheId);
@@ -232,9 +257,7 @@ exports.run = (options) => {
232257
}
233258
} else {
234259
req.url = middleware;
235-
setTimeout(() => {
236-
next();
237-
}, 300);
260+
next();
238261
}
239262
} else { // 一次编译全部资源
240263
let middleware = middlewareCache[projectName],

0 commit comments

Comments
 (0)