LoginSignup
13
5

More than 5 years have passed since last update.

ESLint をブラウザー内で利用する

Last updated at Posted at 2017-12-08

まえがき


追記 (2018/05/24): ブラウザで動作するよう修正済みの Linter クラスを公開しています。

このパッケージを利用する事で、追加の修正無しに Webpack 等で Linter クラスを読み込むことができます。また、このパッケージは Travis CI の Cron 機能により最新の ESLint を元にしたビルドを継続的に作成・公開しています。

ご活用下さい。


ESLint は対外的にはブラウザー内での実行をサポートしていません (eslint/eslint#2585, eslint/eslint#8348)。しかしながら、公式サイトに設置されている オンライン デモ のために、少し細工すればブラウザー内で実行することができます。

この記事では、ESLint をブラウザー内で利用するための webpack の設定について紹介します。

ESLint の Node.js API

ESLint の Node.js API は大別して2つのクラスから構成されています。

CLIEngine
主に使われるクラスです。
ファイルを検証する engine.executeOnFiles(files) や文字列を検証する engine.executeOnText(code, filePath) 等のメソッドを持ちます。これらのメソッドでは、対象ファイルのパスに基づいて設定ファイルを読み込み、設定にある共有設定やプラグインを検索して読み込みます。最後に、得られたコードと設定とプラグインを元に後述する Linter オブジェクトを作成し、検証を実施します。
ファイルシステムと密結合しているため、ブラウザー内では利用できません。
Linter
検証を行う中核クラスです。
ブラウザー内部で利用するために、ファイルシステムに依存しない中核処理だけを抽出したものです。そのため設定ファイルの検索や共有設定・プラグインの解決はできません。linter.defineRule(ruleId, definitionObject) でルールを定義し、linter.verify(code, config) で検証を行います。

今回はもちろん Linter クラスを利用します。

依存パッケージをインストール

必要なパッケージをインストールします。

$ npm install --save-dev eslint webpack string-replace-loader

webpack の設定

Webpack の設定を書きます。

先ほど Linter はファイルシステムに依存しない部分を抽出したものと言いましたが、残念ながら今は 1 カ所だけファイルシステムに依存しています。そのため string-replace-loader で少し手を加えてやる必要があります。

webpack.config.js
const fs = require("fs")
const path = require("path")
const webpack = require("webpack")

module.exports = {
    entry: "./index.js",
    output: {
        path: path.resolve(__dirname, "./dist"),
        publicPath: "/",
        filename: "index.js",
    },
    module: {
        rules: [
            // `eslint/lib/load-rules.js` は `fs` に依存してコアルールを列挙しているため、中身を静的コードに置き換える。
            {
                test: new RegExp(`eslint\\${path.sep}lib\\${path.sep}load-rules\\.js$`),
                loader: "string-replace-loader",
                options: {
                    search: "[\\s\\S]+", // whole file.
                    replace: "module.exports = () => ({})",
                    flags: "g",
                },
            },
        ],
    },
}

サンプル コード

そして ESLint を利用するコードを書きます。

index.js
// "eslint" を読み込むと CLIEngine が含まれてしまうため、内部ファイルを参照する必要がある。
import Linter from "eslint/lib/linter.js"
import semiRule from "eslint/lib/rules/semi.js"

// Linter を作る。
const linter = new Linter()

// 試しにてきとーなルールを定義してみる。
linter.defineRule("no-string", (context) => ({
    Literal(node) {
        if (typeof node.value === "string") {
            context.report({node, message: "Don't use string!"})
        }
    }
}))
// semi ルールも定義してみる。
linter.defineRule("semi", semiRule)

// 検証する
const code = "console.log('Hello!')"
const config = {
    rules: {
        // 上で定義したルールを有効にする設定。
        "no-string": "error",
        "semi": "error"
    }
}
const lintErrors = linter.verify(code, config)

// 表示する
console.log(lintErrors) //→ 結果は以下
結果
[ { ruleId: 'no-string',
    severity: 2,
    message: 'Don\'t use string!',
    line: 1,
    column: 13,
    nodeType: 'Literal',
    source: 'console.log(\'Hello!\')',
    endLine: 1,
    endColumn: 21 },
  { ruleId: 'semi',
    severity: 2,
    message: 'Missing semicolon.',
    line: 1,
    column: 22,
    nodeType: 'ExpressionStatement',
    source: 'console.log(\'Hello!\')',
    fix: { range: [Array], text: ';' } } ]

あとがき

以上、ESLint をブラウザー内で利用する方法でした。

今回は Webpack を利用しましたが、他のバンドラーを使っている場合でも特定のファイルの内容を置き換える仕組みがあれば利用可能です。

先日公開した Playground for eslint-plugin-vue では、このような方法を用いて ESLint を利用しています。
あなたも ESLint を利用した Web アプリを作ってみましょう :smile:

13
5
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
13
5