转载自:https://www.cnblogs.com/ye-hcj/p/7091706.html

dev-server.js详解

require('./check-versions')()

var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
// opn插件是用来打开特定终端的,此文件用来在默认浏览器中打开链接 opn(url)
var opn = require('opn')
var path = require('path')
// nodejs开发框架express,用来简化操作,有兴趣可以自行去了解
var express = require('express')
// 引入webpack模块,用来使用webpack内置插件
var webpack = require('webpack')
// 引入http-proxy-middleware插件,此插件是用来代理请求的只能用于开发环境,目的主要是解决跨域请求后台api
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf') //==========================================================
var mockQueryCode = require('../mock/querySecuritiesCode')
var cookiejar = require('cookiejar')
var fs = require('fs')
var https = require('https')
//==========================================================
// default port where dev server listens for incoming traffic
// 下面是webpack-dev-server 监听的端口号,因为没有设置process.env.PORT,所以下面监听的就是config.dev.port即443
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
// 下面是true,至于为啥,本来就是true还要加!!两个感叹号,估计是vue作者装了个逼吧
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
// 下面是解决开发环境跨域问题的插件,我在config目录index.js文章中有介绍,自行查看
var proxyTable = config.dev.proxyTable
//======================================================================
// 注释https服务器,改回http服务器
//配置https服务器证书和秘钥
var httpsOptions = {
key: fs.readFileSync('./ssl/server.key'),
cert: fs.readFileSync('./ssl/server.crt')
}
//====================================================================== // 下面是创建node.js的express开发框架的实例,别问我为什么这样,自己看node.js去吧
var app = express()
//把配置参数传递到webpack方法中,返回一个编译对象,这个编译对象上面有很多属性,自己去看吧,主要是用到里面的状态函数 如compilation,compile,after-emit这类的
var compiler = webpack(webpackConfig) // 下面是webpack-dev-middleware和webpack-hot-middleware两兄弟,这两个是黄金组合
// 而vue作者用这两个插件也是用的最基本的形式,详情看(1) (2)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true //// 使用friendly-errors-webpack-plugin插件这个必须设置为true,具体看我的wepback-dev-config.js
}) var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
}) // force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
// webpack任何一个插件都plugin这个方法,里面可以传递钩子函数,用来在插件各个阶段做特殊处理,钩子函数种类很多
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
// 当插件html-webpack-plugin产出完成之后,强制刷新浏览器
hotMiddleware.publish({ action: 'reload' })
cb()
})
}) function relayRequestHeaders(proxyReq, req) {
Object.keys(req.headers).forEach(function (key) {
proxyReq.setHeader(key, req.headers[key]);
});
} function relayResponseHeaders(proxyRes, req, res) {
var setCookieHeaders = proxyRes.headers['set-cookie'] || [];
var modifiedSetCookieHeaders = setCookieHeaders
.map(str => new cookiejar.Cookie(str))
.map(cookie => {
//if (cookie.path && cookie.path[0] === '/') {
cookie.path = '/api'
//}
return cookie
})
.map(cookie => cookie.toString());
proxyRes.headers['set-cookie'] = modifiedSetCookieHeaders;
}

// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
// 下面是代理表的处理方法,看看就行了,几乎用不上,除非你是全栈,不用webpack-dev-server,使用后台语言做服务器
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
} options.onProxyReq=relayRequestHeaders;
options.onProxyRes=relayResponseHeaders; app.use(proxyMiddleware(options.filter || context, options))
}) app.use('/mock', mockQueryCode) // handle fallback for HTML5 history API
// 这个插件是用来解决单页面应用,点击刷新按钮和通过其他search值定位页面的404错误
// 详情请看(3)
app.use(require('connect-history-api-fallback')()) // serve webpack bundle output
// app.use是在响应请求之前执行的,用来指定静态路径,挂载静态资源
app.use(devMiddleware) // enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware) // serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
// 挂载静态资源,下面的方法是用虚拟目录来访问资源,staticPath就是虚拟目录路径,其实不管设不设置都是static
app.use(staticPath, express.static('./static')) //mock 数据
//app.use(staticPath,express.static('./mock')) var uri = 'https://localhost:' + port ; var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
}) console.log('> Starting dev server...')
// waitUntilValid是webpack-dev-middleware实例的方法,在编译成功之后调用
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
}) //var server = app.listen(port)
//启动https服务器
var server = https.createServer(httpsOptions,app);
server.listen(port); module.exports = { ready: readyPromise, // promise实例,可以通过readyPromise.then收到数据
  close: () => {
server.close() // 关闭服务器
}
}

