Webpack-2:Webpack

 webpack 是什麼?

        - 官方網站:https://webpack.js.org/

        - 中文網站:https://www.webpackjs.com/

        本質上,`webpack` 是一個現代 `JavaScript` 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地

        構建一個依賴關係圖(dependency graph),其中包含應用程序需要的每個模塊,然後將所有這些模塊打包成一個或多個 bundle。


安裝(兩個工具webpack、webpack-cli)

    `webpack` 是一個使用 `Node.js` 實現的一個模塊化代碼打包工具。所以,我們需要先安裝 webpack,安裝之前需要搭建好 `Node.js` 環境

npm install -D webpack webpack-cli

注:不推薦全局安裝

        `webpack-cli` : 提供 webpack 命令、工具,類似 `create-react-app`

        `webpack` : webpack 代碼,類似 `react`

使用

        ./node_modules/.bin/webpack

查看版本

        ./node_modules/.bin/webpack -v

                也可以編輯 `package.json` 的 `scripts` 來簡化輸入

// package.json

{

  ...,

  "scripts": {

    "start": "webpack"  // scripts 中可以定位到 ./node_modules/.bin/ 目錄下

  }

}

當然,還可以使用更加方便的方式:

                npx webpack

        通過 `npx` 也可以幫助我們定位命令到 `./node_modules/.bin/` 目錄下

        注:npm5.2+ 增加,如果沒有,可以使用 npm i -g npx 來安裝


打包模塊

        打包之前,我們需要了解一個概念,入口文件

入口文件

        入口文件就是我們項目中加載的第一個文件,比如上面的 `main.js` 文件,其它文件都是通過 `import` 等方式引入的,`webpack` 會從

        我們指定的入口文件開始分析所有需要依賴的文件,然後把打包成一個完整文件。

打包命令

webpack ./js/index.js

        上面命令會使用 `webpack` 默認的一些配置對模塊文件進行打包,並把打包後的文件輸出到默認創建的 `./dist` 目錄下,打包後的

        文件名稱默認爲 `main.js`。

        模塊文件打包以後,就可以在不支持 es6 模塊語法的瀏覽器環境下引入使用了。

打包文件分析

                - 把分散的模塊文件打包到一個文件中,不需要外部引入了

                - 內置了一個小型模塊加載器(類似 `requireJS`),實現了打包後的代碼隔離與引用

        以上就是 webpack 最基礎的使用於基本原理,當然強大的 `webpack` 遠遠不止這些功能。

打包配置

        雖然,我們可以直接通過命令的來打包,但是推薦創建一個 `webpack.config.js` 的配置文件來實現更方便和強大的功能。

        `webpack` 命令在運行的時候,默認會讀取運行命令所在的目錄下的 `webpack.config.js` 文件,通常我們會在項目的根目錄下運行命令

        和創建配置文件。

        我們也可以通過 `—config` 選項來指定配置文件路徑:

webpack --config ./configs/my_webpack.config.js

通常情況下,我們的項目目錄大致如下:


核心配置

mode模式

`"production" | "development" | "none"`

 

在webpack.config.js添加就可變成開發環境

module.exports = {

  mode: 'production'

}


entry入口---分析的第一個文件

output出口

        打包後的文件位置

多出口模式

        - 可以指定一個固定的文件名稱,如果是多入口多出口(`entry` 爲對象),則不能使用單文件出口,需要使用下面的方式

        - 通過 `webpack` 內置的變量佔位符:`[name]`


深入功能

        在 `webpack` 中,有一個很重要的特性:模塊不僅僅只是 `js` 的文件,`webpack` 可以把任意文件數據作爲模塊進行處理,

        包括:非 js 文本、css、圖片等等

        但是 `webpack` 默認情況下只能處理 `js` 模塊,如果需要處理其它類型的模塊,則需要使用它提供的一些其它功能

執行簡要流程


Loaders

        https://webpack.js.org/loaders/

1240uploading.4e448015.gif轉存失敗重新上傳取消

        當 `webpack` 碰到不識別的模塊的時候,`webpack` 會在配置的 `module` 中進行該文件解析規則的查找

                - `rules` 就是我們爲不同類型的文件定義的解析規則對應的 loader,它是一個數組

                - 每一種類型規則通過 test 選項來定義,通過正則進行匹配,通常我們會通過正則的方式來匹配文件後綴類型

                - `use` 針對匹配到文件類型,調用對應的 `loader` 進行處理


從一個簡單的案例來了解 loader


raw-loader

        在 webpack 中通過 import 方式導入文件內容,loader 並不是 webpack 內置的,所以首先要安裝

                        npm install --save-dev raw-loader

        然後在 webpack.config.js 中進行配置


file-loader

        把識別出的資源模塊,移動到指定的輸出目錄,並且返回這個資源在輸出目錄的地址(字符串)

                        npm install --save-dev file-loader

                佔位符:https://webpack.js.org/loaders/file-loader#placeholders


url-loader

        可以處理理 `file-loader` 所有的事情,但是遇到圖片格式的模塊,可以選擇性的把圖片轉成 `base64`  格式的字符串,並打包到 `js` 中,

        對小體積的圖片比較合適,大圖片不合適。

                        npm install --save-dev url-loader


css-loader

        分析 `css` 模塊之間的關係,併合成一個 `css`

                        npm install --save-dev css-loader


style-loader

        把 `css-loader` 生成的內容,用 `style` 標籤掛載到頁面的 `head` 中

                        npm install --save-dev style-loader

        同一個任務的 `loader` 可以同時掛載多個,處理順序爲:從右到左,也就是先通過 `css-loader` 處理,然後把處理後的 `css` 字符串

        交給 `style-loader` 進行處理


