6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

javascript / typescriptをはじめるためのnode / npm / sass / webpackな環境をゼロから作る

Last updated at Posted at 2022-10-05

javascriptってhtmlとブラウザがあれば動きますよね。

だけど、「jqueryをscriptタグで読み込んでほぼ生なスクリプト書く」か、
「angularやvueやreactに支配された環境で規約に従う(コピペ)」か、
この両極端しか経験していない人を多く見かけます。

そんな人のために、すごく基本的な環境構成を作る手順をまとめます。

目次

プロジェクトフォルダを作る

デスクトップにjavascriptフォルダを作成してvscodeで開きましょう。
以降このフォルダをプロジェクトフォルダと呼び、
このフォルダ直下をプロジェクトルートと呼びます。

  • vscodeのターミナルから実行する場合は
    以下のコマンドを順次実行してください。
terminal
cd ~/Desktop
mkdir javascript
code -r ./javascript

nodeをインストール

macの場合とwindowsの場合で、nodeのインストールの方法が違います。

macの場合

homebrewをインストール

homebrewはmacのパッケージマネージャーです。

  • homebrew公式サイトに掲載されているインストールコマンドを
    vscodeのターミナルにコピペしてhomebrewのインストールを実行しましょう。
    ※2023/11時点ではこんなコマンドです(なるべく最新を見に行きましょう)
terminal
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • 以下のコマンドを実行してHomebrew x.x.x
    表示されればインストール完了です。
terminal
brew -v

nodebrewをインストール

nodebrewはmacのnodeをバージョンごとに管理するためのツールです。
複数バージョンを共存させる予定が無くてもこちらを使うようにしましょう。

  • 以下のコマンドを実行してhomebrewを使って
    nodebrewをインストールしましょう。
terminal
brew install nodebrew
  • 以下のコマンドを実行してnodebrew x.x.x
    Usage:〜が表示されればインストール完了です。
terminal
nodebrew -v
  • 続けて、以下のコマンドで初期設定を実行しましょう。
terminal
nodebrew setup
  • 環境変数「PATH」にnodebrewのパスを追加する必要があります。
    以下のコマンドでターミナルからviを使って.zshrcを開きましょう。
terminal
vi ~/.zshrc
  • 開かれたviでiキーを入力して挿入モードに変更し、
    以下の1行を先頭行にコピペしましょう。
.zshrc
export PATH=$HOME/.nodebrew/current/bin:$PATH
  • escキーで挿入モードから出て、
    以下のコマンドで保存してviを終了しましょう。
vi
:wq
  • 以下のコマンドで.zshrcを読み込み直すことで、
    再起動せずに環境変数が最新の状態になります。
terminal
source ~/.zshrc

nodebrewでnodeをインストール

やっと本題のnodeです。nodeはjavascriptの実行エンジンであり、
これのお陰でブラウザが無くてもjavascriptを実行することが可能です。

  • 以下のコマンドを実行してnodebrewを使って
    インストール可能なnodeをリストアップしましょう。
terminal
nodebrew ls-remote
  • リストアップされた中からv20.x.x(v20の最新版)を探し出し、
    以下のコマンドを実行してnodeをインストールしましょう。
    v20.x.xの部分を置き換えてください!
terminal
nodebrew install v20.x.x
  • 以下のコマンドを実行してv20.x.x
    表示されればインストール完了です。
terminal
nodebrew ls
  • 以下のコマンドを実行して使用するnodeの
    バージョンを指定しましょう。
    v20.x.xの部分を置き換えてください!
terminal
nodebrew use v20.x.x
  • 以下のコマンドを実行してv20.x.x
    表示されればバージョン指定完了です。
terminal
node -v

windowsの場合

nvm-windowsをインストール

nvm-windowsは、Windows用のNode.jsバージョンマネージャーです。

nvm_ss.png

  • nvm-setup.exeを起動して、こちらの公式の手順通りにnvmをインストールしてください。

  • 以下のコマンドを実行して、バージョンが表示されればインストール完了です。

