見出し画像

Vueアプリを初めて作成した時に理解に苦労した部分やあいまいだった要点のまとめ


こんにちは!15年以上、自社CMSの運用管理を手掛けてきた熟練のASP.NETエンジニアです✨ 現在は、新しい挑戦としてSES先のプロジェクトに参画し、スクラッチ開発のフロントエンドを担当しています。

1.Vueを始めたときに苦労した点

・npmとはなにか
・Node.jsとはなにか
・vite、webpackがわからない
・jQueryと比較して何が違うのか
・モジュールシステムについて
・Vueの表記法が特殊に感じる

2.npmとはなにか

npm(Node Package Manager)はJavascriptのパッケージ管理ツールで、Node.jsに付属しています。これは、プロジェクトで使う外部モジュールのバージョン管理、インストール、アンインストールを助けてくれます。

 ASP.NETでいうとNuGetに当たります。
 PHPでいうとComposerのイメージです。

パッケージはnpm, Incが管理しており、下のサイトにて検索などできます。
 https://www.npmjs.com/

npmはNode.jsのコミュニティが急速に成長するにつれて、Node.jsのモジュールを管理しやすくするために作られました。
VueやReactもnpm, Incのサイトで公開されています。

なお、npm, IncはGitHubの子会社であり、GitHub自身も「GitHub Packages」というパッケージ管理のサービスを提供しておりプライベートなパッケージを安全に管理可能です。

3.Node.jsとはなにか

Node.jsはサーバサイドのJavascript実行環境です。
周辺技術であるExpress.jsなどと組み合わせて、クライアント-サーバ間のフルスタックJavaScriptアプリケーションを作成することも可能です。
Vueはクライアントサイドのフレームワークのため主にブラウザで動作します。

パッケージ管理ツールであるnpmがNode.jsには含まれており、
これはVue.jsなどのフレームワーク開発において必須といえるツールとなっています。

どこの会社がつくってるの?
 Node.jsは、ライアン・ダールによって2009年に作られました。
 最初のリリースはJoyentという会社がサポートしました。
 オープンソースとして開発と維持が行われており、Node.js Foundationがプロジェクトを管理していました。
 現在はOpenJS Foundationとして運営されています。

Node.jsのサポートは?
 公式の有償サポートはありません。
 多くのコントリビューターが寄与し、不具合修正や新機能の追加に取り組んでいます。

4.Vite、Webpackがわからない

Vite(ヴィート)もWebpackもVueをビルドするためのビルドツールです。
この2つ以外にもたくさんのビルドツールがあります。

2022年、ViteはVueのデフォルトのビルドツールになっています。それ以前はWebpackがデフォルトのビルドツールでした。
ViteはVueの作者であるEvan Youによって作られました。

・なぜビルドが必要なのか?何をしてるのか?
ビルドプロセスでは以下の様々な作業を行います:
  ①依存関係解析
    各モジュールがどのモジュールから依存されているのかを解析し、
    これをもとにモジュールを適切な順序でバンドルします
  ②トランスパイル
    新しいJavaScript機能やTypeScriptをブラウザが理解できる
    JavaScriptに変換
  ③Vueのコンパイル
    .vue ファイルをブラウザが理解できるJavaScriptやCSSに変換)
  ④モジュールのバンドル
    アプリケーションのすべてのモジュールを一つのJavaScript
    ファイルにまとめる
  ⑤未使用のコードの削除とコード最適化
    デッドコードの削除/ツリーシェイキングやミニフィケーションを
    行う
  ⑥ビルド結果出力
    ビルドプロセスを経た後のファイルを生成

上記の作業を行うためVue.jsや他のモダンなフロントエンドフレームワークではビルドプロセスが必要になります。

ライブラリとしてビルドしたり、容量肥大化を防ぐためJavascriptを分割してビルドすることも可能で、開発するアプリ要件によって設定が必要です。

参考サイト
https://zenn.dev/nakaakist/articles/86457bf2908379#rollup

5.jQueryと比較して何が違うのか

「デクララティブ」という概念
デクララティブプログラミング(VueやReacct)は、プログラムが何を実現するべきか("What")を宣言し、実装詳細("How")はフレームワークやライブラリに委ねる方式です。つまり、デベロッパーはアプリケーションの状態や挙動を記述し、その状態に基づいたUIの更新はフレームワークが行います。

「リアクティブ」な実装
データの変更に自動的に反応し、それらの変更をUIに反映します。つまり、データまたは状態が変わったときに、自動的にUIが更新されるようにシステムが"反応"します。

jQueryとその他の伝統的なJavaScriptライブラリやフレームワークは一般的に「命令型(Imperative)」と呼ばれます。
例えば、DOM要素を操作するためには、具体的な手順と条件を記述します

// jQuery (Imperative)
if ($('#my-element').is(':visible')) {
  $('#my-element').hide();
} else {
  $('#my-element').show();
}

一方、デクララティブなアプローチでは、ロジックの結果に基づいてUIが自動的に更新されます。開発者は「何を」したいのかを記述し、フレームワークが「どのように」それを達成するのかを決定します

// Vue.js (Declarative)
<template>
  <div v-show="isVisible">My Element</div>
</template>

参考サイト

