Vueのアップグレードでエラー

どのバージョンで変わったか定かではないのだけど、アップグレード後エラーになって起動しなくなった。

変更点

vue.config.jsのエラーメッセージ

 ERROR  SyntaxError: Cannot use import statement outside a module
E:\Work\wtp\workspace\crawler-client\vue.config.js:1
import { defineConfig } from '@vue/cli-service'

import fromをrequireに変更した。

const { defineConfig } = require('@vue/cli-service')

babel.config.jsのエラーメッセージ

 ERROR  SyntaxError: Unexpected token 'export'
E:\Work\wtp\workspace\crawler-client\babel.config.js:1
export const plugins = {

export const pluginsをmodule.exportsに変更した。

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset'
  ]
}

Tempus dominus 4から6にアップグレードする

デフォルトの設定は下記ページのドキュメント参照のこと。
Tempus Dominus

以下は、自プロジェクト用に少し修正したもの。

インポートするJS、CSSファイル

Tempus dominus 4

<script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/js/tempusdominus-bootstrap-4.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.39.0/css/tempusdominus-bootstrap-4.min.css" />

Tempus dominus 6

<script src="https://cdnjs.cloudflare.com/ajax/libs/tempus-dominus/6.7.13/js/tempus-dominus.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempus-dominus/6.7.13/css/tempus-dominus.min.css" />

HTML

Tempus dominus 4と6で特に変更なし。

<label for="accountExpiredDate" th:text="#{user.accountExpiredDate}">user.accountExpiredDate</label>
<div class="input-group date" id="accountExpiredDatePicker" data-target-input="nearest">
  <input type="text" class="form-control datetimepicker-input" th:classappend="${#fields.hasErrors('accountExpiredDate')} ? is-invalid" th:field="*{accountExpiredDate}" th:placeholder="#{datetimepicker.format}" data-target="#accountExpiredDatePicker" />
  <div class="input-group-text" data-target="#accountExpiredDatePicker" data-toggle="datetimepicker">
    <em class="fas fa-calendar"></em>
  </div>
</div>

JavaScript

Tempus dominus 4

$('#accountExpiredDatePicker').datetimepicker({
  locale: 'ja',
  format: 'yyyy/MM/dd HH:mm',
})

Tempus dominus 6
※jQueryの使用は非推奨になった。

new tempusDominus.TempusDominus(document.getElementById('accountExpiredDatePicker'), {
  localization: {
    locale: 'ja',
    format: 'yyyy/MM/dd HH:mm',
  }
})

axios 0.27から1.4にアップグレードする

以下のコマンドで1.4.0にアップグレードする。

npm install axios@1.4.0

アップグレード後、自作プログラムのログイン画面で下記のエラーが発生するようになった。

TypeError: Cannot set properties of undefined (setting ‘Authorization’)

config.headers.common.Authorizationからcommon.を削除する必要があるらしく、問題の箇所を以下の通り修正した。

const instance = axios.create(defaultOptions)

instance.interceptors.request.use(function (config) {
  if (sessionStorage.getItem('crawler-client')) {
    const token = JSON.parse(sessionStorage.getItem('crawler-client')).auth.token;
-    config.headers.common.Authorization = token ? 'Bearer ' + token : ''
+    config.headers.Authorization = token ? 'Bearer ' + token : ''
  }
  return config
})

エラーは発生しなくなった。

ChatGPTを使ってみる

ちょっと試してみたくなった。

ユーザー登録

ユーザー登録だけで、今は無料で使用できる。最初に以下のページにアクセスし、「TRY CHATGPT」をクリックしてユーザー登録を行う。
https://openai.com/blog/chatgpt/

使ってみる

試しに「ChatGPTを上手に使うには?」と質問してみた。

ChatGPT:ChatGPTを上手に使うには以下のようなポイントがあります。

  1. 明確な質問をすること: ChatGPTには具体的な質問をすることが重要です。
  2. 十分な情報を提供すること: 質問に対する回答を最適化するために、できるだけ多くの情報を提供することが大切です。
  3. 自然な言語を使うこと: ChatGPTは人工知能モデルですが、自然な言語を使うことで、より正確な回答を得ることができます。
  4. 信頼性の高い情報ソースからの情報を求めること: ChatGPTはトレーニングデータに基づいていますが、常に正確な情報を保証することはできません。正確な情報を求める場合は信頼性の高い情報ソースからの情報を求めることをお勧めします。

対話式に質問を続けられるはすなので、さらに意地悪に質問を掘り下げてみた。

「ChatGPTからの回答が間違えている可能性はどのくらいあるのか?」

