Optional Chaining のエラーをもう一度整理

前回の反省点として、Optional Chainingに問題をすり替えてしまって、結果、混沌としてしまったです。
よくよく考えれば、ts-loaderもbabelも Optional Chaining はサポートしているのであって、こいつらはローダー君は指定されたバージョンのjavascriptへ変換するのがお仕事です。
つまり、ここが原因でエラーがどうとか話しすと話が混乱するのですな。

ということで、もう一度出力されているエラーを見てみる。

## storybook をビルドして発生するエラー

```
ERROR in ./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts& (./node_modules/vue-docgen-loader/lib??ref--12!./node_modules/ts-loader??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&) 8:36
Module parse failed: Unexpected token (8:36)
File was processed with these loaders:
 * ./node_modules/vue-docgen-loader/lib/index.js
 * ./node_modules/vue-docgen-loader/lib/index.js
 * ./node_modules/ts-loader/index.js
 * ./node_modules/vue-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|         const canvas = ref();
|         watch(canvas, () => {
>             const gl = canvas.value?.getContext("webgl");
|             if (gl) {
|                 gl.clearColor(0.0, 0.0, 0.0, 1.0);
 @ ./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts& 1:0-236 1:252-255 1:257-490 1:257-490
 @ ./src/components/_sandbox/WebGL.vue
 @ ./src/components/_sandbox/WebGL.stories.ts
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/vue/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addParameter.js-generated-other-entry.js ./node_modules/@storybook/addon-knobs/dist/preset/addDecorator.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined
 ```

```Module parse failed: Unexpected token (8:36)``` ということは、どうやら期待されていないトークンに遭遇したらしい。
次に、```const gl = canvas.value?.getContext("webgl");```という、ソースコードの場所を明示してくれている。
で、webpackというヤツはルールに従ってloaderがバケツリレーをしながら javascript に置き換えるので、「誰が音を上げた」というのが問題になる。
スタックトレース的なものが表示されているが、コイツが昇順なのか降順なのか、想像はできるが確定できないので、少し手を変えてみる。

## エラーを表示している場所を探す

スクリプト系の言語なら、エラーを表示しているコードを探せるかも、って事で ```You may need an additional loader to handle the result of these loaders.``` を検索してみると ```webpack/lib/ModuleParseError.js``` で検索されていることがわかる。
こいう時のコツとしては、runtimeのエラー文字列っぽくないものを探すのがコツ。

で、このエラー文字列は ModuleParseError の constructor() で使っている（生成している）ことが分かる。
じゃぁ、どこから呼び出されているのかを調べたくなるので、```console.trace()```を追加してみて、再度ビルドしてみる。

```
Trace
    at new ModuleParseError (/Users/teru/git/uilib/node_modules/webpack/lib/ModuleParseError.js:27:12)
    at handleParseError (/Users/teru/git/uilib/node_modules/webpack/lib/NormalModule.js:469:19)
    at /Users/teru/git/uilib/node_modules/webpack/lib/NormalModule.js:503:5
    at /Users/teru/git/uilib/node_modules/webpack/lib/NormalModule.js:358:12
    at /Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at iterateNormalLoaders (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
    at /Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:236:3
    at context.callback (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at Object.module.exports (/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js:28:5)
    at LOADER_EXECUTION (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:119:14)
    at runSyncOrAsync (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:120:4)
    at iterateNormalLoaders (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:232:2)
    at iterateNormalLoaders (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
    at /Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:236:3
    at context.callback (/Users/teru/git/uilib/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
```

ふむ。。。　あ〜 vue-docgen-loader が居るな。。。
こいつ何なんだろうか。。。
まぁ、それは後で調べるにして、もうちょい情報が欲しいから、この constructor() に渡されるパラメータをダンプしてみよう。
定義はこんな感じ```ModuleParseError(module, source, err, loaders)```だったんで。。。

#### module

