Skip to content

Commit

Permalink
Project reference support enhancements (#1076)
Browse files Browse the repository at this point in the history
* Add test for package json existance

* Add input file of reference as dependency instead of .d.ts file

* Show how output is different when module resolution resolves to .js/.d.ts

* Store tsbuildinfos written on solution builder host and hand it off as asset

* .d.ts as assets only if written

* Make every project include just app and not other lib files

* Fix watching for solution watched files
Add test that doesnt pass yet.
This is same as projectReferencesWatch so technically only change should be
in bundled emit to have out to be lib\out\index.js instead

* Dont depend on .d.ts output of the referenced project since we are depending on .ts file for that
This fixes initial build to complete in single pass

* Make sure to build all solution builder files before and track input and output

* Add all the files from composite project as dependencies as any change in them can result in errors resulting in changes to the own output of the file

* Get output from solutionBuilder for referenced files in transpileOnly mode as well

* Read and write output files from referenced projects to disk

* Test on already built

* Handle written files by solution builder a bit better

* Fix comparison tests where the multiple compilation callbacks were not handled so it didnt show correct output

* Because comparison tests are run only on newer typescript build, build suite during tests instead of commandline to avoid breaking older runs

* Remove node 8 build from travis

* Fix test baselines

* Revert multiple compilation stats per patch, has incorrect baseline that doesnt match actual behavior
This reverts commit 9d62b44.

* update package.json and CHANGELOG.md

Co-authored-by: John Reilly <johnny_reilly@hotmail.com>
  • Loading branch information
sheetalkamat and johnnyreilly committed Apr 15, 2020
1 parent d0c4b41 commit 1908a47
Show file tree
Hide file tree
Showing 287 changed files with 6,574 additions and 825 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -4,7 +4,6 @@ addons:
chrome: stable
language: node_js
node_js:
- "8"
- "10"
- "12"
sudo: required
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## v7.0.0
* [Project reference support enhancements](https://github.com/TypeStrong/ts-loader/pull/1076) - thanks @sheetalkamat!
* Following the end of life of Node 8, `ts-loader` no longer supports Node 8 **BREAKING CHANGE**

## v6.2.2
* [Enable typescript 3.8.3 support when using `webpack.config.ts` files](https://github.com/TypeStrong/ts-loader/issues/1072) - thanks @vladimiry!

Expand Down
4 changes: 2 additions & 2 deletions package.json
@@ -1,13 +1,13 @@
{
"name": "ts-loader",
"version": "6.2.2",
"version": "7.0.0",
"description": "TypeScript loader for webpack",
"main": "index.js",
"types": "dist",
"scripts": {
"build": "tsc --version && tsc --project \"./src\"",
"lint": "tslint --project \"./src\"",
"comparison-tests": "git clean -xfd test/comparison-tests && tsc --project \"./test/comparison-tests\" && npm link ./test/comparison-tests/testLib && node test/comparison-tests/run-tests.js",
"comparison-tests": "git clean -xfd test/comparison-tests && npm link ./test/comparison-tests/testLib && node test/comparison-tests/run-tests.js",
"comparison-tests-generate": "git clean -xfd test/comparison-tests && node test/comparison-tests/stub-new-version.js",
"execution-tests": "git clean -xfd test/execution-tests && node test/execution-tests/run-tests.js",
"test": "git clean -xfd test/comparison-tests && git clean -xfd test/execution-tests && node test/run-tests.js",
Expand Down
132 changes: 65 additions & 67 deletions src/after-compile.ts
Expand Up @@ -4,9 +4,9 @@ import * as webpack from 'webpack';

import * as constants from './constants';
import {
forEachResolvedProjectReference,
getEmitFromWatchHost,
getEmitOutput
getEmitOutput,
isReferencedFile
} from './instances';
import {
TSFile,
Expand Down Expand Up @@ -39,6 +39,12 @@ export function makeAfterCompile(
return;
}

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

removeTSLoaderErrors(compilation.errors);

provideCompilerOptionDiagnosticErrorsToWebpack(
Expand All @@ -65,15 +71,15 @@ export function makeAfterCompile(
modules,
instance
);

provideDeclarationFilesToWebpack(
filesToCheckForErrors,
instance,
compilation
);
provideTsBuildInfoFilesToWebpack(instance, compilation);

provideSolutionErrorsToWebpack(compilation, modules, instance);
provideTsBuildInfoFilesToWebpack(instance, compilation);
provideAssetsFromSolutionBuilderHost(instance, compilation);

instance.filesWithErrors = filesWithErrors;
instance.modifiedFiles = undefined;
Expand Down Expand Up @@ -343,31 +349,51 @@ function provideDeclarationFilesToWebpack(
continue;
}

const outputFiles = getEmitOutput(instance, filePath);
const declarationFiles = outputFiles.filter(outputFile =>
outputFile.name.match(constants.dtsDtsxOrDtsDtsxMapRegex)
);

declarationFiles.forEach(declarationFile => {
const assetPath = path.relative(
compilation.compiler.outputPath,
declarationFile.name
if (!isReferencedFile(instance, filePath)) {
addDeclarationFilesAsAsset(
getEmitOutput(instance, filePath),
compilation
);
compilation.assets[assetPath] = {
source: () => declarationFile.text,
size: () => declarationFile.text.length
};
});
}
}
}

function getOutputPathForBuildInfo(
compiler: typeof ts,
options: ts.CompilerOptions
function addDeclarationFilesAsAsset<T extends ts.OutputFile>(
outputFiles: T[] | IterableIterator<T>,
compilation: webpack.compilation.Compilation,
skipOutputFile?: (outputFile: T) => boolean
) {
outputFilesToAsset(outputFiles, compilation, outputFile =>
skipOutputFile && skipOutputFile(outputFile)
? true
: !outputFile.name.match(constants.dtsDtsxOrDtsDtsxMapRegex)
);
}

function outputFileToAsset(
outputFile: ts.OutputFile,
compilation: webpack.compilation.Compilation
) {
return (compiler as any).getTsBuildInfoEmitOutputFilePath
? (compiler as any).getTsBuildInfoEmitOutputFilePath(options)
: (compiler as any).getOutputPathForBuildInfo(options);
const assetPath = path.relative(
compilation.compiler.outputPath,
outputFile.name
);
compilation.assets[assetPath] = {
source: () => outputFile.text,
size: () => outputFile.text.length
};
}

function outputFilesToAsset<T extends ts.OutputFile>(
outputFiles: T[] | IterableIterator<T>,
compilation: webpack.compilation.Compilation,
skipOutputFile?: (outputFile: T) => boolean
) {
for (const outputFile of outputFiles) {
if (!skipOutputFile || !skipOutputFile(outputFile)) {
outputFileToAsset(outputFile, compilation);
}
}
}

/**
Expand All @@ -377,60 +403,32 @@ function provideTsBuildInfoFilesToWebpack(
instance: TSInstance,
compilation: webpack.compilation.Compilation
) {
if (instance.solutionBuilderHost && instance.modifiedFiles) {
const program = ensureProgram(instance);
if (program) {
forEachResolvedProjectReference(
program.getResolvedProjectReferences(),
resolvedRef => {
if (
resolvedRef.commandLine.fileNames.some(f =>
instance.modifiedFiles!.has(path.resolve(f))
)
) {
const buildInfoPath = getOutputPathForBuildInfo(
instance.compiler,
resolvedRef.commandLine.options
);
if (buildInfoPath) {
const text = instance.compiler.sys.readFile(buildInfoPath);
if (text) {
const assetPath = path.relative(
compilation.compiler.outputPath,
path.resolve(buildInfoPath)
);
compilation.assets[assetPath] = {
source: () => text,
size: () => text.length
};
}
}
}
}
);
}
}

if (instance.watchHost) {
// Ensure emit is complete
getEmitFromWatchHost(instance);
if (instance.watchHost.tsbuildinfo) {
const { tsbuildinfo } = instance.watchHost;
const assetPath = path.relative(
compilation.compiler.outputPath,
path.resolve(tsbuildinfo.name)
);
compilation.assets[assetPath] = {
source: () => tsbuildinfo.text,
size: () => tsbuildinfo.text.length
};
outputFileToAsset(instance.watchHost.tsbuildinfo, compilation);
}

instance.watchHost.outputFiles.clear();
instance.watchHost.tsbuildinfo = undefined;
}
}

/**
* gather all solution builder assets
*/
function provideAssetsFromSolutionBuilderHost(
instance: TSInstance,
compilation: webpack.compilation.Compilation
) {
if (instance.solutionBuilderHost) {
// written files
outputFilesToAsset(instance.solutionBuilderHost.writtenFiles, compilation);
instance.solutionBuilderHost.writtenFiles.length = 0;
}
}

/**
* handle all other errors. The basic approach here to get accurate error
* reporting is to start with a "blank slate" each compilation and gather
Expand Down

0 comments on commit 1908a47

Please sign in to comment.