ChatGPT:ChatGPTはOpenAIによってトレーニングされた大規模な言語モデルですが、常に正確な回答を保証することはできません。トレーニングデータに基づいて回答を生成しますが、トレーニングデータに誤りが含まれていたり、最新の情報が含まれていなかったりする場合があります。また、ChatGPTは意図や文脈を正確に理解することもできない場合があります。そのため、ChatGPTからの回答を単独で信頼することは避け、常に他の情報源と照らし合わせて判断することが重要です。

「そうではなくて、間違いが含まれている可能性の具体的な数値を知りたい。」

ChatGPT:具体的な数値は提供されていませんが、ChatGPTは高精度の言語モデルであり、多くの場合、正確な回答を生成します。ただし、トレーニングデータに基づいているため、トレーニングデータに含まれていない情報や最新の情報に対する回答など、間違いが含まれる可能性があります。また、文脈や意図の誤りなどもありますので、常に他の情報源と照らし合わせて判断することが重要です。

「最新の情報ほど間違いが含まれている可能性が高いということか?」

ChatGPT:はい、そのような傾向があります。トレーニングデータは一定期間前の情報であり、最新の情報は含まれていない可能性があります。また、最新の情報はまだ完全には明らかでない場合もありますので、正確性が低い可能性があります。そのため、最新の情報に関する質問に対しては特に他の情報源と照らし合わせて確認することが重要です。

まとめ

同じような回答になってしまっているところもあるが、自然に会話しているように文章が繋がっている。本当にすごいツールが出てきたと思う。

Nuxt 3が出たので使ってみる

動機

Vue 3に対応したNuxt 3がリリースされたので、早速使ってみる。

ゴール

以前作成した下記のアプリと同等の機能を実装する。すでに、Vue3対応は完了しているため、大きな変更は必要ないはず。
https://github.com/hide6644/crawler-client

今回はインストールまで行う。インストール途中に「

ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time

」のワーニングが表示されるが、今は気にしても仕方がないので、無視する。

インストール

実行環境
Windows 11
node 18

npx nuxi init プロジェクト名
cd プロジェクト名
npm install

実行

npm run dev

実行後、http://localhost:3000/にアクセスすると、welcomeページが表示される。

開発環境

開発環境には、Visual Studio Codeを使用する。インストール済みであれば、先ほどのインストールフォルダで、「code ./」を実行すると即座に起動できる。
(プラグインVolar ExtensionTypeScript Vue Plugin (Volar)のインストール推奨)

WordPressのパーマリンクに日付や投稿名を指定すると404になる場合の対処法

新規に環境を構築したとき、いつものようにパーマリンクを日付と投稿名にすると、リンクが404エラーになってしまうことがある。リンクに日付や投稿名を設定する機能はmod_rewriteによって実行されているため、以下の通り有効にする必要がある。

mod_rewriteの有効化

sudo a2enmod rewrite

.htaccessを使った設定の上書きを許可

httpd.conf内の該当Directory設定のAllowOverrideをallに変更する。

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride all
	Require all granted
</Directory>

さらに、Wordpressをインストールしたフォルダの書き込み権限があることを確認する。Wordpressによってフォルダ下の.htaccessにrewriteの設定が自動的に作成されることになるため、書き込み権限が必要になる。

例えばパーマリンクを日付と投稿名に変更すると、下記のように.htaccessが自動生成される。

# BEGIN WordPress
# "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
# 動的に生成され、WordPress フィルターによってのみ修正が可能です。
# これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /wordpress/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
</IfModule>

# END WordPress

Tempus Dominus Bootstrap Ver.5とFont Awesome Ver.5を同時に使用する

Font Awesome Ver.5を使用している場合、Tempus Dominus Bootstrapのdatetimepickerの時間アイコンが表示されない。表示されない理由はVer.4以前で使用していたアイコン「fa-clock-o」がVer.5から「fa-clock」に変わっているため。

そこで、以下の通り新しいアイコンを直接指定するように修正する。

$('#accountExpiredDatePicker').datetimepicker({
  icons: {
    time: 'fas fa-clock',
    date: 'fas fa-calendar',
    up: 'fas fa-arrow-up',
    down: 'fas fa-arrow-down'
  }
})
<div class="input-group date" id="accountExpiredDatePicker" data-target-input="nearest">
  <input type="text" class="form-control datetimepicker-input" th:classappend="${#fields.hasErrors('accountExpiredDate')} ? is-invalid" th:field="*{accountExpiredDate}" th:placeholder="#{datetimepicker.format}" data-target="#accountExpiredDatePicker" />
  <div class="input-group-append" data-target="#accountExpiredDatePicker" data-toggle="datetimepicker">
    <div class="input-group-text"><em class="fas fa-calendar"></em></div>
  </div>
</div>