UNPKG

3.12 kBPlain TextView Raw
1import browserSync from "browser-sync";
2import {
3 concat,
4 dropWhile,
5 isObject,
6 map,
7 mapValues,
8 reduce
9} from "lodash";
10import MemoryFS from "memory-fs";
11import path from "path";
12import webpack from "webpack";
13import webpackDevMiddleware from "webpack-dev-middleware";
14import webpackHotMiddleware from "webpack-hot-middleware";
15
16export const HMR_ENTRY = "webpack-hot-middleware/client";
17
18export interface IPlugin extends webpack.Plugin {
19 new(): IPlugin;
20}
21
22export const getHmrPluginsByVersion = (): IPlugin[] => {
23 const version = require("webpack/package.json").version;
24 const majarVersion = String(version).split(".")[0];
25
26 switch (majarVersion) {
27 case "1":
28 throw new Error("not support webpack@1");
29 case "2":
30 default:
31 return [
32 webpack.HotModuleReplacementPlugin
33 ] as IPlugin[];
34 }
35};
36
37const concatHMREntry = (entry: string): string[] => [HMR_ENTRY].concat(entry);
38
39const isOneOfPlugins = (PluginList: IPlugin[], plugin: webpack.Plugin) =>
40 reduce(PluginList, (result, Plugin) => (result || (plugin instanceof Plugin)), false);
41
42export const patchEntryWithHMR = (entry: string | { [k: string]: string }): string[] | { [k: string]: string[] } => {
43 if (isObject(entry)) {
44 return mapValues(entry as { [k: string]: string }, concatHMREntry);
45 }
46 return concatHMREntry(entry as string);
47};
48
49export const patchPlugins = (plugins: IPlugin[]) => {
50 const hmrPlugins = getHmrPluginsByVersion();
51 const cleanedPlugins = dropWhile(plugins, (plugin) => isOneOfPlugins(hmrPlugins, plugin));
52 return concat(cleanedPlugins, map(hmrPlugins, (Plugin: IPlugin) => new Plugin()));
53};
54
55export const patchWebConfigWithHMR = (webpackConfig: webpack.Configuration): webpack.Configuration => ({
56 ...webpackConfig,
57 entry: patchEntryWithHMR(webpackConfig.entry as string),
58 plugins: patchPlugins(webpackConfig.plugins as IPlugin[])
59});
60
61export const createMiddlewaresForWebpack = (
62 webpackConfig: webpack.Configuration,
63 index: string,
64 hot: boolean = false
65) => {
66
67 const patchedWebpackConfig = hot
68 ? patchWebConfigWithHMR(webpackConfig)
69 : webpackConfig;
70
71 const bundler = webpack(patchedWebpackConfig);
72
73 const fs = new MemoryFS();
74
75 bundler.outputFileSystem = fs;
76
77 const devMiddleware = webpackDevMiddleware(bundler, {
78 publicPath: (patchedWebpackConfig.output || {}).publicPath!,
79
80 stats: patchedWebpackConfig.stats || {
81 colors: true,
82 reasons: false,
83 hash: false,
84 version: false,
85 timings: true,
86 chunks: false,
87 chunkModules: false,
88 cached: false
89 }
90 });
91
92 const devServerMiddlewares = [
93 devMiddleware,
94 ((req, res, next) => {
95 if (req.method === "GET" && req.url === "/") {
96 devMiddleware.waitUntilValid(() => {
97 const indexFile = path.join(webpackConfig.output!.path!, index);
98 res.end(fs.readFileSync(indexFile));
99 });
100 } else {
101 next();
102 }
103 }) as browserSync.MiddlewareHandler
104 ];
105
106 if (hot) {
107 return [
108 ...devServerMiddlewares,
109 webpackHotMiddleware(bundler)
110 ];
111 }
112
113 return devServerMiddlewares;
114};