注释:

(1)webpack-dev-middleware插件
这个插件只能用于开发环境,下面是这个插件的解释
这是一个简洁的webpack包装中间件,这个插件做这个主要为文件做一件事情,就是当文件修改后提交到webpack服务器,然后处理这些修改后的文件
这个插件有一下几个优点
第一,所有的文件都是写在disk上,文件的处理在内存中进行
第二,如果文件在watch模式下被改动,这个中间件将不会为这些老的bundle服务了,如果这些老的bundle上有文件改动,
这个中间件将不会发送请求,而是等到当前编译结束,当前最新的文件有改动,才会发送请求,所以你不需要手动刷新了
第三,我会在以后的版本中优化
总结,这个中间件是webpack-dev-server的核心,实现修改文件,webapack自动刷新的功能
安装 npm install webpack-deb-middleware --save-dev
使用方法如下,下面的使用方法也是webpack-dev-server实现的代码
var webpackMiddleware = require("webpack-deb-middleware");
app.use(webpackMiddleware(webpack({obj1}),{obj2}))
app.use是express的方法,用来设置静态路径
上面的obj1是webpack配置对象,使用webpack方法转换成compiler编译对象,obj2配置的是更新文件打包后的配置,使用
webpackMiddleware处理之后,就返回一个静态路径,方便获取文件关于obj2的配置项,可以自行查阅,必须要添加publicPath
说到这里,我就不卖关子了,简言之
我们的静态服务器是node.js,现在文件修改了,webpack-dev-middleware将修改的文件编译后,告诉nodejs服务器哪些文件修改了
并且把最新的文件上传到静态服务器,够清楚了吧
(2)webpack-hot-middleware插件
这个插件是用来将webpack-dev-middleware编译更新后的文件通知浏览器,并且告诉浏览器如何更新文件,从而实现 Webpack hot reloading
将这两个插件配合起来使用你就可以不需要webpack-dev-sever,即可以自己实现hot-replacement热替换功能,
webpack-hot-middleware插件通知浏览器更新文件大致是通过一个json对象实现的,具体实现机制这里不多说了,下面来看具体用法
安装 npm install webpack-hot-middleware --save-dev
在使用了webpack-dev-middleware之后,在添加如下代码即可
app.use(require("webpack-hot-middleware")(compiler));
(3)connect-history-api-fallback插件
因为在开发单页面应用时,总的来说项目就一个页面,如果通过点击刷新按钮并且此时链接指的不是主页的地址,就会404;或者我通过其他的链接比如 /login.html 但是并没有login.html就会报错
而这个插件的作用就是当有不正当的操作导致404的情况,就把页面定位到默认的index.html
使用起来也比较简单,记住这样用就可以了
安装 npm install --save connect-history-api-fallback
使用 var history = require('connect-history-api-fallback');
var express = require('express');
var app = express();
app.use(history());

