All files / gulpfile.ts/tasks browserSync.ts

0% Statements 0/42
0% Branches 0/36
0% Functions 0/4
0% Lines 0/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                                                                                                                                                                                                                                                 
import * as MBrowserSync from 'browser-sync'
import chalk from 'chalk'
import * as log from 'fancy-log'
import * as os from 'os'
import * as webpack from 'webpack'
import {
  devLogger,
  devLoggerTitle,
  ITimplaTask,
  projectPath,
  setDisplayName,
  sureLazyImport,
  TIMPLA_PROCESS as TP,
  webpackMultiConfig,
} from '../internal'
 
export const browserSync: ITimplaTask = timplaConfig => cb => {
  if (!timplaConfig.browserSync) {
    log(chalk.yellow('========= Browsersync disabled ========='))
    return cb()
  }
  const browserSyncConfig = timplaConfig.browserSync
  const devConfig = timplaConfig.development
  const middlewareConfig = devConfig.middlewareConfig
  const proxyConfig = browserSyncConfig.proxy || null
 
  if (typeof proxyConfig === 'string') {
    browserSyncConfig.proxy = {
      target: proxyConfig,
    }
  } else if (!proxyConfig && !browserSyncConfig.server && !devConfig.disableServerFallback) {
    browserSyncConfig.server = {
      baseDir: timplaConfig.dest,
    }
  }
 
  // Resolve path from project
  if (
    browserSyncConfig.server &&
    typeof browserSyncConfig.server === 'object' &&
    !(browserSyncConfig.server instanceof Array) &&
    browserSyncConfig.server.baseDir
  ) {
    const baseDir = browserSyncConfig.server.baseDir
    browserSyncConfig.server.baseDir = Array.isArray(baseDir)
      ? baseDir.map(e => projectPath(e))
      : projectPath(baseDir)
  }
 
  // Override open with TIMPLA_RELOAD check so as not to annoy dev mode users!
  browserSyncConfig.open = !TP.isTimplaReloaded && browserSyncConfig.open
 
  const server: MBrowserSync.ServerOptions = (browserSyncConfig.proxy ||
    browserSyncConfig.server) as MBrowserSync.ServerOptions
  const prepMiddleware: any[] = []
  const isCustomisable = typeof server === 'object' && !(server instanceof Array)
 
  // can be a choke point when logging, so let's clear it first...
  // we'll re-set this after we log the config
  if (server.middleware) {
    prepMiddleware.push(...server.middleware)
  }
  delete server.middleware
 
  // Enhance middleware
  if (isCustomisable && middlewareConfig !== false) {
    const webpackConfig = webpackMultiConfig(timplaConfig)('development')
    const compiler = webpack(webpackConfig)
    const webpackDevMiddleware = sureLazyImport('webpack-dev-middleware')
    const webpackHotMiddleware = sureLazyImport('webpack-hot-middleware')
    const historyApiFallback = sureLazyImport('connect-history-api-fallback')
 
    // Two ways to disable the SPA middleware
    const enableSpa = !!middlewareConfig.connectHistoryApiFallbackMiddleware && !proxyConfig
 
    // Two ways to disable HMR
    const enableWebpackHotMiddleware =
      !!middlewareConfig.webpackHotMiddleware && !!devConfig.webpackHotMiddlewareClient
 
    // Add config-controlled middleware
    prepMiddleware.push(
      ...[
        middlewareConfig.webpackDevMiddleware &&
          setDisplayName(
            webpackDevMiddleware(compiler, {
              publicPath: webpackConfig.output.publicPath,
              watchOptions: browserSyncConfig.watchOptions || {},
              ...middlewareConfig.webpackDevMiddleware,
            }),
            'webpack-dev-middleware'
          ),
        enableWebpackHotMiddleware &&
          setDisplayName(
            webpackHotMiddleware(compiler, {
              log: false,
              ...middlewareConfig.webpackHotMiddleware,
            }),
            'webpack-hot-middleware'
          ),
        // Useful for developing spas
        // Redirects requests to root index.html if no corresponding files are found
        enableSpa &&
          setDisplayName(
            historyApiFallback(middlewareConfig.connectHistoryApiFallbackMiddleware),
            'connect-history-api-fallback'
          ),
      ].filter(Boolean)
    )
  }
 
  // User should be informed of the modified browsersyncConfig
  devLoggerTitle('BrowserSync config')
  devLogger('%O', browserSyncConfig)
 
  // Switch server with cloned since we're done logging
  server.middleware = prepMiddleware
 
  let middlewareMessage = 'No middleware used!'
  if (Array.isArray(server.middleware) && server.middleware.length) {
    middlewareMessage = server.middleware
      .map((e: any) => e.displayName || e.constructor.name || e.name)
      .join(', ')
  }
  devLogger('middleware', chalk.magenta(middlewareMessage), os.EOL)
 
  MBrowserSync.init(browserSyncConfig)
  cb()
}