前言
最近自己的 MediaWiki 網站有渲染列表的需求,但眾所周知,MediaWiki 是基於 jQuery 庫開發的專案,雖然 MediaWiki 官方對於 Vue 等新興前端框架持積極態度,而維基百科在數年前也採用 Vue 進行開發,但是對於解決我們的需求沒有實際的幫助。
另一點是,MediaWiki 對於單獨一個頁面的定製化的做的不太完善,在頁面裡新增 CSS 還需要新增擴充套件(如透過解析器引入 CSS 的 Extension:CSS 或支援在模板名稱空間下新增 CSS 檔案的 Extension:TemplateStyles ),否則只能在 MediaWiki:Common.css 或其他全域性 CSS。而 JavaScript 雖然也是一樣的在 MediaWiki:Common.js 這種全域性 JS 頁面內新增,但也沒有什麼擴充套件支援單獨引入 JS 到頁面內的。另外,即便可以在 MediaWiki 名稱空間新建 .css
或 .js
字尾的頁面以儲存程式碼,但對程式碼的引入也比較麻煩(解決方案就是在全域性 JS 裡面加個分支,判斷是哪個頁面就跳到哪裡去,辦法有點鬼233,好奇可以看我另一個文章)。
(類似的知識庫系統 Wiki.js 框架原生支援對單獨頁面定製化,包括 CSS 和 HTML 標籤新增,雖然 Wiki.js 用起來比較難受而且很多功能拖了很久,但是頁面的客製化還是可以的)
思路
- 如果你熟悉 Webpack 打包的配置或者理的清楚路徑相關的內容,那就不用看的很仔細啦!
這篇文章有個前提,就是你能完全掌握自己的 MediaWiki,至少要能在網站根目錄新建檔案,並且有足夠的使用者許可權修改 MediaWiki 內部的內容(至少介面管理員)。
那麼說回正題,應該咋實現呢?觀察一下可以發現,前端專案打包檔案結構都是 index.html 配上幾個名為 css 或者 js 或者 images 的資料夾。打包後的 index.html 裡面無非也就這幾樣東西:Vue 的掛載點 #app、打包後的 JS,如 vendor.js 和 app.js、壓縮後的 CSS,如 app.css 之類的。放個我最近打包的專案的 index.html 做為示例:
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/favicon.ico">
<title>hydcraft-startpage</title>
<script defer="defer" src="/js/chunk-vendors.db4b2f88.js"></script>
<script defer="defer" src="/js/app.9d35b8e4.js"></script>
<link href="/css/app.8be8ea5f.css" rel="stylesheet">
</head>
<body>
<noscript>
<strong>HydCraft Startpage required JavaScript. Please enable it to continue. :)<br>If you see it in DevTools, Never mind.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
那麼我們是不是要把 MediaWiki 頁面的容器當成 index.html 就好了呢?!在 MediaWiki 的頁面中留好掛載點 #app <div id="app"></div>
,引入 JS 和 CSS 檔案就都好了!而 MediaWiki 的文件中,資源載入器剛好就有載入外部檔案的方法。即:
// 給入一個連結和 MIME 型別引數就好了
mw.loader.load( 'http://example.com/mystyles.css?color=blue', 'text/css' ); // 載入 CSS
mw.loader.load( 'http://example.com/myscript.js', 'text/javascript' ); // 載入 JS
// 其實還有個只能引入 Wiki 頁面的方法 importScript('pageName')
importScript('MediaWiki:Script.js'); // 引入 MediaWiki:Script.js 頁面的 JS 檔案
那麼實現起來就很清晰了,只需要在要引入的頁面留好掛載點;把打包完的專案引入,就大功告成了!但是 JS 檔案如果很多一個一個匯入會不會很麻煩?那讓它打包的時候不要分塊不就好了!理論可行開始實現。
實現
假設我希望在 Lemon 頁面載入 Vue 專案程式碼;站點域名為 https://wiki.example.cn;上傳的路徑點為 https://wiki.example.cn/static/list/。
-
建立專案,我自己是用 Vue CLI 建了一個 Vue 2 + JS 的專案,但是從實現方式來看就算是 React、Angular 或者是你自己寫的什麼東西都行。
-
控制 JS 和 CSS 打包的時候不分塊。由於我是 Vue CLI 建立的專案自然而然就是在
vue.config.js
中改了,如果是 Webpack 直接建的在webpack.config.js
修改即可,效果一樣。
module.exports = defineConfig({
productionSourceMap: false,
transpileDependencies: true,
publicPath: '/static/list/', // 這個的控制看步驟二,這個是公共路徑,如果你打包的檔案有字型或者圖片,那麼在 CSS 裡他們的路徑前面會加個這個
configureWebpack: {
optimization: {
splitChunks: false,
runtimeChunk: false
},
output: {
filename: "bundle.js", // JS 輸出的檔名,要改名字可以看你需求改
},
},
css: {
extract: {
filename: "styles.css" // CSS 的檔名
}
}
});
另外,如果希望儘量減少打包出的 JS 檔案(如果有其他的會單獨建立一個 js 資料夾),那麼專案裡引入元件的時候就不要使用動態引入,使用靜態引入。
- 確定要上傳的地方。
此時,把打包好的檔案上傳到你要上傳的地方,把步驟一中的配置檔案的 publicPath 修改成對應的路徑:
如果是 MediaWiki 站點的目錄,那麼不需要把 URL 全部寫出來(畢竟呼叫同域的資源)。舉個例子,我的站點域名是 www.example.wiki,對應的路徑是 /www/wwwroot/example.wiki。我打算把打包後的內容上傳到 /www/wwwroot/example.wiki/static/ 目錄下,對應的 URL 即 www.example.wiki/static/ 下。那麼 publicPath 就需要改成 /static/
,上傳後的 JS 檔案就是 www.example.wiki/static/bundle.js。CSS 檔案同理。
如果是其他的站點,那麼則需要把 URL 寫全了。舉個例子,我把打包後的東西放 https://static.example.com/wiki/,那麼 publicPath 就需要改成 https://static.example.com/wiki/
。呼叫 JS 檔案的時候也就是 https://static.example.com/wiki/bundle.js,CSS 檔案也同理。不過,如果是外部站點,那麼需要注意下跨域的配置是否正常,一般建議直接放到 MediaWiki 站點內部(因為我就這麼幹的,省事,都可以啦看你自己)。
當然!如果你瞭解 publicPath 和各種路徑之間的關係,那就不用那麼複雜的看這個介紹,自己相應的修改即可。
-
打包和上傳檔案到對應的位置。
-
在 MediaWiki 配置相應的內容。
我們需要在 Lemon 頁面新增內容,那麼首先透過原始碼編輯,在這個頁面新增一個<div id="app"></div>
掛載點(主要看打包後的 index.html 裡面是什麼元素,如果你修改了預設掛載點名字那這裡也需要改。一般 Vue 是 #app,React 是 #root)。隨後在 MediaWiki:Common.js(如果你不想放全域性裡面呼叫,可以放到其他頁面去,具體可以看另一篇文章)新增以下內容:
mw.loader.load( 'https://wiki.example.cn/static/list/bundle.js', 'text/javascript' );
mw.loader.load( 'https://wiki.example.cn/static/list/styles.css', 'text/css' );
這裡我寫了兩條,一個是 bundle.js 另一個是 styles.css。實際上就是把打包後的 index.html 內部呼叫的 CSS 和 JS 變成 MediaWiki 呼叫外部資源的方法就可以了!
當然,其實不用每次都看 index.html 裡面的內容,一般打包完就會告訴你有幾個檔案,看那裡基本就能確定了。
此時就大功告成了,直接開啟對應的頁面檢查結果就好了。
(字型和圖片不用引入,因為打包後都在 JS 或者 CSS 裡了,他們的路徑是跟著 publicPath 來的)
後話
想不到什麼要說的,如果上傳了一次以後又覆蓋上傳了,在對應的頁面測試的時候記得 Ctrl+F5 重新整理快取測試(?)。