| | |
| | | * `instance` property. |
| | | */ |
| | | function getTypeScriptInstance(loaderOptions, loader) { |
| | | const existing = instance_cache_1.getTSInstanceFromCache(loader._compiler, loaderOptions.instance); |
| | | const existing = (0, instance_cache_1.getTSInstanceFromCache)(loader._compiler, loaderOptions.instance); |
| | | if (existing) { |
| | | if (!existing.initialSetupPending) { |
| | | utils_1.ensureProgram(existing); |
| | | (0, utils_1.ensureProgram)(existing); |
| | | } |
| | | return { instance: existing }; |
| | | } |
| | | const level = loaderOptions.colors && chalk.supportsColor ? chalk.supportsColor.level : 0; |
| | | const colors = new chalk.Instance({ level }); |
| | | const log = logger.makeLogger(loaderOptions, colors); |
| | | const compiler = compilerSetup_1.getCompiler(loaderOptions, log); |
| | | const compiler = (0, compilerSetup_1.getCompiler)(loaderOptions, log); |
| | | if (compiler.errorMessage !== undefined) { |
| | | return { |
| | | error: utils_1.makeError(loaderOptions, colors.red(compiler.errorMessage), undefined), |
| | | error: (0, utils_1.makeError)(loaderOptions, colors.red(compiler.errorMessage), undefined), |
| | | }; |
| | | } |
| | | return successfulTypeScriptInstance(loaderOptions, loader, log, colors, compiler.compiler, compiler.compilerCompatible, compiler.compilerDetailsLogMessage); |
| | |
| | | const filePathMapperCache = new Map(); |
| | | // FileName lowercasing copied from typescript |
| | | const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g; |
| | | return utils_1.useCaseSensitiveFileNames(compiler, loaderOptions) |
| | | return (0, utils_1.useCaseSensitiveFileNames)(compiler, loaderOptions) |
| | | ? pathResolve |
| | | : toFileNameLowerCase; |
| | | function pathResolve(filePath) { |
| | |
| | | } |
| | | } |
| | | function successfulTypeScriptInstance(loaderOptions, loader, log, colors, compiler, compilerCompatible, compilerDetailsLogMessage) { |
| | | const configFileAndPath = config_1.getConfigFile(compiler, colors, loader, loaderOptions, compilerCompatible, log, compilerDetailsLogMessage); |
| | | const configFileAndPath = (0, config_1.getConfigFile)(compiler, colors, loader, loaderOptions, compilerCompatible, log, compilerDetailsLogMessage); |
| | | if (configFileAndPath.configFileError !== undefined) { |
| | | const { message, file } = configFileAndPath.configFileError; |
| | | return { |
| | | error: utils_1.makeError(loaderOptions, colors.red('error while reading tsconfig.json:' + constants_1.EOL + message), file), |
| | | error: (0, utils_1.makeError)(loaderOptions, colors.red('error while reading tsconfig.json:' + constants_1.EOL + message), file), |
| | | }; |
| | | } |
| | | const { configFilePath, configFile } = configFileAndPath; |
| | |
| | | const existing = getExistingSolutionBuilderHost(configFileKey); |
| | | if (existing) { |
| | | // Reuse the instance if config file for project references is shared. |
| | | instance_cache_1.setTSInstanceInCache(loader._compiler, loaderOptions.instance, existing); |
| | | (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, existing); |
| | | return { instance: existing }; |
| | | } |
| | | } |
| | | const module = loader._module; |
| | | const basePath = loaderOptions.context || path.dirname(configFilePath || ''); |
| | | const configParseResult = config_1.getConfigParseResult(compiler, configFile, basePath, configFilePath, loaderOptions); |
| | | const configParseResult = (0, config_1.getConfigParseResult)(compiler, configFile, basePath, configFilePath, loaderOptions); |
| | | if (configParseResult.errors.length > 0 && !loaderOptions.happyPackMode) { |
| | | const errors = utils_1.formatErrors(configParseResult.errors, loaderOptions, colors, compiler, { file: configFilePath }, loader.context); |
| | | const errors = (0, utils_1.formatErrors)(configParseResult.errors, loaderOptions, colors, compiler, { file: configFilePath }, loader.context); |
| | | /** |
| | | * Since webpack 5, the `errors` property is deprecated, |
| | | * so we can check if some methods for reporting errors exist. |
| | |
| | | module.errors.push(...errors); |
| | | } |
| | | return { |
| | | error: utils_1.makeError(loaderOptions, colors.red('error while parsing tsconfig.json'), configFilePath), |
| | | error: (0, utils_1.makeError)(loaderOptions, colors.red('error while parsing tsconfig.json'), configFilePath), |
| | | }; |
| | | } |
| | | const compilerOptions = compilerSetup_1.getCompilerOptions(configParseResult, compiler); |
| | | const compilerOptions = (0, compilerSetup_1.getCompilerOptions)(configParseResult, compiler); |
| | | const rootFileNames = new Set(); |
| | | const files = new Map(); |
| | | const otherFiles = new Map(); |
| | | const appendTsTsxSuffixesIfRequired = loaderOptions.appendTsSuffixTo.length > 0 || |
| | | loaderOptions.appendTsxSuffixTo.length > 0 |
| | | ? (filePath) => utils_1.appendSuffixesIfMatch({ |
| | | ? (filePath) => (0, utils_1.appendSuffixesIfMatch)({ |
| | | '.ts': loaderOptions.appendTsSuffixTo, |
| | | '.tsx': loaderOptions.appendTsxSuffixTo, |
| | | }, filePath) |
| | |
| | | log, |
| | | filePathKeyMapper, |
| | | }; |
| | | instance_cache_1.setTSInstanceInCache(loader._compiler, loaderOptions.instance, transpileInstance); |
| | | (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, transpileInstance); |
| | | return { instance: transpileInstance }; |
| | | } |
| | | // Load initial files (core lib files, any files specified in tsconfig.json) |
| | |
| | | } |
| | | catch (exc) { |
| | | return { |
| | | error: utils_1.makeError(loaderOptions, colors.red(`A file specified in tsconfig.json could not be found: ${normalizedFilePath}`), normalizedFilePath), |
| | | error: (0, utils_1.makeError)(loaderOptions, colors.red(`A file specified in tsconfig.json could not be found: ${normalizedFilePath}`), normalizedFilePath), |
| | | }; |
| | | } |
| | | const instance = { |
| | |
| | | log, |
| | | filePathKeyMapper, |
| | | }; |
| | | instance_cache_1.setTSInstanceInCache(loader._compiler, loaderOptions.instance, instance); |
| | | (0, instance_cache_1.setTSInstanceInCache)(loader._compiler, loaderOptions.instance, instance); |
| | | return { instance }; |
| | | } |
| | | function getExistingSolutionBuilderHost(key) { |
| | |
| | | const addAssetHooks = !!webpack.version.match(/^4.*/) |
| | | ? (loader, instance) => { |
| | | // add makeAfterCompile with addAssets = true to emit assets and report errors |
| | | loader._compiler.hooks.afterCompile.tapAsync('ts-loader', after_compile_1.makeAfterCompile(instance, instance.configFilePath)); |
| | | loader._compiler.hooks.afterCompile.tapAsync('ts-loader', (0, after_compile_1.makeAfterCompile)(instance, instance.configFilePath)); |
| | | } |
| | | : (loader, instance) => { |
| | | // We must be running under webpack 5+ |
| | | // makeAfterCompile is a closure. It returns a function which closes over the variable checkAllFilesForErrors |
| | | // We need to get the function once and then reuse it, otherwise it will be recreated each time |
| | | // and all files will always be checked. |
| | | const cachedMakeAfterCompile = after_compile_1.makeAfterCompile(instance, instance.configFilePath); |
| | | const cachedMakeAfterCompile = (0, after_compile_1.makeAfterCompile)(instance, instance.configFilePath); |
| | | // compilation is actually of type webpack.compilation.Compilation, but afterProcessAssets |
| | | // only exists in webpack5 and at the time of writing ts-loader is built using webpack4 |
| | | const makeAssetsCallback = (compilation) => { |
| | |
| | | customerTransformers = require(customerTransformers); |
| | | } |
| | | catch (err) { |
| | | throw new Error(`Failed to load customTransformers from "${instance.loaderOptions.getCustomTransformers}": ${err.message}`); |
| | | throw new Error(`Failed to load customTransformers from "${instance.loaderOptions.getCustomTransformers}": ${err instanceof Error ? err.message : ''}`); |
| | | } |
| | | if (typeof customerTransformers !== 'function') { |
| | | throw new Error(`Custom transformers in "${instance.loaderOptions.getCustomTransformers}" should export a function, got ${typeof getCustomTransformers}`); |
| | |
| | | // Setup watch run for solution building |
| | | if (instance.solutionBuilderHost) { |
| | | addAssetHooks(loader, instance); |
| | | loader._compiler.hooks.watchRun.tapAsync('ts-loader', watch_run_1.makeWatchRun(instance, loader)); |
| | | loader._compiler.hooks.watchRun.tapAsync('ts-loader', (0, watch_run_1.makeWatchRun)(instance, loader)); |
| | | } |
| | | } |
| | | else { |
| | |
| | | if (instance.loaderOptions.experimentalWatchApi) { |
| | | instance.log.logInfo('Using watch api'); |
| | | // If there is api available for watch, use it instead of language service |
| | | instance.watchHost = servicesHost_1.makeWatchHost(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences); |
| | | instance.watchHost = (0, servicesHost_1.makeWatchHost)(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences); |
| | | instance.watchOfFilesAndCompilerOptions = instance.compiler.createWatchProgram(instance.watchHost); |
| | | instance.builderProgram = instance.watchOfFilesAndCompilerOptions.getProgram(); |
| | | instance.program = instance.builderProgram.getProgram(); |
| | | instance.transformers = getCustomTransformers(instance.program); |
| | | } |
| | | else { |
| | | instance.servicesHost = servicesHost_1.makeServicesHost(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences); |
| | | instance.servicesHost = (0, servicesHost_1.makeServicesHost)(getScriptRegexp(instance), loader, instance, instance.configParseResult.projectReferences); |
| | | instance.languageService = instance.compiler.createLanguageService(instance.servicesHost, instance.compiler.createDocumentRegistry()); |
| | | instance.transformers = getCustomTransformers(instance.languageService.getProgram()); |
| | | } |
| | | addAssetHooks(loader, instance); |
| | | loader._compiler.hooks.watchRun.tapAsync('ts-loader', watch_run_1.makeWatchRun(instance, loader)); |
| | | loader._compiler.hooks.watchRun.tapAsync('ts-loader', (0, watch_run_1.makeWatchRun)(instance, loader)); |
| | | } |
| | | } |
| | | exports.initializeInstance = initializeInstance; |
| | |
| | | instance.reportTranspileErrors = false; |
| | | // happypack does not have _module.errors - see https://github.com/TypeStrong/ts-loader/issues/336 |
| | | if (!instance.loaderOptions.happyPackMode) { |
| | | const solutionErrors = servicesHost_1.getSolutionErrors(instance, loader.context); |
| | | const solutionErrors = (0, servicesHost_1.getSolutionErrors)(instance, loader.context); |
| | | const diagnostics = instance.program.getOptionsDiagnostics(); |
| | | const errors = utils_1.formatErrors(diagnostics, instance.loaderOptions, instance.colors, instance.compiler, { file: instance.configFilePath || 'tsconfig.json' }, loader.context); |
| | | const errors = (0, utils_1.formatErrors)(diagnostics, instance.loaderOptions, instance.colors, instance.compiler, { file: instance.configFilePath || 'tsconfig.json' }, loader.context); |
| | | /** |
| | | * Since webpack 5, the `errors` property is deprecated, |
| | | * so we can check if some methods for reporting errors exist. |
| | |
| | | } |
| | | exports.reportTranspileErrors = reportTranspileErrors; |
| | | function buildSolutionReferences(instance, loader) { |
| | | if (!utils_1.supportsSolutionBuild(instance)) { |
| | | if (!(0, utils_1.supportsSolutionBuild)(instance)) { |
| | | return; |
| | | } |
| | | if (!instance.solutionBuilderHost) { |
| | | // Use solution builder |
| | | instance.log.logInfo('Using SolutionBuilder api'); |
| | | const scriptRegex = getScriptRegexp(instance); |
| | | instance.solutionBuilderHost = servicesHost_1.makeSolutionBuilderHost(scriptRegex, loader, instance); |
| | | instance.solutionBuilderHost = (0, servicesHost_1.makeSolutionBuilderHost)(scriptRegex, loader, instance); |
| | | const solutionBuilder = instance.compiler.createSolutionBuilderWithWatch(instance.solutionBuilderHost, instance.configParseResult.projectReferences.map(ref => ref.path), { verbose: true }); |
| | | solutionBuilder.build(); |
| | | instance.solutionBuilderHost.ensureAllReferenceTimestamps(); |
| | |
| | | : undefined; |
| | | } |
| | | function getOutputFileNames(instance, configFile, inputFileName) { |
| | | const ignoreCase = !utils_1.useCaseSensitiveFileNames(instance.compiler, instance.loaderOptions); |
| | | const ignoreCase = !(0, utils_1.useCaseSensitiveFileNames)(instance.compiler, instance.loaderOptions); |
| | | if (instance.compiler.getOutputFileNames) { |
| | | return instance.compiler.getOutputFileNames(configFile, inputFileName, ignoreCase); |
| | | } |
| | |
| | | if (instance.solutionBuilderHost) { |
| | | return instance.solutionBuilderHost.getInputFileNameFromOutput(filePath); |
| | | } |
| | | const program = utils_1.ensureProgram(instance); |
| | | const program = (0, utils_1.ensureProgram)(instance); |
| | | return (program && |
| | | program.getResolvedProjectReferences && |
| | | forEachResolvedProjectReference(program.getResolvedProjectReferences(), ({ commandLine }) => { |
| | |
| | | } |
| | | exports.getInputFileNameFromOutput = getInputFileNameFromOutput; |
| | | function getEmitFromWatchHost(instance, filePath) { |
| | | const program = utils_1.ensureProgram(instance); |
| | | const program = (0, utils_1.ensureProgram)(instance); |
| | | const builderProgram = instance.builderProgram; |
| | | if (builderProgram && program) { |
| | | if (filePath) { |
| | |
| | | if (fileExtensionIs(filePath, instance.compiler.Extension.Dts)) { |
| | | return []; |
| | | } |
| | | if (utils_1.isReferencedFile(instance, filePath)) { |
| | | if ((0, utils_1.isReferencedFile)(instance, filePath)) { |
| | | return instance.solutionBuilderHost.getOutputFilesFromReferencedProjectInput(filePath); |
| | | } |
| | | const program = utils_1.ensureProgram(instance); |
| | | const program = (0, utils_1.ensureProgram)(instance); |
| | | if (program !== undefined) { |
| | | const sourceFile = program.getSourceFile(filePath); |
| | | const outputFiles = []; |