Vue.jsの管理画面の雛型が存在してた模様。あと、Veturが非推奨になっていくらしい

www.theregister.com

Microsoft Azureの資源が足りてないんか...

既存顧客優先ってことは、新規顧客の機会損失が甚大になりそうな気がしますかね...

Vue.jsで管理画面の雛型が存在してた模様

何かと仕様が分かり辛いVue.jsですが、

panjiachen.github.io

github.com

⇧ 管理画面の雛型が用意されてる模様。

TypeScript対応バージョンについては、

github.com

⇧ 別の方が作ってくれてらっしゃる、ありがたや~。

エラーになるけど...

で、動かしてみようとしたところ、見事に、エラーになってくれますと...

ログを抜粋してみました。

10898 verbose stack Error: command failed
10898 verbose stack     at ChildProcess.<anonymous> (C:\Users\Toshinobu\AppData\Roaming\nvm\v16.13.1\node_modules\npm\node_modules\@npmcli\promise-spawn\index.js:64:27)
10898 verbose stack     at ChildProcess.emit (node:events:390:28)
10898 verbose stack     at maybeClose (node:internal/child_process:1064:16)
10898 verbose stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5)
10899 verbose pkgid fibers@5.0.0
10900 verbose cwd C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-typescript-admin-template
10901 verbose Windows_NT 10.0.19043
10902 verbose argv "C:\\nodejs\\node.exe" "C:\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "--save-dev" "--legacy-peer-deps"
10903 verbose node v16.13.1
10904 verbose npm  v8.1.2
10905 error code 1
10906 error path C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-typescript-admin-template\node_modules\fibers
10907 error command failed
10908 error command C:\WINDOWS\system32\cmd.exe /d /s /c node build.js || nodejs build.js
10909 error gyp info it worked if it ends with ok
10909 error gyp info using node-gyp@8.3.0
10909 error gyp info using node@16.13.1 | win32 | x64
10909 error gyp info find Python using Python version 3.10.0 found at "C:\Users\Toshinobu\AppData\Local\Programs\Python\Python310\python.exe"
10909 error gyp info find VS using VS2017 (15.9.28307.1778) found at:
10909 error gyp info find VS "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools"
10909 error gyp info find VS run with --verbose for detailed information
10909 error gyp info spawn C:\Users\Toshinobu\AppData\Local\Programs\Python\Python310\python.exe
10909 error gyp info spawn args [
10909 error gyp info spawn args   'C:\\Users\\Toshinobu\\AppData\\Roaming\\nvm\\v16.13.1\\node_modules\\npm\\node_modules\\node-gyp\\gyp\\gyp_main.py',
10909 error gyp info spawn args   'binding.gyp',
10909 error gyp info spawn args   '-f',
10909 error gyp info spawn args   'msvs',
10909 error gyp info spawn args   '-I',
10909 error gyp info spawn args   'C:\\Users\\Toshinobu\\Desktop\\soft_work\\vue_work\\vue-typescript-admin-template\\node_modules\\fibers\\build\\config.gypi',
10909 error gyp info spawn args   '-I',
10909 error gyp info spawn args   'C:\\Users\\Toshinobu\\AppData\\Roaming\\nvm\\v16.13.1\\node_modules\\npm\\node_modules\\node-gyp\\addon.gypi',
10909 error gyp info spawn args   '-I',
10909 error gyp info spawn args   'C:\\Users\\Toshinobu\\AppData\\Local\\node-gyp\\Cache\\16.13.1\\common.gypi',
10909 error gyp info spawn args   '-Dlibrary=shared_library',
10909 error gyp info spawn args   '-Dvisibility=default',
10909 error gyp info spawn args   '-Dnode_root_dir=C:\\Users\\Toshinobu\\AppData\\Local\\node-gyp\\Cache\\16.13.1',
10909 error gyp info spawn args   '-Dnode_gyp_dir=C:\\Users\\Toshinobu\\AppData\\Roaming\\nvm\\v16.13.1\\node_modules\\npm\\node_modules\\node-gyp',
10909 error gyp info spawn args   '-Dnode_lib_file=C:\\\\Users\\\\Toshinobu\\\\AppData\\\\Local\\\\node-gyp\\\\Cache\\\\16.13.1\\\\<(target_arch)\\\\node.lib',
10909 error gyp info spawn args   '-Dmodule_root_dir=C:\\Users\\Toshinobu\\Desktop\\soft_work\\vue_work\\vue-typescript-admin-template\\node_modules\\fibers',
10909 error gyp info spawn args   '-Dnode_engine=v8',
10909 error gyp info spawn args   '--depth=.',
10909 error gyp info spawn args   '--no-parallel',
10909 error gyp info spawn args   '--generator-output',
10909 error gyp info spawn args   'C:\\Users\\Toshinobu\\Desktop\\soft_work\\vue_work\\vue-typescript-admin-template\\node_modules\\fibers\\build',
10909 error gyp info spawn args   '-Goutput_dir=.'
10909 error gyp info spawn args ]
10909 error gyp: C:\Users\Toshinobu\AppData\Local\node-gyp\Cache\16.13.1\common.gypi not found (cwd: C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-typescript-admin-template\node_modules\fibers) while reading includes of binding.gyp while trying to load binding.gyp
10909 error gyp ERR! configure error
10909 error gyp ERR! stack Error: `gyp` failed with exit code: 1
10909 error gyp ERR! stack     at ChildProcess.onCpExit (C:\Users\Toshinobu\AppData\Roaming\nvm\v16.13.1\node_modules\npm\node_modules\node-gyp\lib\configure.js:261:16)
10909 error gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
10909 error gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
10909 error gyp ERR! System Windows_NT 10.0.19043
10909 error gyp ERR! command "C:\\nodejs\\node.exe" "C:\\Users\\Toshinobu\\AppData\\Roaming\\nvm\\v16.13.1\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--release"
10909 error gyp ERR! cwd C:\Users\Toshinobu\Desktop\soft_work\vue_work\vue-typescript-admin-template\node_modules\fibers
10909 error gyp ERR! node -v v16.13.1
10909 error gyp ERR! node-gyp -v v8.3.0
10909 error gyp ERR! not ok
10909 error node-gyp exited with code: 1
10909 error Please make sure you are using a supported platform and node version. If you
10909 error would like to compile fibers on this machine please make sure you have setup your
10909 error build environment--
10909 error Windows + OS X instructions here: https://github.com/nodejs/node-gyp
10909 error Ubuntu users please run: `sudo apt-get install g++ build-essential`
10909 error RHEL users please run: `yum install gcc-c++` and `yum groupinstall 'Development Tools'`
10909 error Alpine users please run: `sudo apk add python make g++`
10909 error 'nodejs' �́A�����R�}���h�܂��͊O���R�}���h�A
10909 error ����\�ȃv���O�����܂��̓o�b�` �t�@�C���Ƃ��ĔF������Ă��܂���B
10910 verbose exit 1

⇧ 文字化けどうにかして欲しい...

で、エラーの原因はというと、

teratail.com

なのでnpm installのタイミングでCやC++ソースコードコンパイルして実行形式にする作業が挟まります。
この橋渡しをしてくれるのがnode-gypです。

npm installをしたら発生するエラー

⇧ 上記サイト様によりますと、node-gypってのが失敗してますと。

自分の場合は、「fibers」ってライブラリでエラーが起こってたので、調べたところ、

mykii.blog

If you are running 64-bit nodejs version 12.x or 14.x on Linux, OS X, or Windows (7 or later) then you should be able to install fibers from npm just fine. 

fibers v5 はまだ Node.js v16に対応していない。 | eureka

⇧ 上記サイト様によりますと、Node.jsのバージョンの問題のようです。

自分の環境を確認してみると、Node.jsのバージョンが16.13.1だったので対応してるバージョンをインストールすることに。

⇧ 失敗してるけど...

issueが上がってました。

github.com

Solutions : nvm use 14.19.0 its got installed successfully

https://github.com/coreybutler/nvm-windows/issues/799

⇧ まさかのバグ...LTS(Long Time Support)の意味ない...

 アンインストールして、14.19.0をインストール。

改めて、トライ。

開発系のサーバーを起動で。

ファイアウォールでブロックされる場合は、「アクセスを許可する(A)」で。

なんか、ERROR出るんやけど...

何やら、

github.com

⇧ webpackのバージョン下げれば動くと。

■変更前

"webpack": "^5.30.0"    

■変更後

"webpack": "^4.45.0"    

で、webpackをインストールし直して、

再度、開発用サーバーを起動。

⇧ むっちゃエラーが出てはいますが、「Object is possibly ’undefined’」ってことは、TypeScriptの型の問題ってことですかね...

それとも、型チェックとかしてるVeturが悪さしてるんだろうか...

engineers-blog.agest.co.jp

Vue.js といえば vscode 拡張機能の Vetur が有名でしたが、今後は Volar が推奨されるようです。Vue.js の開発者である Evan You 氏曰く Volar が Vue2 のサポートを行なったタイミングで Vetur は非推奨になるとのこと。

2022年のVue3推奨開発環境 - AGEST Engineers Blog

Vetur では Typescript サポートに対応するのが難しい状況だったのと、開発者の方が活動を停止してしまったのがきっかけで Volar が生まれたとコメントがありました。

2022年のVue3推奨開発環境 - AGEST Engineers Blog

⇧ あり得そうね...

どちらにしろ、Veturは非推奨になっていくらしいので、Volarってほうに移行していく必要はありそう。

で、エラーは出まくってますが、一応、アクセスはできました。

Ctrl + C で開発用サーバー停止。

まぁ、何て言うか、ライブラリの依存関係の問題って、サーバーサイドもフロントエンドも変わらず悩ましてくれますな...

パッケージ管理の意味をなしてないんだよな...

毎度モヤモヤ感が半端ない...

2022年10月19日(水)追記:↓ ここから

yarnだとエラーなく動作しました。

Mock serverが9528ポートで開始ってなってるけど、アクセスしたら404になったので、Mock serverの役割はよく分かりません...

ちなみに、利用してるNode.jsのバージョンは、v14.19.0です。

2022年10月19日(水)追記:↑ ここまで

2022年10月20日(木)追記:↓ ここから

Mock serverは、おそらく、axiosなんかの飛び先で利用してる模様。あと、package.jsonを確認したら、コマンドを並列に実行してて、Mock serverは並列で起動してるらしい、たぶん...

■vue-typescript-admin-template/package.json

{
  "name": "vue-typescript-admin-template",
  "version": "1.0.0",
  "private": true,
  "author": "Chong Guo <armourcy@gmail.com>",
  "scripts": {
    "serve": "concurrently \"npm:mock\" \"vue-cli-service serve\"",
    "test:unit": "jest --clearCache && vue-cli-service test:unit",
    "lint": "vue-cli-service lint",
    "build:prod": "vue-cli-service build",
    "build:stage": "vue-cli-service build --mode staging",
    "svg": "vsvg -s ./src/icons/svg -t ./src/icons/components --ext ts --es6",
    "mock": "cd mock && ts-node-dev mock-server.ts"
  },
  "dependencies": {
    "@tinymce/tinymce-vue": "^3.2.6",
    "@toast-ui/editor": "^2.5.1",
    "axios": "^0.21.1",
    "clipboard": "^2.0.8",
    "codemirror": "^5.60.0",
    "core-js": "^3.10.0",
    "cors": "^2.8.5",
    "driver.js": "^0.9.8",
    "echarts": "^5.0.2",
    "element-ui": "^2.15.1",
    "faker": "^5.5.2",
    "file-saver": "^2.0.5",
    "fuse.js": "^6.4.6",
    "js-cookie": "^2.2.1",
    "jsonlint": "^1.6.3",
    "jszip": "^3.6.0",
    "lodash": "^4.17.21",
    "morgan": "^1.10.0",
    "normalize.css": "^8.0.1",
    "nprogress": "^0.2.0",
    "path-to-regexp": "^6.2.0",
    "register-service-worker": "^1.7.2",
    "screenfull": "^5.1.0",
    "script-loader": "^0.7.2",
    "sortablejs": "^1.13.0",
    "tinymce": "^5.7.1",
    "vue": "^2.6.12",
    "vue-class-component": "^7.2.6",
    "vue-count-to": "^1.0.13",
    "vue-i18n": "^8.24.2",
    "vue-image-crop-upload": "^2.5.0",
    "vue-property-decorator": "^9.1.2",
    "vue-router": "^3.5.1",
    "vue-splitpane": "^1.0.6",
    "vue-svgicon": "^3.2.9",
    "vue2-dropzone": "^3.6.0",
    "vuedraggable": "^2.24.3",
    "vuex": "^3.6.2",
    "vuex-module-decorators": "^1.0.1",
    "xlsx": "^0.16.9",
    "yamljs": "^0.3.0",
    "yarn": "^1.22.19"
  },
  "devDependencies": {
    "@types/clipboard": "^2.0.1",
    "@types/codemirror": "^0.0.108",
    "@types/compression": "^1.7.0",
    "@types/cors": "^2.8.10",
    "@types/express": "^4.17.11",
    "@types/faker": "^5.5.0",
    "@types/file-saver": "^2.0.1",
    "@types/jest": "^26.0.22",
    "@types/js-cookie": "^2.2.6",
    "@types/lodash": "^4.14.168",
    "@types/morgan": "^1.9.2",
    "@types/node": "^14.14.37",
    "@types/nprogress": "^0.2.0",
    "@types/sortablejs": "^1.10.6",
    "@types/tinymce": "^4.6.0",
    "@types/vue-splitpane": "^1.0.1",
    "@types/vuedraggable": "^2.23.2",
    "@types/webpack-env": "^1.16.0",
    "@types/yamljs": "^0.2.31",
    "@typescript-eslint/eslint-plugin": "^4.20.0",
    "@typescript-eslint/parser": "^4.20.0",
    "@vue/cli-plugin-babel": "^4.5.12",
    "@vue/cli-plugin-eslint": "^4.5.12",
    "@vue/cli-plugin-pwa": "^4.5.12",
    "@vue/cli-plugin-router": "^4.5.12",
    "@vue/cli-plugin-typescript": "^4.5.12",
    "@vue/cli-plugin-unit-jest": "^4.5.12",
    "@vue/cli-plugin-vuex": "^4.5.12",
    "@vue/cli-service": "^4.5.12",
    "@vue/eslint-config-standard": "^6.0.0",
    "@vue/eslint-config-typescript": "^7.0.0",
    "@vue/test-utils": "^1.1.3",
    "babel-loader": "^8.2.2",
    "concurrently": "^6.0.0",
    "eslint": "^7.23.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-promise": "^4.3.1",
    "eslint-plugin-vue": "^7.8.0",
    "fibers": "^5.0.0",
    "lint-staged": "^10.5.4",
    "sass": "^1.32.8",
    "sass-loader": "^10.1.1",
    "style-resources-loader": "^1.4.1",
    "swagger-routes-express": "^3.3.0",
    "ts-jest": "^26.5.4",
    "ts-node-dev": "^1.1.6",
    "typescript": "4.2.3",
    "vue-cli-plugin-element": "^1.0.1",
    "vue-cli-plugin-style-resources-loader": "^0.1.5",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^5.30.0"
  },
  "bugs": {
    "url": "https://github.com/armour/vue-typescript-admin-template/issues"
  },
  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "keywords": [
    "vue",
    "typescript",
    "admin",
    "template",
    "element-ui"
  ],
  "lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "vue-cli-service lint"
    ]
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/armour/vue-typescript-admin-template.git"
  }
}
    

⇧ npm:mockで、mockフォルダの中のファイルを実行してるってことですかね?

akabeko.me

qiita.com

⇧ 上記サイト様によりますと、concurrentlyっていうnpmのライブラリがコマンドを並列実行してくれるものらしい。

■vue-typescript-admin-template/.env.production

# Base api
# Remeber to change this to your production server address
# Here I used my mock server for this project
VUE_APP_BASE_API = 'https://vue-typescript-admin-mock-server-armour.vercel.app/mock-api/v1/'
    

⇧ .envファイルで、設定してる変数が、

■vue-typescript-admin-template/src/utils/request.ts

import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import { UserModule } from '@/store/modules/user'

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000
  // withCredentials: true // send cookies when cross-domain requests
})

// Request interceptors
service.interceptors.request.use(
  (config) => {
    // Add X-Access-Token header to every request, you can add other custom headers here
    if (UserModule.token) {
      config.headers['X-Access-Token'] = UserModule.token
    }
    return config
  },
  (error) => {
    Promise.reject(error)
  }
)

// Response interceptors
service.interceptors.response.use(
  (response) => {
    // Some example codes here:
    // code == 20000: success
    // code == 50001: invalid access token
    // code == 50002: already login in other place
    // code == 50003: access token expired
    // code == 50004: invalid user (user not exist)
    // code == 50005: username or password is incorrect
    // You can change this part for your own usage.
    const res = response.data
    if (res.code !== 20000) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        MessageBox.confirm(
          '你已被登出,可以取消继续留在该页面,或者重新登录',
          '确定登出',
          {
            confirmButtonText: '重新登录',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(() => {
          UserModule.ResetToken()
          location.reload() // To prevent bugs from vue-router
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return response.data
    }
  },
  (error) => {
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service
    

⇧ axiosの設定でリクエスト先に指定されてるんで、.envファイルのVUE_APP_BASE_APIJavaアプリケーションサーバーであるTomcatまでのパスとかにすれば、サーバーサイドと連携できるってことになりそうな気がしますかね。

2022年10月20日(木)追記:↑ ここまで

今回はこのへんで。