小議webpack下的AOP式無侵入註入

来源:http://www.cnblogs.com/zhuanzhuanfe/archive/2017/11/11/7775320.html
-Advertisement-
Play Games

說起來, 面向切麵編程(AOP)自從誕生之日起,一直都是電腦科學領域十分熱門的話題,但是很奇怪的是,在前端圈子裡,探討AOP的文章似乎並不是多,而且多數拘泥在給出理論,然後實現個片段的定式)難免陷入了形而上學的尷尬境地,本文列舉了兩個生產環境的實際例子論述webpack和AOP預編譯處理的結合,意 ...


說起來, 面向切麵編程(AOP)自從誕生之日起,一直都是電腦科學領域十分熱門的話題,但是很奇怪的是,在前端圈子裡,探討AOP的文章似乎並不是多,而且多數拘泥在給出理論,然後實現個片段的定式)難免陷入了形而上學的尷尬境地,本文列舉了兩個生產環境的實際例子論述webpack和AOP預編譯處理的結合,意在拋磚引玉。當然,筆者能力有限,如果有覺得不妥之處,還請大家積極的反饋出來, 共同進步哈。

重要的概念

AOP: 面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。

Joint point:表示在程式中明確定義的點,典型的包括方法調用,對類成員的訪問以及異常處理程式塊的執行等等,它自身還可以嵌套其它 joint point。

Advice:Advice 定義了在 pointcut 裡面定義的程式點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之後還是代替執行的代碼。

通過前面的定義,我們可以提煉出一句更簡單的定義,利用靜/動態的方式使代碼塊在何時/何地運行。

性能統計

項目的背景是一個利用vue+webpack打造的多頁面應用 (多入口點),她的結構大概是這個樣子的

var baseConf = {
// code here
entry: {
index: 'src/index',
list: 'src/list',
detail: 'src/detail',
// and so on ...
},
// code here
}

 

然後以index入口點舉例,大概代碼為src/index/index.js

import Vue from 'vue'
import App from './app'
new Vue({
el: '#app',
render: h => h(App)
})

 

期望引入一個vue插件,能夠自動的監控當前頁面的性能,於是,代碼看起來像是這個樣子

import Vue from 'vue'
Vue.use(performance) //性能統計
import App from './app'
new Vue({
el: '#app',
render: h => h(App)
})

 

由於這種方式意味著每個入口點均需要進行修改,(實際上這個項目的入口點超過30個,而且隨時可能繼續增加下去)簡直就是一個體力活。所以,讓我們用AOP的思想來考慮一下如何處理這個問題

首先觀察入口點邏輯

原:引入vue -> 引入app組件 -> 實例化vue組件

新:引入vue -> 應用性能統計組件 -> 引入app組件 -> 實例化vue組件

套用到我們的定義上,可以輕鬆的得到

  • Joint point(何處) 引入vue
  • advice(何時) 之後

這樣理論上的東西似乎閉著眼睛都可以推論出來,但是如何將這樣的步驟替換到每一個入口點就是一個大問題了orz。幸運的是這是一個import,而翻閱webpack的文檔恰好有著這樣一個神奇的屬性--alias

