eslintをバンドルして持ち歩こうと思ったが無理だった話

eslintをgithub actionsに組み込みたくてバンドルしようとしていましたが、無理でした
ここにその記録を残しておきます。

github actionsを再現するのは面倒なので、別ディレクトリにあるファイルをリントしてみます。

まずはディレクトリ構成です。

> 
> │
> ├───test-bundle
> │       .eslintrc.js
> │       package-lock.json
> │       package.json
> │
> └───target
>         sample.js


```javascript:target/sample.js
function snake_case() {
}
```

```json:test-bundle/package.json
{
  "name": "test-bundle",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "esbuild": "^0.20.0",
    "eslint-config-airbnb-base": "^15.0.0"
  }
}
```

```javascript:test-bundle/.eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    'airbnb-base',
  ],
  parserOptions: {
    ecmaVersion: 'latest',
  },
};
```

ここでリントをかければ通常通りに行われます。

```console
test-bundle> npm install
test-bundle> npx eslint -c .eslintrc.js ..\target\sample.js

target\sample.js
  1:10  error  Identifier 'snake_case' is not in camel case  camelcase
  1:10  error  'snake_case' is defined but never used        no-unused-vars
```

しかしnode_modulesを消して単一ファイルにしなければ持ち運ぶことはできません。
eslintをバンドルします。

エントリーファイルはこうです。
https://github.com/eslint/eslint/blob/main/lib/cli.js#L327
を見ながら作りました。

```javascript:test-bundle/main.js
const cli = require("./node_modules/eslint/lib/cli");
const debug = require("debug")

const CONFIG_PATH = "./.eslintrc.js";
const target = "../target/sample.js";

debug.enable("eslint:*,-eslint:code-path,eslintrc:*");

(async () => {
  await cli.execute(["npx", "eslint", "--config", CONFIG_PATH, target]);
})();
```
動かしてみます。

```console
test-bundle> node main

target\sample.js
  1:10  error  Identifier 'snake_case' is not in camel case  camelcase
  1:10  error  'snake_case' is defined but never used        no-unused-vars

✖ 2 problems (2 errors, 0 warnings)
```

無事動きました。
それではバンドルしてみます。

