您好,欢迎访问一九零五行业门户网

webpack自动刷新与解析的使用

这次给大家带来webpack自动刷新与解析的使用,使用webpack自动刷新与解析的注意事项有哪些,下面就是实战案例,一起来看一下。
前端需要频繁的修改js和样式,且需要根据浏览器的页面效果不断的做调整;而且往往我们的开发目录和本地发布目录不是同一个,修改之后需要发布一下;另外一点就是并不是所有的效果都可以直接双击页面就能看到,我们常常需要在本地用nginx建一个站点来观察(自己电脑上ok了才放到测试环境去)。所以如果要用手工刷新浏览器和手动(或点击)发布,还要启动站点,确实是个不小的体力活。而这三点webpack可以帮我们做到。
webpack-dev-serverwebpack是通过webpack-dev-server(wds)来实现自动刷新。wds是一个运行在内存中的开发服务器(一个express)。启动之后,它会检测文件是否发生改变并再自动编译一次。
1.安装npm install webpack-dev-server --save-dev
先通过npm将其安装到开发目录。安装完成之后会在node_modules/bin下找到。
2.npm启动然后修改package.json:(基于上一节)
scripts: {    start: webpack-dev-server --env development,    build: webpack --env production   }
现在就可以通过npm run start 或者 npm start来启动了。
启动之后,可以看到project is running at http://localhost:8080 上面。打开页面
说明wds已经帮我们自动建了一个站点.我们修改component.js ,cmd中会出现编译,页面会自动刷新。
3.直接启动官网介绍可以直接通过下面的命令启动wds。
webpack-dev-server --env development
但会出现webpack-dev-server --env development 不是内部命令的提示,这种问题都是环境变量的问题,将你开发的bin目录设置到环境变量中即可,比如我的目录是‘e:\html5\node_modules\.bin’,就加上分号写在后面。
c:\users\administrator.9bbofzpacscxlg2\appdata\roaming\npm;c:\program files (x86)\microsoft vs code\bin;e:\html5\node_modules\.bin
4.8080端口占用如果默认的8080端口占用,wds会换一个。比如用nginx先发布一个。
server{       listen       8080;       location / {            root   e:/html5/build;            index  index.html index.htm;         }     }
再启动wds:
端口切到了8081。也可以手动配置端口:
devserver:{   //...     port: 9000}
nodemon 自动启动 wds是监视开发文件的,webpack.config.js改变不会引起自动启动。所以我们需要nodemon去做这件事情。
npm install nodemon --save-dev
先安装在开发目录,然后修改package.json:
scripts: {   start: nodemon --watch webpack.config.js --exec \webpack-dev-server --env development\,    build: webpack --env production   },
等于让nodemon去监视webpack.config.js,变化了就去启动它。
这样就你可以让你的双手专心的开发了。
代理不过有一点疑问,就是wds这个站点的替代性,因为我们自己部署的nginx有一些api的代理。如果挂在wds的这个默认站点上自然是无法访问的。换句话说可否给wds配置一个刷新路径。如果文件改变去刷新指定的地址,或者让我去配个代理。既然它本身是一个http服务器,肯定也有代理的功能。搜了下果然有:https://github.com/webpack/webpack-dev-server/tree/master/examples/proxy-advanced
module.exports = {     context: dirname,     entry: ./app.js,     devserver: {        proxy: {            /api: {                 target: http://jsonplaceholder.typicode.com/,                 changeorigin: true,                 pathrewrite: {                    ^/api:                  },                 bypass: function(req) {                    if(req.url === /api/nope) {                        return /bypass.html;                     }                 }             }         }     } }
即将api这个字段替换成http://jsonplaceholder.typicode.com/,并将其从原地址中删掉,这样就可以自己实现代理了。皆大欢喜!wds是通过 http-proxy-middleware 来实现代理。更多参考:http://webpack.github.io/docs/webpack-dev-server.html#bypass-the-proxy;https://github.com/chimurai/http-proxy-middleware#options
but,这种刷新是怎么实现的呢?因为页面上没有嵌入什么别的js,去翻原码 web-dev-server/server.js中有这么一段:
server.prototype._watch = function(path) {    const watcher = chokidar.watch(path).on(change, function() {        this.sockwrite(this.sockets, content-changed);     }.bind(this))    this.contentbasewatchers.push(watcher); }
用chokidar来监视文件变化,server的内部维护的有一个socket集合:
server.prototype.sockwrite = function(sockets, type, data) {     sockets.foreach(function(sock) {         sock.write(json.stringify({             type: type,             data: data         }));     }); }
sock是一个sockjs对象。https://github.com/sockjs/sockjs-client,从http://localhost:8080/webpack-dev-server/页面来看,sockjs是用来通信记录日志的。
var onsocketmsg = {     hot: function() {         hot = true;         log(info, [wds] hot module replacement enabled.);     },     invalid: function() {         log(info, [wds] app updated. recompiling...);         sendmsg(invalid);     },     hash: function(hash) {         currenthash = hash;     }, ... }
我们在看app.js,其中有一个onsocketmsg 对象。
var onsocketmsg = {     hot: function() {         hot = true;         log(info, [wds] hot module replacement enabled.);     },     invalid: function() {         log(info, [wds] app updated. recompiling...);         sendmsg(invalid);     },     hash: function(hash) {         currenthash = hash;     },    still-ok: function() {         log(info, [wds] nothing changed.)        if(usewarningoverlay || useerroroverlay) overlay.clear();         sendmsg(stillok);     },    log-level: function(level) {         loglevel = level;     },    overlay: function(overlay) {        if(typeof document !== undefined) {            if(typeof(overlay) === boolean) {                 usewarningoverlay = overlay;                 useerroroverlay = overlay;             } else if(overlay) {                 usewarningoverlay = overlay.warnings;                 useerroroverlay = overlay.errors;             }         }     },     ok: function() {         sendmsg(ok);        if(usewarningoverlay || useerroroverlay) overlay.clear();        if(initial) return initial = false;         reloadapp();     },    content-changed: function() {         log(info, [wds] content base changed. reloading...)         self.location.reload();     },     warnings: function(warnings) {         log(info, [wds] warnings while compiling.);        var strippedwarnings = warnings.map(function(warning) {            return stripansi(warning);         });         sendmsg(warnings, strippedwarnings);        for(var i = 0; i < strippedwarnings.length; i++)             console.warn(strippedwarnings[i]);        if(usewarningoverlay) overlay.showmessage(warnings);        if(initial) return initial = false;         reloadapp();     },     errors: function(errors) {         log(info, [wds] errors while compiling. reload prevented.);        var strippederrors = errors.map(function(error) {            return stripansi(error);         });         sendmsg(errors, strippederrors);        for(var i = 0; i < strippederrors.length; i++)             console.error(strippederrors[i]);        if(useerroroverlay) overlay.showmessage(errors);     },     close: function() {         log(error, [wds] disconnected!);         sendmsg(close);     } };
view code
ok的时候触发一个reloadapp
function reloadapp() {    if(hot) {         log(info, [wds] app hot update...);        var hotemitter = webpack_require(./node_modules/webpack/hot/emitter.js);         hotemitter.emit(webpackhotupdate, currenthash);        if(typeof self !== undefined) {            // broadcast update to window             self.postmessage(webpackhotupdate + currenthash, *);         }     } else {         log(info, [wds] app updated. reloading...);        self.location.reload();     } }
也就是说wds先检测文件是否变化,然后通过sockjs通知到客户端,这样就实现了刷新。之前websocket的第三方只用过socket.io,看起来sockjs也蛮好用的。不必外带一个js,在主js里面就可以写了。
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
h5的缓存manifest的使用
webpack的模块热替换详解
webpack的样式加载详解
js事件先发布后订阅的方法
以上就是webpack自动刷新与解析的使用的详细内容。
其它类似信息

推荐信息