首頁
文章
隱私
  • 繁體中文
  • 简体中文
首頁
文章
隱私
  • 繁體中文
  • 简体中文

【開發筆記】VuePress 2 那些編譯起來的奇怪事

為了獲得主題顏色暗模式(Dark Mode)的支援,最近把使用很久的 VuePress 從 1.0 更新到 2.0 RC。雖然 2.0 RC 不是最終版本,但是預計未來底層架構的更動應該不會有太大的變化,既然早晚都是要更新的,所以就這樣壯烈的入了坑...

Cannot use import statement outside a module

說壯烈或許有點誇大。不過最大的困擾,就是別人的解方通通不適用於自己的情況。從錯誤的提示,會讓人單純以為是 CommonJS vs ES6 的問題。所以試過在 package.json 中加上 "type": "module",也調整過副檔名(extension)從 .js 變成 .mjs。甚至受到影響的 module,也嘗試過把源碼結構在引入時,從 import ... from 改成 const ... require。而在輸出的部分,也從 export ... 改成 module.exports。

// 修改前(ES6)
import { ... } from './...';
...
..
.
export default { ... };

// 修改後(CommonJS)
const { ... } = require('./...');
...
..
.
module.exports = { ... };

沒有意外,以上的嘗試通通都沒有順利地解決問題,不然這篇筆記也不用寫了。最後是把默認的 bundler 從 vite 改成 webpack 才獲得解決。不過 vuepress 使用 webpack 做 bundler 需要在 config.js 內做額外的設定。另外,整個專案編譯所需的時間也因此增加了不少。

import { webpackBundler } from '@vuepress/bundler-webpack'

export default defineUserConfig({
    ...,
    bundler: webpackBundler({
        postcss: {},
        vue: {},
    }),
    ...,
}

$router 組件外取值

在組件內或是 .vue 中來說,我們要取得路由的查詢參數只要 $router.currentRoute.query 就可以了。但是組件外,例如 markdown 文件中要取得查詢參數,則需要做一點小小變化 $router.currentRoute.value.query 才行。算是附帶一提的小插曲。

留意 ref 對象的存在有可能是浮動的

最後這點就真的很燒腦了。過程中無論是開發環境或是生產環境,編譯時都沒有出現任何錯誤提示,實際在操作上也沒有任何異常。不過部署後整合測試卻通過不了。深究其原因發現 $ref 參照的對象調用得太早,此時元件對象還沒有真正地生成被加到頁面中,導致 focus 無法被設置到不存在的輸入元件。目前是在調用 focus 時,刻意加上延遲來獲得解決。

<template>
    ...
        <input ref="search" ... />
    ...
</template>

<scripts>
...
mounted() {
    // 加上一個延遲來確保 ref 對象存在
    setTimeout(() => {
        this.setFocusInput();
    }, 600);
},
methods: {
    setFocusInput() {
        const search = this.$refs.search;
        // 需要檢查 ref 和 element 可能為 undefined
        if (!search || !search.$el) {
            return;
        }
        search.$el.focus();
    }
}
...
</scripts>