```js
/* NormalModule */ {
  dependencies: [],
  blocks: [],
  variables: [],
  type: 'javascript/auto',
  context: '/Users/teru/git/uilib/src/components/_sandbox',
  debugId: 1422,
  hash: undefined,
  renderedHash: undefined,
  resolveOptions: {},
  factoryMeta: {},
  warnings: [],
  errors: [],
  buildMeta: { tsLoaderFileVersion: 1 },
  buildInfo: {
    cacheable: true,
    fileDependencies: Set { '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue' },
    contextDependencies: Set {},
    assets: undefined,
    assetsInfo: undefined
  },
  reasons: [
    ModuleReason {
      module: [NormalModule],
      dependency: [HarmonyImportSideEffectDependency],
      explanation: undefined,
      _chunks: null
    },
    ModuleReason {
      module: [NormalModule],
      dependency: [HarmonyImportSpecifierDependency],
      explanation: undefined,
      _chunks: null
    },
    ModuleReason {
      module: [NormalModule],
      dependency: [HarmonyImportSideEffectDependency],
      explanation: undefined,
      _chunks: null
    },
    ModuleReason {
      module: [NormalModule],
      dependency: [HarmonyExportImportedSpecifierDependency],
      explanation: undefined,
      _chunks: null
    }
  ],
  _chunks: SortableSet [Set] {
    _sortFn: [Function: sortById],
    _lastActiveSortFn: null,
    _cache: undefined,
    _cacheOrderIndependent: undefined
  },
  id: null,
  index: null,
  index2: null,
  depth: null,
  issuer: NormalModule {
    dependencies: [
      [HarmonyCompatibilityDependency],
      [HarmonyInitDependency],
      [ConstDependency],
      [HarmonyImportSideEffectDependency],
      [HarmonyExportHeaderDependency],
      [HarmonyExportExpressionDependency],
      [HarmonyImportSpecifierDependency],
      [ConstDependency],
      [HarmonyImportSideEffectDependency],
      [HarmonyExportImportedSpecifierDependency]
    ],
    blocks: [],
    variables: [],
    type: 'javascript/auto',
    context: '/Users/teru/git/uilib/src/components/_sandbox',
    debugId: 1421,
    hash: undefined,
    renderedHash: undefined,
    resolveOptions: {},
    factoryMeta: {},
    warnings: [],
    errors: [],
    buildMeta: { exportsType: 'namespace' },
    buildInfo: {
      cacheable: true,
      fileDependencies: Set {},
      contextDependencies: Set {},
      assets: undefined,
      assetsInfo: undefined,
      strict: true,
      exportsArgument: '__webpack_exports__'
    },
    reasons: [ [ModuleReason], [ModuleReason], [ModuleReason], [ModuleReason] ],
    _chunks: SortableSet [Set] {
      _sortFn: [Function: sortById],
      _lastActiveSortFn: null,
      _cache: undefined,
      _cacheOrderIndependent: undefined
    },
    id: null,
    index: null,
    index2: null,
    depth: null,
    issuer: NormalModule {
      dependencies: [Array],
      blocks: [],
      variables: [],
      type: 'javascript/auto',
      context: '/Users/teru/git/uilib/src/components/_sandbox',
      debugId: 1217,
      hash: undefined,
      renderedHash: undefined,
      resolveOptions: {},
      factoryMeta: {},
      warnings: [],
      errors: [],
      buildMeta: [Object],
      buildInfo: [Object],
      reasons: [Array],
      _chunks: [SortableSet [Set]],
      id: null,
      index: null,
      index2: null,
      depth: null,
      issuer: [NormalModule],
      profile: undefined,
      prefetched: false,
      built: true,
      used: null,
      usedExports: null,
      optimizationBailout: [],
      _rewriteChunkInReasons: undefined,
      useSourceMap: true,
      _source: [OriginalSource],
      request: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue',
      userRequest: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue',
      rawRequest: './WebGL.vue',
      binary: false,
      parser: [Parser],
      generator: JavascriptGenerator {},
      resource: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue',
      matchResource: undefined,
      loaders: [Array],
      error: null,
      _sourceSize: null,
      _buildHash: 'd57de076f7ac96f23ab1c0ce9011f9e8',
      buildTimestamp: 1613107043574,
      _cachedSources: Map {},
      lineToLine: false,
      _lastSuccessfulBuildMeta: [Object],
      _ast: null
    },
    profile: undefined,
    prefetched: false,
    built: true,
    used: null,
    usedExports: null,
    optimizationBailout: [],
    _rewriteChunkInReasons: undefined,
    useSourceMap: true,
    _source: OriginalSource {
      _value: 'import mod from "-!../../../node_modules/vue-docgen-loader/lib/index.js??ref--12!../../../node_modules/ts-loader/index.js??ref--4-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./WebGL.vue?vue&type=script&lang=ts&"; export default mod; export * from "-!../../../node_modules/vue-docgen-loader/lib/index.js??ref--12!../../../node_modules/ts-loader/index.js??ref--4-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./WebGL.vue?vue&type=script&lang=ts&"',
      _name: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/vue-loader/lib/loaders/pitcher.js??ref--4!/Users/teru/git/uilib/node_modules/ts-loader/index.js??ref--4-0!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&'
    },
    request: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/vue-loader/lib/loaders/pitcher.js??ref--4!/Users/teru/git/uilib/node_modules/ts-loader/index.js??ref--4-0!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
    userRequest: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
    rawRequest: './WebGL.vue?vue&type=script&lang=ts&',
    binary: false,
    parser: Parser {
      _pluginCompat: [SyncBailHook],
      hooks: [Object],
      options: {},
      sourceType: 'auto',
      scope: undefined,
      state: undefined,
      comments: undefined
    },
    generator: JavascriptGenerator {},
    resource: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
    matchResource: undefined,
    loaders: [ [Object], [Object], [Object], [Object] ],
    error: null,
    _sourceSize: null,
    _buildHash: '76f6da385d20205e0eefa56e89ec04d1',
    buildTimestamp: 1613107043951,
    _cachedSources: Map {},
    lineToLine: false,
    _lastSuccessfulBuildMeta: { exportsType: 'namespace' },
    _ast: null
  },
  profile: undefined,
  prefetched: false,
  built: true,
  used: null,
  usedExports: null,
  optimizationBailout: [],
  _rewriteChunkInReasons: undefined,
  useSourceMap: true,
  _source: SourceMapSource {
    _value: 'import { defineComponent, ref, watch } from "@vue/composition-api";\n' +
      'export default defineComponent({\n' +
      '    name: "WebGL",\n' +
      '    props: {},\n' +
      '    setup: (props, ctx) => {\n' +
      '        const canvas = ref();\n' +
      '        watch(canvas, () => {\n' +
      '            const gl = canvas.value?.getContext("webgl");\n' +
      '            if (gl) {\n' +
      '                gl.clearColor(0.0, 0.0, 0.0, 1.0);\n' +
      '                gl.clear(gl.COLOR_BUFFER_BIT);\n' +
      '            }\n' +
      '        });\n' +
      '        return { canvas };\n' +
      '    }\n' +
      '});\n',
    _name: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/ts-loader/index.js??ref--4-0!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
    _sourceMap: {
      version: 3,
      file: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue.ts',
      sourceRoot: '',
      sources: [Array],
      names: [],
      mappings: 'AAKA,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAEnE,eAAe,eAAe,CAAC;IAC7B,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,MAAM,GAAG,GAAG,EAAqB,CAAC;QACxC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE;YACjB,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,EAAE,EAAE;gBACN,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBAClC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;aAC/B;QACH,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,CAAC;IACpB,CAAC;CACF,CAAC,CAAC',
      sourcesContent: [Array]
    },
    _originalSource: undefined,
    _innerSourceMap: undefined,
    _removeOriginalSource: undefined
  },
  request: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/ts-loader/index.js??ref--4-0!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
  userRequest: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js??ref--12!/Users/teru/git/uilib/node_modules/ts-loader/index.js??ref--4-0!/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js??vue-loader-options!/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
  rawRequest: '-!../../../node_modules/vue-docgen-loader/lib/index.js??ref--12!../../../node_modules/ts-loader/index.js??ref--4-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./WebGL.vue?vue&type=script&lang=ts&',
  binary: false,
  parser: Parser {
    _pluginCompat: SyncBailHook {
      _args: [Array],
      taps: [Array],
      interceptors: [],
      call: [Function: lazyCompileHook],
      promise: [Function: lazyCompileHook],
      callAsync: [Function: lazyCompileHook],
      _x: undefined
    },
    hooks: {
      evaluateTypeof: [HookMap],
      evaluate: [HookMap],
      evaluateIdentifier: [HookMap],
      evaluateDefinedIdentifier: [HookMap],
      evaluateCallExpressionMember: [HookMap],
      statement: [SyncBailHook],
      statementIf: [SyncBailHook],
      label: [HookMap],
      import: [SyncBailHook],
      importSpecifier: [SyncBailHook],
      export: [SyncBailHook],
      exportImport: [SyncBailHook],
      exportDeclaration: [SyncBailHook],
      exportExpression: [SyncBailHook],
      exportSpecifier: [SyncBailHook],
      exportImportSpecifier: [SyncBailHook],
      varDeclaration: [HookMap],
      varDeclarationLet: [HookMap],
      varDeclarationConst: [HookMap],
      varDeclarationVar: [HookMap],
      canRename: [HookMap],
      rename: [HookMap],
      assigned: [HookMap],
      assign: [HookMap],
      typeof: [HookMap],
      importCall: [SyncBailHook],
      call: [HookMap],
      callAnyMember: [HookMap],
      new: [HookMap],
      expression: [HookMap],
      expressionAnyMember: [HookMap],
      expressionConditionalOperator: [SyncBailHook],
      expressionLogicalOperator: [SyncBailHook],
      program: [SyncBailHook],
      hotAcceptCallback: [SyncBailHook],
      hotAcceptWithoutCallback: [SyncBailHook]
    },
    options: {},
    sourceType: 'auto',
    scope: undefined,
    state: undefined,
    comments: undefined
  },
  generator: JavascriptGenerator {},
  resource: '/Users/teru/git/uilib/src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&',
  matchResource: undefined,
  loaders: [
    {
      options: [Object],
      ident: 'ref--12',
      loader: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js'
    },
    {
      loader: '/Users/teru/git/uilib/node_modules/vue-docgen-loader/lib/index.js',
      options: [Object],
      ident: 'ref--12'
    },
    {
      loader: '/Users/teru/git/uilib/node_modules/ts-loader/index.js',
      options: [Object],
      ident: 'ref--4-0'
    },
    {
      loader: '/Users/teru/git/uilib/node_modules/vue-loader/lib/index.js',
      options: {},
      ident: 'vue-loader-options'
    }
  ],
  error: null,
  _sourceSize: null,
  _buildHash: '',
  buildTimestamp: 1613107043952,
  _cachedSources: Map {},
  lineToLine: false,
  _lastSuccessfulBuildMeta: {},
  _ast: null
}
```

