From 6f9a48559ff9c597f39ad6447ee719979f986c23 Mon Sep 17 00:00:00 2001 From: johnnyreilly Date: Tue, 10 Nov 2026 18:31:03 +0000 Subject: [PATCH] refactor: make the loader an async function Replace the callback-threading (`successLoader` / `makeSourceMapAndFinish`) with a single `async compile()` that returns `{ output, sourceMap }` or throws, and convert `mapToInputSourceMap` to async/await. `this.async()` is still called once: webpack only forwards `content` from a loader's returned promise, so returning would drop the source map. Comparison snapshots updated for the renamed stack frames only. Co-Authored-By: Claude Opus 5.5 --- src/index.ts | 213 +++++++----------- .../expectedOutput/bundle.js | 2 +- .../expectedOutput/output.txt | 7 +- .../expectedOutput-transpile/bundle.js | 2 +- .../expectedOutput-transpile/output.txt | 5 +- .../tsconfigInvalid/expectedOutput/bundle.js | 2 +- .../tsconfigInvalid/expectedOutput/output.txt | 5 +- .../expectedOutput-transpile/bundle.js | 2 +- .../expectedOutput-transpile/output.txt | 8 +- .../expectedOutput/bundle.js | 2 +- .../expectedOutput/output.txt | 8 +- 11 files changed, 101 insertions(+), 155 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0f7803ddc..63be67619 100644 --- a/src/index.ts +++ b/src/index.ts @@ -39,61 +39,79 @@ const canUseSourceMapConsumer = const loaderOptionsCache: LoaderOptionsCache = {}; -function loader( +async function loader( this: webpack.LoaderContext, contents: string, inputSourceMap?: Record, ) { // eslint-disable-next-line @typescript-eslint/no-unused-expressions this.cacheable && this.cacheable(); + // Still needed despite `async`: webpack only takes `content` from a + // returned promise, so the source map has to go through the callback. const callback = this.async(); - const configParseErrorMessage = successLoader( - this, - contents, - inputSourceMap, - callback, - ); - if (configParseErrorMessage !== undefined) { - // Reconstructed here, in `loader`'s own frame, so the stack trace - // matches classic ts-loader's single `at Object.loader (...)` frame. - callback(new Error(configParseErrorMessage)); + let result: { output: string; sourceMap: RawSourceMap | undefined }; + try { + result = await compile(this, contents, inputSourceMap); + } catch (error) { + callback(error instanceof Error ? error : new Error(String(error))); + return; } + callback(null, result.output, result.sourceMap); } -function successLoader( +async function compile( loaderContext: webpack.LoaderContext, contents: string, inputSourceMap: Record | undefined, - callback: ReturnType['async']>, -): string | undefined { - try { - const options = getLoaderOptions(loaderContext); - const instance = getTypeScriptInstance(options, loaderContext); - const rawFilePath = path.normalize(loaderContext.resourcePath); - const filePath = appendSuffixesIfRequired(rawFilePath, options); - const fileVersion = updateFileInCache(filePath, contents, instance); - const { outputText, sourceMapText, configParseErrorMessage } = - getTypeScriptEmit(filePath, contents, instance, loaderContext); - - if (configParseErrorMessage !== undefined) { - return configParseErrorMessage; - } +) { + const options = getLoaderOptions(loaderContext); + const instance = getTypeScriptInstance(options, loaderContext); + const rawFilePath = path.normalize(loaderContext.resourcePath); + const filePath = appendSuffixesIfRequired(rawFilePath, options); + const fileVersion = updateFileInCache(filePath, contents, instance); + const { outputText, sourceMapText, configParseErrorMessage } = + getTypeScriptEmit(filePath, contents, instance, loaderContext); - makeSourceMapAndFinish( - sourceMapText, - outputText, - filePath, - contents, - loaderContext, - fileVersion, - callback, - options.allowTsInNodeModules, - inputSourceMap, + if (configParseErrorMessage !== undefined) { + throw new Error(configParseErrorMessage); + } + + setModuleMeta(loaderContext, fileVersion); + + if (outputText === null || outputText === undefined) { + // Most commonly a node_modules file: the API skips emit for external + // library files. + const additionalGuidance = + !options.allowTsInNodeModules && filePath.indexOf('node_modules') !== -1 + ? ' By default, ts-loader will not compile .ts files in node_modules.\n' + + 'You should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option.\n' + + 'See: https://github.com/Microsoft/TypeScript/issues/12358' + : ''; + throw new Error( + `TypeScript emitted no output for ${filePath}.${additionalGuidance}`, ); - } catch (error) { - callback(error instanceof Error ? error : new Error(String(error))); } - return undefined; + + const { sourceMap, output } = makeSourceMap( + sourceMapText, + outputText, + filePath, + contents, + loaderContext, + ); + + if (sourceMap === undefined || !inputSourceMap || !canUseSourceMapConsumer) { + return { output, sourceMap }; + } + + return { + output, + sourceMap: await mapToInputSourceMap( + sourceMap, + loaderContext, + inputSourceMap as unknown as RawSourceMap, + ), + }; } function getTypeScriptInstance( @@ -515,65 +533,6 @@ function arrify(value: T | T[] | undefined) { return value === undefined ? [] : Array.isArray(value) ? value : [value]; } -function makeSourceMapAndFinish( - sourceMapText: string | undefined, - outputText: string | undefined, - filePath: string, - contents: string, - loaderContext: webpack.LoaderContext, - fileVersion: number, - callback: ReturnType['async']>, - allowTsInNodeModules: boolean, - inputSourceMap?: Record, -) { - if (outputText === null || outputText === undefined) { - setModuleMeta(loaderContext, fileVersion); - // Most commonly a node_modules file: the API skips emit for external - // library files. - const additionalGuidance = - !allowTsInNodeModules && filePath.indexOf('node_modules') !== -1 - ? ' By default, ts-loader will not compile .ts files in node_modules.\n' + - 'You should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option.\n' + - 'See: https://github.com/Microsoft/TypeScript/issues/12358' - : ''; - callback( - new Error( - `TypeScript emitted no output for ${filePath}.${additionalGuidance}`, - ), - outputText, - undefined, - ); - return; - } - - const { sourceMap, output } = makeSourceMap( - sourceMapText, - outputText, - filePath, - contents, - loaderContext, - ); - - setModuleMeta(loaderContext, fileVersion); - - if (sourceMap === undefined || !inputSourceMap || !canUseSourceMapConsumer) { - callback(null, output, sourceMap); - return; - } - - mapToInputSourceMap( - sourceMap, - loaderContext, - inputSourceMap as unknown as RawSourceMap, - ) - .then(mappedSourceMap => { - callback(null, output, mappedSourceMap); - }) - .catch((e: Error) => { - callback(e); - }); -} - function setModuleMeta( loaderContext: webpack.LoaderContext, fileVersion: number, @@ -604,46 +563,32 @@ function makeSourceMap( }; } -function mapToInputSourceMap( +async function mapToInputSourceMap( sourceMap: RawSourceMap, loaderContext: webpack.LoaderContext, inputSourceMap: RawSourceMap, ): Promise { - return new Promise((resolve, reject) => { - const inMap: RawSourceMap = { - file: loaderContext.remainingRequest, - mappings: inputSourceMap.mappings, - names: inputSourceMap.names, - sources: inputSourceMap.sources, - sourceRoot: inputSourceMap.sourceRoot, - sourcesContent: inputSourceMap.sourcesContent, - version: inputSourceMap.version, - }; - Promise.all([ - new SourceMapConsumer(inMap), - new SourceMapConsumer(sourceMap), - ]) - .then(sourceMapConsumers => { - try { - const generator = SourceMapGenerator.fromSourceMap( - sourceMapConsumers[1], - ); - generator.applySourceMap(sourceMapConsumers[0]); - const mappedSourceMap = generator.toJSON(); - - sourceMapConsumers.forEach(sourceMapConsumer => - sourceMapConsumer.destroy(), - ); - resolve(mappedSourceMap); - } catch (e) { - sourceMapConsumers.forEach(sourceMapConsumer => - sourceMapConsumer.destroy(), - ); - reject(e); - } - }) - .catch(reject); - }); + const inMap: RawSourceMap = { + file: loaderContext.remainingRequest, + mappings: inputSourceMap.mappings, + names: inputSourceMap.names, + sources: inputSourceMap.sources, + sourceRoot: inputSourceMap.sourceRoot, + sourcesContent: inputSourceMap.sourcesContent, + version: inputSourceMap.version, + }; + const [inputConsumer, outputConsumer] = await Promise.all([ + new SourceMapConsumer(inMap), + new SourceMapConsumer(sourceMap), + ]); + try { + const generator = SourceMapGenerator.fromSourceMap(outputConsumer); + generator.applySourceMap(inputConsumer); + return generator.toJSON(); + } finally { + inputConsumer.destroy(); + outputConsumer.destroy(); + } } export = loader; diff --git a/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/bundle.js b/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/bundle.js index 37dbf6b0c..4a2aa6f0f 100644 --- a/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/bundle.js +++ b/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/bundle.js @@ -26,7 +26,7 @@ eval("{\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\ncon \*********************************/ /***/ (() => { -eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: TypeScript emitted no output for /nodeModulesMeaningfulErrorWhenImportingTs/node_modules/a/index.ts. By default, ts-loader will not compile .ts files in node_modules./nYou should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option./nSee: https://github.com/Microsoft/TypeScript/issues/12358/n at makeSourceMapAndFinish (/Users/johnreilly/code/github/ts-loader/dist/index.js:336:18)/n at successLoader (/Users/johnreilly/code/github/ts-loader/dist/index.js:75:9)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:57:37)\");\n\n//# sourceURL=webpack:///./node_modules/a/index.ts?\n}"); +eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: TypeScript emitted no output for /nodeModulesMeaningfulErrorWhenImportingTs/node_modules/a/index.ts. By default, ts-loader will not compile .ts files in node_modules./nYou should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option./nSee: https://github.com/Microsoft/TypeScript/issues/12358/n at compile (/Users/johnreilly/code/github/ts-loader/dist/index.js:89:15)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:24)\");\n\n//# sourceURL=webpack:///./node_modules/a/index.ts?\n}"); /***/ }) diff --git a/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/output.txt b/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/output.txt index 5065093a1..1d42c298d 100644 --- a/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/output.txt +++ b/test/comparison-tests/nodeModulesMeaningfulErrorWhenImportingTs/expectedOutput/output.txt @@ -1,4 +1,4 @@ -asset bundle.js 3.22 KiB [emitted] (name: main) +asset bundle.js 3.12 KiB [emitted] (name: main) ./app.ts 117 bytes [built] [code generated] ./node_modules/a/index.ts 39 bytes [built] [code generated] [1 error] @@ -7,9 +7,8 @@ Module build failed (from ../../index.js): Error: TypeScript emitted no output for node_modules/a/index.ts. By default, ts-loader will not compile .ts files in node_modules. You should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option. See: https://github.com/Microsoft/TypeScript/issues/12358 - at makeSourceMapAndFinish (dist/index.js:336:18) - at successLoader (dist/index.js:75:9) - at Object.loader (dist/index.js:57:37) + at compile (dist/index.js:89:15) + at Object.loader (dist/index.js:62:24) @ ./app.ts 3:10-22 webpack compiled with 1 error \ No newline at end of file diff --git a/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/bundle.js b/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/bundle.js index e99e450a8..6fbdacf94 100644 --- a/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/bundle.js +++ b/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/bundle.js @@ -15,7 +15,7 @@ \****************/ /***/ (() => { -eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: /u001b[31merror while parsing tsconfig.json/u001b[39m/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:18)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); +eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: /u001b[31merror while parsing tsconfig.json/u001b[39m/n at compile (/Users/johnreilly/code/github/ts-loader/dist/index.js:78:15)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:24)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); /***/ }) diff --git a/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/output.txt b/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/output.txt index 06c88f882..c03113c06 100644 --- a/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/output.txt +++ b/test/comparison-tests/tsconfigInvalid/expectedOutput-transpile/output.txt @@ -1,4 +1,4 @@ -asset bundle.js 1.37 KiB [emitted] (name: main) +asset bundle.js 1.44 KiB [emitted] (name: main) ./app.ts 39 bytes [built] [code generated] [3 errors] ERROR in tsconfig.json @@ -14,7 +14,8 @@ ERROR in tsconfig.json ERROR in ./app.ts Module build failed (from ../../index.js): Error: error while parsing tsconfig.json - at Object.loader (dist/index.js:62:18) + at compile (dist/index.js:78:15) + at Object.loader (dist/index.js:62:24) 2 errors have detailed information that is not shown. Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. diff --git a/test/comparison-tests/tsconfigInvalid/expectedOutput/bundle.js b/test/comparison-tests/tsconfigInvalid/expectedOutput/bundle.js index e99e450a8..6fbdacf94 100644 --- a/test/comparison-tests/tsconfigInvalid/expectedOutput/bundle.js +++ b/test/comparison-tests/tsconfigInvalid/expectedOutput/bundle.js @@ -15,7 +15,7 @@ \****************/ /***/ (() => { -eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: /u001b[31merror while parsing tsconfig.json/u001b[39m/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:18)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); +eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: /u001b[31merror while parsing tsconfig.json/u001b[39m/n at compile (/Users/johnreilly/code/github/ts-loader/dist/index.js:78:15)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:24)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); /***/ }) diff --git a/test/comparison-tests/tsconfigInvalid/expectedOutput/output.txt b/test/comparison-tests/tsconfigInvalid/expectedOutput/output.txt index 06c88f882..c03113c06 100644 --- a/test/comparison-tests/tsconfigInvalid/expectedOutput/output.txt +++ b/test/comparison-tests/tsconfigInvalid/expectedOutput/output.txt @@ -1,4 +1,4 @@ -asset bundle.js 1.37 KiB [emitted] (name: main) +asset bundle.js 1.44 KiB [emitted] (name: main) ./app.ts 39 bytes [built] [code generated] [3 errors] ERROR in tsconfig.json @@ -14,7 +14,8 @@ ERROR in tsconfig.json ERROR in ./app.ts Module build failed (from ../../index.js): Error: error while parsing tsconfig.json - at Object.loader (dist/index.js:62:18) + at compile (dist/index.js:78:15) + at Object.loader (dist/index.js:62:24) 2 errors have detailed information that is not shown. Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it. diff --git a/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/bundle.js b/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/bundle.js index 61c564ba8..d0bac4c27 100644 --- a/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/bundle.js +++ b/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/bundle.js @@ -15,7 +15,7 @@ \****************/ /***/ (() => { -eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: ts-loader was supplied with an unexpected loader option: notRealOption/n/nPlease take a look at the options you are supplying; the following are valid options:/nsilent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames/n/n at validateLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:235:19)/n at getLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:264:5)/n at successLoader (/Users/johnreilly/code/github/ts-loader/dist/index.js:66:25)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:57:37)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); +eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: ts-loader was supplied with an unexpected loader option: notRealOption/n/nPlease take a look at the options you are supplying; the following are valid options:/nsilent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames/n/n at validateLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:330:19)/n at getLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:359:5)/n at compile (/Users/johnreilly/code/github/ts-loader/dist/index.js:71:21)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:24)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); /***/ }) diff --git a/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/output.txt b/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/output.txt index f750ea443..7c989cd1e 100644 --- a/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/output.txt +++ b/test/comparison-tests/validateLoaderOptionNames/expectedOutput-transpile/output.txt @@ -8,9 +8,9 @@ Error: ts-loader was supplied with an unexpected loader option: notRealOption Please take a look at the options you are supplying; the following are valid options: silent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames - at validateLoaderOptions (dist/index.js:235:19) - at getLoaderOptions (dist/index.js:264:5) - at successLoader (dist/index.js:66:25) - at Object.loader (dist/index.js:57:37) + at validateLoaderOptions (dist/index.js:330:19) + at getLoaderOptions (dist/index.js:359:5) + at compile (dist/index.js:71:21) + at Object.loader (dist/index.js:62:24) webpack compiled with 1 error \ No newline at end of file diff --git a/test/comparison-tests/validateLoaderOptionNames/expectedOutput/bundle.js b/test/comparison-tests/validateLoaderOptionNames/expectedOutput/bundle.js index 61c564ba8..d0bac4c27 100644 --- a/test/comparison-tests/validateLoaderOptionNames/expectedOutput/bundle.js +++ b/test/comparison-tests/validateLoaderOptionNames/expectedOutput/bundle.js @@ -15,7 +15,7 @@ \****************/ /***/ (() => { -eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: ts-loader was supplied with an unexpected loader option: notRealOption/n/nPlease take a look at the options you are supplying; the following are valid options:/nsilent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames/n/n at validateLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:235:19)/n at getLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:264:5)/n at successLoader (/Users/johnreilly/code/github/ts-loader/dist/index.js:66:25)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:57:37)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); +eval("{throw new Error(\"Module build failed (from ../../index.js):/nError: ts-loader was supplied with an unexpected loader option: notRealOption/n/nPlease take a look at the options you are supplying; the following are valid options:/nsilent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames/n/n at validateLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:330:19)/n at getLoaderOptions (/Users/johnreilly/code/github/ts-loader/dist/index.js:359:5)/n at compile (/Users/johnreilly/code/github/ts-loader/dist/index.js:71:21)/n at Object.loader (/Users/johnreilly/code/github/ts-loader/dist/index.js:62:24)\");\n\n//# sourceURL=webpack:///./app.ts?\n}"); /***/ }) diff --git a/test/comparison-tests/validateLoaderOptionNames/expectedOutput/output.txt b/test/comparison-tests/validateLoaderOptionNames/expectedOutput/output.txt index f750ea443..7c989cd1e 100644 --- a/test/comparison-tests/validateLoaderOptionNames/expectedOutput/output.txt +++ b/test/comparison-tests/validateLoaderOptionNames/expectedOutput/output.txt @@ -8,9 +8,9 @@ Error: ts-loader was supplied with an unexpected loader option: notRealOption Please take a look at the options you are supplying; the following are valid options: silent / logLevel / logInfoToStdOut / instance / compiler / configFile / transpileOnly / ignoreDiagnostics / errorFormatter / colors / appendTsSuffixTo / appendTsxSuffixTo / getCustomTransformers / reportFiles / allowTsInNodeModules / projectReferences / resolveModuleName / resolveTypeReferenceDirective / useCaseSensitiveFileNames - at validateLoaderOptions (dist/index.js:235:19) - at getLoaderOptions (dist/index.js:264:5) - at successLoader (dist/index.js:66:25) - at Object.loader (dist/index.js:57:37) + at validateLoaderOptions (dist/index.js:330:19) + at getLoaderOptions (dist/index.js:359:5) + at compile (dist/index.js:71:21) + at Object.loader (dist/index.js:62:24) webpack compiled with 1 error \ No newline at end of file