VSCodeでFE&BEを同時に管理するプロジェクトを作ろうと思うのだが【2025年版】

ひとりごとの作業記録です。

# 0.今回のゴール

下記のような階層のプロジェクトを作成したい。

```
project/
│
├── frontend/   # Vue.jsアプリケーション
│   ├── src/
│   ├── public/
│   ├── package.json
│   └── ...
│
├── backend/    # Flaskアプリケーション
│   ├── app/
│   │   ├── __init__.py
│   │   ├── routes.py
│   │   └── ...
│   ├── venv/
│   ├── requirements.txt
│   └── run.py
│
└── README.md
```

その他の要件

```
・エディタには「VSCode」を使う。
・frontendは「vuejs」、backendは「python」フレームワークは「flask」
・frontendとbackendは「REST API」でやりとりする。
・開発環境は「MacOS Sequoia 15.2」
・pythonとかnodeとかVSCとか入ってる
```

# 1.projectフォルダを作成

```bash
mkdir project
```

うむ。これは当然問題はない。

# 2.フロントエンド作成工程

次にフロントエンドの階層を作っていこう。
今回フロントはvuejsだ。

## 2-1.プロジェクトを作成

```bash
mkdir frontend
cd frontend

vue create .
＞Default (Vue 3) (babel, eslint) を選ぶ

npm install axios
```

「REST API」を使うので、とりあえず「axios」を入れてる。
ただそれだけだ。深い意味はない。

## 2-2. App.vue作成

テストだから、なんでもいい。

frontend/src/App.vue

```jsx
<template>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      message: '',
    };
  },
  async created() {
    try {
      const response = await axios.get('http://localhost:5000/api/hello');
      this.message = response.data.message;
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  },
};
</script>
```

よし。ひとまずOK。

つぎはバックエンドだ。

# 3.バックエンド作成工程

バックエンドはflaskを使う。

## 3-1.ptyhonバージョン確認

そういえば、pythonのバージョンってどうなってだろう？

```bash
python --version
Python 3.11.4
```

下記を参照見てみると・・・。

https://devguide.python.org/versions/

アップデートの余地ありだな。
3.11.11にアップデートしよう。

```bash
pyenv install 3.11.11
pyenv global 3.11.11

python --version
Python 3.11.11
```

よし。次だ。

## 3-2.仮想環境の作成

ひとまず「venv」で行く。

```bash
python -m venv venv
source venv/bin/activate
```

まぁ、こんなもんだろう。

## 3-3.Flaskインストール

flaskをインストールだ

```bash
pip install flask
```

### １）問題発生！

```php
pip install flask
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
Could not fetch URL https://pypi.org/simple/flask/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/flask/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
ERROR: Could not find a version that satisfies the requirement flask (from versions: none)
ERROR: No matching distribution found for flask
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
```

なんじゃこりゃ？

### ２）原因調査

```php
このエラーは、PythonインタプリタでSSLモジュールが利用できないため、
pipがHTTPS接続を確立できず、パッケージのダウンロードに失敗していることを示しています。
```

なるほど。
OpenSSLがロードできてないのか。

てか、本当か？
やってみなけりゃわからない。

```php
python -c "import ssl; print(ssl.OPENSSL_VERSION)"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/mac-user/.pyenv/versions/3.11.11/lib/python3.11/ssl.py", line 100, in <module>
    import _ssl             # if we can't import it, let the error propagate
    ^^^^^^^^^^^
ImportError: dlopen(/Users/mac-user/.pyenv/versions/3.11.11/lib/python3.11/lib-dynload/_ssl.cpython-311-darwin.so, 0x0002): Library not loaded: /opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib
  Referenced from: <5FC80B1A-4E22-3C4B-A4C2-871CA752C6F3> /Users/mac-user/.pyenv/versions/3.11.11/lib/python3.11/lib-dynload/_ssl.cpython-311-darwin.so
  Reason: tried: '/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/opt/homebrew/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/usr/local/lib/libssl.1.1.dylib' (no such file), '/usr/lib/libssl.1.1.dylib' (no such file, not in dyld cache)
```

おおぅ・・・。
確かにできない。

疑って悪かった・・・。

となると・・・

PythonがSSLモジュール（_ssl）を初期化する際に、
必要なOpenSSLライブラリ（libssl.1.1.dylib）が見つからないために発生

している、ということだね。

・・・いやいやいやいやいや・・・。
でもさ・・・でもさ・・・。

OpenSSLって入ってるよね？

```php
openssl version
OpenSSL 3.4.0 22 Oct 2024 (Library: OpenSSL 3.4.0 22 Oct 2024)
```