※ 上手くいかなければ、VSCodeを再起動してみましょう。

terminal
nvm -v

nvmからnodeをインストール

  • 以下のコマンドを実行する。

LTSとは、Long Time Supportの略です。長期の保守運用が約束されたバージョンですので、こちらを使うようにしましょう。

terminal
nvm install lts
  • 下記のように表示されたらインストールは完了です。
    現時点(2023/11)では、20.10.0がインストールされました。
Downloading node.js version 20.10.0 (64-bit)...
Extracting...
Complete


Installation complete. If you want to use this version, type

nvm use 20.10.0
  • 下記コマンドで、インストールした20.10.0を使えるようにします。
terminal
nvm use 20.10.0
  • 以下のコマンドを実行して20.10.0
    表示されればバージョン指定完了です。
terminal
node -v

npmの初期設定

npm(node package manager)とは、javascriptから利用できる
様々なパッケージを管理するためのツールです。

  • 以下のコマンドを実行して、このプロジェクトで
    npmを有効にするための初期設定となる
    package.jsonファイルを作成しましょう。
terminal
npm init -y
  • vscodeで作成されたpackage.jsonを開き、
    scriptsの項目を以下のように書き換えて保存しましょう。
package.json
  "scripts": {
    "start": "node index.js"
  },

Hello, world!

これでjavascriptが実行できる環境が整いました!
動かしてみましょう。

  • プロジェクトルートにindex.jsファイルを作成し、
    中身を以下のように書き換えて保存しましょう。
index.js
console.log('Hello, world!');
  • 以下のコマンドを実行してindex.jsを実行し、
    ターミナルに「Hello, world!」と表示されれば成功です。
terminal
npm run start
  • npm run startpackege.jsonに書いた
    以下のコマンドを実行することと同じです。
terminal
node index.js

npmパッケージの利用

npmパッケージを利用してみましょう。
ここでは、日付関連の便利機能が詰まったdate-fnsを使用してみます。

  • 以下のコマンドを実行して、npmを使って
    date-fnsをインストールしましょう。
terminal
npm install --save date-fns
  • node_modulesフォルダとその中にdate-fnsフォルダがあり、
    package.jsonに以下の行が追加されていればインストール成功です。
    x.x.xはその時の最新版になります。
package.json
  "dependencies": {
    "date-fns": "^x.x.x"
  }
  • index.jsを以下のように書き換えて、npm run start
    年月日時分秒が正しく表示されることを確認しましょう。
index.js
// node_modulesのdate-fnsからformat関数だけを読み込み
const { format } = require('date-fns/format');

// javascript組み込みの日付データ
const rawDate = new Date();
// date-fns/formatによる整形
const formatDate = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');

// 出力内容の差異を確認
console.log(rawDate);
console.log(formatDate);

htmlに組み込む

さて、ここからはhtmlでこのindex.jsやsassによるcssを
利用できる環境を整えていきましょう。

  • 以下のフォルダ構造を作成しましょう。
explorer
javascript
| - public
    | - js
    | - css
  • index.jsをpublic/jsフォルダに移動し、
    中身を以下のように書き換えましょう。
    date-fns関連をコメントアウトしています。
public/index.js
// node_modulesのdate-fnsからformat関数だけを読み込み
// const format = require('date-fns/format');

// javascript組み込みの日付データ
const rawDate = new Date();
// date-fns/formatによる整形
// const formatDate = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');

// 出力内容の差異を確認
console.log(rawDate);
// console.log(formatDate);
  • public直下にindex.htmlを作成し、
    以下のように中身を書き換えましょう。
    ※先頭行でhtml:5と入力してコードスニペットを活用しましょう。
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="js/index.js"></script> <!-- この行を追加入力 -->
    <title>Document</title>
</head>
<body>
    
