GX博客

分享个人 Full-Stack JavaScript 项目开发经验

使用Grunt实时重载静态页面

在静态页面的开发过程中,我们希望启动一个连接静态文件的 web 服务器(这样可以解决一些文件系统无法满足的需求,如 cookie 的使用),并且在对相关文件进行添加、修改或删除等操作后,页面能够重新加载。通过 grunt-contrib-connect 和 grunt-contrib-watch 插件可以实现以上功能。如果你还没使用过 Grunt,可先阅读Grunt的安装及其插件的选择。下面具体介绍它们的配置:


安装插件

yarn add --dev grunt-contrib-connect
yarn add --dev grunt-contrib-watch

grunt-contrib-connect


该插件用于启动一个连接静态文件的 web 服务器。默认情况下,一旦 grunt 的任务执行完毕,该服务会自动关闭。默认配置如下:

connect: {
  option: {
    port: 8000,
    protocol: 'http',
    hostname: '0.0.0.0',
    base: '.',
    directory: null,
    keepalive: false,
    debug: false,
    livereload: false,
    open: false,
    useAvailablePort: false,
    onCreateServer: null,
    middleware: null
  },
  // ...
},
// ...
  • port

    服务器响应的端口号。默认情况下,如果指定的端口号已被占用,则任务将失败。

  • protocol

    协议名称。一般使用默认的 'http'。

  • hostname

    服务器的主机名称。设置为 '*', 表示任何IPv4地址,如本地地址('127.0.0.1')、分配到以太网或无线接口的地址(如 '192.168.0.x' 或 '10.0.0.x' )等。

  • base

    静态文件服务的根目录,默认为 '.',即 Gruntfile 的同级目录。当参数为数组,如 [ 'public', 'www-root' ],表示基于多个目录的服务,数组最后一个元素也作为浏览器打开时展示的目录。数组形式适合如样式表、脚本和 html 分别存放在不同目录的情况,而我们只想查看 html 目录。参数还可以是包含 path 和 options 属性的对象,其中 options 包含的属性如下:

    acceptRanges:启用或禁用 Range 请求,默认为 true。禁用此功能将不会发送 Accept-Ranges 响应标头和忽略 Range 请求标头的内容。

    cacheControl:启用或禁用设置 Cache-Control 响应标头,默认为 true。禁用此选项将忽略 immutable 和 maxAge 选项。

    dotfiles:遇到以 '.' 开头的文件和目录是的处理方式。在自定义根目录时,只会检测根目录下级的文件和子目录。该选项可以设置成三种情况:'allow'(没有特殊处理)、'deny'(拒绝请求)、'ignore'(忽略它们),默认为 'ignore'。

    etag:启用或禁用 ETag 响应标头,默认为 true,启用。

    extensions:设置文件扩展名后备,默认为 false。设置为 true 后,如果找不到文件,则会将给定的扩展名添加到文件名中并进行搜索。存在的第一个匹配将被提供。如:['html', 'htm']。

    fallthrough:默认值为 true。客户端错误(例如错误请求或对不存在文件的请求)时,它将简单地 next() 下一个中间件。当值为 false,将调用这些错误(包括404),使用 next(err)。

    immutable:在 Cache-Control 响应标头中启用或禁用 immutable,默认为 false。如果设置为 true,则还应指定 maxAge 以启用缓存。immutable 指令将阻止受支持的客户端在 maxAge 选项的生命周期内发出条件请求,以检查文件是否已更改。

    index:默认情况下,该模块将发送目录中的 “index.html” 文件以响应对目录的请求(浏览器将直接打开该 html 页面)。要禁用该行为,可设置为 false 或提供新索引(按首选顺序传递字符串或数组)。

    maxAge

    lastModified:默认为 true,启用 Last-Modified 响应标头,设置值为文件系统的最后修改时间。

    maxAge:默认值为 0,用于设置 Cache-Control 响应标头中 max-age 的值,单位为毫秒。它也支持使用满足ms模块要求的字符串。

    redirect:默认为 true,当路径名为目录时,点击后重定向到对应目录。

    setHeaders:设置自定义响应标头的函数,接收三个参数:res(响应对象)、path(正在发送的文件路径)、stat(正在发送的文件的stat对象)。

  • directory

    用于直接指定浏览器打开时展示的目录。它覆盖 base 中的浏览器展示目录。(该目录仅为展示目录,若果 base 中没有指定该目录为静态文件服务目录,则那些静态文件无法访问。)

  • keepalive

    默认情况下,一旦 grunt 的任务执行完毕,该 web 服务器就会关闭。keepalive 设置为 true 可保持服务器开启,但后续任务将无法运行。它允许命令行直接运行任务目标时开启,如 grunt connect:targetname:keepalive。

  • debug

    debug 设置为 true 时,开启日志记录,控制台将显示请求方法名、请求路径、耗时等信息。

  • livereload

    livereload 设置为 true 或者一个端口号,则会在你的页面中插入重载脚本的 script 标签。它不会主动执行实时重载。它旨在与 grunt-contrib-watch 或其它任务一起使用,这些任务将在文件更改时触发实时重载页面。

  • open

    使用系统默认浏览器打开服务页面。有两种设置形式:

    1. 设置为 true,打开默认的路径,即 protocol、hostname 和 port 组成的 URL。
    2. 设置为默认路径下的具体打开目录,如 'http://localhost:8000/html'。

  • useAvailablePort

    如果 useAvailablePort 设置为 true,任务将在 port 选项端口被占用时,查找下一个可用端口。

  • onCreateServer

    在创建服务器对象之后调用的函数(接收 server、connect、options 三个参数),以允许集成需要访问 connect 的服务器对象的库,如 Socket.IO。

  • middleware

    默认为用于连接 options.base 静态文件和目录浏览的中间件。它允许你添加自己的 Connect 中间件,使用例子见project Gruntfileproject unit tests