```console
test-bundle> npx esbuild main.js --bundle --platform=node --outfile=dist.js

  dist.js  3.6mb

Done in 1017ms

test-bundle> node dist
  eslint:cli CLI args: [ '--config', './.eslintrc.js', '../target/sample.js' ] +0ms
  eslint:cli Using flat config? undefined +3ms
  eslint:cli Running on files +4ms
  eslintrc:config-array-factory Loading JSON config file: test-bundle\package.json +0ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\.eslintrc.js +2ms
  eslintrc:config-array-factory Loading {extends:"airbnb-base"} relative to test-bundle\.eslintrc.js +9ms
  eslintrc:config-array-factory Loaded: eslint-config-airbnb-base@15.0.0 (test-bundle\node_modules\eslint-config-airbnb-base\index.js) +13ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\best-practices.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +6ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\best-practices.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\best-practices.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\best-practices.js) +1ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\best-practices.js +0ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\errors.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +4ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\errors.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\errors.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\errors.js) +0ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\errors.js +1ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\node.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +3ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\node.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +3ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\node.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\node.js) +0ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\node.js +1ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\style.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +3ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\style.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\style.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\style.js) +1ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\style.js +0ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\variables.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +37ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\variables.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\variables.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\variables.js) +2ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\variables.js +1ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\es6.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +13ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\es6.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +0ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\es6.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\es6.js) +1ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\es6.js +0ms
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\imports.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +4ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\imports.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\imports.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\imports.js) +0ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\imports.js +1ms
  eslintrc:config-array-factory Loading plugin "import" from test-bundle\node_modules\eslint-config-airbnb-base\rules\imports.js +3ms
  eslintrc:config-array-factory Loaded: eslint-plugin-import@2.29.1 (test-bundle\node_modules\eslint-plugin-import\lib\index.js) +5ms
  eslintrc:config-array-factory Plugin test-bundle\node_modules\eslint-plugin-import\lib\index.js loaded in: 1906ms +2s
  eslintrc:config-array-factory Loading {extends:"C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\strict.js"} relative to test-bundle\node_modules\eslint-config-airbnb-base\index.js +1ms
  eslintrc:config-array-factory package.json was not found: Cannot find module 'test-bundle\node_modules\eslint-config-airbnb-base\rules\strict.js/package.json'
Require stack:
- test-bundle\node_modules\eslint-config-airbnb-base\index.js +2ms
  eslintrc:config-array-factory Loaded: test-bundle\node_modules\eslint-config-airbnb-base\rules\strict.js (test-bundle\node_modules\eslint-config-airbnb-base\rules\strict.js) +0ms
  eslintrc:config-array-factory Loading JS config file: test-bundle\node_modules\eslint-config-airbnb-base\rules\strict.js +1ms
  eslintrc:ignore-pattern Create with: [ _IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: 'C:\work\\test-bundle', loose: false } ] +0ms
  eslintrc:ignore-pattern   processed: { basePath: 'C:\work\\test-bundle', patterns: [ '/**/node_modules/*' ] } +2ms
  eslintrc:ignore-pattern Create with: [ _IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: 'C:\work\\test-bundle', loose: false } ] +1ms
  eslintrc:ignore-pattern   processed: { basePath: 'C:\work\\test-bundle', patterns: [ '/**/node_modules/*' ] } +0ms
  eslint:file-enumerator Start to iterate files: [ '../target/sample.js' ] +0ms
  eslint:file-enumerator File: target\sample.js +1ms
  eslintrc:cascading-config-array-factory Load config files for target. +0ms
  eslintrc:cascading-config-array-factory No cache found: target. +1ms
  eslintrc:config-array-factory Config file not found on target +12ms
  eslintrc:cascading-config-array-factory No cache found: C:\work. +3ms
  eslintrc:config-array-factory Config file not found on C:\work +3ms
  eslintrc:cascading-config-array-factory Stop traversing because of considered root. +1ms
  eslintrc:cascading-config-array-factory Configuration was determined: ConfigArray(11) [ { type: 'config', name: 'DefaultIgnorePattern', filePath: '', criteria: null, env: undefined, globals: undefined, ignorePattern: _IgnorePattern { patterns: [Array], basePath: 'C:\work\\test-bundle', loose: false }, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: undefined, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\best-practices.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\best-practices.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'accessor-pairs': 'off', 'array-callback-return': [Array], 'block-scoped-var': 'error', complexity: [Array], 'class-methods-use-this': [Array], 'consistent-return': 'error', curly: [Array], 'default-case': [Array], 'default-case-last': 'error', 'default-param-last': 'error', 'dot-notation': [Array], 'dot-location': [Array], eqeqeq: [Array], 'grouped-accessor-pairs': 'error', 'guard-for-in': 'error', 'max-classes-per-file': [Array], 'no-alert': 'warn', 'no-caller': 'error', 'no-case-declarations': 'error', 'no-constructor-return': 'error', 'no-div-regex': 'off', 'no-else-return': [Array], 'no-empty-function': [Array], 'no-empty-pattern': 'error', 'no-eq-null': 'off', 'no-eval': 'error', 'no-extend-native': 'error', 'no-extra-bind': 'error', 'no-extra-label': 'error', 'no-fallthrough': 'error', 'no-floating-decimal': 'error', 'no-global-assign': [Array], 'no-native-reassign': 'off', 'no-implicit-coercion': [Array], 'no-implicit-globals': 'off', 'no-implied-eval': 'error', 'no-invalid-this': 'off', 'no-iterator': 'error', 'no-labels': [Array], 'no-lone-blocks': 'error', 'no-loop-func': 'error', 'no-magic-numbers': [Array], 'no-multi-spaces': [Array], 'no-multi-str': 'error', 'no-new': 'error', 'no-new-func': 'error', 'no-new-wrappers': 'error', 'no-nonoctal-decimal-escape': 'error', 'no-octal': 'error', 'no-octal-escape': 'error', 'no-param-reassign': [Array], 'no-proto': 'error', 'no-redeclare': 'error', 'no-restricted-properties': [Array], 'no-return-assign': [Array], 'no-return-await': 'error', 'no-script-url': 'error', 'no-self-assign': [Array], 'no-self-compare': 'error', 'no-sequences': 'error', 'no-throw-literal': 'error', 'no-unmodified-loop-condition': 'off', 'no-unused-expressions': [Array], 'no-unused-labels': 'error', 'no-useless-call': 'off', 'no-useless-catch': 'error', 'no-useless-concat': 'error', 'no-useless-escape': 'error', 'no-useless-return': 'error', 'no-void': 'error', 'no-warning-comments': [Array], 'no-with': 'error', 'prefer-promise-reject-errors': [Array], 'prefer-named-capture-group': 'off', 'prefer-regex-literals': [Array], radix: 'error', 'require-await': 'off', 'require-unicode-regexp': 'off', 'vars-on-top': 'error', 'wrap-iife': [Array], yoda: 'error' }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\errors.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\errors.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'for-direction': 'error', 'getter-return': [Array], 'no-async-promise-executor': 'error', 'no-await-in-loop': 'error', 'no-compare-neg-zero': 'error', 'no-cond-assign': [Array], 'no-console': 'warn', 'no-constant-condition': 'warn', 'no-control-regex': 'error', 'no-debugger': 'error', 'no-dupe-args': 'error', 'no-dupe-else-if': 'error', 'no-dupe-keys': 'error', 'no-duplicate-case': 'error', 'no-empty': 'error', 'no-empty-character-class': 'error', 'no-ex-assign': 'error', 'no-extra-boolean-cast': 'error', 'no-extra-parens': [Array], 'no-extra-semi': 'error', 'no-func-assign': 'error', 'no-import-assign': 'error', 'no-inner-declarations': 'error', 'no-invalid-regexp': 'error', 'no-irregular-whitespace': 'error', 'no-loss-of-precision': 'error', 'no-misleading-character-class': 'error', 'no-obj-calls': 'error', 'no-promise-executor-return': 'error', 'no-prototype-builtins': 'error', 'no-regex-spaces': 'error', 'no-setter-return': 'error', 'no-sparse-arrays': 'error', 'no-template-curly-in-string': 'error', 'no-unexpected-multiline': 'error', 'no-unreachable': 'error', 'no-unreachable-loop': [Array], 'no-unsafe-finally': 'error', 'no-unsafe-negation': 'error', 'no-unsafe-optional-chaining': [Array], 'no-unused-private-class-members': 'off', 'no-useless-backreference': 'error', 'no-negated-in-lhs': 'off', 'require-atomic-updates': 'off', 'use-isnan': 'error', 'valid-jsdoc': 'off', 'valid-typeof': [Array] }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\node.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\node.js', criteria: null, env: { node: true }, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'callback-return': 'off', 'global-require': 'error', 'handle-callback-err': 'off', 'no-buffer-constructor': 'error', 'no-mixed-requires': [Array], 'no-new-require': 'error', 'no-path-concat': 'error', 'no-process-env': 'off', 'no-process-exit': 'off', 'no-restricted-modules': 'off', 'no-sync': 'off' }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\style.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\style.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'array-bracket-newline': [Array], 'array-element-newline': [Array], 'array-bracket-spacing': [Array], 'block-spacing': [Array], 'brace-style': [Array], camelcase: [Array], 'capitalized-comments': [Array], 'comma-dangle': [Array], 'comma-spacing': [Array], 'comma-style': [Array], 'computed-property-spacing': [Array], 'consistent-this': 'off', 'eol-last': [Array], 'function-call-argument-newline': [Array], 'func-call-spacing': [Array], 'func-name-matching': [Array], 'func-names': 'warn', 'func-style': [Array], 'function-paren-newline': [Array], 'id-denylist': 'off', 'id-length': 'off', 'id-match': 'off', 'implicit-arrow-linebreak': [Array], indent: [Array], 'jsx-quotes': [Array], 'key-spacing': [Array], 'keyword-spacing': [Array], 'line-comment-position': [Array], 'linebreak-style': [Array], 'lines-between-class-members': [Array], 'lines-around-comment': 'off', 'lines-around-directive': [Array], 'max-depth': [Array], 'max-len': [Array], 'max-lines': [Array], 'max-lines-per-function': [Array], 'max-nested-callbacks': 'off', 'max-params': [Array], 'max-statements': [Array], 'max-statements-per-line': [Array], 'multiline-comment-style': [Array], 'multiline-ternary': [Array], 'new-cap': [Array], 'new-parens': 'error', 'newline-after-var': 'off', 'newline-before-return': 'off', 'newline-per-chained-call': [Array], 'no-array-constructor': 'error', 'no-bitwise': 'error', 'no-continue': 'error', 'no-inline-comments': 'off', 'no-lonely-if': 'error', 'no-mixed-operators': [Array], 'no-mixed-spaces-and-tabs': 'error', 'no-multi-assign': [Array], 'no-multiple-empty-lines': [Array], 'no-negated-condition': 'off', 'no-nested-ternary': 'error', 'no-new-object': 'error', 'no-plusplus': 'error', 'no-restricted-syntax': [Array], 'no-spaced-func': 'error', 'no-tabs': 'error', 'no-ternary': 'off', 'no-trailing-spaces': [Array], 'no-underscore-dangle': [Array], 'no-unneeded-ternary': [Array], 'no-whitespace-before-property': 'error', 'nonblock-statement-body-position': [Array], 'object-curly-spacing': [Array], 'object-curly-newline': [Array], 'object-property-newline': [Array], 'one-var': [Array], 'one-var-declaration-per-line': [Array], 'operator-assignment': [Array], 'operator-linebreak': [Array], 'padded-blocks': [Array], 'padding-line-between-statements': 'off', 'prefer-exponentiation-operator': 'error', 'prefer-object-spread': 'error', 'quote-props': [Array], quotes: [Array], 'require-jsdoc': 'off', semi: [Array], 'semi-spacing': [Array], 'semi-style': [Array], 'sort-keys': [Array], 'sort-vars': 'off', 'space-before-blocks': 'error', 'space-before-function-paren': [Array], 'space-in-parens': [Array], 'space-infix-ops': 'error', 'space-unary-ops': [Array], 'spaced-comment': [Array], 'switch-colon-spacing': [Array], 'template-tag-spacing': [Array], 'unicode-bom': [Array], 'wrap-regex': 'off' }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\variables.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\variables.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'init-declarations': 'off', 'no-catch-shadow': 'off', 'no-delete-var': 'error', 'no-label-var': 'error', 'no-restricted-globals': [Array], 'no-shadow': 'error', 'no-shadow-restricted-names': 'error', 'no-undef': 'error', 'no-undef-init': 'error', 'no-undefined': 'off', 'no-unused-vars': [Array], 'no-use-before-define': [Array] }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\es6.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\es6.js', criteria: null, env: { es6: true }, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: { ecmaVersion: 6, sourceType: 'module', ecmaFeatures: [Object] }, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'arrow-body-style': [Array], 'arrow-parens': [Array], 'arrow-spacing': [Array], 'constructor-super': 'error', 'generator-star-spacing': [Array], 'no-class-assign': 'error', 'no-confusing-arrow': [Array], 'no-const-assign': 'error', 'no-dupe-class-members': 'error', 'no-duplicate-imports': 'off', 'no-new-symbol': 'error', 'no-restricted-exports': [Array], 'no-restricted-imports': [Array], 'no-this-before-super': 'error', 'no-useless-computed-key': 'error', 'no-useless-constructor': 'error', 'no-useless-rename': [Array], 'no-var': 'error', 'object-shorthand': [Array], 'prefer-arrow-callback': [Array], 'prefer-const': [Array], 'prefer-destructuring': [Array], 'prefer-numeric-literals': 'error', 'prefer-reflect': 'off', 'prefer-rest-params': 'error', 'prefer-spread': 'error', 'prefer-template': 'error', 'require-yield': 'error', 'rest-spread-spacing': [Array], 'sort-imports': [Array], 'symbol-description': 'error', 'template-curly-spacing': 'error', 'yield-star-spacing': [Array] }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\imports.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\imports.js', criteria: null, env: { es6: true }, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: { ecmaVersion: 6, sourceType: 'module' }, plugins: { import: [Object] }, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { 'import/no-unresolved': [Array], 'import/named': 'error', 'import/default': 'off', 'import/namespace': 'off', 'import/export': 'error', 'import/no-named-as-default': 'error', 'import/no-named-as-default-member': 'error', 'import/no-deprecated': 'off', 'import/no-extraneous-dependencies': [Array], 'import/no-mutable-exports': 'error', 'import/no-commonjs': 'off', 'import/no-amd': 'error', 'import/no-nodejs-modules': 'off', 'import/first': 'error', 'import/imports-first': 'off', 'import/no-duplicates': 'error', 'import/no-namespace': 'off', 'import/extensions': [Array], 'import/order': [Array], 'import/newline-after-import': 'error', 'import/prefer-default-export': 'error', 'import/no-restricted-paths': 'off', 'import/max-dependencies': [Array], 'import/no-absolute-path': 'error', 'import/no-dynamic-require': 'error', 'import/no-internal-modules': [Array], 'import/unambiguous': 'off', 'import/no-webpack-loader-syntax': 'error', 'import/no-unassigned-import': 'off', 'import/no-named-default': 'error', 'import/no-anonymous-default-export': [Array], 'import/exports-last': 'off', 'import/group-exports': 'off', 'import/no-default-export': 'off', 'import/no-named-export': 'off', 'import/no-self-import': 'error', 'import/no-cycle': [Array], 'import/no-useless-path-segments': [Array], 'import/dynamic-import-chunkname': [Array], 'import/no-relative-parent-imports': 'off', 'import/no-unused-modules': [Array], 'import/no-import-module-exports': [Array], 'import/no-relative-packages': 'error' }, settings: { 'import/resolver': [Object], 'import/extensions': [Array], 'import/core-modules': [], 'import/ignore': [Array] } }, { type: 'config', name: '--config » eslint-config-airbnb-base » C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\strict.js', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\rules\\strict.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: undefined, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: { strict: [Array] }, settings: undefined }, { type: 'config', name: '--config » eslint-config-airbnb-base', filePath: 'C:\work\\test-bundle\\node_modules\\eslint-config-airbnb-base\\index.js', criteria: null, env: undefined, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: undefined, rules: {}, settings: undefined }, { type: 'config', name: '--config', filePath: 'C:\work\\test-bundle\\.eslintrc.js', criteria: null, env: { node: true }, globals: undefined, ignorePattern: undefined, noInlineConfig: undefined, parser: undefined, parserOptions: { ecmaVersion: 'latest' }, plugins: undefined, processor: undefined, reportUnusedDisableDirectives: undefined, root: true, rules: undefined, settings: undefined } ] on target +109ms
  eslintrc:ignore-pattern Create with: [ _IgnorePattern { patterns: [ '/**/node_modules/*' ], basePath: 'C:\work\\test-bundle', loose: false } ] +137ms
  eslintrc:ignore-pattern   processed: { basePath: 'C:\work\\test-bundle', patterns: [ '/**/node_modules/*' ] } +1ms
  eslintrc:ignore-pattern Check {
  filePath: 'C:\work\\target\\sample.js',
  dot: false,
  relativePath: '../target/sample.js',
  result: false
} +1ms
  eslint:cli-engine Lint target\sample.js +0ms
  eslint:linter Linting code for target\sample.js (pass 1) +0ms
  eslint:linter Verify +0ms
  eslint:linter With ConfigArray: target\sample.js +1ms
  eslint:linter Parsing: target\sample.js +1ms
  eslint:linter Parsing successful: target\sample.js +4ms
  eslint:linter Scope analysis: target\sample.js +1ms
  eslint:linter Scope analysis successful: target\sample.js +2ms
  eslint:linter Generating fixed text for target\sample.js (pass 1) +43ms
  eslint:source-code-fixer Applying fixes +0ms
  eslint:source-code-fixer shouldFix parameter was false, not attempting fixes +2ms
  eslint:file-enumerator Complete iterating files: ["../target/sample.js"] +196ms
  eslint:cli-engine Linting complete in: 200ms +56ms
There was a problem loading formatter: test-bundle\formatters\stylish
Error: Cannot find module 'test-bundle\formatters\stylish'
Require stack:
- test-bundle\dist.js

test-bundle>
```