dev-server.js详解的更多相关文章

  1. webpack.dev.conf.js详解

    转载自:https://www.cnblogs.com/ye-hcj/p/7087205.html webpack.dev.conf.js详解 //引入当前目录下的utils.js文件模块var ut ...

  2. [js高手之路]深入浅出webpack系列2-配置文件webpack.config.js详解

    接着上文,重新在webpack文件夹下面新建一个项目文件夹demo2,然后用npm init --yes初始化项目的package.json配置文件,然后安装webpack( npm install ...

  3. [js高手之路]深入浅出webpack教程系列3-配置文件webpack.config.js详解(下)

    本文继续接着上文,继续写下webpack.config.js的其他配置用法. 一.把两个文件打包成一个,entry怎么配置? 在上文中的webpack.dev.config.js中,用数组配置entr ...

  4. [js高手之路]深入浅出webpack教程系列2-配置文件webpack.config.js详解(上)

    [js高手之路]深入浅出webpack教程系列索引目录: [js高手之路]深入浅出webpack教程系列1-安装与基本打包用法和命令参数 [js高手之路]深入浅出webpack教程系列2-配置文件we ...

  5. 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结

    为什么说JAVA中要慎重使用继承   这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...

  6. 【three.js详解之一】入门篇

    [three.js详解之一]入门篇   开场白 webGL可以让我们在canvas上实现3D效果.而three.js是一款webGL框架,由于其易用性被广泛应用.如果你要学习webGL,抛弃那些复杂的 ...

  7. 【three.js详解之二】渲染器篇

    [three.js详解之二]渲染器篇   本篇文章将详细讲解three.js中渲染器(renderer)的设置方法. three.js文档中渲染器的分支如下: Renderers CanvasRend ...

  8. zabbix server安装详解

    简介 zabbix(音同 zæbix)是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以 ...

  9. Tomcat配置(二):tomcat配置文件server.xml详解和部署简介

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

随机推荐

  1. Linxu内核参数详解

    #表示SYN队列的长度,默认为1024,加大队列长度,可以容纳更多等待连接的网络连接数. net.ipv4.tcp_max_syn_backlog = 65536 #每个网络接口接收数据包的速率比内核 ...

  2. CPU GPU设计工作原理《转》

    我知道这非常长,可是,我坚持看完了.希望有幸看到这文章并对图形方面有兴趣的朋友,也能坚持看完.一定大有收获.毕竟知道它们究竟是怎么"私下勾搭"的.会有利于我们用程序来指挥它们... ...

  3. Java Tomcat 启动闪屏-原因之一---配置问题

    如Tomcat启动异常,首先确保Java安装和Tomcat安装版本是否对应,环境变量是否配置正确,如检查通过后,依然启动闪屏.可以依次解决: 1.在Tomcat启动文件Startup.bat之中最后添 ...

  4. U盘重装Windows系统

    1.制作一个U盘老毛桃或者大白菜 2.进入BIOS 3.Secure Boot-Disabled,作用是关闭微软的Secure BOOT,这个功能开启会导致不能识别U盘启动系统的安装 4.Lauch ...

  5. Github Pages建立个人博客

    使用Github Pages可以建立个人博客.官方教程:https://pages.github.com/步骤(以下步骤中假设用户名为username):1.建立一个项目,项目名为username.g ...

  6. 【BZOJ1005/1211】[HNOI2008]明明的烦恼/[HNOI2004]树的计数 Prufer序列+高精度

    [BZOJ1005][HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可 ...

  7. 【BZOJ4808/3175】马/[Tjoi2013]攻击装置 最小割

    [BZOJ4808]马 Description 众所周知,马后炮是中国象棋中很厉害的一招必杀技."马走日字".本来,如果在要去的方向有别的棋子挡住(俗称"蹩马腿" ...

  8. ios 开发证书制作

    1.首先打开Mac中的keychain 选择钥匙串访问-证书助手-创建证书-导出CertificateSigningRequest.CertSigningRequest.CertSigningRequ ...

  9. 深入分析Cocos2d-x 2.0中的“纹理”

    对CCImage的绘制是通过CCTexture2D来实现的(OPENGL es)通过纹理绘制到某个面. (本文中所提到的方法在cocos2d2.0中部分有调整,请应用时候具体察看源码)1. 首先来了解 ...

  10. 160407、java实现多线程同步

    多线程就不说了,很好理解,同步就要说一下了.同步,指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系.所以同步的关键是多个线程对象竞争同一个共享资源. 同步分为外同步和内同步.外同步就是在外 ...