1 | import browserSync from "browser-sync";
|
2 | import compress from "compression";
|
3 | import connectHistoryApiFallback from "connect-history-api-fallback";
|
4 | import interpret from "interpret";
|
5 | import { get } from "lodash";
|
6 | import path from "path";
|
7 | import { getBaseDir } from "./utils";
|
8 | import { createMiddlewaresForWebpack } from "./WebpackOptions";
|
9 |
|
10 | export interface IOptions {
|
11 | config: string;
|
12 | index: string;
|
13 | proxy: string;
|
14 | webpack: boolean;
|
15 | hot: boolean;
|
16 | compress: boolean;
|
17 | historyApiFallback: boolean;
|
18 | }
|
19 |
|
20 | interface IInterpret {
|
21 | module: string
|
22 | register: (module: any) => void
|
23 | }
|
24 |
|
25 | type TModuleDescriptor = null | string | string[] | IInterpret
|
26 |
|
27 | function registerCompiler(moduleDescriptor: TModuleDescriptor) {
|
28 | if (moduleDescriptor) {
|
29 | if (typeof moduleDescriptor === "string") {
|
30 | require(moduleDescriptor);
|
31 | } else if (!Array.isArray(moduleDescriptor)) {
|
32 | moduleDescriptor.register(require(moduleDescriptor.module));
|
33 | } else {
|
34 | for (const moduleName of moduleDescriptor) {
|
35 | if (moduleName) {
|
36 | try {
|
37 | registerCompiler(moduleName);
|
38 | break;
|
39 | } catch (e) {
|
40 |
|
41 | }
|
42 | }
|
43 | }
|
44 | }
|
45 | }
|
46 | }
|
47 |
|
48 | const createBrowserSyncOptions = (options: IOptions): browserSync.Options => {
|
49 | const webpackConfigFile = path.join(process.cwd(), options.config);
|
50 | const webpackConfigFileExt = path.extname(webpackConfigFile);
|
51 |
|
52 | registerCompiler(interpret.extensions[webpackConfigFileExt] as any);
|
53 |
|
54 | const webpackConfig = require(webpackConfigFile);
|
55 |
|
56 | let middlewares: browserSync.MiddlewareHandler[] = [];
|
57 |
|
58 | if (options.historyApiFallback) {
|
59 | middlewares = middlewares.concat(connectHistoryApiFallback({
|
60 | index: "/"
|
61 | }) as any);
|
62 | }
|
63 |
|
64 | if (options.webpack) {
|
65 | middlewares = middlewares.concat(createMiddlewaresForWebpack(webpackConfig, options.index, options.hot) as any);
|
66 | }
|
67 |
|
68 | if (options.compress) {
|
69 | middlewares = middlewares.concat(compress({ level: 6 }) as browserSync.MiddlewareHandler);
|
70 | }
|
71 |
|
72 | if (options.proxy) {
|
73 | return {
|
74 | ...(get(webpackConfig, "devServer.browserSync")),
|
75 | proxy: {
|
76 | target: options.proxy as string,
|
77 | middleware: middlewares as browserSync.MiddlewareHandler[]
|
78 | } as any
|
79 | };
|
80 | }
|
81 |
|
82 | return {
|
83 | ...(get(webpackConfig, "devServer.browserSync")),
|
84 | ...(process.env.PORT ? ({
|
85 | port: Number(process.env.PORT)
|
86 | }) : {}),
|
87 | server: {
|
88 | baseDir: getBaseDir(webpackConfig.output.path, webpackConfig.output.publicPath),
|
89 | index: path.join(webpackConfig.output.publicPath || "/", options.index),
|
90 | middleware: middlewares as browserSync.MiddlewareHandler[],
|
91 | },
|
92 | notify: false
|
93 | };
|
94 | };
|
95 |
|
96 | export const create = (opts: IOptions) => browserSync(createBrowserSyncOptions(opts));
|