だめみたいです。
`test-bundle\formatters\stylish`がないと怒られていますが、これは
`node_modules\eslint\lib\cli\formatters\stylish`にあります。

stylishはダイナミックインポートされているためバンドルされていません。
esbuildではダイナミックインポートをサポートしていませんのでesbuildではできないということになります。
https://github.com/evanw/esbuild/issues/700

やろうと思えばできますがeslintの方もバンドルする使い方は想定指定なさそうです。
eslint以外のリントツールがあればいいですがairbnbが使えるのはない…

あきらめるしかなさそう。

## おまけ

flatconfigならなんとかなるかと思いましたが同じダイナミックインポートができない問題で使えないでここに供養します。


```javascript:scripts/build.js
import fs from 'fs/promises';
import path from 'path';
import { build } from "esbuild";

const DESTINATION='./action/config.js'
const BACKUP_DESTINATION='./action/config.js.bk'

function backup(){
    return fs.rename(DESTINATION,BACKUP_DESTINATION)
}
function restore(){
    return fs.rename(BACKUP_DESTINATION,DESTINATION)
}

async function generateConfig(){
    const TemporaryConfigPath='./eslint.config.dist.js'
    const options = {
        entryPoints: ["./eslint.config.js"],
        minify: false,
        bundle: true,
        outfile: TemporaryConfigPath,
        platform: "node",
        define: {
            "import.meta.url": "import_meta_url",
          },
          inject: [
            path.join(process.cwd(),"scripts", "import-meta-url.js"),
          ],
              };

    await build(options)

    const content = await fs.readFile(TemporaryConfigPath);
    const fileBody=`export default '${Buffer.from(content).toString('base64')}'`
    return await    Promise.all([
        fs.writeFile(DESTINATION,fileBody),
        fs.unlink(TemporaryConfigPath),
    ])
}

async function main(){

    await backup()
    await generateConfig()
    const options = {
        entryPoints: ["./action/src.js"],
        minify: false,
        bundle: true,
        outfile: "./action/dist.js",
        platform: "node",
        
      };

    await build(options)


    await restore()
}

main().catch(async e=>{
    console.error(e)
    const stats=await fs.stat(BACKUP_DESTINATION)
    if(stats.isFile()){
        await restore()
    }
    process.exit(1)
})
```


