>  기사  >  웹 프론트엔드  >  webpack 자동 새로 고침 사용법에 대한 자세한 설명

webpack 자동 새로 고침 사용법에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-04-28 17:13:572127검색

이번에는 webpack 자동 새로고침 사용에 대해 자세히 설명드리겠습니다. webpack 자동새로고침 사용시 주의사항은 무엇인가요? 실제 사례를 살펴보겠습니다.

프런트 엔드는 js와 스타일을 자주 수정해야 하고 브라우저의 페이지 효과에 따라 지속적으로 조정해야 하며 종종 개발 디렉터리와 로컬 게시 디렉터리가 동일하지 않아 수정 후 게시해야 합니다. 또 다른 요점은 페이지를 두 번 클릭하면 효과를 볼 수 있다는 것입니다. 우리는 관찰하기 위해 로컬로 사이트를 구축하기 위해 nginx를 사용해야 하는 경우가 많습니다(테스트 환경에 넣기 전에 자체 컴퓨터에서도 괜찮습니다). 따라서 수동으로 브라우저를 새로 고치고 수동으로(또는 클릭하여) 게시하고 사이트를 시작해야 한다면 실제로 많은 물리적 작업이 필요합니다. 그리고 이 세 가지 포인트 webpack이 우리가 이를 수행하는 데 도움이 될 수 있습니다.

webpack-dev-serverwebpack

은 WDS(webpack-dev-server)를 통해 자동 새로 고침을 구현합니다. WDS는 메모리에서 실행되는 개발 서버(익스프레스)입니다. 시작한 후에는 파일이 변경되었는지 감지하고 자동으로 다시 컴파일합니다.

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를 통해 시작할 수 있습니다.

시작하면 http://localhost:8080에서 프로젝트가 실행되고 있는 것을 확인할 수 있습니다. 페이지를 열면

WDS가 자동으로 사이트를 구축했음을 알 수 있습니다. 우리가 구성요소.js를 수정하면 컴파일이 cmd에 나타나고 페이지가 자동으로 새로 고쳐집니다.

3. 직접 시작

공식 홈페이지에는 다음 명령을 통해 WDS를 직접 시작할 수 있다고 소개되어 있습니다.

webpack-dev-server --env development

하지만 webpack-dev-server --env 개발이 내부 명령이 아니라는 메시지가 표시됩니다. 이런 종류의 문제는 환경 변수에 개발한 bin 디렉터리를 설정하면 됩니다. , 내 디렉토리는 'E:Html5node_modules.bin'입니다. 세미콜론을 추가하고 끝에 쓰십시오.

C:UsersAdministrator.9BBOFZPACSCXLG2AppDataRoamingnpm;C:Program Files (x86)Microsoft VS Codebin;E:Html5node_modules.bin

4.8080 포트가 사용됨

기본값이 80인 경우 포트 80이 사용 중이면 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를 모니터링하고 변경되면 시작하도록 하는 것과 같습니다.

이렇게 하면 손을 개발에만 집중할 수 있습니다.

Proxy

하지만 우리가 직접 배포한 nginx에는 일부 API 프록시가 있기 때문에 WDS 사이트의 대체 가능성에 대해서는 약간의 의심이 듭니다. 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;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");
  }
};

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里面就可以写了。

小结:效率提高的一方面是将一些机械的重复性流程或动作自动化起来。WDS和nodemon就是两个为你干活的小弟。

demo:webpack-ch2_jb51.rar

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

proxyTable代理跨域使用详解

CSS Modules优雅模式使用

위 내용은 webpack 자동 새로 고침 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.