タグ「JavaScript」の 記事 5 件中 1 ~ 5 件を表示しています。

JavaScript 開発に必須

昨今の JavaScript 開発において ECMAScript 6 で記述してビルド時にブラウザで解釈できるレガシーな JavaScript に変換するために Babel などのトランスパイラの設定は必須になっていると思うが、私は以前より Laravel Mix という Laravel に付属している簡単に使えるトランスパイラを愛用している。 以前書いた記事だと Laravel プロジェクトからファイルを引っ張ってくる方法だったが、今回試した方法だともっとシンプルにいけたのでメモ。 尚、これを試すのに arms inc. Engineers' Blog 様の記事が大変参考になった。 前提条件として Node.js は既にインストールされているものとする。

1. 新規 Node.js プロジェクトを作成しインストール

まず PhpStorm で新規プロジェクトを作成する時に Node.js プロジェクトにする。 こうすると package.json のみが含まれたシンプルな Node.js プロジェクトが生成される。 ここで以下を叩き Laravel Mix と cross-env をインストールする:

npm install laravel-mix cross-env --save-dev

そして package.json に Laravel Mix のビルド用のスクリプトを配置する (各コマンドの説明は省略する):

{
  "scripts": {
    "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --watch",
    "prod": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  }
}

ちなみに私の環境だと --hide-modules オプションがついているとスクリプト実行時にエラーになった。 この場合 --hide-modules を削除すると実行できた。

2. webpack.mix.js ファイルの配置と動作確認

webpack.mix.js はビルド用の設定ファイルとなっている。 今回は JavaScript と SASS で書くことにする。 TypeScript や LESS を使いたかったりする場合は別途書き換える。 プロジェクト配下に webpack.mix.js というファイルを以下のように作る:

const mix = require('laravel-mix');
mix.js('src/app.js', 'dist/')
    .sass('src/app.scss', 'dist/')

この例の場合 src/app.js に置かれた JavaScript が dist/app.js にビルドされ src/app.scss に書かれた SCSS が dist/app.css にビルドされることとなる。 ということで srcdist ディレクトリを作成し src/app.jssrc/app.scss に適当な記述をしたファイルを作成し npm run dev を叩く。 webpack compiled successfully が表示され、正しく dist/app.jsdist/app.css が作成されることを確認する。 更に npm run watch を叩いて適当に src/app.jssrc/app.scss を書き換えて保存するとそれぞれビルドされて dist/app.jsdist/app.css が書き換わることを確認する。

Vue.js のコンポーネントファイル (いわゆる Hoge.vue) 内で最初から <style> タグが用意されているので疑いもせずに CSS で書いていたのだが、これが普通に SCSS (SASS) で書けるのを今日知った……。 <style lang="scss"> と書き換えると SCSS で記述できる。 この程度のことはまず疑問をもって調べるのが良いと身を持って感じた。

最近 PHP のフレームワークとして Laravel をよく使用している。 Laravel にバンドルされている ES6 や SASS を JavaScript や CSS にトランスパイルする仕組みがよくできていると感心していた。 この Laravel Mix という仕組みが実は Laravel を使用していないプロジェクトでも簡単に導入できたのでここに書き記しておく。

導入

  1. Laravel 公式を参考に Laravel の新規プロジェクトを適当に作る
  2. そのプロジェクト直下の package.jsonwebpack.mix.js を取り出して適用したいプロジェクトにコピー
  3. そのプロジェクト直下の resources/js/app.jsresources/js/bootstrap.jsresources/sass/app.scss を取り出して同じく適用したいプロジェクトにコピー
  4. package.json があるディレクトリで npm install を叩く

npm run dev を叩いて public/js/app.jspublic/css/app.css にビルドされるのを確認する。 ビルド先を変えたい場合は webpack.mix.js を適当に書き換える。

使い方

Laravel 公式参照。 基本的に npm run watch を叩くと変更を監視してくれるのでその状態のまま開発を進めると楽。

恥ずかしながら今まで jQuery ばかり使用していたので document.querySelector の存在を知らなかったのでメモ。 Laravel の Blade テンプレート内でデフォルトで head 要素内に以下のように meta タグで CSRF トークンが出力されている:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    ...
</head>

上記は Blade 内なので {{ csrf_token }} という Blade の記法で取得できるが、この値を Vue.js のコンポーネント内で取得するのに meta タグから取り出す必要があった。 そこで私は最初「jQuery なら一発で取れるのに」と思いながら以下のように書いてしまった:

/**
 * メタ要素から CSRF トークンを取得する.
 *
 * @returns {string} CSRF トークン
 */
csrfToken() {
    let children = document.head.children;
    for (const child of children) {
        if (child.getAttribute('name') === 'csrf-token') {
            return child.getAttribute('content');
        }
    }
    return null;
}

しかしこれを書き終えた後で「Laravel で使われている Axios でヘッダに CSRF トークンを付与しているはずだがそこはどうやっているのか」と思い bootstrap.js を参照してみたら以下のように書かれていた:

let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

この querySelector というのを知らなかったのだが、どうも CSS の記法でセレクタを記述することで jQuery のように DOM 要素を取得できる DOM のメソッドらしい。 最近できたのかと思いきや IE8 から利用可能なようで意外とレガシーなものだった……。 最初の 1 件を取得したい場合 querySelector を使用し、複数件数取得したい場合は querySelectorAll を使用する。

これから Vue.js のようなモダンな JS フレームワークをメインとし脱 jQuery としていくにあたって必須知識だろう。 覚えておきたい。

Vue.js を使用していて Vuex を使用すべきか否かというのがよく分からなかった。 公式にも以下のように書いてある:

もし、あなたが大規模な SPA を構築することなく、Vuex を導入した場合、冗長で恐ろしいと感じるかもしれません。そう感じることは全く普通です。あなたのアプリがシンプルであれば、Vuex なしで問題ないでしょう。

シンプルとはどのような状態を指すのか、というところだがこの場合のシンプルというのは「単一のコンポーネントのみで構成されるようなもの」だということが作っているうちに分かってきた。 Vue.js は子コンポーネント同士、若しくは子コンポーネントから親コンポーネントに伝達させるのに this.$emit などというよく分からないものを使用し、これがバケツリレーのように冗長だし記法も分かりにくい。

今回後から Vuex を導入したが、後から変更すると既存をそのように修正しなければならず面倒だ。 コンポーネントで分割することが最初から分かっているならばはじめから Vuex を導入してしまったほうがいいと思う。 「大規模向け」とかそういうワードに惑わされると損だ。