自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在終端里輸入 npm start 后都發(fā)生了啥

開發(fā) 前端
要想對 JavaScript 代碼進行打包,我們可以依賴 webpack 對我們的幫助我們完成這一件事情。要想使用 webpack,首先需要我們安裝 webpack,首先對項目進行初始化。

前言

在前面的內(nèi)容純屬胡說八道,如果想要看正文,請直接滾動條往下拉,以省下寶貴的時間繼續(xù)卷。

要想對 JavaScript 代碼進行打包,我們可以依賴 webpack 對我們的幫助我們完成這一件事情。要想使用 webpack,首先需要我們安裝 webpack,首先對項目進行初始化:

npm init -y

生成配置配置文件:

圖片圖片

要想使用 webpack,首先需要安裝 webpack 以及 webpack-cli,這里還有 html-webpack-plugin,用于生成 html 模板,具體命令如下:

npm install  webpack webpack-cli html-webpack-plugin -D

依賴安裝完成之后,我們需要在跟目錄上面創(chuàng)建一個名為 webpack.config.js,當然,你也可以創(chuàng)建其他文件名的 js 文件,并添加以下配置:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./dist"),
  },
  mode: "production",
  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
  ],
};

為了能執(zhí)行打包命令,我們在 package.json 文件中的 script 中添加這一段命令:

"build": "webpack"

如果你使用的 webpack 配置文件名為其他的則需要在該命令中添加相對應的路徑,否則在執(zhí)行命令的時候 webpack-cli 則無法找到相關的配置。

接下來我們創(chuàng)建在根目錄下創(chuàng)建一個 src 目錄,在目錄下面創(chuàng)建一個 index.js 文件,作為整個項目的入口,并在文件中添加一些自己想寫的代碼:

console.log("hello webpack");

此時,在命令行中輸入一下命令:

npm run build

此時文件被輸出出來了:

圖片圖片

生成的文件是根據(jù)我們前面的 webpack 配置文件中生成的,通過運行 index.html 文件,hello webpack 也被輸出在瀏覽器控制臺上面:

圖片圖片

但是這個方法存在弊端,當我們對源代碼進行修改的時候,它并不會對我所修改的代碼進行重新編譯,要想能夠在瀏覽器中看到最新效果,你必須通過重新執(zhí)行 npm run build 打包才可以,開發(fā)效率極其低下。

watch

webpack 有一個 watch 屬性可以監(jiān)聽文件的變化,當監(jiān)聽到文件變化,當它們修改后會重新編譯,要啟用 watch,你只需要在 webpack.config.js 文件中設置 watch:true即可,詳情如下:

module.exports = {
  ...,
  watch: true,
};

或者在 package.json 文件中 script 下修改添加 --watch.代碼如下所示:

"build": "webpack --watch"

控制臺再次執(zhí)行 npm run build,你會發(fā)現(xiàn)這次控制臺不會結(jié)束了,會一直開啟著,詳情請看下圖:

圖片圖片

當我們修改文件內(nèi)容的時候,watch 會監(jiān)聽著文件變化,如下圖終端所示:

圖片圖片

并且瀏覽器上的內(nèi)容也會隨著變化而變化,你也可以配置 watchOptions 來使你的項目更快,例如:

watchOptions: {
  aggregateTimeout: 6000,
  ignored: /node_modules/,
},

在上面的配置中,當?shù)谝粋€文件更改,會在重新構(gòu)建前增加延遲,它會將這段時間內(nèi)的所有更改都聚合到一次重新構(gòu)建中,以毫秒為單位。對于某些系統(tǒng),監(jiān)聽大量文件會導致大量的 CPU 或內(nèi)存占用??梢允褂谜齽t排除像 node_modules 如此龐大的文件夾。

盡管有這些配置,效率仍然不高,編譯成功后,都會生成新的文件,并且需要開啟 live-server,但是這個插件屬于 vscode 的,但是在其他編輯器上并沒有,并不屬于 webpack。

live-server 每次都會重新刷新整個頁面,并不能保存當前頁面的狀態(tài),還會編譯所有的代碼。

webpack-dev-server的基本使用

webpack-dev-server(簡稱 WDS) 為你提供了一個基本的 web server,并且具有 live reloading(實時重新加載)功能。要想使用使用你首先要安裝該依賴:

