一、编写服务程序
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const zlib = require('zlib'); // gzip压缩模块
const mime = require('mime-types'); // 需npm安装
/**
* 静态服务器
* @param {String} options.hostname 主机
* @param {Number} options.port 端口
* @param {String} options.root 静态资源目录
* @param {String} options.index 入口页面
* @param {Boolean} options.gzip 是否开启gzip压缩
* @param {String} options.compress 指定压缩的文件格式(多个格式中间以|分隔)
* @param {Boolean} options.openBrowser 自动打开默认浏览器
*/
function staticServer(options) {
const defaults = {
hostname: 'localhost',
port: 80,
root: '../dist',
index: 'index.html',
gzip: true,
compress: 'html|css|js',
openBrowser: false
};
const settings = Object.assign({}, defaults, options); // 合并配置
const rootPath = path.join(__dirname, settings.root); // 获取静态根目录路径
//创建服务程序
const server = http.createServer((request, response) => {
let pathname = url.parse(request.url).pathname; //获得请求url路径
const filePath = path.join(rootPath, pathname.slice(-1) === '/' ? settings.index : pathname); // 如果url是/,默认加载index页面
// 检测文件是否存在
if (fs.existsSync(filePath)) {
try {
const mimeType = mime.lookup(filePath); //读取文件mime类型
response.setHeader("Content-Type", mimeType || 'text/plain');
const raw = fs.createReadStream(filePath); // 以流的形式读取文件
const ext = path.extname(filePath).slice(1); // 获得文件扩展名
const acceptEncoding = request.headers['accept-encoding'];
const gzipExt = settings.gzip && settings.compress.includes(ext); // 开启了gzip压缩,且文件类型在压缩格式范围内
if (gzipExt && acceptEncoding.includes('gzip')) {
response.writeHead(200, "Ok", { 'Content-Encoding': 'gzip' });
raw.pipe(zlib.createGzip()).pipe(response);
} else if (gzipExt && acceptEncoding.includes('deflate')) {
response.writeHead(200, "Ok", { 'Content-Encoding': 'deflate' });
raw.pipe(zlib.createDeflate()).pipe(response);
} else {
response.writeHead(200, "Ok");
raw.pipe(response);
}
} catch (err) {
response.writeHead(500, { 'Content-Type': 'text/plain' });
response.end(err);
}
} else {
//如果文件不存在返回404
response.writeHead(404, { 'Content-Type': 'text/plain' });
response.write("This request URL " + pathname + " was not found on this server.");
response.end();
}
});
// 打开默认浏览器
const openDefaultBrowser = (url) => {
const { exec } = require('child_process');
console.log(process.platform)
switch (process.platform) {
case "darwin":
exec('open ' + url);
break;
case "win32":
exec('start ' + url);
break;
default:
exec('xdg-open', [url]);
}
}
//监听主机端口
const { hostname, port, openBrowser } = settings;
server.listen(port, hostname, () => {
const url = `http://${hostname}:${port}`
console.log(`服务器运行在 ${url}`);
openBrowser && openDefaultBrowser(url); // 打开默认浏览器
});
}
// 启动静态服务器
staticServer({
hostname: '127.0.0.1', //主机
port: 3000, // 端口
root: './dist', // 静态文件目录
index: 'index.html', // 入口文件
gzip: true, // 开启gzip压缩
compress: 'html|css|js', // 压缩这三种格式
openBrowser: true // 服务启动后自动打开浏览器
});
二、运行服务程序
node .server.js
参考资料:https://blog.csdn.net/qq_30422457/article/details/82497468