#### source

```js
import { defineComponent, ref, watch } from "@vue/composition-api";
export default defineComponent({
    name: "WebGL",
    props: {},
    setup: (props, ctx) => {
        const canvas = ref();
        watch(canvas, () => {
            const gl = canvas.value?.getContext("webgl");
            if (gl) {
                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                gl.clear(gl.COLOR_BUFFER_BIT);
            }
        });
        return { canvas };
    }
});
```

#### err

```
SyntaxError: Unexpected token (8:36)
    at Parser.pp$4.raise (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2825:15)
    at Parser.pp.unexpected (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:689:10)
    at Parser.pp$3.parseExprAtom (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2270:12)
    at Parser.pp$3.parseExprSubscripts (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2089:21)
    at Parser.pp$3.parseMaybeUnary (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2066:19)
    at Parser.pp$3.parseExprOps (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2010:21)
    at Parser.pp$3.parseMaybeConditional (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1993:21)
    at Parser.pp$3.parseMaybeAssign (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1968:21)
    at Parser.pp$3.parseMaybeConditional (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1998:30)
    at Parser.pp$3.parseMaybeAssign (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1968:21)
    at Parser.pp$1.parseVar (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1228:26)
    at Parser.pp$1.parseVarStatement (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1092:10)
    at Parser.pp$1.parseStatement (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:842:19)
    at Parser.pp$1.parseBlock (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:1161:23)
    at Parser.pp$3.parseFunctionBody (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2671:24)
    at Parser.pp$3.parseArrowExpression (/Users/teru/git/uilib/node_modules/acorn/dist/acorn.js:2634:10) {
  pos: 260,
  loc: Position { line: 8, column: 36 },
  raisedAt: 261
}
```