コードを比較して処理を追うと、変数の変化に応じて変わる部分が格段にわかりやすいなと感じました。

jQueryでゴリゴリ書いたコードをVue.jsで書き換えてみた話|ss_shimada (note.com)

6.モジュールシステムについて

外部ファイルを読み込み、依存関係を解決する仕組みです。
VB.NETのImportsやPHPのrequireに似ています。
モジュールに分割して必要な時にインポートできるような仕組みにすることで大規模なアプリケーション構築がしやすくなっています。


いろいろな規格があり、文法や対応しているツールなどが異なります。ECMAScriptが長期的に優位性を持つと予測されています。

  • CommonJS (CJS)

  • Asynchronous Module Definition (AMD)

  • ECMAScript 2015 modules (ESM)

  • Universal Module Definition (UMD)

  • SystemJS


ECMAScriptモジュール(ESM)システムでは、「export default」を使用して、モジュールから一つのデフォルトエクスポートを設定することができます。一つのモジュールからは一つのexport defaultのみが許されます。

以下に、通常のエクスポートとexport defaultを使用したサンプルコードを示します。

// エクスポートの例
// mathUtils.js
export function multiply(x, y) {
  return x * y;
}
export default function add(x, y) {
  return x + y;
}

ここでは、multiplyという関数を通常のエクスポートし、addという関数をexport defaultでエクスポートしています。

// インポートの例
// main.js
import addFunction, { multiply } from './mathUtils.js'; 
console.log(addFuction(2, 3));  // Outputs: 5
console.log(multiply(2, 3)); // Outputs: 6

export defaultでエクスポートされた関数は、任意の名前(この例ではaddFunction)でインポート可能です。ただし、通常のエクスポートでエクスポートされた関数は、そのままの名前(この例ではmultiply)でインポートする必要があります。必要な場合は、エイリアスを使用することも可能です。


2017年頃からブラウザーがモジュール機能をネイティブに対応し始めた

ブラウザでは例1のようにスクリプトタグで読み込んだJSファイルは基本的にグローバルに登録されて相互に参照が可能です。

// 例1
// test.html
<!DOCTYPE html>
<html>
<head>
    <title>module</title>
</head>
<body>
<script type="javascript" src="/script1.js"></script>
<script type="javascript" src="/script2.js"></script>
</body>
</html>

一方、モジュールシステムを利用すると(import/exportしない限り)それができなくなります。(module1.js、module2.jsは相互に参照できない)

<!DOCTYPE html>
<html>
<head>
<title>module</title>
</head>
<body>
<script type="module" src="/module1.js"></script>
<script type="module" src="/module2.js"></script>
</body>
</html>

7.Vueの表記法が特殊に感じる

Vueの記述方法が特異に感じられる要素

  • ディレクティブ: Vue独自の表記法(例:v-if, v-for)。

  • リアクティブバインディング: データの変更とビューの自動更新。

  • バージョン依存の文法: Vue3のComposition APIのような新機能。

  • JSXの導入: Reactで一般的な表記法。

  • モジュールシステム: コードの再利用を容易にし、構造化されたコードの記述をサポートします。

これらの要素が組み合わさることで理解を難しくしていると思います。

Vue バージョン1~ Options API
https://stackblitz.com/edit/vitejs-vite-tvgrxp?file=src%2FApp.vue

// App.vue
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">
      Increment
    </button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

Vue バージョン2~ JSX ※別途プラグインが必要
https://stackblitz.com/edit/vue3-jsx-starter-nqbegq?file=src%2FApp.js

// App.vue
import { h } from 'vue';
export const App = {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment() {
      this.count++;
    },
  },
  render() {
    return (
      <div>
        <p>{this.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  },
};

Vue バージョン3~ Composition API
https://stackblitz.com/edit/vitejs-vite-tvgrxp?file=src%2FApp.vue

// App.vue
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">
      Increment
    </button>
  </div>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    
    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}
</script>

Vue バージョン3.2~ Composition API script setup
https://stackblitz.com/edit/vitejs-vite-tvgrxp?file=src%2FApp.vue

// App.vue
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">
      Increment
    </button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)

const increment = () => {
  count.value++
}
</script>

※参考まで以下のUdemyの動画はComposition APIで説明されています。
はじめてのVue.js 3 入門!jQuery を使わないウェブ開発 - 導入からアプリケーション開発まで体系的に学ぶ | Udemy

8.サンプル

クイックスタートの手順でサンプルプロジェクトを作成します。(皆さんよければお試しください)
Node.jsが入っていない場合などはstackblitz.comのサイトで実行してください。

各フォルダの内容
dist・・・ビルド結果が入ります
node_modules・・・npm installで取得したモジュール
public・・・静的ファイル(ビルドされない)
src/assets・・・静的ファイル(ビルドされる)
src/components・・・Vueコンポーネント
package-lock.json・・・npm用の設定ファイル(触らない)
package.json・・・npm用の設定ファイル
vite.config.js・・・ビルド用設定ファイル

クイックスタート | Vue.js (vuejs.org)
https://stackblitz.com/edit/vitejs-vite-tvgrxp?file=index.html&terminal=dev


この記事が気に入ったらサポートをしてみませんか?