</body>
</html>
  • vscode拡張機能Live Serverをインストールして、
    index.htmlがエディタに表示された状態で、
    画面右下に出るGo Liveを押すとブラウザが起動します。
    表示されたページでF12を押してDeveloper Toolsを開き、
    コンソールに以下のように現在時刻が表示されれば成功です。
Developer Tools - console
Sun Dec 31 2022 12:34:56 GMT+0900 (日本標準時)     index.js:10

webpackを導入する

この状態でdate-fnsのコメントアウトを解除すると、
requireができずにエラーが表示されてしまいます。

requireはNode.jsのようなブラウザ以外の環境、
つまり、node index.jsなどのコマンドにより
実行するような環境でのみ使用できる構文だからです。

また、このpublicフォルダはいずれ公開用のサーバーに
移動されるということを考えると、node_modulesの中に
入っているdate-fnsを使えないのは当然のことですよね。

そこで、実行時に使うファイルをすべてまとめる必要があり、
それを実現するのがwebpackという仕組みです。

  • ターミナルから以下のコマンドを実行してnpmを使用して
    webpackとwebpack-cliをインストールしましょう。
terminal
npm install --save-dev webpack webpack-cli
  • node_modulesフォルダの中にたくさんのフォルダが追加され、
    package.jsonに以下の行が追加されていればインストール成功です。
    x.x.xはその時の最新版になります。
package.json
  "devDependencies": {
    "webpack": "^x.x.x",
    "webpack-cli": "^x.x.x"
  },
  • プロジェクトルートにwebpack.config.jsという
    ファイルを作成し、中身を以下のように置き換えてください。
webpack.config.js
const path = require('path');
module.exports = {
  mode: 'development', // production:難読化と容量削減
  entry: './index.js',
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: 'index.js',
  },
};
  • public/js/index.jsをプロジェクトルートに
    移動して、中身を次のように置き換えてください。
    date-fnsのrequireをブラウザ環境でも使用可能な
    import構文に書き換えています。
index.js
// node_modulesのdate-fnsからformat関数だけを読み込み
import { format } from 'date-fns/format';

// javascript組み込みの日付データ
const rawDate = new Date();
// date-fns/formatによる整形
const formatDate = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');

// 出力内容の差異を確認
console.log(rawDate);
console.log(formatDate);
  • 以下のコマンドを実行してwebpackを使用して
    index.jsとdate-fnsをパッケージ化しましょう。
    public/js/index.jsが新たに作成されれば成功です。
terminal
npx webpack
  • index.htmlがエディタに表示された状態で、
    画面右下に出るGo Liveを押すとブラウザが起動します。
    表示されたページでF12を押してDeveloper Toolsを開き、
    コンソールに以下のように整形後の現在時刻が表示されれば成功です。
Developer Tools - console
Sun Dec 31 2022 12:34:56 GMT+0900 (日本標準時)     index.js:12
2022年12月31日 12時34分56秒789ミリ秒                                   index.js:13

sassを導入する

sassはcssをより使いやすくするための言語です。
このような関係性を「メタ言語」と言います。
sassはcssのメタ言語であり、typescriptはjavascriptのメタ言語です。

sassには同じ目的で書き方の異なるscssが存在しますが、
今回はsassを採用します。

  • vscode拡張機能Sassをインストールして、.sassファイルの
    フォーマットや色付けができるようにしましょう。
    そしてプロジェクトルートにstyle.sassファイルを作成し、
    中身を以下のように置き換えましょう。
style.sass
body
    background-color: lavenderblush
  • index.htmlを以下のように中身を書き換えましょう。
    link:cssと入力してスニペットを活用しましょう。
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css"> <!-- この行を追加入力 -->
    <script src="js/index.js"></script>
    <title>Document</title>
</head>
<body>
    
</body>
</html>
  • メタ言語は実行可能な元の言語に置き換えるための翻訳
    (コンパイルとかトランスパイルとか呼びます)が必要です。
    以下のコマンドを実行してnpmを使用して
    sassをインストールしましょう。