#### loaders

```js
[
  './node_modules/vue-docgen-loader/lib/index.js',
  './node_modules/vue-docgen-loader/lib/index.js',
  './node_modules/ts-loader/index.js',
  './node_modules/vue-loader/lib/index.js'
]
```

ここにきて、ようやくエラーの根源を発見！（実は、当初のビルドで表示されているんだけどね）
```acorn``` が例外投げてるっぽい。
で、```acorn```って、何者だ？

あと、errのスタックトレースが acorn 内で終わっているので、そもそも、これ呼び出しているのは誰？って事で調べてみる。

## エラーの根源

もう一度、整理すると。

* ModuleParseError でエラーが構成されているが、これは発生したエラーを受け、表示用にエラーを構成しているもので、エラーそのものではない。
* ModuleParseError を誰かが呼び出している。
* エラーの発生は ```acorn``` で確定。

ということで、ModuleParseError って誰が呼び出しているのかを調べてみる。

### ModuleParseError の生成箇所を追う

とりあえず、検索してみると ```NormalModule.js``` で生成していることが分かる。
そして、NormalModule.build() 内で、 doBuild() を呼び出し、ここのコールバックで生成している。
で、条件としては、 ```this.parser.parse()``` でエラーが発生した時、または、```this.parser.parse()```が例外を発生させた時のみ。
念の為、この２つのケースに ```console.log()``` を入れてみて確認してみると、catch節で ModuleParseError が生成されることを確認した。

