Webpack の自動更新と解析の使用

php中世界最好的语言
php中世界最好的语言オリジナル
2018-03-16 14:29:182060ブラウズ

今回は、webpack の自動更新と解析の使用方法について説明します。webpack を使用して自動更新と解析を行う場合の 注意事項 について説明します。以下は実際的なケースです。

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

webpack-dev-server

webpack は、webpack-dev-server (WDS) を通じて自動更新を実装します。 WDS は、メモリ内で実行される開発サーバー (エクスプレス) です。起動後、ファイルが変更されたかどうかを検出し、自動的に再度コンパイルされます。

1.

npm install webpack-dev-server --save-dev
をインストールする

まず、npm経由で開発ディレクトリにインストールします。インストールが完了すると、node_modules/bin の下に見つかります。

2.npm start

次に、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:\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 を監視させ、変更があれば起動するのと同じです。

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

プロキシ

しかし、私たちが自分たちでデプロイした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#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里面就可以写了。

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

推荐阅读:

H5的缓存Manifest的使用

webpack的模块热替换详解

webpack的样式加载详解

JS事件先发布后订阅的方法

以上がWebpack の自動更新と解析の使用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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