ホームページ  >  記事  >  ウェブフロントエンド  >  Webpack自動更新の使い方の詳しい説明

Webpack自動更新の使い方の詳しい説明

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-28 17:13:572071ブラウズ

今回は、webpack 自動更新の使用方法について詳しく説明します。webpack 自動更新を使用する際の 注意事項 は何ですか?実際の事例を見てみましょう。

フロントエンドは js とスタイルを頻繁に変更する必要があり、ブラウザのページ効果に応じて常に調整する必要があります。多くの場合、開発ディレクトリとローカル公開ディレクトリは同じではないため、変更後に公開する必要があります。もう 1 つの点は、ページをダブルクリックするだけですべての効果が確認できるわけではないということです。多くの場合、nginx を使用してローカルにサイトを構築して観察する必要があります (テスト環境に置く前に自分のコンピューター上で行うことは問題ありません)。したがって、ブラウザを手動で更新し、手動で (またはクリックして) 公開し、サイトを開始する必要がある場合、それは確かに多くの物理的な作業になります。これら 3 つのポイント webpack は、それを実現するのに役立ちます。

webpack-dev-serverwebpack

は、webpack-dev-server (WDS) による自動更新を実装します。 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 が自動的にサイトを構築したことがわかります。component.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 を監視させ、変更があれば起動するのと同じです。

これにより、開発に集中できるようになります。

プロキシ

しかし、私たちが自分たちでデプロイした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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。