1. CDN
1.1 什么是CDN诫咱?
CDN稱之為內容分發(fā)網絡(Content Delivery Network或Content Distribution Network,縮寫:CDN)
- 它是指通過相互連接的網絡系統洪灯,利用最靠近每個用戶的服務器坎缭;
- 更快、更可靠地將音樂签钩、圖片掏呼、視頻、應用程序及其他文件發(fā)送給用戶铅檩;
-
來提供高性能憎夷、可擴展性及低成本的網絡內容傳遞給用戶;
image.png
在開發(fā)中昧旨,我們使用CDN主要是兩種方式:
- 方式一:打包的所有靜態(tài)資源拾给,放到CDN服務器,用戶所有資源都是通過CDN服務器加載的兔沃;
- 方式二:一些第三方資源放到CDN服務器上蒋得;
1.2 購買CDN服務器
如果所有的靜態(tài)資源都想要放到CDN服務器上,我們需要購買自己的CDN服務器乒疏;
- 目前阿里额衙、騰訊、亞馬遜缰雇、Google等都可以購買CDN服務器入偷;
-
我們可以直接修改publicPath,在打包時添加上自己的CDN地址
image.png
打包后的文件
image.png
1.3 第三方庫的CDN服務器
通常一些比較出名的開源框架都會將打包后的源碼放到一些比較出名的械哟、免費的CDN服務器上:
- 國際上使用比較多的是unpkg、JSDelivr殿雪、cdnjs暇咆;
- 國內也有一個比較好用的CDN是bootcdn
在項目中,我們如何去引入這些CDN呢?
- 第一爸业,在打包的時候我們不再需要對類似于lodash或者dayjs這些庫進行打包其骄;
- 第二,在html模塊中扯旷,我們需要自己加入對應的CDN服務器地址拯爽;
第一步,我們可以通過webpack配置钧忽,來排除一些庫的打包:
module.exports = {
mode: "production",
externals: {
// window._
lodash: "_",
// window.dayjs
dayjs: "dayjs"
}
}
第二步毯炮,在html模板中,加入CDN服務器地址:
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
1.4 html模板中開發(fā)環(huán)境的判斷
<!-- ejs中的if判斷 -->
<% if (process.env.NODE_ENV === 'production') { %>
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<% } %>
2 shimming
shimming是一個概念耸黑,是某一類功能的統稱:
- shimming翻譯過來我們稱之為 墊片桃煎,相當于給我們的代碼填充一些墊片來處理一些問題;
- 比如我們現在依賴一個第三方的庫大刊,這個第三方的庫本身依賴lodash为迈,但是默認沒有對lodash進行導入(認為全局存在lodash)捞蚂,那么我們就可以通過ProvidePlugin來實現shimming的效果庸论;
注意: webpack并不推薦隨意的使用shimming
- Webpack背后的整個理念是使前端開發(fā)更加模塊化;
- 也就是說汗贫,需要編寫具有封閉性的伴郁、不存在隱含依賴(比如全局變量)的彼此隔離的模塊另患;
目前我們的lodash、dayjs都使用了CDN進行引入蛾绎,所以相當于在全局是可以使用_和dayjs的
-
假如一個文件中我們使用了axios昆箕,但是沒有對它進行引入,那么下面的代碼是會報錯的租冠;
image.png
我們可以通過使用ProvidePlugin來實現shimming的效果:
- ProvidePlugin能夠幫助我們在每個模塊中鹏倘,通過一個變量來獲取一個package;
- 如果webpack看到這個模塊顽爹,它將在最終的bundle中引入這個模塊纤泵;
- 另外ProvidePlugin是webpack默認的一個插件,所以不需要專門導入镜粤;
const webpack = require('webpack');
module.exports = {
plugins: [
// 當在代碼中遇到某一個變量找不到時, 我們會通過ProvidePlugin, 自動導入對應的庫
new webpack.ProvidePlugin({
axios: "axios",
get: ["axios", "get"]
})
],
}
3. Hash捏题、ContentHash、ChunkHash
在我們給打包的文件進行命名的時候肉渴,會使用placeholder公荧,placeholder中有幾個屬性比較相似:
- hash、chunkhash同规、contenthash循狰;
- hash本身是通過MD4的散列函數處理后窟社,生成一個128位的hash值(32個十六進制);
hash值的生成和整個項目有關系:
- 比如我們現在有兩個入口index.js和main.js绪钥;
- 它們分別會輸出到不同的bundle文件中灿里,并且在文件名稱中我們有使用hash;
- 這個時候程腹,如果修改了index.js文件中的內容匣吊,那么hash會發(fā)生變化;
- 那就意味著兩個文件的名稱都會發(fā)生變化寸潦;
chunkhash可以有效的解決上面的問題色鸳,它會根據不同的入口進行借來解析來生成hash值:
- 比如我們修改了index.js,那么main.js的chunkhash是不會發(fā)生改變的甸祭;
contenthash表示生成的文件hash名稱缕碎,只和內容有關系:
- 比如我們的index.js,引入了一個style.css池户,style.css有被抽取到一個獨立的css文件中咏雌;
- 這個css文件在命名時,如果我們使用的是chunkhash校焦;
- 那么當index.js文件的內容發(fā)生變化時赊抖,css文件的命名也會發(fā)生變化;
- 這個時候我們可以使用contenthash寨典;