terminal
npm install --save-dev sass
  • package.jsonを開き、
    scriptsの項目を以下のように書き換えて保存しましょう。
package.json
  "scripts": {
    "start": "node index.js",
    "sass": "sass ./style.sass ./public/css/style.css --no-source-map"
  },
  • 以下のコマンドを実行してsassをコンパイルして、
    index.htmlをブラウザで表示した際の背景が
    ピンク色に変わっていれば成功です。
terminal
npm run sass

ボタンを実装する

ここまででjavascriptもcssも準備できましたので、
ボタンの設置と押下時の処理をやってみましょう。

  • index.htmlを以下のように中身を書き換えましょう。
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/index.js"></script>
    <title>Document</title>
</head>
<body>
    <div class="container"> <!-- ここから追加入力 -->
        <div class="button-wrap">
            <button id="run">実行</button>
        </div>
    </div> <!-- ここまで追加入力 -->
</body>
</html>
  • style.sassを以下のように中身を書き換えましょう。
style.sass
*
    margin: 0
    padding: 0

body
    background-color: lavenderblush

div.container
    height: 100vh
    display: flex
    flex-direction: column
    justify-content: center

    > div.button-wrap
        display: flex
        justify-content: center

        > button#run
            padding: 10px 40px
            cursor: pointer
  • index.jsを以下のように中身を書き換えましょう。
index.js
// node_modulesのdate-fnsからformat関数だけを読み込み
import { format } from 'date-fns/format';

// htmlがすべて読み込まれて表示されたら {} 内を実行する
window.addEventListener('load', () => {
    // id="run"のついたボタンがクリックされたら {} 内を実行する
    document.getElementById('run').addEventListener('click', () => {
        // javascript組み込みの日付データ
        const rawDate = new Date();
        // date-fns/formatによる整形
        const formatDate = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');
        // 画面表示
        alert(formatDate);
    });
});
  • 以下のコマンドでsassをコンパイルし、
    javascriptをひとまとめにしましょう。
    index.htmlをブラウザで表示して、
    ピンク色の画面中央に配置されたボタンを押したら、
    現在日時がアラートで表示されれば成功です。
terminal
npm run sass
npx webpack

typescriptに変更する

では、これをtypescriptに変更していきましょう。
javascript版を上書きしてしまうともったいないので、
コピーして新たにプロジェクトフォルダを作成します。
macの場合とwindowsの場合で、コピーの仕方が少し違うので注意してください。

macのフォルダのコピー

  • 以下のコマンドを実行してrsyncを使用してフォルダをコピー、
    そのフォルダをvscodeで開きましょう。
    ※コピー先フォルダ名をtypescriptとしています。
    node_modulesフォルダは容量が大きい為除外しています。
terminal
rsync -av ../javascript/ ../typescript/ --exclude "node_modules*"
code ../typescript

windowsのフォルダのコピー

  • 以下のコマンドを実行して、1階層上のディレクトリに移動して、typescriptフォルダを作成しましょう。
terminal
cd ..
mkdir typescript
  • 1階層上のまま、以下のコマンドを実行してフォルダをコピーして、
    そのフォルダをvscodeで開きましょう。。
    node_modulesフォルダは容量が大きい為除外しています。
terminal
robocopy .\javascript .\typescript /mir /xd node_modules
code ./typescript

typescriptのセットアップ

  • 以下のコマンドを実行して、typescriptに必要な
    npmパッケージを追加しましょう。
    コピーの際にnode_modulesを除外していましたが、
    コマンド実行時に同時にpackage.jsonを元に復元されます。
terminal
npm install --save-dev typescript @types/node
  • 以下のコマンドを実行して、typescriptのコンパイラーである
    tscの設定ファイルtsconfig.jsonを作成しましょう。
terminal
npx tsc --init
  • 作成されたtsconfig.jsonoutDir
    に関する記述を以下のように置き換えましょう。