```javascript:scripts/import-meta-url.js
export var import_meta_url = require("url").pathToFileURL(__filename);
```

結果はこうです。

```console
eslint:cli CLI args: [ '--config', './eslint.config.js', '.' ]
eslint:cli Using flat config? true
eslint:cli Running on files
eslint:flat-eslint calucukateconfig
eslint:flat-eslint Override config file path is ./eslint.config.js
eslint:flat-eslint Loading config from /target/eslint.config.js
eslint:flat-eslint Config file URL is file:///target/eslint.config.js
eslint:flat-eslint Config file URl load  ddfile:///target/eslint.config.js?mtime=1706156930172}
eslint:flat-eslint TypeError: Cannot convert object to primitive value
    at loadFlatConfigFile (/work/dist.js:118410:35)
    at async calculateConfigArray (/work/dist.js:118460:28)
    at async FlatESLint.lintFiles (/work/dist.js:118686:25)
    at async Object.execute (/work/dist.js:121207:21)
    at async /work/dist.js:121275:5
eslint:flat-eslint Config file URl load}
eslint:flat-eslint Config file URl load fin}
eslint:flat-eslint calucukateconfigfinish
eslint:flat-eslint deletecache
eslint:flat-eslint Deleting cache file at /target/.eslintcache
/work/dist.js:109069
            throw new UnexpectedKeyError(key);
            ^

UnexpectedKeyError: Unexpected key "default" found.
    at _ObjectSchema.validate (/work/dist.js:109069:19)
    at /work/dist.js:109044:16
    at Array.reduce (<anonymous>)
    at _ObjectSchema.merge (/work/dist.js:109043:24)
    at /work/dist.js:109625:49
    at Array.reduce (<anonymous>)
    at FlatConfigArray.getConfig (/work/dist.js:109624:45)
    at FlatConfigArray.isFileIgnored (/work/dist.js:109647:21)
    at /work/dist.js:117901:41
    at Array.reduce (<anonymous>)
```