ほら！
この通り、OpenSSL3系が入っている。

にもかかわらず、なぜか「1.1系」を要求されているの？？？
おかしくね？

まぁ、よくわからないが
言われるがままに「1.1」をいれてみる。

「えい！」

```php
brew install openssl@1.1
==> Auto-updating Homebrew...
Adjust how often this is run with HOMEBREW_AUTO_UPDATE_SECS or disable with
HOMEBREW_NO_AUTO_UPDATE. Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Auto-updated Homebrew!
==> Updated Homebrew from 55f399c10d to 55475cb11a.
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
binocle          c2patool         cargo-cache      diary            json2hcl
==> New Casks
spectrolite

You have 9 outdated formulae installed.

Error: openssl@1.1 has been disabled because it is not supported upstream! It was disabled on 2024-10-24.
```

エラーになった。

はっはーん。1.1系はもうダメだってことだな。
そりゃそうだろ。

っていうか、なんだこれ？

「1.1系を入れろ」って言われたから入れたのになにこの仕打ち。

### **３）状況がよくわからなくなったので再度整理する**

**そもそもやりたいことって？**

*venvで作った仮想環境に、パイソン3.11.11にFlaskを入れたい。*

そうだよ。そうだよ。
やりたいことはこれだよ。

「opensslのインストールがどうのこうの・・・」
って罠に引っかかってると、そのまま沼にハマる。

やべぇ。

でかしたぞ、俺！

### ４）再度、原因調査(ver. ChatGPT o1)

ChatGPT o1に質問。

「venvで作った仮想環境に、パイソン3.11.11にFlaskを入れたいのだけど、
　こんなエラーがでて困ってるんだよ。
　でもさぁ、openssl3は入ってるのに、openssl1系を求められるとかも意味わかんないし。
　本来の目的を達成するためには、どうしたらいい？」

---

最もよくある原因は、**Python のビルド/インストールが SSL ライブラリを正しく取り込めていないこと**です。

- macOS の場合、システム標準の OpenSSL が古い/または LibreSSL が使われているなどの理由で、Python が SSL 関係のモジュールをうまく組み込めないケースがよくあります。
- 「`openssl version` では 3.x が入っている」と表示されても、**Python が実際にその OpenSSL を見つけてリンクしているか**は別問題です。
- 一部のインストール方法（例: Homebrew から Python を入れた、pyenv でコンパイルした等）によっては、Python がビルドされる際に必要な OpenSSL のヘッダやライブラリが適切に読み込まれず、SSL サポートが無効化された状態でインストールされることがあります。

---

ほほう、なるほど。

なんとなく現在の状況が理解できたぞ。

ならば・・・

### **５）諸々インストールし直す**

これが一番早い気がする。

```bash
brew update

brew install openssl@3

brew info openssl@3
==> openssl@3: stable 3.4.0 (bottled)
Cryptography and SSL/TLS Toolkit
https://openssl-library.org
Installed
/opt/homebrew/Cellar/openssl@3/3.4.0 (7,236 files, 33.4MB) *
  Poured from bottle using the formulae.brew.sh API on 2025-01-23 at 07:15:04
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/o/openssl@3.rb
License: Apache-2.0
==> Dependencies
Required: ca-certificates ✔
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@3/certs

and run
  /opt/homebrew/opt/openssl@3/bin/c_rehash
==> Analytics
install: 317,619 (30 days), 1,198,660 (90 days), 4,906,371 (365 days)
install-on-request: 39,374 (30 days), 166,937 (90 days), 638,675 (365 days)
build-error: 6,004 (30 days)
```

よし。

で、「.zshrc」の内容を確認して、以下があることを確認。

```php
export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@3/lib/pkgconfig"
```

pythonもインストールしなおすぞ。

```php

pyenv uninstall 3.11.11
pyenv install 3.11.11
pyenv global 3.11.11
python --version

Python 3.11.11
```

よし。

では、pythonからopensslが見られるかどうか確認しよう。

```bash
python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 3.4.0 22 Oct 2024
```

オッケーだね。

### ６）今回の障害のまとめ

ssl モジュールが必要だったのだが、pythonが認識できる状態になかった。
なので、もろもろ再インストールを行ったことで解決した。

では気を取り直して

### ７）環境構築再開

すでにつくった仮想環境を消す。

```bash

deactivate
rm -rf venv
```

環境を作る

```bash
python -m venv venv
source venv/bin/activate
```

flask入れる

```bash
pip install flask
```

よし、問題なし。

ここまで長かった！

## 3-4.routes.pyとrun.pyを作成