resolve: {
alias: {
'vue$': resolve('src/vueHook.js')
}

 

src/vueHook.js

import vue from 'vue/dist/vue.common'
vue.use(performance)
export default vue

 

這樣,我們就完成了一個vue的全局鉤子模塊,我們按照步驟歸納,並且找到註入的位置 ,最後利用替換的方式成功的完成了無侵入式的組件應用

code spliting

可能上面的例子有點小打小鬧的感覺,那麼我們換一個案例,再來體驗一下這種靜態替換式的註入的威力,我們採用官方支持較差的react作為參考(vue在code spliting方面做得真心是超級棒~)

import SingleImage from '../../component-modules/magic-single-image/src/index';
import DoubleImage from '../../component-modules/magic-double-image/src/index';
import ThreeImage from '../../component-modules/magic-three-image/src/index';
// many component here
switch (componentName) {
case 'SingleImage':
PreviewingComponent = SingleImage;
break;
case 'DoubleImage':
PreviewingComponent = DoubleImage;
break;
case 'ThreeImage':
PreviewingComponent = ThreeImage;
break;
// many component here
}
return(<PreviewingComponent></PreviewingComponent>)

 

一段中規中矩的代碼,對吧?相信大家已經發現了,在上述的代碼裡面似乎並不是每個組件都是必須的,那麼,基於以上的思考,可以對上面組件進行按需載入處理。 Bundle.jsx

import React, { Component, PropTypes } from 'react';
class Bundle extends Component {
static propTypes = {
load: PropTypes.func,
children: PropTypes.func,
}
state = {
mod: null,
}
componentWillMount() {
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps);
}
}
load(props) {
this.setState({
mod: null,
});
props.load().then((mod) => {
this.setState({
// handle both es imports and cjs
mod: mod.default ? mod.default : mod,
});
});
}
render() {
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
export default Bundle;

 

以及相應的alias hook

export default (
<Bundle
load={() => import(/* webpackChunkName: "widget" */
`../../component-modules/magic-single-image/src/index`
)}
>
{Widget => <Widget {...props} />}
</Bundle>
)

 

思考,當組件多的時候每一個模塊都需要一個人口點嗎,可以從webpack.context角度簡化這個問題嗎?

以上兩個例子均是模塊引用作為join point來進行註入操作的,而且完成了無侵入式的功能增強,這得益於webpack將js模塊作為一等公民。我們擁有著超多的權利完成靜態式的註入工作。 本文並沒有在技術上涉及太多,還是那句話,拋磚引玉哈~~~

 

 如果你喜歡我們的文章,關註我們的公眾號和我們互動吧。

 

我們是轉轉FE團隊,歡迎大家關註公眾號 大轉轉FE 。更多的瞭解我們。官網 http://zzfe.org
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • DTOJ 2704:數字互換 解題報告 2017.11.11 第一版 ——由翱翔的逗比w原創 題目信息: 題目描述 輸入兩個數作為交換數,輸出已交換順序後的兩個值。 輸入兩個數作為交換數,輸出已交換順序後的兩個值。 輸入 兩個整數,空格隔開 兩個整數,空格隔開 輸出 交換後的兩個整數,空格隔開 交換 ...
  • #include #define uint unsigned int #define uchar unsigned char sbit wei=P2^7; sbit duan=P2^6; sbit key1=P3^4; sbit key2=P3^5; sbit key3=P3^6; uchar co... ...
  • 本文主要針對Mac的jdk的安裝、環境變數配置、jdk卸載方面進行方法總結。 ...
  • 前言 - 思考還是 socket 寫過一點點, 總感覺很彆扭. 例如 read, recv, recvfrom 這些為啥這麼奇葩. 這是 linux 的設計嗎. 這種強糅合的 read 代碼, '帶壞'了多少人. 想起很久以前看過的 <<UNIX痛恨者手冊>>, 外加上常寫點跨平臺 庫. 不得不思考 ...
  • 、`const`關鍵字 在 之前, 中變數預設是全局性的,只存在函數級作用域,聲明函數曾經是創造作用域的唯一方法。這點和其他編程語言存在差異,其他語言大多數都存在塊級作用域。所以在 中,新提出的 和 關鍵字使這個缺陷得到了修複。 同時還引入的概念 ,用來定義一個常量,一旦定義以後不可以修改,如果是引 ...
  • 數組去重 function getSingle (arr) { var res = []; var jj = {}; for (i = 0; i < arr.length; i++) { if(!jj[arr[i]]) { res.push(arr[i]); jj[arr[i]] = 1; } } ...
  • 最近面試拿了很多公司的實習offer,只要是面試的都通過了,但其實目標是BTA或者到一個公司的核心技術部,無奈將這些公司一一拒絕。 接下來就分析下麵試題,也能給自己一個提升吧,以便後續的面試更輕車熟路些,題目沒什麼順序,想起什麼寫什麼,還有我面試過程中的一些小套路。 估計要寫好多,每天寫幾道題,而且 ...
  • 前言 深入瞭解一下表格的一些特性。 一、案例需求 首先寫一個表格,然後讓表格隔行換色,具體的效果如下所示: 那麼要怎麼實現呢? 二、實例分析 首先我們需要知道,之前我們學習過表格相關的標簽,但是那時候學習的,只有<table></table>、<tr></tr>、<td></td>等標簽,但是表格的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...