Skip to content

Commit

Permalink
Merge branch 'master' into incrementalBuildPerf
Browse files Browse the repository at this point in the history
  • Loading branch information
berickson1 authored Feb 19, 2021
2 parents 57a606f + 953358e commit 857737f
Show file tree
Hide file tree
Showing 54 changed files with 261 additions and 148 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
comparison_test:
name: Ubuntu Comparison Tests
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 25
steps:
- uses: actions/checkout@v2

Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
matrix:
os: [ubuntu, windows]
node: [10, 12, 14]
ts: [3.6.5, 3.7.5, 3.8.3, 3.9.3, 4.0.3, 4.1.2, next]
ts: [3.8.3, 3.9.3, 4.0.3, 4.1.2, next]
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## v8.0.17
* [Included correct webpack source location in emitted errors](https://github.com/TypeStrong/ts-loader/issues/1199) - thanks @lorenzodallavecchia

## v8.0.16
* [Re-Fixed missing errors in watch mode in webpack5](https://github.com/TypeStrong/ts-loader/issues/1204) - thanks @appzuka

## v8.0.15
* [Update definition files in watch mode in webpack@5](https://github.com/TypeStrong/ts-loader/pull/1249) - thanks @appzuka,@JonWallsten,@alexander-akait
* [Add afterDeclarations to getCustomTransformers in README.md](https://github.com/TypeStrong/ts-loader/pull/1248) - thanks @appzuka

## v8.0.14
* [Upgrade `chalk`, `loader-utils`, and `semver` to latest stable versions](https://github.com/TypeStrong/ts-loader/pull/1237) - thanks Avi Vahl

## v8.0.13
* [Speed up builds by adding an in-memory cache to file path lookups](https://github.com/TypeStrong/ts-loader/pull/1228) - thanks @berickson1

## v8.0.12
* [Instead of checking date, check time thats more accurate to see if something has changed](https://github.com/TypeStrong/ts-loader/pull/1217) - thanks @sheetalkamat

Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ These options should be functions which will be used to resolve the import state
#### getCustomTransformers
| Type |
|------|
| ` (program: Program) => { before?: TransformerFactory<SourceFile>[]; after?: TransformerFactory<SourceFile>[]; } ` |
| ` (program: Program) => { before?: TransformerFactory<SourceFile>[]; after?: TransformerFactory<SourceFile>[]; afterDeclarations?: TransformerFactory<SourceFile>[]; } ` |

Provide custom transformers - only compatible with TypeScript 2.3+ (and 2.4 if using `transpileOnly` mode). For example usage take a look at [typescript-plugin-styled-components](https://github.com/Igorbek/typescript-plugin-styled-components) or our [test](test/comparison-tests/customTransformer).

Expand Down Expand Up @@ -729,12 +729,22 @@ In order to make use of this option your project needs to be correctly configure
Because TS will generate .js and .d.ts files, you should ignore these files, otherwise watchers may go into an infinite watch loop. For example, when using webpack, you may wish to add this to your webpack.conf.js file:

```javascript
// for webpack 4
plugins: [
new webpack.WatchIgnorePlugin([
/\.js$/,
/\.d\.ts$/
])
],

// for webpack 5
plugins: [
new webpack.WatchIgnorePlugin(
paths:{[
/\.js$/,
/\.d\.ts$/
]})
],
```

It's worth noting that use of the `LoaderOptionsPlugin` is [only supposed to be a stopgap measure](https://webpack.js.org/plugins/loader-options-plugin/). You may want to look at removing it entirely.
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ts-loader",
"version": "8.0.12",
"version": "8.0.17",
"description": "TypeScript loader for webpack",
"main": "index.js",
"types": "dist",
Expand Down Expand Up @@ -54,16 +54,16 @@
},
"homepage": "https://github.com/TypeStrong/ts-loader",
"dependencies": {
"chalk": "^2.3.0",
"chalk": "^4.1.0",
"enhanced-resolve": "^4.0.0",
"loader-utils": "^1.0.2",
"loader-utils": "^2.0.0",
"micromatch": "^4.0.0",
"semver": "^6.0.0"
"semver": "^7.3.4"
},
"devDependencies": {
"@types/micromatch": "^3.1.0",
"@types/node": "*",
"@types/semver": "^6.0.0",
"@types/semver": "^7.3.4",
"@types/webpack": "^4.4.30",
"@typescript-eslint/eslint-plugin": "^4.0.0",
"@typescript-eslint/parser": "^4.0.0",
Expand Down
54 changes: 22 additions & 32 deletions src/after-compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ import {
*/
export function makeAfterCompile(
instance: TSInstance,
addAssets: boolean,
provideErrors: boolean,
configFilePath: string | undefined
) {
let getCompilerOptionDiagnostics = true;
Expand All @@ -47,22 +45,18 @@ export function makeAfterCompile(
}

if (instance.loaderOptions.transpileOnly) {
if (addAssets) {
provideAssetsFromSolutionBuilderHost(instance, compilation);
}
provideAssetsFromSolutionBuilderHost(instance, compilation);
callback();
return;
}
removeCompilationTSLoaderErrors(compilation, instance.loaderOptions);

if (provideErrors) {
provideCompilerOptionDiagnosticErrorsToWebpack(
getCompilerOptionDiagnostics,
compilation,
instance,
configFilePath
);
}
provideCompilerOptionDiagnosticErrorsToWebpack(
getCompilerOptionDiagnostics,
compilation,
instance,
configFilePath
);
getCompilerOptionDiagnostics = false;

const modules = determineModules(compilation, instance);
Expand All @@ -74,25 +68,21 @@ export function makeAfterCompile(
checkAllFilesForErrors = false;

const filesWithErrors: TSFiles = new Map();
if (provideErrors) {
provideErrorsToWebpack(
filesToCheckForErrors,
filesWithErrors,
compilation,
modules,
instance
);
provideSolutionErrorsToWebpack(compilation, modules, instance);
}
if (addAssets) {
provideDeclarationFilesToWebpack(
filesToCheckForErrors,
instance,
compilation
);
provideTsBuildInfoFilesToWebpack(instance, compilation);
provideAssetsFromSolutionBuilderHost(instance, compilation);
}
provideErrorsToWebpack(
filesToCheckForErrors,
filesWithErrors,
compilation,
modules,
instance
);
provideSolutionErrorsToWebpack(compilation, modules, instance);
provideDeclarationFilesToWebpack(
filesToCheckForErrors,
instance,
compilation
);
provideTsBuildInfoFilesToWebpack(instance, compilation);
provideAssetsFromSolutionBuilderHost(instance, compilation);

instance.filesWithErrors = filesWithErrors;
instance.modifiedFiles = undefined;
Expand Down
79 changes: 48 additions & 31 deletions src/instances.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import chalk, { Chalk } from 'chalk';
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as path from 'path';
import * as typescript from 'typescript';
Expand Down Expand Up @@ -58,7 +58,9 @@ export function getTypeScriptInstance(
return { instance: existing };
}

const colors = new chalk.constructor({ enabled: loaderOptions.colors });
const level =
loaderOptions.colors && chalk.supportsColor ? chalk.supportsColor.level : 0;
const colors = new chalk.Instance({ level });
const log = logger.makeLogger(loaderOptions, colors);
const compiler = getCompiler(loaderOptions, log);

Expand Down Expand Up @@ -87,31 +89,43 @@ function createFilePathKeyMapper(
compiler: typeof typescript,
loaderOptions: LoaderOptions
) {
// Cache file path key - a map lookup is much faster than filesystem/regex operations & the result will never change
const filePathMapperCache = new Map<string, FilePathKey>();
// FileName lowercasing copied from typescript
const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g;
return useCaseSensitiveFileNames(compiler, loaderOptions)
? pathResolve
: toFileNameLowerCase;

function pathResolve(x: string) {
return path.resolve(x) as FilePathKey;
function pathResolve(filePath: string) {
let cachedPath = filePathMapperCache.get(filePath);
if (!cachedPath) {
cachedPath = path.resolve(filePath) as FilePathKey;
filePathMapperCache.set(filePath, cachedPath);
}
return cachedPath;
}

function toFileNameLowerCase(x: string) {
const filePathKey = pathResolve(x);
return fileNameLowerCaseRegExp.test(filePathKey)
? (filePathKey.replace(fileNameLowerCaseRegExp, ch =>
ch.toLowerCase()
) as FilePathKey)
: filePathKey;
function toFileNameLowerCase(filePath: string) {
let cachedPath = filePathMapperCache.get(filePath);
if (!cachedPath) {
const filePathKey = pathResolve(filePath);
cachedPath = fileNameLowerCaseRegExp.test(filePathKey)
? (filePathKey.replace(fileNameLowerCaseRegExp, ch =>
ch.toLowerCase()
) as FilePathKey)
: filePathKey;
filePathMapperCache.set(filePath, cachedPath);
}
return cachedPath;
}
}

function successfulTypeScriptInstance(
loaderOptions: LoaderOptions,
loader: webpack.loader.LoaderContext,
log: logger.Logger,
colors: Chalk,
colors: chalk.Chalk,
compiler: typeof typescript,
compilerCompatible: boolean,
compilerDetailsLogMessage: string
Expand Down Expand Up @@ -309,33 +323,36 @@ const addAssetHooks = !!webpack.version!.match(/^4.*/)
// add makeAfterCompile with addAssets = true to emit assets and report errors
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, true, true, instance.configFilePath)
makeAfterCompile(instance, instance.configFilePath)
);
}
: (loader: webpack.loader.LoaderContext, instance: TSInstance) => {
// We must be running under webpack 5+

// Add makeAfterCompile with addAssets = false to suppress emitting assets
// during the afterCompile stage. Errors will be still be reported to webpack
loader._compiler.hooks.afterCompile.tapAsync(
'ts-loader',
makeAfterCompile(instance, false, true, instance.configFilePath)
// 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 = makeAfterCompile(
instance,
instance.configFilePath
);

// Emit the assets at the afterProcessAssets stage
loader._compilation.hooks.afterProcessAssets.tap(
'ts-loader',
(_: any) => {
makeAfterCompile(
instance,
true,
false,
instance.configFilePath
)(loader._compilation, () => {
// 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: any) => {
compilation.hooks.afterProcessAssets.tap('ts-loader', () =>
cachedMakeAfterCompile(compilation, () => {
return null;
});
}
);
})
);
};

// 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);

// 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);

// It may be better to add assets at the processAssets stage (https://webpack.js.org/api/compilation-hooks/#processassets)
// This requires Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL, which does not exist in webpack4
Expand Down
15 changes: 14 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ export interface ErrorInfo {
context: string;
}

export type FileLocation = { line: number; character: number };
export type FileLocation = {
/** 1-based */
line: number;
/** 1-based */
character: number;
};

export type WebpackSourcePosition = {
/** 1-based */
line: number;
/** 0-based */
column?: number;
};
export interface WebpackError {
module?: any;
file?: string;
message: string;
loc?: { start: WebpackSourcePosition; end?: WebpackSourcePosition };
/* ts-loader extra properties */
location?: FileLocation;
loaderSource: string;
}
Expand Down
Loading

0 comments on commit 857737f

Please sign in to comment.