npm install --save-dev webpack webpack-dev-server

繼續(xù)在 package.json 文件中 script 下修改添加一段命令.代碼如下所示:

"start": "webpack serve --open"

完成之后,在終端下輸入以下命令執(zhí)行:

npm start

WDS 會自動為為你自動開啟電腦上的默認瀏覽器,并且默認的端口為 http://localhost:8080/,在終端里有如下輸出:

圖片圖片

在瀏覽器上有如下輸出:

圖片圖片

默認開啟 live Reload ,當代碼發(fā)生改變時會自動重新對代碼進行編譯。

WDS 原理

webpack-dev-server 啟動了一個使用 express 的HTTP服務,這個服務器與客戶端采用 WebSocket 通信協(xié)議,當原始文件發(fā)生改變,webpack-dev-server 會實時編譯,但是對 index.html 的修改不會做出處理。

通過查看 webpack-dev-server 源碼中的 package.json 文件,我們發(fā)現(xiàn)這里定義了一個 bin 字段,那么這個 bin 有什么用呢?

bin 字段是命令名到本地文件名的映射。當我們使用 npm 或者 yarn 命令安裝包時,如果該包的 package.json 文件有 bin 字段,就會在 node_modules 文件夾下面的 .bin 目錄中復制了 bin 字段鏈接的執(zhí)行文件。我們在調(diào)用執(zhí)行文件時,可以不帶路徑,直接使用命令名來執(zhí)行相對應的執(zhí)行文件。

也就是說,當我們在終端中輸入 npm install webpack-dev-server -D 的時候,會在 node_modules/.bin 目錄下生成了三個文件:

圖片圖片

這三個文件中,其中的 ·cmd 是 windows 中默認的可執(zhí)行文件,當我們不添加后綴名時,自動根據(jù) pathext 查找文件。

當我們執(zhí)行 npm start 的時候,會在 node_modules/.bin 目錄下找到 webpack-dev-server.cmd 目錄,因為這個文件是 windows 的批處理腳本:

@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0

IF EXIST "%dp0%\node.exe" (
  SET "_prog=%dp0%\node.exe"
) ELSE (
  SET "_prog=node"
  SET PATHEXT=%PATHEXT:;.JS;=;%
)

endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%"  "%dp0%..\webpack-dev-server\bin\webpack-dev-server.js" %*

在這寫代碼里的最后一行 "%dp0%..\webpack-dev-server\bin\webpack-dev-server.js" 命令中,通過軟連接鏈接到 node_modules/webpack-dev-server/bin 中的 webpack-dev-server.js 目錄。

所以當我們運行 npm start 的時候,也就是相當于運行 node_modules/.bin/webpack-dev-server.cmd serve 命令,并最終以 webpack-dev-server/bin/webpack-dev-server.js 就是整個命令行的入口,通過這里,它會自動給你開啟 webpack-cli,詳情請看下圖:

圖片圖片

所以當我們沒有安裝 webpack-cli 的時候運行 npm start 時會有以下提示:

圖片圖片

在這里 webpack 就會基于我們 webpack.config.js 里創(chuàng)建一個 compiler,然后基于 compiler 和 devServer 相關配置生成一個 WebpackDevServer 實例,該實例會啟動一個expores 服務來幫我們監(jiān)聽靜態(tài)資源變化并更新。