tsconfig.json
"outDir": "./build",
  • index.jsindex.tsにファイル名を変更し、
    中身を以下のように置き換えましょう。
index.ts
// node_modulesのdate-fnsからformat関数だけを読み込み
import { format } from 'date-fns/format';

// htmlがすべて読み込まれて表示されたら {} 内を実行する
window.addEventListener('load', () => {
    // id="run"のついたボタンがクリックされたら {} 内を実行する
    const runButton: HTMLButtonElement = document.getElementById('run') as HTMLButtonElement;
    runButton.addEventListener('click', () => {
        // javascript組み込みの日付データ
        const rawDate: Date = new Date();
        // date-fns/formatによる整形
        const formatDate: string = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');
        // 画面表示
        alert(formatDate);
    });
});
  • package.jsonを開き、scriptsの項目を
    以下のように書き換えて保存しましょう。
    npm run buildがさらにnpm run tscを呼び出し、
    npx tscが実行されることで、index.ts
    build/index.jsにトランスパイルされます。
package.json
  "scripts": {
    "start": "npm run tsc && node build/index.js",
    "build": "npm run tsc && npm run webpack && npm run sass",
    "tsc": "npx tsc",
    "webpack": "npx webpack",
    "sass": "sass ./style.sass ./public/css/style.css --no-source-map",
    "watch:tsc": "npx tsc -w",
    "watch:webpack": "npx webpack --watch",
    "watch:sass": "sass --watch ./style.sass ./public/css/style.css --no-source-map"
  },
  • プロジェクトルートのwebpack.config.js
    以下のように修正して、トランスパイルされた
    build/index.jsをwebpackの対象にしましょう。
webpack.config.js
const path = require('path');
module.exports = {
  mode: 'development', // production:難読化と容量削減
  entry: './build/index.js', // ←ここのパスを修正
  output: {
    path: path.join(__dirname, 'public/js'),
    filename: 'index.js',
  },
};
  • 以下のコマンドを実行して、typescriptとsassをトランスパイルし、
    webpackでjavascriptをひとまとめにしましょう。
    index.htmlをブラウザで表示して、ピンク色の画面中央に
    配置されたボタンを押したら、現在日時が表示されれば成功です。
terminal
npm run build

フォルダ構造を変更する

プロジェクトルートにindex.tsstyle.sass
そのまま置いてあるのはちょっと気になりますよね。
フォルダ構造を直しておきましょう。

  • 以下のようにフォルダ構造を変更しましょう。
    srcフォルダを作り、その中にindex.tsを配置、
    さらにsassフォルダを作り、その中にstyle.sassを配置しています。
explorer
typescript
| - src
    | - index.ts
    | - sass
        | - style.sass
  • package.jsonを以下のように変更して、
    変更後のstyle.sassを見るようにしましょう。
package.json
  "scripts": {
    "start": "npm run tsc && node build/index.js",
    "build": "npm run tsc && npm run webpack && npm run sass",
    "tsc": "npx tsc",
    "webpack": "npx webpack",
    "sass": "sass ./src/sass/style.sass ./public/css/style.css --no-source-map",
    "watch:tsc": "npx tsc -w",
    "watch:webpack": "npx webpack --watch",
    "watch:sass": "sass --watch ./src/sass/style.sass ./public/css/style.css --no-source-map"
  },
  • tscはデフォルトでsrcフォルダを見に行くようになっていますので、
    index.tsの場所変更については何も変更がありません。
    以下のコマンドを実行して、ブラウザでの表示結果が全く同じになれば成功です。
terminal
npm run build

typescriptのみ動かしたい場合には

ここまでで、htmlとjavascript/typescriptとcss/sassの
連携ができるようになりました。
最後にtypescriptのみ動かす場合の例を挙げて終わりとします。

  • index.tsを以下のように書き換えましょう。
    ※htmlに関連するコードはコメントアウトして残しています。
