vue項目目錄的執行順序是怎么樣的?
-
1、package.json
在執行npm run dev時,會在當前目錄尋找package.json文件,此文件包含了項目的名稱版本、項目依賴等相關信息。 -
2、webpack.config.js(會被@vue-cli腳手架隱藏)
-
3、vue.config.js
對webpack進行配置,webpack打包的時候會自動對這個文件的配置進行加載。 -
4、index.html
提供一個div給vue掛載。 -
5、main.js
引入了vue、app和router模塊,創建了一個vue對象并把app.vue模板的內容掛載到index.html的id為app的div標簽下,并綁定了一個路由配置。 -
6、App.vue
上面 main.js 把 App.vue 模板的內容,放置在了 index.html 的 div 標簽下面。查看 App.vue 的內容我們看到,這個文件的內容就是整個項目的頁面放置的地方(router-view)。
React調用順序: index.html → index.js → components/組件
原文鏈接:React進階(十):React 項目啟動原理詳解
vue如何加載main.js
npm run dev的時候會出來頁面, 是因為你根目錄下的package.json文件里script配置了:
"dev": "node build/dev-server.js",
也就是其實執行的是dev-server.js這個文件,里面有定義。
var webpackConfig = require(‘./webpack.dev.conf’);
因為我們這個腳手架工具里是用webpack來打包項目文件的,依賴的webpack.dev.conf文件里又定義了。
var baseWebpackConfig = require(‘./webpack.base.conf’);
在這個依賴webpack.base.conf文件里面entry入口文件就配置了。
app: ‘./src/main.js’
所以當你運行npm run dev的時候就從main.js這個入口文件開始執行了。
怎么設置入口文件和打包路徑
vue:在項目的根目錄下的vue.config.js文件里添加配置(如果項目中沒有這個文件,可以手動創建一個):
pages屬性用于設置項目中多頁應用的入口文件;
publicPath屬性用于設置項目中所有靜態資源的基礎路徑。默認情況下是’/‘,表示根路徑。可以根據需要修改這個路徑,比如設置為’/my-app/‘,表示靜態資源會以’/my-app/‘作為基礎路徑。
假設一個Vue項目生產環境需要部署到域名的子目錄,如https://example.com/my-app/,則需要在vue.config.js中將publicPath設置為’/my-app/'。這樣打包后的靜態資源引用路徑就會自動加上/my-app/前綴。
// vue.config.jsmodule.exports = {pages: {index: {entry: 'src/main.js',//入口文件template: 'public/index.html',filename: 'index.html'},subpage: {//多個入口文件entry: 'src/subpage.js',template: 'public/subpage.html',filename: 'subpage.html'}}
publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/'// 其他配置};
react:使用命令行npm run eject暴露webpack文件,然后在webpack.config.dev.js中修改配置,但不推薦這個做法:
執行 eject 產生了什么變化?
create-react-app 框架本身將 webpack、babel 的相關配置封裝在了 react-scripts 中, 執行 npm run eject 后,會將 webpack、babel 等配置暴露在 config 目錄下,同時 scripts 目錄下會有新的命令文件更新,package.json 文件中 scripts 命令同步更新。
執行 eject 帶來了什么問題?
首先,執行 eject 是不可逆的,復雜的 webpack 等配置由框架本身轉交給用戶自己進行維護了。
其次,在版本迭代時,如果更新了 react、react-scripts、eslint、tsconfig 等依賴,有可能會引起版本依賴的問題,即使我們按錯誤信息修復了之后,項目還是無法運行。
推薦使用插件 react-app-rewired 更改配置文件,安裝插件后,在根目錄下配置 config-overrides.js 文件 (類似 vue.config.js)
const path = require('path')
const paths = require('react-scripts/config/paths')
paths.appBuild = path.join(path.dirname(paths.appBuild),'../myApp.org')
封裝圖片上傳組件要適配各個端的話,要考慮的風險點有哪些,以及怎么解決
1、風險點:平臺API調用差異
解決方案:判斷當前所處的平臺,然后再去調用對應的api
2、風險點:上傳性能瓶頸,如文件過大,上傳時間過久
解決方案:實現分片上傳(如按2MB分塊),展示上傳進度條。(上傳進度可視化公式:上傳進度 = 已傳輸分片數 / 總分片數 ×100%)
3、風險點:將其他格式的文件修改為圖片格式后上傳
解決方案:不使用截取后綴名判斷文件格式的方式,使用文件內容也就是二進制數據去判斷文件格式(文件的魔術數字(Magic Numbers)或文件簽名)。
步驟一:讀取文件二進制數據
使用FileReader讀取文件的前幾個字節(通常前4-32字節足夠):
async function readFileHeader(file) {return new Promise((resolve) => {const reader = new FileReader();reader.onload = (e) => {const buffer = e.target.result;const bytes = new Uint8Array(buffer);resolve(bytes);};// 僅讀取前32字節reader.readAsArrayBuffer(file.slice(0, 32));});
}
步驟二:定義魔術數字規則
根據文件類型的十六進制簽名定義檢測規則:
const fileSignatures = {jpeg: { offset: 0, bytes: [0xFF, 0xD8] },png: { offset: 0, bytes: [0x89, 0x50, 0x4E, 0x47] }, // ‰PNGpdf: { offset: 0, bytes: [0x25, 0x50, 0x44, 0x46] }, // %PDFzip: { offset: 0, bytes: [0x50, 0x4B, 0x03, 0x04] }, // PK..gif: { offset: 0, bytes: [0x47, 0x49, 0x46, 0x38] }, // GIF8
};
步驟三:實現檢測函數
對比文件的字節與簽名是否匹配:
function detectFileFormat(bytes) {for (const [type, { offset, bytes: signature }] of Object.entries(fileSignatures)) {const slice = bytes.slice(offset, offset + signature.length);if (slice.every((byte, i) => byte === signature[i])) {return type;}}return 'unknown';
}
步驟四:整合使用
async function checkFileFormat(file) {const bytes = await readFileHeader(file);const format = detectFileFormat(bytes);console.log('Detected format:', format);
}
響應式布局該怎么實現
1、百分比布局
百分比是相對于 包含塊 的計量單位,通過對屬性設置百分比來適應不同的屏幕
包含塊:
-
有父元素相對于父元素
-
無父元素相對于視口
-
或者繼承于父元素
2、rem布局
rem(font size of the root element)是指相對于根元素的字體大小的單位,rem只是一個相對單位
題外: rem和em的對比
1. rem和em都是相對單位2. rem相對于根元素3. em相對于父元素情景描述:1. 設置HTML的根元素的font-size為20px2. 設置一個正方形寬高為2rem3. 則正方形的寬高為40px4. 所以1rem === 根元素字號 === 20px
項目中如何方便的使用的rem呢?設想一個場景,如果一個元素的寬需要47px,根元素是20px,如果要適應不同的終端,需要轉為rem,除以20px得到相應的rem值,很麻煩,那么就需要找一個可以簡單計算的數值.1. 設想屏幕寬度為750px,設計稿寬度也為750px
2.設置 font-size = 1rem = 屏幕寬度*100/設計稿寬度 = 100px (乘以100的原因,屏幕寬度/設計稿寬度得出的值是1,而瀏覽器可以接受的最小字號12px,所以乘以100既可以滿足瀏覽器最小字號的要求,也比較好計算)
3. 屏幕寬度不會只是750px,假設屏幕寬度為width(getBoundingClientRect().width可以獲取寬度),在該寬度下的字號為fontSize
4.width/(750*fontsize)=750/(750*100)
5. 通過上面這個方法可以計算出fontSize的值
3、媒體查詢 @media screen
CSS媒體查詢是實現響應式布局的核心技術,通過檢測設備屏幕特性(如寬度、分辨率)動態調整樣式。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>@media screen</title><style>.box {width: 10rem;height: 10rem;background-color: pink;margin-left: 20rem;}@media screen and (min-width: 1200px) {html {font-size: 20px;}}@media screen and (max-width: 1200px) {html {font-size: 10px;}}</style></head><body><div class="box"></div></body>
</html>
4 、flex布局
5、vw 和 vh
vw表示相對于視圖窗口的寬度,vh表示相對于視圖窗口高度,除了vw和vh外,還有vmin和vmax兩個相關的單位。各個單位具體的含義如下:
vw 相對于視窗的寬度,1vw 等于視口寬度的1%,即視窗寬度是100vw
vh 相對于視窗的高度,1vh 等于視口高度的1%,即視窗高度是100vh
vmin vw和vh中的較小值
vmax vw和vh中的較大值
答案出自響應式布局的實現方式(5種)
webpack跟vite有什么區別
- 核心區別
構建方式
Webpack:采用 打包優先 的模式,需 預構建所有依賴 并生成打包文件后才能啟動開發服務器,導致 冷啟動時間較長1。
Vite:利用瀏覽器原生支持的 ES Modules (ESM),實現 按需編譯,啟動時僅加載當前所需模塊,速度極快。
開發體驗
Webpack:熱更新(HMR)需重新構建修改的模塊及其依賴鏈,響應速度隨項目規模增長而下降。
Vite:HMR 直接更新修改的模塊,無需重新打包,響應速度與項目復雜度無關,實現 毫秒級更新。
生產構建
Webpack:內置成熟的代碼分割、Tree Shaking 等優化策略,適合復雜場景。
Vite:默認使用 Rollup 進行生產構建,配置更簡潔,但對插件生態的依賴度較高。
配置復雜度
Webpack:需手動配置加載器(Loader)、插件(Plugin)等,學習曲線陡峭。
Vite:內置對 TypeScript、CSS 預處理器等的支持,開箱即用,配置更簡單。
2. 適用場景
選擇 Webpack 的情況:
需要兼容舊版本瀏覽器(如 IE11);
項目依賴大量 Webpack 專屬插件(如復雜代碼分割策略);
已有成熟 Webpack 配置的大型遺留系統。
選擇 Vite 的情況:
面向現代瀏覽器的應用開發(如 Vue/React 單頁應用);
追求極速啟動與熱更新效率的新項目;
希望減少構建配置的復雜度,快速搭建開發環境。
3. 實戰示例對比
Webpack 啟動耗時:典型項目冷啟動時間:30秒以上
npm run dev
Vite 啟動耗時:典型項目冷啟動時間:1秒以內
npm run dev
1. 打包機制
Webpack:采用傳統打包模式,通過靜態分析將所有模塊(如JS、CSS、圖片)提前打包成一個或多個bundle。開發環境下需等待整個打包完成才能啟動服務,可能導致冷啟動較慢4。
Webpack流程: 代碼分析 → 依賴圖構建 → 打包bundle → 啟動服務
Webpack流程: 代碼分析 → 依賴圖構建 → 打包bundle → 啟動服務Vite:基于瀏覽器原生ES模塊(ESM)支持,開發環境按需編譯。僅編譯當前頁面所需模塊,大幅減少初始等待時間。生產環境則使用Rollup進行優化打包4。
Vite流程: 啟動服務 → 按需編譯模塊
Vite流程: 啟動服務 → 按需編譯模塊2. 配置復雜度
Webpack:配置復雜,需手動處理加載器(Loader)、插件(Plugin)及代碼分割規則。例如,處理Sass需配置sass-loader、css-loader和style-loader2。
Vite:開箱即用,內置對TypeScript、CSS預處理器等的支持,默認配置覆蓋常見場景。支持自定義配置,但更注重簡化流程。
3. 開發環境性能
冷啟動速度:
Webpack需打包全部模塊,項目越大啟動越慢。
Vite直接啟動開發服務器,僅編譯入口文件,速度極快4。
熱更新(HMR):
Webpack需重新打包修改的模塊及其依賴,可能導致延遲。
Vite通過ESM實現精準HMR,僅更新修改的模塊,響應更快。
4. 生產環境構建
Webpack:自行處理生產構建,支持代碼分割、Tree Shaking等優化,適合復雜項目5。
Vite:使用Rollup進行生產打包(盡管開發環境用ESBuild)。Rollup在生成小體積代碼方面表現優異,但復雜場景下可能需額外配置。
5. 插件生態
Webpack:擁有龐大成熟的插件生態,覆蓋各類需求(如壓縮、懶加載)。
Vite:插件生態較新,但兼容Rollup插件,且社區正在快速擴展。
6. 適用場景
Webpack:適合大型復雜項目(如多入口、自定義構建流程),需要深度優化和長期維護3。
Vite:適合快速原型開發、中小型項目或現代框架(如Vue/React)的輕量化應用3。
Vite是否需要打包?
開發環境無需打包:Vite在開發模式下直接使用瀏覽器原生ES模塊加載能力,通過按需編譯實現秒級啟動。例如修改單文件組件時,僅重新編譯當前文件。
生產環境需要打包:為了優化資源加載性能(如代碼壓縮、Tree-shaking、懶加載),Vite在生產環境必須進行打包構建,此時會將代碼轉換為兼容性更好的傳統靜態資源格式。
二、生產環境構建流程
依賴預構建
使用esbuild將CommonJS模塊轉換為ES模塊
合并碎片化依賴為單個文件,減少網絡請求
建立模塊緩存機制加速構建
Rollup打包階段
代碼分割(Code Splitting)
資源壓縮(JS/CSS minify)
靜態資源處理(圖片轉base64、文件名哈希)
兼容性語法轉換(通過Babel)
環境變量注入
根據.env.production等文件注入變量
在構建時通過import.meta.env替換實際值2
vite為什么生產環境不用esbuild?
雖然esbuild打包速度比Rollup快10-100倍,但Vite仍選擇Rollup的核心原因:
插件生態兼容性:現有Vite插件體系基于Rollup API設計
功能完整性:Rollup對CSS代碼分割、復雜模塊轉換等場景支持更成熟
穩定性驗證:Rollup經過長期生產環境驗證(Webpack、Parcel等工具也采用其核心)
seo
SEO,全稱Search Engine Optimization,即搜索引擎優化。它是一種利用搜索引擎的規則來提高網站在搜索引擎內自然排名的方式,從而吸引更多的用戶訪問網站,提高網站的訪問量,進而提升網站的銷售能力和宣傳能力,達到提升網站品牌效應的目的。
SEO主要分為兩種:站外SEO和站內SEO。站外SEO則是指從外部網站對搜索引擎排名的影響,其中最有用的外部因素通常是反向鏈接,即外部鏈接。站內SEO指的是網站的內部優化,包括代碼標簽優化、內容優化和網址優化等。
站外SEO
1.外部鏈接建設
外部鏈接是站外SEO最重要的一種策略。這些鏈接是指從其他網站鏈接到你的網站,被視為一種“投票”,可以提高你網站的排名和權重。
2.搜索引擎收錄提交
如果搜索引擎沒有及時抓取和收錄你的網站內容,那么網站內容就無法在搜索引擎上展現。因此,你可以通過搜索引擎的提交入口(百度、搜狗、360、谷歌)進行提交,以便加快收錄速度。
站內SEO
1.使用title標簽
標簽包裹的文字要對網頁內容有準確而簡潔,能夠吸引用戶,而且長度要適中。
<title>博客網</title>
2.使用meta標簽
meta標簽在HTML語言中,是head區的一個輔助性標簽,主要用于提供有關HTML文檔的元數據。這些元數據不會顯示在頁面上,但會被瀏覽器解析,用于指導瀏覽器的行為,或者為搜索引擎提供關于頁面的信息。
description:用于提供網頁的描述,這有助于搜索引擎理解網頁內容。
keywords:用于提供網頁的關鍵詞,這有助于搜索引擎對網頁進行分類和排名。
author:用于標識網頁的作者。
viewport:用于控制網頁在移動設備上的視口設置。
robots:用于指導搜索引擎爬蟲如何處理頁面,例如是否允許索引或跟蹤鏈接。
<meta name="description" content="這是一個面試題記錄博客">
3.多使用語義化標簽
HTML5新出的 Header, Nav,Aside,Article,Footer等語義化標簽,能幫助爬蟲更好的獲取頁面內容。img的alt屬性,為搜索引擎提供替代文本,圖片使用alt標簽優化。
4. robots文件
robots.txt 是一個文本文件,用于指導搜索引擎爬蟲如何訪問和索引網站的頁面。可以通過合理地使用 robots.txt 來幫助優化網站的 SEO(搜索引擎優化)。
1.了解基礎
robots.txt 文件應位于網站的根目錄下。
它的語法相對簡單,主要使用 User-agent 和 Disallow 指令。
User-agent 用于指定爬蟲的名稱,例如 * 表示所有爬蟲。
Disallow 用于指定不希望爬蟲訪問的 URL 路徑。
2. 允許爬蟲訪問:
默認情況下,如果不設置 robots.txt,爬蟲會嘗試訪問并索引網站的所有頁面。
為了確保網站內容能被搜索引擎找到,通常建議允許所有爬蟲訪問。
3.排除敏感或重復內容:
使用 Disallow 指令排除不希望被索引的頁面,例如后臺管理頁面、重復內容、測試頁面等。
這有助于減少搜索引擎的噪音,提高網站的整體質量得分。
4.優化爬蟲效率:
通過 robots.txt 可以指導爬蟲優先訪問重要頁面,但這主要依賴于搜索引擎的實現,不一定總是有效。
確保 robots.txt 文件盡可能小,以減少爬蟲的加載時間。
5.定期檢查和更新:
隨著網站內容的更新和結構的調整,可能需要定期檢查和更新 robots.txt。
確保它始終與網站的當前狀態保持一致。
5.網站性能
網站打開速度越快,識別效果越好,否則爬蟲會認為該網站對用戶不友好,降低爬取效率,這時候就要考慮壓縮文件體積之類的性能優化了。
6.使用https
使用HTTPS,因為它提供更高的安全性和更好的用戶體驗。當您的網站使用HTTPS時,搜索引擎會將其視為更可信和更安全的網站。
答案出自作為前端工程師如何SEO優化
websocket
一、WebSocket協議簡介
WebSocket是HTML5引入的一種基于TCP的全雙工通信協議,由W3C于2011年標準化。與HTTP的請求-響應模式不同,WebSocket通過一次握手即可建立持久連接,允許客戶端和服務器隨時雙向傳輸數據,適用于實時性要求高的場景。
二、協議特點
基于TCP與應用層協議:
WebSocket運行在TCP之上,屬于獨立的第七層協議,默認端口為80(WS)或443(WSS)。
幀結構設計:
數據通過二進制幀傳輸,幀頭包含操作碼(如 0x1表示文本幀)、FIN標志(標記消息結束)及掩碼(客戶端到服務端需掩碼加密)。
握手過程:
客戶端發送包含Sec-WebSocket-Key的HTTP升級請求,服務端響應時生成Sec-WebSocket-Accept,計算方式為:
Sec-WebSocket-Accept=Base64(SHA-1(Sec-WebSocket-Key+
258EAFA5-E914-47DA-95CA-C5AB0DC85B11))
Sec-WebSocket-Accept=Base64(SHA-1(Sec-WebSocket-Key+258EAFA5-E914-47DA-95CA-C5AB0DC85B11))
驗證成功后,連接升級為WebSocket協議。
三、應用場景
實時通信
如在線聊天、彈幕系統,消息可實時推送2。
協同編輯工具
多用戶同時編輯文檔時同步內容變更。
金融交易與游戲
股票價格實時推送、多玩家在線游戲的即時狀態同步。
四、示例代碼
// 創建WebSocket連接
const socket = new WebSocket('wss://example.com/ws');// 監聽消息
socket.onmessage = function(event) {console.log('收到數據:', event.data);
};// 發送數據
socket.send('Hello Server!');
WebSocket (WS) 和 WebSocket Secure (WSS) 的定義與區別
- 定義 WebSocket (WS) 基于 HTML5 的通信協議,支持客戶端與服務端在單個 TCP 連接上進行全雙工雙向通信。通過一次握手建立持久連接,允許雙方主動推送數據,適用于實時性要求高的場景(如在線聊天、實時游戲)。協議標識為 ws://,默認使用80端口(與 HTTP相同)。
WebSocket Secure (WSS) 是 WS 的安全版本,通過 SSL/TLS加密傳輸數據,確保通信內容的機密性和完整性。協議標識為 wss://,默認使用443端口(與 HTTPS相同)。常用于需要保護敏感信息的場景(如金融交易、隱私數據傳輸)。
- 核心區別:
- 應用場景
WS:適合內部系統或對安全性要求不高的實時通信,如本地測試、局域網監控。
WSS:必須用于涉及用戶隱私或敏感數據的場景,如在線支付、醫療信息同步。
axios斷連怎么處理
1、可以在請求攔截器和響應攔截器里面對錯誤信息進行判斷,如果是網絡錯誤則可以通過事件總線或者vuex的方式通知app.vue,顯示一個網絡錯誤相關的頁面,如刷新按鈕等,等用戶點擊或者執行某個動作后重新發起請求。
2、當發生網絡錯誤的時候,我們也可以自動重新發起請求,但是需要設置一個重試次數和延遲時間。對于請求重試的功能來說,我們希望讓用戶不僅能夠設置重試次數,而且可以設置重試延時時間。當請求失敗的時候,若該請求的配置對象配置了重試次數,而 Axios 就會重新發起請求進行重試操作。為了能夠全局進行請求重試,接下來我們在響應攔截器上來實現請求重試功能,具體代碼如下所示:
axios.interceptors.response.use(null, (err) => {let config = err.config;if (!config || !config.retryTimes) return Promise.reject(err);const { __retryCount = 0, retryDelay = 300, retryTimes } = config;// 在請求對象上設置重試次數config.__retryCount = __retryCount;// 判斷是否超過了重試次數if (__retryCount >= retryTimes) {return Promise.reject(err);}// 增加重試次數config.__retryCount++;// 延時處理const delay = new Promise((resolve) => {setTimeout(() => {resolve();}, retryDelay);});// 重新發起請求return delay.then(function () {return axios(config);});
});
前端性能優化相關知識
一、代碼層面優化
Vue框架優化
使用v-if替代v-show:v-if是惰性渲染,適合切換頻率低的場景;v-show通過CSS控制顯示,適合頻繁切換場景
列表渲染添加唯一key:幫助Vue高效復用DOM元素
組件懶加載:通過script setup或defineAsyncComponent延遲加載非關鍵組件
// 異步組件示例
const AsyncComponent = defineAsyncComponent(() => import(‘./AsyncComponent.vue’))
通用JavaScript優化
避免強制同步布局(Layout Thrashing)
使用事件委托減少事件監聽器數量
采用Web Workers處理CPU密集型任務
二、構建工具優化(Webpack)
代碼分割
// webpack.config.js
optimization: {
splitChunks: {
chunks: ‘all’
}
}
Tree Shaking
使用ES6模塊語法(import/export)
配置sideEffects標記無副作用模塊
資源壓縮
啟用TerserPlugin壓縮JS
使用CssMinimizerPlugin壓縮CSS
配置圖片壓縮(image-webpack-loader)
三、基礎Web技術優化
圖片優化(核心優化項)
使用WebP格式(比JPEG小25-34%)
響應式圖片:通過與srcset適配不同分辨率
SVG圖標替代位圖
HTTP緩存策略
Nginx
Nginx配置示例
location ~* .(js|css|png)$ {
expires 1y;
add_header Cache-Control “public”;
}
通過Last-Modified和ETag實現條件請求3
CDN加速
靜態資源部署到CDN
啟用HTTP/2協議提升并發性能4
資源預加載
<link rel="preload" href="critical.css" as="style">
<link rel="preconnect" href="https://cdn.example.com">
四、監控與持續優化
性能指標監測
核心Web指標:LCP(最大內容渲染)、FID(首次輸入延遲)、CLS(累計布局偏移)
工具鏈