grunt-contrib-watch


该插件用于监听文件的添加、更改或删除,然后运行预定义任务。用配置可见minimatch,下面是一些额外配置的默认值:

watch: {
  option: {
    task: [],
    spawn: true,
    interrupt: false,
    debounceDelay: 500,
    interval: 100,
    event: 'all',
    reload: false,
    forever: true,
    dateFormat:function(){},
    atBegin: false,
    livereload: false,
    livereloadOnError: true
  },
  // ...
},
// ...
  • task

    在监视文件事件发生时要运行的 grunt 任务,如:['jshint']、['jshint:frontend']。

  • spawn

    是否在子进程中运行生成任务。spawn 设置为 false,可提高监听响应速度,并允许后续任务运行在共享的上下文,但会使监听更容易失败。

  • interrupt

    在修改文件时,此监视任务将在子进程中生成任务。默认只会在上一个进程完成时为每个目标生成一个新的子进程。interrupt 设置为 true,将终止上一个进程,并在以后更改时生成一个新进程。

  • debounceDelay

    在为相同的文件路径和状态连续发出事件之前要等待的时间(毫秒)。

  • interval

    参数传递给 fs.watchFile,建议忽略该配置,使用默认值。

  • event

    指定触发指定任务的监视事件类型。可以是 'changed'、'added' 和 'deleted' 的一个或多个,如 [ 'added', 'changed' ],或者使用 'all'。

  • reload

    默认情况下,如果 Gruntfile.js 也被监听,则对其进行更改将触发监视任务重新启动,并重新加载 Gruntfile.js。当 reload 设置为 true,改变任何的监听文件时都会触发监听任务重新启动,重新加载 Gruntfile.js。如果你 Gruntfile.js 依赖于其它文件时,这将特别有用。

  • forever

    这是一个任务级别选项,无法为每个目标配置(即必须在 watch.options.forever 下配置)。默认情况下,监视任务将覆盖 grunt.fatal 和 grunt.warn 以尝试阻止它们退出监视进程。如果你不想 grunt.fatal 和 grunt.warn 被覆盖,请将 forever 选项设置为 false。

  • dateFormat

    这是一个任务级别选项,无法为每个目标配置。默认情况下,当监听完成运行任务时,它将显示类似的消息:Completed in 1.301s at Wed Oct 31 2018 14:58:21 GMT-0700 (PDT) - Waiting...。你可以提供函数重写这条信息,例如:

    options: {
      dateFormat: function(time) {
        grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
        grunt.log.writeln('Waiting for more changes...');
      },
      // ...
    },
    // ...
  • atBegin

    此选项将在监听任务启动时,触发每个指定任务的运行。

  • livereload

    设置实时重载的端口号(默认并且推荐使用 35729)。一般设置为 true,或者使用 grunt 模板字符串指定 grunt-contrib-connect 中设定的端口号,如:

    options: {
      livereload: '<%= connect.server.options.livereload %>',
      // ...
    },
    // ...
  • livereloadOnError

    默认地,如果执行的任务遇到错误,则阻止实时重载。如果设置为 false,则仅在所有任务成功完成时才会触发实时重载。

设置监听文件范围时,应该尽可能的减少监听文件数量,这样可以提高监听性能。

示例

在实际静态页面开发中,下面的简单配置已经基本满足需求。

const {dir} = require('./grunt.config');
// ...
connect: {
  server: {
    options: {
      hostname: '*',
      livereload: 35729,
      open: true,
      base: {
        path: '.',
        options: {
          index: false
        }
      }
    }
  }
},
watch: {
  watchFrontend: {
    options: {
      livereload: true
    },
    files: [
      'Gruntfile.js',
      'grunt.config.js',
      `${dir.imageDev}/**/*`,
      `${dir.cssDev}/**/*.css`,
      `${dir.jsDev}/**/*.js`,
      `${dir.html}/**/*.html`
    ]
  }
},
// ...

配置中,以 Gruntfile.js 所在目录作为连接静态文件 web 服务器的服务目录和浏览器默认打开目录,监听开发目录下的图片、样式表、脚本、html,及 Gruntfile.js 和其配置文件。通过 grunt 命令,依次执行 connect 和 watch 任务后,静态文件目录会映射到默认浏览器的 web 页面上。这时打开对应的开发页面,编辑器修改具体代码并保存时,浏览器将会自动实时刷新。配合双显示屏,可以大大提高开发效率。

版权声明:

本文为博主原创文章,若需转载,须注明出处,添加原文链接。

https://leeguangxing.cn/blog_post_11.html