Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start consuming webpack loader types #1325

Merged
merged 10 commits into from May 22, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

## v9.2.2

* [Start consuming webpack loader types](https://github.com/TypeStrong/ts-loader/issues/1325) - thanks @johnnyreilly
* [Add webpack minimum version in peerDependencies](https://github.com/TypeStrong/ts-loader/issues/1324) - thanks @afdev82

## v9.2.1
Expand Down
4 changes: 2 additions & 2 deletions src/config.ts
Expand Up @@ -4,7 +4,7 @@ import type * as typescript from 'typescript';
import * as webpack from 'webpack';

import { getCompilerOptions } from './compilerSetup';
import { LoaderOptions, WebpackLoaderContext } from './interfaces';
import { LoaderOptions } from './interfaces';
import * as logger from './logger';
import { formatErrors, useCaseSensitiveFileNames } from './utils';

Expand All @@ -16,7 +16,7 @@ interface ConfigFile {
export function getConfigFile(
compiler: typeof typescript,
colors: Chalk,
loader: WebpackLoaderContext,
loader: webpack.LoaderContext<LoaderOptions>,
loaderOptions: LoaderOptions,
compilerCompatible: boolean,
log: logger.Logger,
Expand Down
35 changes: 17 additions & 18 deletions src/index.ts
@@ -1,6 +1,7 @@
import * as crypto from 'crypto';
import * as path from 'path';
import type * as typescript from 'typescript';
import type * as webpack from 'webpack';

import * as constants from './constants';
import {
Expand All @@ -17,8 +18,6 @@ import {
LoaderOptionsCache,
LogLevel,
TSInstance,
WebpackLoaderCallback,
WebpackLoaderContext,
} from './interfaces';
import {
appendSuffixesIfMatch,
Expand All @@ -32,9 +31,9 @@ const loaderOptionsCache: LoaderOptionsCache = {};
/**
* The entry point for ts-loader
*/
function loader(this: WebpackLoaderContext, contents: string) {
function loader(this: webpack.LoaderContext<LoaderOptions>, contents: string) {
this.cacheable && this.cacheable();
const callback = this.async() as WebpackLoaderCallback;
const callback = this.async();
const options = getLoaderOptions(this);
const instanceOrError = getTypeScriptInstance(options, this);

Expand All @@ -48,9 +47,9 @@ function loader(this: WebpackLoaderContext, contents: string) {
}

function successLoader(
loaderContext: WebpackLoaderContext,
loaderContext: webpack.LoaderContext<LoaderOptions>,
contents: string,
callback: WebpackLoaderCallback,
callback: ReturnType<webpack.LoaderContext<LoaderOptions>['async']>,
instance: TSInstance
) {
initializeInstance(loaderContext, instance);
Expand Down Expand Up @@ -96,9 +95,9 @@ function makeSourceMapAndFinish(
outputText: string | undefined,
filePath: string,
contents: string,
loaderContext: WebpackLoaderContext,
loaderContext: webpack.LoaderContext<LoaderOptions>,
fileVersion: number,
callback: WebpackLoaderCallback,
callback: ReturnType<webpack.LoaderContext<LoaderOptions>['async']>,
instance: TSInstance
) {
if (outputText === null || outputText === undefined) {
Expand Down Expand Up @@ -135,19 +134,19 @@ function makeSourceMapAndFinish(
}

function setModuleMeta(
loaderContext: WebpackLoaderContext,
loaderContext: webpack.LoaderContext<LoaderOptions>,
instance: TSInstance,
fileVersion: number
) {
// _module.meta is not available inside happypack
if (
!instance.loaderOptions.happyPackMode &&
loaderContext._module.buildMeta !== undefined
loaderContext._module!.buildMeta !== undefined
) {
// Make sure webpack is aware that even though the emitted JavaScript may be the same as
// a previously cached version the TypeScript may be different and therefore should be
// treated as new
loaderContext._module.buildMeta.tsLoaderFileVersion = fileVersion;
loaderContext._module!.buildMeta.tsLoaderFileVersion = fileVersion;
}
}

Expand All @@ -174,8 +173,8 @@ function getOptionsHash(loaderOptions: LoaderOptions) {
* either retrieves loader options from the cache
* or creates them, adds them to the cache and returns
*/
function getLoaderOptions(loaderContext: WebpackLoaderContext) {
const loaderOptions = loaderContext.getOptions(undefined);
function getLoaderOptions(loaderContext: webpack.LoaderContext<LoaderOptions>) {
const loaderOptions = loaderContext.getOptions();

// If no instance name is given in the options, use the hash of the loader options
// In this way, if different options are given the instances will be different
Expand Down Expand Up @@ -389,7 +388,7 @@ function getEmit(
rawFilePath: string,
filePath: string,
instance: TSInstance,
loaderContext: WebpackLoaderContext
loaderContext: webpack.LoaderContext<LoaderOptions>
) {
const outputFiles = getEmitOutput(instance, filePath);
loaderContext.clearDependencies();
Expand Down Expand Up @@ -435,7 +434,7 @@ function getEmit(

addDependenciesFromSolutionBuilder(instance, filePath, addDependency);

loaderContext._module.buildMeta.tsLoaderDefinitionFileVersions = dependencies.map(
loaderContext._module!.buildMeta.tsLoaderDefinitionFileVersions = dependencies.map(
defFilePath =>
path.relative(loaderContext.rootContext, defFilePath) +
'@' +
Expand Down Expand Up @@ -586,7 +585,7 @@ function getTranspilationEmit(
fileName: string,
contents: string,
instance: TSInstance,
loaderContext: WebpackLoaderContext
loaderContext: webpack.LoaderContext<LoaderOptions>
) {
if (isReferencedFile(instance, fileName)) {
const outputFiles = instance.solutionBuilderHost!.getOutputFilesFromReferencedProjectInput(
Expand Down Expand Up @@ -625,7 +624,7 @@ function getTranspilationEmit(
loaderContext.context
);

errors.forEach(error => module.addError(error));
errors.forEach(error => module!.addError(error));
}

return { outputText, sourceMapText };
Expand All @@ -636,7 +635,7 @@ function makeSourceMap(
outputText: string,
filePath: string,
contents: string,
loaderContext: WebpackLoaderContext
loaderContext: webpack.LoaderContext<LoaderOptions>
) {
if (sourceMapText === undefined) {
return { output: outputText, sourceMap: undefined };
Expand Down
2 changes: 1 addition & 1 deletion src/instance-cache.ts
Expand Up @@ -27,7 +27,7 @@ export function getTSInstanceFromCache(
}

export function setTSInstanceInCache(
key: webpack.Compiler,
key: webpack.Compiler | undefined,
name: string,
instance: TSInstance
) {
Expand Down
39 changes: 18 additions & 21 deletions src/instances.ts
Expand Up @@ -9,13 +9,7 @@ import { getCompiler, getCompilerOptions } from './compilerSetup';
import { getConfigFile, getConfigParseResult } from './config';
import { dtsDtsxOrDtsDtsxMapRegex, EOL, tsTsxRegex } from './constants';
import { getTSInstanceFromCache, setTSInstanceInCache } from './instance-cache';
import {
FilePathKey,
LoaderOptions,
TSFiles,
TSInstance,
WebpackLoaderContext,
} from './interfaces';
import { FilePathKey, LoaderOptions, TSFiles, TSInstance } from './interfaces';
import * as logger from './logger';
import {
getSolutionErrors,
Expand Down Expand Up @@ -45,10 +39,10 @@ const instancesBySolutionBuilderConfigs = new Map<FilePathKey, TSInstance>();
*/
export function getTypeScriptInstance(
loaderOptions: LoaderOptions,
loader: WebpackLoaderContext
loader: webpack.LoaderContext<LoaderOptions>
): { instance?: TSInstance; error?: webpack.WebpackError } {
const existing = getTSInstanceFromCache(
loader._compiler,
loader._compiler!,
loaderOptions.instance
);
if (existing) {
Expand Down Expand Up @@ -119,7 +113,7 @@ function createFilePathKeyMapper(

function successfulTypeScriptInstance(
loaderOptions: LoaderOptions,
loader: WebpackLoaderContext,
loader: webpack.LoaderContext<LoaderOptions>,
log: logger.Logger,
colors: chalk.Chalk,
compiler: typeof typescript,
Expand Down Expand Up @@ -159,7 +153,7 @@ function successfulTypeScriptInstance(
}
}

const module = loader._module;
const module = loader._module!;
const basePath = loaderOptions.context || path.dirname(configFilePath || '');
const configParseResult = getConfigParseResult(
compiler,
Expand Down Expand Up @@ -304,7 +298,10 @@ function getExistingSolutionBuilderHost(key: FilePathKey) {
return undefined;
}

function addAssetHooks(loader: WebpackLoaderContext, instance: TSInstance) {
function addAssetHooks(
loader: webpack.LoaderContext<LoaderOptions>,
instance: TSInstance
) {
// 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.
Expand All @@ -329,14 +326,14 @@ function addAssetHooks(loader: WebpackLoaderContext, instance: TSInstance) {

// We need to add the hook above for each run.
// For the first run, we just need to add the hook to loader._compilation
makeAssetsCallback(loader._compilation);
makeAssetsCallback(loader._compilation!);

// For future calls in watch mode we need to watch for a new compilation and add the hook
loader._compiler.hooks.compilation.tap('ts-loader', makeAssetsCallback);
loader._compiler!.hooks.compilation.tap('ts-loader', makeAssetsCallback);
}

export function initializeInstance(
loader: WebpackLoaderContext,
loader: webpack.LoaderContext<LoaderOptions>,
instance: TSInstance
) {
if (!instance.initialSetupPending) {
Expand Down Expand Up @@ -384,13 +381,13 @@ export function initializeInstance(
// Setup watch run for solution building
if (instance.solutionBuilderHost) {
addAssetHooks(loader, instance);
loader._compiler.hooks.watchRun.tapAsync(
loader._compiler!.hooks.watchRun.tapAsync(
'ts-loader',
makeWatchRun(instance, loader)
);
}
} else {
if (!loader._compiler.hooks) {
if (!loader._compiler!.hooks) {
throw new Error(
"You may be using an old version of webpack; please check you're using at least version 4"
);
Expand Down Expand Up @@ -433,7 +430,7 @@ export function initializeInstance(

addAssetHooks(loader, instance);

loader._compiler.hooks.watchRun.tapAsync(
loader._compiler!.hooks.watchRun.tapAsync(
'ts-loader',
makeWatchRun(instance, loader)
);
Expand All @@ -456,7 +453,7 @@ function getScriptRegexp(instance: TSInstance) {

export function reportTranspileErrors(
instance: TSInstance,
loader: WebpackLoaderContext
loader: webpack.LoaderContext<LoaderOptions>
) {
if (!instance.reportTranspileErrors) {
return;
Expand All @@ -479,13 +476,13 @@ export function reportTranspileErrors(
loader.context
);

[...solutionErrors, ...errors].forEach(error => module.addError(error));
[...solutionErrors, ...errors].forEach(error => module!.addError(error));
}
}

export function buildSolutionReferences(
instance: TSInstance,
loader: WebpackLoaderContext
loader: webpack.LoaderContext<LoaderOptions>
) {
if (!supportsSolutionBuild(instance)) {
return;
Expand Down