在 webpack-dev-server 源代碼中,有一個 Server.js 的目錄,創(chuàng)建了一個 Server 類,用于啟動的是 start(...) 方法中通過 socket 監(jiān)聽一個端口,默認使用的是 8080,初始化 client 和 dev-server,以 p[lugin 的形式掛載到 compiler 上,添加 hooks 插件,實例化 express 服務等等,有以下代碼,詳情可自行查看,可以通過安裝依賴的方式,也可以到 GitHub:

圖片圖片

接下來我們看看 await this initialize(...) 都干了些啥?詳情請看下列代碼(省略了后面部分):

async initialize() {
    if (this.options.webSocketServer) {
      const compilers =
        /** @type {MultiCompiler} */
        (this.compiler).compilers || [this.compiler];

      compilers.forEach((compiler) => {
        this.addAdditionalEntries(compiler);
        const webpack = compiler.webpack || require("webpack");
        new webpack.ProvidePlugin({
          __webpack_dev_server_client__: this.getClientTransport(),
        }).apply(compiler);

        compiler.options.plugins = compiler.options.plugins || [];
        if (this.options.hot) {
          const HMRPluginExists = compiler.options.plugins.find(
            (p) => p.constructor === webpack.HotModuleReplacementPlugin
          );
          if (HMRPluginExists) {
            this.logger.warn(
              `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
            );
          } else {
            // Apply the HMR plugin
            const plugin = new webpack.HotModuleReplacementPlugin();
            plugin.apply(compiler);
          }
        }
      });

      if (
        this.options.client &&
        /** @type {ClientConfiguration} */ (this.options.client).progress
      ) {
        this.setupProgressPlugin();
      }
    }

在 initialize() 方法中還有以下方法的調(diào)用:

this.setupHooks();
this.setupApp();
this.setupHostHeaderCheck();
this.setupDevMiddleware();
this.setupBuiltInRoutes();
this.setupWatchFiles();
this.setupWatchStaticFiles();
this.setupMiddlewares();
this.createServer();

在這里,主要做的事情是將 client 以 plugin 的形式掛載到 compiler,如果存在 HMR,則開啟 HMR,通過 this.setupWatchFiles() 監(jiān)聽文件變化。

在 this.setupHooks() 中,主要做的事情就是在 webpack 的 done 鉤子上掛了個給客戶端廣播消息的回調(diào),通過這個回調(diào)就知道工程代碼有更新,這時候客戶端就會發(fā)送請求給 express 服務去請求最新的 webpack 打包的代碼,詳情請看以下代碼:

setupHooks() {
    this.compiler.hooks.invalid.tap("webpack-dev-server", () => {
      if (this.webSocketServer) {
        this.sendMessage(this.webSocketServer.clients, "invalid");
      }
    });
    this.compiler.hooks.done.tap(
      "webpack-dev-server",
      /**
       * @param {Stats | MultiStats} stats
       */
      (stats) => {
        if (this.webSocketServer) {
          this.sendStats(this.webSocketServer.clients, this.getStats(stats));
        }

        /**
         * @private
         * @type {Stats | MultiStats}
         */
        this.stats = stats;
      }
    );
  }

當客戶端接收到 websocket 廣播的消息后,會觸發(fā)reloadApp方法(webpack打包時注入進去的)reloadApp會根據(jù)廣播消息里的更新類型選擇是頁面更新 liveReload 還是模塊更新 HMR,通過測試,發(fā)現(xiàn)每次修改正是都會經(jīng)過 sendMessage 方法。

圖片圖片

上圖正是 webpack-dev-server 的整個流程圖,到這來,這篇文章的內(nèi)容也就講完了,如有錯誤,煩請批評指出。

本文轉(zhuǎn)載于:https://juejin.cn/post/7187368174952644665

參考文獻

  • # webpack-dev-server運行原理[1]
  • WDS源碼[2]
責任編輯:武曉燕 來源: 量子前端
相關推薦

2024-05-06 10:53:22

瀏覽器TCPHTTPS

2011-02-22 09:59:44

互聯(lián)網(wǎng)Email網(wǎng)站

2013-02-25 11:40:04

云計算大數(shù)據(jù)阿里云

2019-12-23 16:24:47

人工智能機器學習技術(shù)

2016-11-02 06:57:33

科技新聞早報

2011-03-31 09:20:45

URLDNSWeb應用程序

2018-10-08 09:32:55

2023-01-14 16:11:27

瀏覽器URL回車

2019-08-26 09:35:25

命令ping抓包

2020-09-01 11:40:01

HTTPJavaTCP

2021-12-16 15:58:48

Linux內(nèi)存微軟

2022-05-26 23:36:36

SQLMySQL數(shù)據(jù)

2020-10-09 08:59:55

輸入網(wǎng)址解密

2021-05-27 10:26:00

地址欄URLhttp

2023-11-02 08:00:00

ClickHouse數(shù)據(jù)庫

2022-02-15 13:20:28

特斯拉電動車

2019-06-12 11:01:19

TCPUDPHTTP

2019-11-28 15:36:43

Redis數(shù)據(jù)庫高延遲

2023-12-13 17:04:51

終端命令shell

2022-03-28 08:38:00

面試DNS解析
點贊
收藏

51CTO技術(shù)棧公眾號