### acorn って何者？

で、javascriptのパーサーでした。
npm で週4千万ダウンロードされてる、神様的なライブラリですね。
いつもお世話になっているのに、知らなくてゴメンね。
で、この子は、文字列とパラメータを与えると、構文解析して、ESTree Specにくれるものみたいです。

https://github.com/acornjs/acorn/tree/master/acorn

つまり、この子が理解できないと例外を発生させたのですが、最新の acorn 8.0.5 は ECMA12までサポートしてます。
storybook が使っている acorn はというと。。。　storybook -> webpack -> acorn で 7.1.0 か。。。
どうなんだろう？　これかな？

### そういえば NormalModule って？

そうそう、エラー出しているのは NormalModule の ```this.parser.parse()``` だったっけ。
ところで、こいつの ```this.parser``` って何者なんだ？
acron にも parse() って関数あるんだけど、引数違うから、まだ途中に誰か居るな。

ということで、 NormalModule.parser は誰なのか追ってみる。

どうやら、```this.parser```に代入している箇所は、constructor() と updateCacheModule() だが、取り敢えず、何者かを知りたいので、constructor に絞って探してみる。
（あ〜、動的型付け言語は追いづれ〜〜〜）
試しに、 "new NormalModule" で検索してみると、```NormalModuleFactory.js``` がヒットするので、何となくコレっぽい。

```js
  let createdModule = this.hooks.createModule.call(result);
  if (!createdModule) {
    if (!result.request) {
      return callback(new Error("Empty dependency (no request)"));
    }

    createdModule = new NormalModule(result);
  }
```

が、こいつ、条件付きで new されるみたいで、hook とかいうヤツが生成する場合がある（どっちが多いんだか分からん）。

ちと、 NormalModule って、資料ないのかと調べてみる。

https://webpack.js.org/api/loaders/

あれ？　webpack 本家サイトで "NormalObject" が登場するのはここしかない。
NormalObject を生成するファクトリについては解説しているが。。。
https://webpack.js.org/api/normalmodulefactory-hooks/

何だ？　知ってて当然で、知らない人はお断り的なヤツなんか？
まぁ、実際はwebpackの内部クラスで、webpack作っている方々以外は触るもんじゃないんでしょう。
で、NormalModuleを置き換えるプラグイン的な切り口については解説してますな。
https://webpack.js.org/plugins/normal-module-replacement-plugin/

ここまでくると、デバッガで動かさないと分からん。。。
ひとます、置いといて。。。

え〜っと、何やってるんだっけ？（苦笑）

## 残りは vue-docgen-loader

こいつは、vue を解析して、propertyやらeventやらを抽出する便利なヤツです。
こいつが動くってことは、誰かが呼び出しているはずなので探してみると。。。。
@storybook/addon-docs の中で、webpackFilnal() 関数の中におりました。
まともに動かないのを覚悟で、 vue-docgen-loader を module.rules に追加している箇所をコメントアウトしてみると。

```
ERROR in ./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts& (./node_modules/ts-loader??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts&) 8:36
Module parse failed: Unexpected token (8:36)
File was processed with these loaders:
 * ./node_modules/ts-loader/index.js
 * ./node_modules/vue-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|         const canvas = ref();
|         watch(canvas, () => {
>             const gl = canvas.value?.getContext("webgl");
|             if (gl) {
|                 gl.clearColor(0.0, 0.0, 0.0, 1.0);
 @ ./src/components/_sandbox/WebGL.vue?vue&type=script&lang=ts& 1:0-174 1:190-193 1:195-366 1:195-366
 @ ./src/components/_sandbox/WebGL.vue
 @ ./src/components/_sandbox/WebGL.stories.ts
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/vue/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/addParameter.js-generated-other-entry.js ./node_modules/@storybook/addon-knobs/dist/preset/addDecorator.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined
 ```

まだエラー出てるけど、vue-docgen-loader がエラー出てるんじゃないのね。
で、更に、webpackの設定周りを追っていると、 ```iframe-webpack.config.js``` にぶちあたり、"generated-stories-entry.js" という、エラーで見かけた文字列を発見。

こりゃ、まだ続くな。。。

## 取り敢えず、これまでの解析結果は。。。

* storybook で Optional Chaining を使うとエラーになる
* tsconfig.json で　target を ES6 にするとエラーはなくなる
* エラーの発生に関連するものは。。。
  * acron（例外発生場所）
  * webpack の NormalModule.build() （エラーハンドリング場所）
  * vue-docgen-loader