• 前端开发 Grunt 之 Connect详解


    在前端开发过程中,我们需要在开发过程中,将开发中的站点部署到服务器上,然后,在浏览器中查看实际的效果,在 Grunt 环境下,可以直接使用集成在 Grunt 中的 Connect 插件完成站点服务器的支持,在开发过程中,直接查看效果。

    1. Connect 资源

    与 Grunt 集成的 Connect 可以在 GitHub 上找到,地址:https://github.com/gruntjs/grunt-contrib-connect

    安装的时候,直接通过 NPM 就可以,不用自己下载。执行下面的命令将 grunt-contrib-connect 安装到你的项目中。

    npm install grunt-contrib-connect --save-dev

    安装之后,需要在你的 Gruntfile.js 项目文件中,加载这个插件。

    grunt.loadNpmTasks('grunt-contrib-connect');

    具体的配置信息见下一步了。

    2.  基本配置

    在你的 Gruntfile.js 中,添加一个 connect 的配置节。

    在 connect 中设置一个 connect 任务的名字,注意不要叫 options ,这是 connect 保留的配置名。我们这里称为 server。

    完成之后的 Gruntfile.js 文件如下:

    复制代码
    'use strict';  
    
    module.exports = function (grunt) {  
    
        // Project configuration.  
        grunt.initConfig({  
    
            connect: {
                server: {
                    options: {
                        port: 8000,
                        hostname: '*',
                        base: ['src/']
                    }
                }
            }
    
        });
    
        grunt.loadNpmTasks('grunt-contrib-connect');
    }
    复制代码

    这里的配置是说服务器将工作在 8000 端口,网站的根目录映射到物理目录的 src/ 中。

    我们可以在 src 中创建一个名为 index.html 的网页,进行测试。
    保存配置文件之后,在命令行执行  grunt connect

    PS C:studygrunt> grunt connect
    Running "connect:server" (connect) task
    Started connect web server on http://localhost:8000
    
    Done, without errors.

    在执行 Grunt 的过程中,网站服务器将会启动,你可以通过浏览器来访问这个服务器。但是,在 grunt 执行完成之后,服务器将会被自动关闭。所以,你可能根本来不及切换到浏览器去访问你的页面。

    使用 keepalive 这个选项可以使得 grunt 在执行到 connect 的时候,不会退出这个任务,保持服务器的持续执行,这样你就可以一直访问这个服务器了。但是,需要注意的是,这个 grunt 任务会阻塞后继任务的执行,所以,你需要将这个任务排在最后一个任务。

    复制代码
    'use strict';  
    
    module.exports = function (grunt) {  
    
        // Project configuration.  
        grunt.initConfig({  
    
            connect: {
                server: {
                    options: {
    protocol: 'http', port: 8000, hostname: '*', keepalive: true, base: ['src/'] } } } }); grunt.loadNpmTasks('grunt-contrib-connect'); }
    复制代码

    这个时候,重新执行 grunt connect 就会看到 Waiting forever... 的输出,直到你 Ctrl+C 终止这个任务,grunt 会一直停留在 connect 这个任务上。

    PS C:studygrunt> grunt connect
    Running "connect:server" (connect) task
    Waiting forever...
    Started connect web server on http://localhost:8000
    ^CTerminate batch job (Y/N)? y

    在这一步,我们配置了如下的服务器参数:

    • protocol 服务协议,可以是 'http' 或者 'https', 如果使用 https ,需要额外配置服务器证书。
    • port 服务器的端口,默认为 8000
    • base 可以是一个字符串,或者一个数组,或者一个对象,用来表示映射到网站虚拟根目录的目标。
      • 字符串,映射到网站虚拟根目录的物理路径,默认为 Gruntfile.js 所在的目录
      • 数组,多个被映射到网站虚拟根目录的物理路径
      • 对象,每个路径可以配置更加详细的选项,可以通过 { path: xxx, options: xxxx} 进行配置,其中 options 会传递给 serve-state 模块处理。
    • hostname 默认为 '0.0.0.0',表示可以从任何网络地址来访问。
    • keepalive 是否保持服务,不会退出服务

    3. 高级配置

    1. open

    如果你希望在启动服务之后,自动打开浏览器,而不用自己打开浏览器,再输入访问地址,可以将 open 设置为 true。

    open 可以设置 boolean, 字符串,对象。

    默认为 false,设置为 true 将会自动打开浏览器。

    如果设置为字符串,则为浏览器打开的地址。

    对象的配置将会直接传递给 open 处理。

    {
      target: 'http://localhost:8000', // target url to open, 目标路径
      appName: 'chrome', // name of the app that opens, ie: open, start, xdg-open,自动启动的应用名称, 比如你的浏览器:chrome
      callback: function() {} // called when the app has opened
    }

    2. livereload

    可以配置为 boolean 或者 数值,用来表示是否支持 livereload。

    设置为 true 或者数值表示支持 connect-livereload,但是这个设置不能直接使用,需要 connect-livereload 的配合,所以并不能直接实现自动加载。你还需要 grunt-contrib-watch 或者其他的库支持来实现文件修改时的自动加载。

    下一次我们将会介绍这个 livereload 的使用。

    3. useAvailablePort

    如何使用端口,如果设置为 true,则任务会寻找 port 指定的下一个可用的端口,默认为 false.

    4. onCreateServer

    服务创建之后的回调函数,允许集成其它库到网站中,例如,集成 Socket.IO 的示例。注意,这需要你先准备好了 socket.io 模块。

    复制代码
    grunt.initConfig({
      connect: {
        server: {
          options: {
            port: 8000,
            hostname: '*',
            onCreateServer: function(server, connect, options) {
              var io = require('socket.io').listen(server);
              io.sockets.on('connection', function(socket) {
                // do something with socket
              });
            }
          }
        }
      }
    });
    复制代码

    5. middleware 

    很显然,网站处理的中间件。如果你觉得这个默认的静态文件服务器不够强大的话,可以通过中间件进行扩展。

    可以配置一个函数或者数组,默认为使用 options.base 处理静态文件和目录浏览的数组。

    如果提供了一个数组的话,就会取代默认的服务器处理,直接采用自定义的中间件进行处理,这需要我们完全定义服务器中的处理。

    数组的示例

    复制代码
    grunt.initConfig({
      connect: {
        server: {
          options: {
            middleware: [
              function myMiddleware(req, res, next) {
                res.end('Hello, world!');
              }
            ],
          },
        },
      },
    });
    复制代码

    如果是函数的话,会自动添加默认的静态文件处理中间件,再执行自定义的中间件函数。

    函数的示例

    复制代码
    grunt.initConfig({
      connect: {
        server: {
          options: {
            middleware: function(connect, options, middlewares) {
              // inject a custom middleware into the array of default middlewares
              middlewares.unshift(function(req, res, next) {
                if (req.url !== '/hello/world') return next();
    
                res.end('Hello, world from port #' + options.port + '!');
              });
    
              return middlewares;
            },
          },
        },
      },
    });
    复制代码

    这部分的源码如下:

    复制代码
        //  The middleware options may be null, an array of middleware objects,
        //  or a factory function that creates an array of middleware objects.
        //  * For a null value, use the default array of middleware
        //  * For a function, include the default array of middleware as the last arg
        //    which enables the function to patch the default middleware without needing to know
        //    the implementation of the default middleware factory function
        var middleware;
        if (options.middleware instanceof Array) {
          middleware = options.middleware;
        } else {
          middleware = createDefaultMiddleware.call(this, connect, options);
    
          if (typeof(options.middleware) === 'function') {
            middleware = options.middleware.call(this, connect, options, middleware);
          }
        }
    复制代码


    6. 多个服务器

    可以配置多个服务器,需要注意的是,如果有一个服务器的 keepalive 设置为 true,就会阻塞其它的服务器。

    复制代码
    // Project configuration.
    grunt.initConfig({
      connect: {
        site1: {
          options: {
            port: 9000,
            base: 'www-roots/site1'
          }
        },
        site2: {
          options: {
            port: 9001,
            base: 'www-roots/site2'
          }
        }
      }
    });
    复制代码


    7. HTTPS

    使用 https 协议需要预先进行证书的配置。

    如果没有证书的话,可以使用 OpenSSL 创建自签名的证书作为本地的根证书。

    复制代码
    ### Create ca.key, use a password phrase when asked
    ### When asked 'Common Name (e.g. server FQDN or YOUR name) []:' use your hostname, i.e 'mysite.dev'
    openssl genrsa -des3 -out ca.key 1024
    openssl req -new -key ca.key -out ca.csr
    openssl x509 -req -days 365 -in ca.csr -out ca.crt -signkey ca.key
    
    ### Create server certificate
    openssl genrsa -des3 -out server.key 1024
    openssl req -new -key server.key -out server.csr
    
    ### Remove password from the certificate
    cp server.key server.key.org
    openssl rsa -in server.key.org -out server.key
    
    ### Generate self-siged certificate
    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
    复制代码

    而 Gruntfile.js 中则需要进行相应的配置。

    复制代码
    // Project configuration.
    grunt.initConfig({
      connect: {
        server: {
          options: {
            protocol: 'https',
            port: 8443,
            key: grunt.file.read('server.key').toString(),
            cert: grunt.file.read('server.crt').toString(),
            ca: grunt.file.read('ca.crt').toString()
          },
        },
      },
    });
    复制代码

    如果你已经看到这里,你应该可以使用 grunt 创建一个开发中的测试服务器

  • 相关阅读:
    Codeforces Round #702 (Div. 3) 题解
    Educational Codeforces Round 104 (Rated for Div. 2) A~E题解
    AtCoder Regular Contest 112 A~D题解
    Codeforces Round #701 (Div. 2) A~E 题解
    java String, StringBuffer, StringBuilder简单介绍和使用
    货仓选址
    线程的同步
    数据结构课设作业
    线程的生命周期(java 图)
    JAVA多线程的创建和使用
  • 原文地址:https://www.cnblogs.com/koleyang/p/5567350.html
Copyright © 2020-2023  润新知