Grunt Connect Web Server
grunt-contrib-connect is a Grunt plugin designed to start a static web server using the `connect` middleware framework. It is currently at stable version 5.0.1, with recent updates, including a major version bump (v5.0.0) in early 2024, indicating an active, though mature, maintenance cycle. This plugin enables developers to configure server parameters such as port, hostname, protocol (HTTP, HTTPS, or HTTP2), and a flexible base directory for serving files, including support for multiple roots and `serve-static` options. Its primary differentiation is its tight integration into the Grunt build system, facilitating seamless local development servers or serving static assets during build processes, often used in conjunction with other Grunt tasks like `grunt-contrib-qunit` for testing. The plugin wraps the popular `connect` server, providing a familiar API within the Grunt ecosystem.
Common errors
-
Fatal error: Port 9000 is already in use by another process.
cause The specified port in the `connect` task configuration is already occupied by another application or process on your system.fixChange the `port` option in your Gruntfile's `connect` task to an unused port, or enable `useAvailablePort: true` (if supported and desired) to automatically find a free port. -
Warning: Task "connect" not found. Use --force to continue.
cause The `grunt-contrib-connect` plugin has not been loaded correctly in your Gruntfile, or it's not installed.fixEnsure you have `npm install grunt-contrib-connect --save-dev` and `grunt.loadNpmTasks('grunt-contrib-connect');` in your Gruntfile. -
Error: listen EADDRINUSE: address already in use :::8000
cause This is a low-level Node.js error indicating that the server tried to bind to a network address and port that is already in use by another process.fixThis typically means another server is running on the same port. Use `lsof -i :8000` (macOS/Linux) or `netstat -ano | findstr :8000` (Windows) to identify and terminate the conflicting process, or change the port in your Gruntfile.
Warnings
- breaking Version 5.0.0 replaced `node-http2` with `http2-wrapper`. If your Gruntfile had custom configurations or relied on specific behaviors of the previous HTTP/2 implementation, this change might introduce breaking changes. Review HTTP/2 related options and ensure compatibility.
- gotcha Using the `keepalive: true` option will prevent any subsequent Grunt tasks from running, as the server will remain active indefinitely. This is intended behavior for long-running servers but can be a common pitfall.
- gotcha When `hostname` is set to a wildcard like `'0.0.0.0'`, the `open` option will default to using `localhost` in the browser URL. If you need a specific IP or hostname opened, explicitly set the `open` option to a full URL (e.g., `open: 'http://192.168.1.100:9000'`).
- gotcha Attempting to use `protocol: 'http2'` may lead to browser compatibility issues if the client browser does not fully support HTTP/2 or the specific server configuration. Ensure your client environment is up-to-date.
Install
-
npm install grunt-contrib-connect -
yarn add grunt-contrib-connect -
pnpm add grunt-contrib-connect
Imports
- connect
import { connect } from 'grunt-contrib-connect'; const connect = require('grunt-contrib-connect');grunt.loadNpmTasks('grunt-contrib-connect'); - Task Configuration
grunt.config.set('connect', { /* ... */ });grunt.initConfig({ connect: { // options here } });
Quickstart
// Gruntfile.js
module.exports = function(grunt) {
// Load the plugin that provides the 'connect' task.
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch'); // Often used alongside connect
grunt.initConfig({
connect: {
options: {
port: 9000,
hostname: 'localhost', // '0.0.0.0' for external access
livereload: 35729 // Set a specific port for live reload
},
dev: {
options: {
open: true, // Automatically open the browser
base: 'app' // Serve files from the 'app' directory
}
},
test: {
options: {
port: 9001,
base: ['temp', 'test'], // Serve from multiple directories
keepalive: true // Keep server alive for continuous testing
}
}
},
watch: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'app/**/*.{html,css,js}',
'!app/vendor/**/*.js' // Ignore vendor files
],
tasks: [] // No tasks, just trigger livereload
}
});
// Register a default task that runs connect and watch
grunt.registerTask('default', ['connect:dev', 'watch']);
grunt.registerTask('serve-test', ['connect:test']);
};