<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
1.第一個登錄頁面,里面有提交表單,action提交到index.html頁面中
2.第二個頁面,可以使用第一個頁面的參數,這樣實現了一個數據不同頁面之間的傳遞效果
3.第二個頁面之所以可以使用第一個頁面的數據,是利用了URL里面的location.search參數
4.在第二個頁面中,需要把這個參數提取出來
5.第一步去掉提取到參數的中的?,利用substr
6.第二步利用=號分割鍵和值,分割后得到一個數組,通過數組獲得值 split('=')
圖1
圖2
圖2
圖3
者:dragonnahs
轉發鏈接:https://segmentfault.com/a/1190000023289245
在多頁面框架打包的過程中會,隨著業務的增加頁面越來越多,使用的三方包也會越來越多,但并不是所有頁面都會使用到三方插件,使用webpack打包會讓所有的三方包打包到一起,會導致vendor.js(三方包打包后的文件)越來越大,即使沒使用過三方插件的頁面也會引入,頁面加載會越來越慢.
webpack 就像一條生產線,要經過一系列處理流程后才能將源文件轉換成輸出結果。 這條生產線上的每個處理流程的職責都是單一的,多個流程之間有存在依賴關系,只有完成當前處理后才能交給下一個流程去處理。插件就像是一個插入到生產線中的一個功能,在特定的時機對生產線上的資源做處理。webpack 通過 Tapable 來組織這條復雜的生產線。 webpack 在運行過程中會廣播事件,插件只需要監聽它所關心的事件,就能加入到這條生產線中,去改變生產線的運作。
webpack本身引入的有tapable插件來管理構建流程,在編譯的時候會觸發tapalbe的鉤子事件,我們編寫一個webpack插件就是找到對應的鉤子,然后寫入自己的業務,就是在鉤子上注冊自己的事件,和發布訂閱模式是一樣的,當webpack構建時插件注冊的事件就會在鉤子觸發的時候執行。
每個 Webpack 插件都需要向外暴露一個 apply(compiler) 方法,在compiler上找到對應的鉤子寫入自己的業務處理。目前這個插件處理的就是在生成了html頁面之后把頁面對應的js和css插入到html代碼中,因此這個插件是依賴于html-webpack-plugin的,他會向complation中再注入一個鉤子htmlWebpackPluginAfterHtmlProcessing當該鉤子觸發時,已經生成了一個html頁面
compiler.hooks.compilation.tap(
this.constructor.name,
compilation=> {
let hook=compilation.hooks.htmlWebpackPluginAfterHtmlProcessing;
hook.tapAsync(
this.constructor.name,
(htmlPluginData, callback)=> {
try {
// 當htmlWebpackPluginAfterHtmlProcessing鉤子觸發后會調用addLinks方法,傳入compilation和當前當html頁面信息
callback(null, this.addLinks(compilation, htmlPluginData));
} catch (error) {
callback(error);
}
}
);
}
);
// 將頁面所依賴的js和css注入到頁面中
addLinks(compilation, htmlPluginData){
// 獲取當前頁面所依賴的chunk
const extractedChunks=extractChunks({
compilation,
optionsInclude: Object.keys(htmlPluginData.assets.chunks),
});
...
// 獲取所有chunks的files
const allFiles=extractedChunks.reduce((accumulated, chunk)=> {
return accumulated.concat(chunk.files);
}, []);
// 這一步是將根據allFiles處理后的鏈接注入到html頁面
htmlPluginData.html=insertLinksIntoHtml({
links,
html: htmlPluginData.html,
});
return htmlPluginData;
}
具體例子如下:
// vue.config.js
const { resolve }=require('path')
const getEntries=require('./build/getEntries')
const WebpackBundleAnalyzer=require('webpack-bundle-analyzer')
const AutoInjectPlugin=require('auto-inject-plugin')
const pages=getEntries(resolve(__dirname, 'src/features/*/index.js'))
module.exports={
pages,
productionSourceMap: false,
assetsDir: 'static',
publicPath: '/',
chainWebpack: config=> {
config.resolve.alias.set('vue$', 'vue/dist/vue.esm.js')
if(process.env.NODE_ENV==='production'){
// 分離第三方包
config.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
elementUI: {
name: 'chunk-elementUI',
priority: 20,
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
},
swiper: {
name: 'chunk-swiper',
priority: 20,
test: /[\\/]node_modules[\\/]_?swiper(.*)/,
}
}
})
// 將依賴自動注入到對應頁面中
config.plugin('AutoInjectPlugin').use(AutoInjectPlugin)
config.optimization.runtimeChunk({name: 'manifest'})
}
if(process.env.npm_config_report){
config.plugin('analyzer').use(WebpackBundleAnalyzer.BundleAnalyzerPlugin)
}
config
.plugin('copy')
.tap(args=> {
const { toType }=args[0][0]
args[0]=[]
args[0].push({
from: resolve(__dirname, 'public'),
to: resolve(__dirname, 'dist/static/js'),
toType
})
return args
})
}
}
抽離第三方包后的前后對比:
抽離前
抽離后
使用自動注入插件前后生成的html頁面:使用前:
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Document</title>
<link href=/bk_static/css/chunk-elementUI.ad4ace96.css rel=preload as=style>
<link href=/bk_static/css/home.340fe3f2.css rel=preload as=style>
<link href=/bk_static/js/chunk-elementUI.1ea80d29.js rel=preload as=script>
<link href=/bk_static/js/chunk-libs.89fd9e1d.js rel=preload as=script>
<link href=/bk_static/js/home.12708c2b.js rel=preload as=script>
<link href=/bk_static/js/manifest.1dcac3f8.js rel=preload as=script>
<link href=/bk_static/css/home.340fe3f2.css rel=stylesheet>
</head>
<body>
<div id=root></div>
<script src=/bk_static/js/home.12708c2b.js></script>
</body>
</html>
所依賴的代碼并未自動引入進來
使用后:
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Document</title>
<link href=/bk_static/css/chunk-elementUI.ad4ace96.css rel=preload as=style>
<link href=/bk_static/css/home.340fe3f2.css rel=preload as=style>
<link href=/bk_static/js/chunk-elementUI.1ea80d29.js rel=preload as=script>
<link href=/bk_static/js/chunk-libs.89fd9e1d.js rel=preload as=script>
<link href=/bk_static/js/home.aa83744c.js rel=preload as=script>
<link href=/bk_static/js/manifest.1dcac3f8.js rel=preload as=script>
<link href=/bk_static/css/home.340fe3f2.css rel=stylesheet>
<link href="/bk_static/css/chunk-elementUI.ad4ace96.css" rel=stylesheet>
</head>
<body>
<div id=root></div>
<script src=/bk_static/js/home.aa83744c.js></script>
<script src=/bk_static/js/chunk-elementUI.1ea80d29.js></script>
<script src=/bk_static/js/chunk-libs.89fd9e1d.js></script>
<script src=/bk_static/js/manifest.1dcac3f8.js></script>
</body>
</html>
所依賴的代碼已經自動注入html頁面中.
auto-inject-plugin插件地址:https://github.com/dragonnahs/auto-inject-plugin
Demo vue-multipage地址:https://github.com/dragonnahs/vue_multipage_build_optimize
《尤大大:Vue 3 正式進入 RC 階段 》
《前后端分離 Vue + NodeJS(Koa) + MongoDB實踐 》
《Vue.js的6個最佳表單生成器組件 》
《從Vue源碼角度深挖Watch、Computed 》
《Vue3全家桶 + Vite + TS + TSX嘗鮮,先人一步 》
《精讀《Vue3.0 Function API》 》
《手把手教你Electron + Vue實戰教程(六) 》
《Vue中mixin怎么理解? 》
《封裝一個精致vue視頻播放器組件》
《入口開始解讀Vue源碼系列(一)——造物創世》
《深入淺出探索 Vue 路由「值得收藏」》
《學會使用Vue JSX,一車老干媽都是你的》
《細聊Vue 3 系列之 JSX 語法》
《「速圍」尤雨溪詳細介紹 Vue 3 的最新進展》
《細聊single-spa + vue來實現前端微服務項目》
《前端新工具—vite從入門到實踐》
《一文帶你搞懂Vue3 底層源碼》
《9個優秀的 VUE 開源項目》
《細聊Single-Spa + Vue Cli 微前端落地指南「實踐」》
《通俗易懂的Vue異步更新策略及 nextTick 原理》
《通俗易懂的Vue響應式原理以及依賴收集》
《原生JS +Vue實現框選功能》
《Vue.js輪播庫熱門精選》
《一文帶你搞懂vue/react應用中實現ssr(服務端渲染)》
《Vue+CSS3 實現圖片滑塊效果》
《教你Vue3 Compiler 優化細節,如何手寫高性能渲染函數(上)》
《教你Vue3 Compiler 優化細節,如何手寫高性能渲染函數(下)》
《vue實現一個6個輸入框的驗證碼輸入組件》
《一用驚人的Vue實踐技巧「值得推薦」》
《Vue常見的面試知識點匯總(上)「附答案」》
《Vue常見的面試知識點匯總(下)「附答案」》
《Kbone原理詳解與小程序技術選型》
《為什么我不再用Vue,改用React?》
《讓Jenkins自動部署你的Vue項目「實踐」》
《20個免費的設計資源 UI套件背景圖標CSS框架》
《Deno將停止使用TypeScript,并公布五項具體理由》
《前端骨架屏都是如何生成的》
《Vue原來可以這樣寫開發效率杠杠的》
《用vue簡單寫一個音樂播放組件「附源碼」》
《為什么Vue3.0不再使用defineProperty實現數據監聽?》
《「干貨」學會這些Vue小技巧,可以早點下班和女神約會》
《探索 Vue-Multiselect》
《細品30張腦圖帶你從零開始學Vue》
《Vue后臺項目中遇到的技術難點以及解決方案》
《手把手教你Electron + Vue實戰教程(五)》
《手把手教你Electron + Vue實戰教程(四)》
《手把手教你Electron + Vue實戰教程(三)》
《手把手教你Electron + Vue實戰教程(二)》
《手把手教你Electron + Vue實戰教程(一)》
《收集22種開源Vue模板和主題框架「干貨」》
《如何寫出優秀后臺管理系統?11個經典模版拿去不謝「干貨」》
《手把手教你實現一個Vue自定義指令懶加載》
《基于 Vue 和高德地圖實現地圖組件「實踐」》
《一個由 Vue 作者尤雨溪開發的 web 開發工具—vite》
《是什么讓我愛上了Vue.js》
《1.1萬字深入細品Vue3.0源碼響應式系統筆記「上」》
《1.1萬字深入細品Vue3.0源碼響應式系統筆記「下」》
《「實踐」Vue 數據更新7 種情況匯總及延伸解決總結》
《尤大大細說Vue3 的誕生之路「譯」》
《提高10倍打包速度工具Snowpack 2.0正式發布,再也不需要打包器》
《大廠Code Review總結Vue開發規范經驗「值得學習」》
《Vue3 插件開發詳解嘗鮮版「值得收藏」》
《帶你五步學會Vue SSR》
《記一次Vue3.0技術干貨分享會》
《Vue 3.x 如何有驚無險地快速入門「進階篇」》
《「干貨」微信支付前后端流程整理(Vue+Node)》
《帶你了解 vue-next(Vue 3.0)之 爐火純青「實踐」》
《「干貨」Vue+高德地圖實現頁面點擊繪制多邊形及多邊形切割拆分》
《「干貨」Vue+Element前端導入導出Excel》
《「實踐」Deno bytes 模塊全解析》
《細品pdf.js實踐解決含水印、電子簽章問題「Vue篇」》
《基于vue + element的后臺管理系統解決方案》
《Vue仿蘑菇街商城項目(vue+koa+mongodb)》
《基于 electron-vue 開發的音樂播放器「實踐」》
《「實踐」Vue項目中標配編輯器插件Vue-Quill-Editor》
《基于 Vue 技術棧的微前端方案實踐》
《消息隊列助你成為高薪 Node.js 工程師》
《Node.js 中的 stream 模塊詳解》
《「干貨」Deno TCP Echo Server 是怎么運行的?》
《「干貨」了不起的 Deno 實戰教程》
《「干貨」通俗易懂的Deno 入門教程》
《Deno 正式發布,徹底弄明白和 node 的區別》
《「實踐」基于Apify+node+react/vue搭建一個有點意思的爬蟲平臺》
《「實踐」深入對比 Vue 3.0 Composition API 和 React Hooks》
《前端網紅框架的插件機制全梳理(axios、koa、redux、vuex)》
《深入Vue 必學高階組件 HOC「進階篇」》
《深入學習Vue的data、computed、watch來實現最精簡響應式系統》
《10個實例小練習,快速入門熟練 Vue3 核心新特性(一)》
《10個實例小練習,快速入門熟練 Vue3 核心新特性(二)》
《教你部署搭建一個Vue-cli4+Webpack移動端框架「實踐」》
《2020前端就業Vue框架篇「實踐」》
《詳解Vue3中 router 帶來了哪些變化?》
《Vue項目部署及性能優化指導篇「實踐」》
《Vue高性能渲染大數據Tree組件「實踐」》
《尤大大細品VuePress搭建技術網站與個人博客「實踐」》
《10個Vue開發技巧「實踐」》
《是什么導致尤大大選擇放棄Webpack?【vite 原理解析】》
《帶你了解 vue-next(Vue 3.0)之 小試牛刀【實踐】》
《帶你了解 vue-next(Vue 3.0)之 初入茅廬【實踐】》
《實踐Vue 3.0做JSX(TSX)風格的組件開發》
《一篇文章教你并列比較React.js和Vue.js的語法【實踐】》
《手拉手帶你開啟Vue3世界的鬼斧神工【實踐】》
《深入淺出通過vue-cli3構建一個SSR應用程序【實踐】》
《怎樣為你的 Vue.js 單頁應用提速》
《聊聊昨晚尤雨溪現場針對Vue3.0 Beta版本新特性知識點匯總》
《【新消息】Vue 3.0 Beta 版本發布,你還學的動么?》
《Vue真是太好了 壹萬多字的Vue知識點 超詳細!》
《Vue + Koa從零打造一個H5頁面可視化編輯器——Quark-h5》
《深入淺出Vue3 跟著尤雨溪學 TypeScript 之 Ref 【實踐】》
《手把手教你深入淺出vue-cli3升級vue-cli4的方法》
《Vue 3.0 Beta 和React 開發者分別杠上了》
《手把手教你用vue drag chart 實現一個可以拖動 / 縮放的圖表組件》
《Vue3 嘗鮮》
《總結Vue組件的通信》
《Vue 開源項目 TOP45》
《2020 年,Vue 受歡迎程度是否會超過 React?》
《尤雨溪:Vue 3.0的設計原則》
《使用vue實現HTML頁面生成圖片》
《實現全棧收銀系統(Node+Vue)(上)》
《實現全棧收銀系統(Node+Vue)(下)》
《vue引入原生高德地圖》
《Vue合理配置WebSocket并實現群聊》
《多年vue項目實戰經驗匯總》
《vue之將echart封裝為組件》
《基于 Vue 的兩層吸頂踩坑總結》
《Vue插件總結【前端開發必備】》
《Vue 開發必須知道的 36 個技巧【近1W字】》
《構建大型 Vue.js 項目的10條建議》
《深入理解vue中的slot與slot-scope》
《手把手教你Vue解析pdf(base64)轉圖片【實踐】》
《使用vue+node搭建前端異常監控系統》
《推薦 8 個漂亮的 vue.js 進度條組件》
《基于Vue實現拖拽升級(九宮格拖拽)》
《手摸手,帶你用vue擼后臺 系列二(登錄權限篇)》
《手摸手,帶你用vue擼后臺 系列三(實戰篇)》
《前端框架用vue還是react?清晰對比兩者差異》
《Vue組件間通信幾種方式,你用哪種?【實踐】》
《淺析 React / Vue 跨端渲染原理與實現》
《10個Vue開發技巧助力成為更好的工程師》
《手把手教你Vue之父子組件間通信實踐講解【props、$ref 、$emit】》
《1W字長文+多圖,帶你了解vue的雙向數據綁定源碼實現》
《深入淺出Vue3 的響應式和以前的區別到底在哪里?【實踐】》
《干貨滿滿!如何優雅簡潔地實現時鐘翻牌器(支持JS/Vue/React)》
《基于Vue/VueRouter/Vuex/Axios登錄路由和接口級攔截原理與實現》
《手把手教你D3.js 實現數據可視化極速上手到Vue應用》
《吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【上】》
《吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【中】》
《吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】》
《Vue3.0權限管理實現流程【實踐】》
《后臺管理系統,前端Vue根據角色動態設置菜單欄和路由》
作者:dragonnahs
轉發鏈接:https://segmentfault.com/a/1190000023289245
*請認真填寫需求信息,我們會在24小時內與您取得聯系。