ひとまずAPIをさくっと作成。

backend/app/routes.py

```php
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/hello')
def hello():
    return jsonify({'message': 'Hello from Flask!'})
```

backend/run.py

```php
from app.routes import app

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
```

よしできた。

# 4.VSCodeで開く

おっと・・・。

まだVSCodeでファイル開いてなかった笑

なので、開く。

## 4-1.VSCodeで「project」フォルダを開く

### １）問題発生！

開いてみたのだが、frontendのvueファイルでなんかエラーが出てる

```php
Parsing error: No Babel config file detected 
for /Users/mac-user/git/project/frontend/src/App.vue. 
Either disable config file checking with requireConfigFile: false, 
or configure Babel so that it can find the config files.eslint
```

え？なにこれ？

### ２）原因

---

これは、**プロジェクトに Babel の設定ファイル(babel.config.js や .babelrc 等)が存在しないため**

に起こっています。Vue CLI を使って新規プロジェクトを作成するときの選択内容によっては、Babel が設定されないまま生成されるケースがあります。

```bash
vue create .
```

この時に、「Default (Vue 3) or Default (Vue 2) 」を選ぶと、通常 Babel が含まれます。

---

うーーーん、まさかの作り間違え？

再度作成やってみる・・・。

が・・・解決しなかった・・・。

なにこれ？

### ３）本当の原因

原因は「フォルダの構造」と、プロジェクトを開いている「場所」。

「frontend」をVSCodeで開けば問題ない。
だけど、「project」フォルダを開いていることにより問題が起こる。

```php
project/
│
├── frontend/   # Vue.jsアプリケーション
│   └── ...
```

うーん。

だけども望んでいるのは

「project」フォルダを開いた時も、「frontend」フォルダを開いた時も、
どちらでも正しく動くこと。

***そのためにどうしたらいいのだろうか？***

### ４）対応策

**「マルチルート ワークスペース」を利用することで解決**するらしい。

なるほど、試してみよう。

projectフォルダの直下に以下を作成する。

project.code-workspace

```php
// project.code-workspace
{
  "folders": [
    {
      "path": "frontend"
    },
    {
      "path": "backend"
    }
  ],
  "settings": {
    "eslint.workingDirectories": [
      // frontend ディレクトリをルートに (Babel/ESLint) を実行
      {
        "directory": "frontend",
        "changeProcessCWD": true
      }
    ]
  }
}

```

そして、VSCodeで「project.code-workspace」を開く。

すると・・・。

解決した！

# 5.実行テスト

では、frontとbackの動作確認テストだ。

## 5-1.フロントエンド実行

```php
npm run serve
```

問題なく動作した。

## 5-2.バックエンド実行

```php
source venv/bin/activate
python run.py
```

### １）問題発生！

```php
 python run.py
 * Serving Flask app 'app.routes'
 * Debug mode: on
Address already in use
Port 5000 is in use by another program. Either identify and stop that program, or start the server with a different port.
On macOS, try disabling the 'AirPlay Receiver' service from System Preferences -> General -> AirDrop & Handoff.
```

うぉぉぉ。なんじゃこりゃ？

落ち着いてエラーをみると・・・。

### ２）原因

**Mac だと AirPlay Receiver が当該ポート(5000)を使ってる**

なるほど。

### ３）対策

じゃぁ、

**「 Flaskを別のポートで起動」**

で対応しよう。

backend/run.py

```php
if __name__ == "__main__":
    app.run(debug=True, port=5001)
```

こうやってポートを変更。

当然、vueの方もURLを変更するよ

```jsx
const response = await axios.get('http://localhost:5001/api/hello');
```

### ４）再実行

```bash
python run.py
```

```bash

 * Serving Flask app 'app.routes'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5001
 * Running on http://192.168.13.38:5001
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 123-835-018
```

よし起動した。

## 5-3.実行確認

早速ブラウザでフロントにアクセス。



```jsx

```

あれ？真っ白だな。

なんだこれ？

ブラウザのデベロッパーツールで確認してみると・・・。

```jsx
localhost/:1 Access to XMLHttpRequest at 'http://localhost:5001/api/hello' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

おおう、CORSのエラーか・・・。

ならば、バックエンドに下記をインストール。

```jsx
pip install flask-cors
```

backend/app/routes.pyもこんな感じに書き換える。

```jsx
from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app) 

@app.route('/api/hello')
def hello():
    return jsonify({'message': 'Hello from Flask!'})
```

気を取り直して再チャレンジ。

http://localhost:8080/

```jsx
Hello from Flask!
```

よし。

(fin)