src/index.ts
// node_modulesのdate-fnsからformat関数だけを読み込み
import { format } from 'date-fns/format';

// 処理開始日時
console.log(format(new Date(), 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒'));
// 0〜10までの掛け合わせ表
const data: number[][] = [...Array(11)].map((_, i) => [...Array(11)].map((_, j) => i * j));
// 表形式でコンソール出力
console.table(data);
// 処理終了日時
console.log(format(new Date(), 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒'));

// // htmlがすべて読み込まれて表示されたら {} 内を実行する
// window.addEventListener('load', () => {
//     // id="run"のついたボタンがクリックされたら {} 内を実行する
//     const runButton: HTMLButtonElement = document.getElementById('run') as HTMLButtonElement;
//     runButton.addEventListener('click', () => {
//         // javascript組み込みの日付データ
//         const rawDate: Date = new Date();
//         // date-fns/formatによる整形
//         const formatDate: string = format(rawDate, 'yyyy年MM月dd日 HH時mm分ss秒SSSミリ秒');
//         // 画面表示
//         alert(formatDate);
//     });
// });
  • 以下のコマンドでtscによりtypescriptをコンパイルして、
    nodeによりbuild/index.jsを実行しましょう。
terminal
npm run start
  • ターミナルに以下のような表が出力されれば成功です。
terminal
2022年12月31日 12時34分56秒789ミリ秒
┌─────────┬───┬────┬────┬────┬────┬────┬────┬────┬────┬────┬─────┐
│ (index) │ 0 │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 10  │
├─────────┼───┼────┼────┼────┼────┼────┼────┼────┼────┼────┼─────┤
│    0    │ 0 │ 0  │ 0  │ 0  │ 0  │ 0  │ 0  │ 0  │ 0  │ 0  │  0  │
│    1    │ 0 │ 1  │ 2  │ 3  │ 4  │ 5  │ 6  │ 7  │ 8  │ 9  │ 10  │
│    2    │ 0 │ 2  │ 4  │ 6  │ 8  │ 10 │ 12 │ 14 │ 16 │ 18 │ 20  │
│    3    │ 0 │ 3  │ 6  │ 9  │ 12 │ 15 │ 18 │ 21 │ 24 │ 27 │ 30  │
│    4    │ 0 │ 4  │ 8  │ 12 │ 16 │ 20 │ 24 │ 28 │ 32 │ 36 │ 40  │
│    5    │ 0 │ 5  │ 10 │ 15 │ 20 │ 25 │ 30 │ 35 │ 40 │ 45 │ 50  │
│    6    │ 0 │ 6  │ 12 │ 18 │ 24 │ 30 │ 36 │ 42 │ 48 │ 54 │ 60  │
│    7    │ 0 │ 7  │ 14 │ 21 │ 28 │ 35 │ 42 │ 49 │ 56 │ 63 │ 70  │
│    8    │ 0 │ 8  │ 16 │ 24 │ 32 │ 40 │ 48 │ 56 │ 64 │ 72 │ 80  │
│    9    │ 0 │ 9  │ 18 │ 27 │ 36 │ 45 │ 54 │ 63 │ 72 │ 81 │ 90  │
│   10    │ 0 │ 10 │ 20 │ 30 │ 40 │ 50 │ 60 │ 70 │ 80 │ 90 │ 100 │
└─────────┴───┴────┴────┴────┴────┴────┴────┴────┴────┴────┴─────┘
2022年12月31日 12時34分56秒799ミリ秒

終わりに

普段はjquery書いてますとか、Reactでやってますとかいう人も、
配列関連など複雑な処理を書くときに、確認や性能検証などに
ちょっと書いてすぐ動かせる場所があると、開発が捗ります。

また、ゼロから構築できるようになっておくと、
新しい仕組み(テスト系とかCI系とか)を導入する際に
単純な構成で事前に仕組みを確認しやすくなります。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?