# 來點 Webpack 動態 CDN (publicPath) 用webpack打包的專案,如果你使用 環境參數來指定 cdn 網址 ```environment= // env.beta ASSET_PATH = 'http://beta.cdn.com' ``` 然後再把自己設定好的環境參數丟給 webpack ```typescript= import webpack from 'webpack'; const ASSET_PATH = process.env.ASSET_PATH || '/'; export default { output: { publicPath: ASSET_PATH }, plugins: { new webpack.DefinePlugin({ 'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH) }) } }; ``` 等於是有 6 個環境就要分別下 6 次不同指令做 6 次打包 這就是 666 罷… 能不能只打包一次進 docker image ,之後所有 container 都是從這個 image 建立出來 從 開發(dev) 到 測試(test) , 封測 (beta) , 上線(prod) 都使用同一個image 並且修改掉 cdn ? 答案是 ***YES ! 你可以*** > 其實這樣的需求很符合邏輯,在不同環境的打包或者 node, npm, yarn 版本有所不同打包出來的東西都會不一樣,即使 yarn.lock似乎會幫你瑣住那些版本,但只要 dependencies沒有設定好 yarn install下去依舊有機會安裝到非預期的套件版本,重新打包永遠都帶有風險。 先說結論 `__webpack_public_path__` 就是他! [官方文件](https://webpack.js.org/guides/public-path/) ## 什麼是 PublicPath 很多人會寫 V A R 三大框架,但絕大多數的人並沒有自己去設定過 webpack, 打包時我們可以設定 publicPath 來改變所有打包過的檔案的 baseurl 如下 ```typescript= // 打包前 const img = require('img/taiwan_can_help.jpg'); // 打包後 const img = 'img/taiwan_can_help.ef1241s.jpg'; // 設定 { publicPath: 'http://dev.cdn.com' } const img = 'http://dev.cdn.com/img/taiwan_can_help.ef1241s.jpg'; ``` `publicPath` 影響著 .js .css. .html img… 幾乎所有檔案都囊括了,但當你寫在 webpack.config.js 內時,就注定有幾個環境就得打包幾次… ### 如何讓他動態被定義呢? 首先我們必須使用到另一個技術 webpackChunk ,chunk可以將你肥肥的程式碼切分了許多塊,在適當的時機讓使用者載入,大大的降低伺服器負載並友善了使用者體驗。chunk 會在打包時整理出一份 vendor.js 裡面存放著所有將會使用到的檔案的路徑,並在使用者瀏覽 App 時利用 vendor 去找到那些檔案路徑,而我們就是要搶在檔案尚未被真正加載之前改掉他的 base url 這時候就要用到 `__webpack_public_path__` 這個動態變數 如果他在 你的入口檔案 (也就是 [Entry Point](https://webpack.js.org/concepts/entry-points/)) 的最一開始被定義,那麼接下來 vendor 讀出的檔案都會改訪問新的 `publicPath` ### 為什麼不直接定義在 `<head><script>` 內 webpack 所有處理都會被包進去 一個 function 內,所以 `__webpack_public_path__` 在 bowser 情境下是一個 scope variable,是無法使用 `window.__webpack_public_path__` 從外部改變的喔 接下來只要簡單的在 `docker run container` 前去修改 domain.js 的 `window.cdnDomain` 間接去影響 `__webpack_public_path__` 就不用為了變換 cdn 再次打包了! 記得 檢查自己的 webpack 是否有使用 **PreloadPlugin** 這個套件 他會把路徑 直接打包在 `<head>` 內,`__webpack_public_path__` 無法動態影響他,記得刪掉並使用內建的 `webpackPrefech` 來達到最好的效果喔!
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up