基于gulp,webpack完成天真的 livereload 效劳

webpack 供应了 webpack-dev-server 能够完成高效的页面自动革新,然则这个 server 有一点局限性:

  • 虽然能够做为 server 中间件运用,但自身不供应别的资本的静态效劳

  • 关于打包文件之外的变化它是蒙昧的,也就没法去革新

  • 假如是本身的页面须要引入 script,修正设置 entry,本身别的供应文件效劳,步骤烦琐

如今假定我们有本身的 html 页面,页面引入了当地的 css,然则 js 是由 webpack 打包的,须要完成文件修正自动革新的页面的话我们须要以下几个模块:

  • 文件看管 – gulp.watch()

  • 静态资本效劳 – gulp-serve 模块

  • livereload效劳 (担任接收变化要求并关照页面革新) – gulp-livereload 模块

  • 自动增加 livereload 前端剧本 – connect-livereload 模块 (或许运用livereload浏览器插件)

代码以下:

// npm i gulp-serve gulp-livereload webpack gulp-util gulp connect-livereload -D
var serve = require('gulp-serve')
var livereload = require('gulp-livereload')
var webpack = require('webpack')
var gutil = require('gulp-util')
var gulp = require('gulp')
var webpackConfig = require('./webpack.config.js')
var inject = require('connect-livereload')()
var path = require('path')
var myConfig = Object.create(webpackConfig)
// for debugging
myConfig.devtool = 'sourcemap'
myConfig.debug = true

var paths = {
  scripts: ['index.js'],
  // file list for watching
  asserts: ['*.css', 'index.html']
}

gulp.task('default', ['build-dev'])

gulp.task('build-dev', ['webpack:build-dev', 'serve'], function () {
  livereload.listen({
    start: true
  })
  // build js files on change
  gulp.watch(paths.scripts, ['webpack:build-dev'])
  var watcher = gulp.watch(paths.asserts)
  watcher.on('change', function (e) {
    livereload.changed(e.path)
  })
})

// static server
gulp.task('serve', serve({
  root: [__dirname],
  // inject livereload script ot html
  middleware: inject
}))

var devCompiler = webpack(myConfig)
var outputFile = path.resolve(myConfig.output.path, myConfig.output.filename)

gulp.task('webpack:build-dev', function (callback) {
  devCompiler.run(function (err, stats) {
    if (err) throw new gutil.pluginError('webpack:build-dev', err) //eslint-disable-line
    gutil.log('[webpack:build-dev]', stats.toString({
      colors: true
    }))
    livereload.changed(outputFile)
    callback()
  })
})

这类做法最大的优点就是 html 和 css 没必要都让 webpack 去处置惩罚也能做到自动革新,然则比拟 webpack-dev-server, 它是JS悉数从新打包的,所以机能会差许多,此时我们能够运用 webpack-dev-server 完成打包文件的监听,同时让本来背景供应别的文件效劳。假定背景运用 3000 端口,我们运用 webpack-dev-server inline形式须要以下设置:

gulp.task('webpack:dev-server', function () {
  var devServerConfig = Object.create(myConfig)
  // webpack need this to send request to webpack-dev-server
  devServerConfig.output.publicPath = 'http://localhost:8080/'
  devServerConfig.plugins = devServerConfig.plugins || []
  devServerConfig.plugins.push(new webpack.HotModuleReplacementPlugin())
  // inline mode
  devServerConfig.entry.unshift('webpack-dev-server/client?http://localhost:8080', 'webpack/hot/dev-server')
  var compiler = webpack(devServerConfig)
  new WebpackDevServer(compiler, {
    contentBase: 'http://localhost:3000/',
    // Set this as true if you want to access dev server from arbitrary url.
    // This is handy if you are using a html5 router.
    historyApiFallback: false,
    // Don't forget this for dev-server
    publicPath: '/build/',
    lazy: false,
    hot: true
  }).listen(8080, 'localhost', function (err) {
    if (err) throw new gutil.PluginError('webpack-dev-server', err)
    // Server listening
    gutil.log('[webpack-dev-server]', 'http://localhost:8080/')
  })
})

gulp webpack:dev-server 如今能够启动效劳了,但同时要求 bundle.js script也要修正为:

<script src="http://localhost:8080/bundle.js" type="text/javascript" charset="utf-8"></script>

如许 webpack-dev-server 才举行热加载。

另有一种看起来更好的体式格局是运用 proxy 来代办,此时你接见 webpack-dev-server时它没法处置惩罚的要求都邑转发给你的背景效劳,设置起来比拟上面要简朴一些:

  • html 页面无需修正

  • config.output.publicPath 运用本来的相对路径

  • webpack-dev-server 设置 proxy 选项

gulp.task('webpack:dev-server', function () {
  var devServerConfig = Object.create(myConfig)
  // webpack need this to send request to webpack-dev-server
  devServerConfig.plugins = devServerConfig.plugins || []
  devServerConfig.plugins.push(new webpack.HotModuleReplacementPlugin())
  // inline mode
  devServerConfig.entry.unshift('webpack-dev-server/client?http://localhost:8080', 'webpack/hot/dev-server')
  var compiler = webpack(devServerConfig)
  new WebpackDevServer(compiler, {
    // contentBase: {target: 'http://localhost:3000/'},
    // Set this as true if you want to access dev server from arbitrary url.
    // This is handy if you are using a html5 router.
    historyApiFallback: false,
    proxy: {
      '*': 'http://localhost:3000'
    },
    publicPath: '/build/',
    lazy: false,
    hot: true
  }).listen(8080, 'localhost', function (err) {
    if (err) throw new gutil.PluginError('webpack-dev-server', err)
    // Server listening
    gutil.log('[webpack-dev-server]', 'http://localhost:8080/')
  })
})

这么做只须要接见 webpack-dev-server 就能够直接接见页面,别的装备经由过程 ip 也能直接接见到,免去了修正的贫苦。实在 webpack-dev-server 假如能够直接增加静态文件效劳的功用,我们偶然就没必要折腾的这么贫苦了,大概是作者不想损坏它功用上的简约以及防止滥用致使不良的效果吧。

    原文作者:chemzqm
    原文地址: https://segmentfault.com/a/1190000003881087
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