sass-loader

        把 `sass` 語法轉換成 `css` ,依賴 `node-sass` 模塊

                        npm install --save-dev sass-loader node-sass


Plugins(插件)

        擴展 `webpack` 本身的一些功能,它們會運行在各種模塊解析完成以後的打包編譯階段,比如對解析後的模塊文件進行壓縮等

HtmlWebpackPlugin

        在打包結束後,自動生成一個 `html` 文件,並把打包生成的 js 模塊引入到該 `html` 中

                        npm install --save-dev html-webpack-plugin

        在 `html` 模板中,可以通過 `<%=htmlWebpackPlugin.options.XXX%>` 的方式獲取配置的值


clean-webpack-plugin

        刪除(清理)構建目錄

                        npm install --save-dev clean-webpack-plugin

mini-css-extract-plugin

        提取 `CSS` 到一個單獨的文件中

                        npm install --save-dev mini-css-extract-plugin

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {

  ...,

  module: {

    rules: [

      {

        test: /\.s[ac]ss$/,

        use: [

          {

            loader: MiniCssExtractPlugin.loader

          },

          'css-loader',

          'sass-loader'

        ]

      }

    ]

  },

  plugins: [

    ...,

    new MiniCssExtractPlugin({

      filename: '[name].css'

    }),

    ...

  ]

}


sourceMap

        我們實際運行在瀏覽器的代碼是通過 `webpack` 打包合併甚至是壓縮混淆過的代碼,所生成的代碼並不利於我們的調試和錯誤定位,

        我們可以通過 `sourceMap` 來解決這個問題,`sourceMap` 本質是一個記錄了編譯後代碼與源代碼的映射關係的文件,我們可以通過

         `webpack` 的 `devtool` 選項來開啓 `sourceMap`

        首先,編譯後會爲每一個編譯文件生成一個對應的 `.map` 文件,同時在編譯文件中添加一段對應的 `map` 文件引入代碼

        同時,現代瀏覽器都能夠識別 `sourceMap` 文件,如 `chrome`,會在 `Sources` 面板中顯示根據編譯文件與對應的 `map` 文件定位到

        源文件中,有利於我們的調試和錯誤定位


WebpackDevServer

        每次的代碼修改都需要重新編譯打包,刷新瀏覽器,特別麻煩,我們可以通過安裝 `webpackDevServer` 來改善這方面的體驗

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

啓動命令:

                npx webpack-dev-server

或者,`package.json` 中添加 `scripts`

修改 `webpack.config.js`

        啓動服務以後,`webpack` 不在會把打包後的文件生成到硬盤真實目錄中了,而是直接存在了內存中(同時虛擬了一個存放目錄路徑),

        後期更新編譯打包和訪問速度大大提升


Proxy

        當下前端的開發都是前後端分離開發的,前端開發過程中代碼會運行在一個服務器環境下(如當前的 `WebpackDevServer`),那麼在

        處理一些後端請求的時候通常會出現跨域的問題。`WebpackDevServer` 內置了一個代理服務,通過內置代理就可以把我們的跨域請求

        轉發目標服務器上(`WebpackDevServer` 內置的代理髮送的請求屬於後端 - `node`,不受同源策略限制),具體如下:

const Koa = require('koa');

const KoaRouter = require('koa-router');

const app = new Koa();

const router = new KoaRouter();

router.get('/api/info', async ctx => {

    ctx.body = {

        username: 'zMouse',

        gender: 'male'

    }

})

app.use( router.routes() );

app.listen(8787);

axios({

  url: 'http://localhost:8787/api/info'

}).then(res => {

  console.log('res',res.data);

})

        默認情況下,該代碼運行以後會出現跨域請求錯誤,修改 `webpack` 配置

module.exports = {

  ...,

  devServer: {

    // 生成的虛擬目錄路徑

    contentBase: "./dist",

    // 自動開啓瀏覽器

    open: true,

    // 端口

    port: 8081,

    proxy: {

      '/api': {

        target: 'http://localhost:8787'

      }

    }

  }

}

 

通過 `proxy` 設置,當我們在當前 `WebpackDevServer` 環境下發送以 `/api` 開頭的請求都會被轉發到 http://localhost:8787 目標服務器下

axios({

  //url: 'http://locahost:8081/api/info',

  url: '/api/info'

}).then(res => {

  console.log('res',res.data);

})


Hot Module Replacement(熱重載)

        在之前當代碼有變化,我們使用的 `live reload`,也就是刷新整個頁面,雖然這樣爲我們省掉了很多手動刷新頁面的麻煩,但是這樣

        即使只是修改了很小的內容,也會刷新整個頁面,無法保持頁面操作狀態。`HMR` 隨之就出現了,它的核心的局部(模塊)更新,

        也就是不刷新頁面,只更新變化的部分

        開啓 `HMR` 以後,當代碼發生變化,`webpack` 即會進行編譯,並通過 `websocket` 通知客戶端(瀏覽器),我們需要監聽處理

        來自 `webpack` 的通知,然後通過 `HMR` 提供的  `API` 來完成我們的局部更新邏輯

        上面代碼就是 當 ./fn1.js 模塊代碼發生變化的時候,把最新的 fn1 函數綁定到 box1.onclick 上

        從上面就可以看到,`HMR` 其實就是以模塊爲單位,當模塊代碼發生修改的時候,通知客戶端進行對應的更新,而客戶端則根據具體

        的模塊來更新我們的頁面邏輯(這些邏輯需要自己去實現),好在當前一些常用的更新邏輯都有了現成的插件

https://github.com/gaearon/react-hot-loader

https://github.com/vuejs/vue-loader

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章