$ node -v
v22.8.0
$ npm -v
10.8.2
# Angular 用のコマンドをインストールする
$ npm install -g @angular/cli
$ ng version
Angular CLI: 18.2.4
# プロジェクトを作る
$ ng new practice-angular --standalone=true --style=css --routing=false --ssr=false --minimal=true --inline-style=false --inline-template=false
$ tree ./practice-angular/ -I '.git|node_modules'
./practice-angular/
├── README.md
├── angular.json
├── package.json
├── public
│ └── favicon.ico
├── src
│ ├── app
│ │ ├── app.component.css
│ │ ├── app.component.html
│ │ ├── app.component.ts
│ │ └── app.config.ts
│ ├── index.html
│ ├── main.ts
│ └── styles.css
├── tsconfig.app.json
└── tsconfig.json
# 開発サーバをとりあえず起動する
$ cd ./practice-angular/
$ npm start -- --host 0.0.0.0
# サービスクラスを作るコマンドはこんな感じ
$ npm run ng generate service app
CREATE src/app/app.service.ts (132 bytes)
./src/app/app.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppService } from './app.service';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule], // 必要なモジュールを読み込む
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
// 画面に表示されるメッセージ
public message: Promise<string> | null = null;
// サービスクラスを使う宣言
constructor(private readonly appService: AppService) { }
// 画面初期表示時に、サービスクラスからデータを取ってくる
public ngOnInit(): void {
this.message = this.appService.generateMessage();
}
}
./src/app/app.component.html
<h1>Hello : {{ message | async }}</h1>
./src/app/app.service.ts
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class AppService {
// 3秒待ってから「Test Text」という文字列を返す関数
public async generateMessage(): Promise<string> {
await new Promise((resolve) => setTimeout(resolve, 3000));
return 'Test Text';
}
}
→ コレで、画面を開くと3秒後に「Test Text」と表示されるサンプルページが作れた。
# プロジェクトを作る
$ npm create vue@latest
✔ Project name: … practice-vue
✔ Add TypeScript? … No / [Yes]
✔ Add JSX Support? … [No] / Yes
✔ Add Vue Router for Single Page Application development? … [No] / Yes
✔ Add Pinia for state management? … [No] / Yes
✔ Add Vitest for Unit Testing? … [No] / Yes
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … [No] / Yes
✔ Add Vue DevTools 7 extension for debugging? (experimental) … [No] / Yes
$ tree ./practice-vue/
./practice-vue/
├── README.md
├── env.d.ts
├── index.html
├── package.json
├── public
│ └── favicon.ico
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── base.css
│ │ ├── logo.svg
│ │ └── main.css
│ ├── components
│ │ ├── HelloWorld.vue
│ │ ├── TheWelcome.vue
│ │ ├── WelcomeItem.vue
│ │ └── icons
│ │ ├── IconCommunity.vue
│ │ ├── IconDocumentation.vue
│ │ ├── IconEcosystem.vue
│ │ ├── IconSupport.vue
│ │ └── IconTooling.vue
│ └── main.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
# とりあえず開発サーバを起動する
$ cd ./practice-vue/
$ npm install
$ npm run dev -- --host=0.0.0.0
「Vue Official vue.volar
」という VSCode 拡張機能を入れることで、.vue
ファイルにシンタックスハイライト (色) が付くようになる。
import
部分の解釈に一部不具合があり、正しいコードなのにエラーが付いてしまうことがある。回避策調査中不要なサンプルファイルを消して、Angular 版と似たようなコードを書いてみる。
./src/App.vue
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue';
</script>
<template>
<h1>Vue App</h1>
<HelloWorld />
</template>
<style scoped>
h1 {
color: #f00;
}
</style>
./src/components/HelloWorld.vue
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { HelloService } from '../services/HelloService';
const message = ref('No Value');
// 画面初期表示時に、サービスクラスからデータを取ってくる
onMounted(async () => {
message.value = await HelloService.generateMessage();
});
</script>
<template>
<h2>{{ message }}</h2>
</template>
<style scoped>
h2 {
color: #0c0;
}
</style>
./src/services/HelloService.ts
.vue
ファイルの中のコードが増えて全体が見通しにくくなるclass HelloServiceSingleton {
// インスタンスを控えるプロパティ
private static instance: HelloServiceSingleton;
// 外部からのインスタンス生成を防ぐためプライベート・コンストラクタを宣言しておく
private constructor() { }
// シングルトンなインスタンスを生成する
public static getInstance(): HelloServiceSingleton {
if(HelloServiceSingleton.instance == null) HelloServiceSingleton.instance = new HelloServiceSingleton();
return HelloServiceSingleton.instance;
}
// 3秒待ってから「Test Text」という文字列を返す関数
public async generateMessage(): Promise<string> {
await new Promise((resolve) => setTimeout(resolve, 3000));
return 'Test Text';
}
}
export const HelloService = HelloServiceSingleton.getInstance();
→ コレで、画面を開くと3秒後に「Test Text」と表示されるサンプルページが作れた。
vue-ts
で作った場合Vite が用意する雛形の方が、Vue 公式の雛形よりは若干簡素だが、ほぼ差はない。
$ npm create vite@latest practice-vue-vite -- --template vue-ts
$ tree ./practice-vue-vite/
./practice-vue-vite/
├── README.md
├── index.html
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.vue
│ ├── assets
│ │ └── vue.svg
│ ├── components
│ │ └── HelloWorld.vue
│ ├── main.ts
│ ├── style.css
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
create-react-app
という雛形提供の仕組みがあった# プロジェクトを作る
$ npm create vite@latest practice-react -- --template react-ts
$ tree ./practice-react/
./practice-react/
├── README.md
├── eslint.config.js
├── index.html
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
# とりあえず開発サーバを起動する
$ cd ./practice-react/
$ npm install
$ npm run dev
「React zhang-renyang.vscode-react
」という VSCode 拡張機能を入れることで、.tsx
(.jsx
) ファイルにシンタックスハイライト (色) が付くようになる。
不要なサンプルファイルを消して、Angular 版、Vue 版と似たようなコードを書いてみる。
./src/main.tsx
import
で書くのが特徴import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import './index.css';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<h1>Hello</h1>
<App />
</StrictMode>
);
./src/index.css
h1 { color: #f00; }
./src/App.tsx
import
で取り込んでいるHelloService
は Vue プロジェクトで作ったモノと全く同じファイルを流用したuseEffect
・useState
といった React によく出てくる Hook という概念を理解しないとコーディングを読み解きづらいかもimport { useEffect, useState } from 'react';
import { HelloService } from './HelloService';
import './App.css';
function App() {
const [message, setMessage] = useState('No Value');
useEffect(() => { // 特定の処理を1回だけ行うための `useEffect`
(async () => {
// 画面初期表示に、サービスクラスからデータを取ってくる
const generatedMessage = await HelloService.generateMessage();
setMessage(generatedMessage);
})();
}, []);
return (
<>
<h2>{ message }</h2>
</>
)
}
export default App;
→ コレで、画面を開くと3秒後に「Test Text」と表示されるサンプルページが作れた。