Skip to content

Commit ece3ea2

Browse files
committed
Implement getCustomTransformer in makeSolutionBuilderHost
This allows us to pass on the custom transformer while the project references are built.
1 parent 3720126 commit ece3ea2

23 files changed

+293
-1
lines changed

src/servicesHost.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type * as typescript from 'typescript';
33
import * as webpack from 'webpack';
44
import { getParsedCommandLine } from './config';
55
import * as constants from './constants';
6-
import { getOutputFileNames } from './instances';
6+
import { getCustomTransformers, getOutputFileNames } from './instances';
77
import {
88
CacheableHost,
99
ConfigFileInfo,
@@ -766,6 +766,11 @@ export function makeSolutionBuilderHost(
766766
reportSolutionBuilderStatus,
767767
reportWatchStatus
768768
);
769+
770+
// Keeps track of the various `typescript.CustomTransformers` for each program that is created.
771+
const customTransformers = new Map<string, typescript.CustomTransformers>();
772+
773+
// let lastBuilderProgram: typescript.CreateProgram | undefined = undefined;
769774
const solutionBuilderHost: SolutionBuilderWithWatchHost = {
770775
...sysHost,
771776
...moduleResolutionHost,
@@ -789,12 +794,28 @@ export function makeSolutionBuilderHost(
789794
);
790795
instance.typeReferenceResolutionCache?.update(instance.compilerOptions);
791796
instance.moduleResolutionCache?.update(instance.compilerOptions);
797+
798+
if (options) {
799+
// The `configFilePath` is the same value that is used as the `project` parameter of
800+
// `getCustomtransformers` below.
801+
const project = options.configFilePath?.toString();
802+
if (project) {
803+
// Custom transformers need a reference to the `typescript.Program`, that reference is
804+
// unavailable during the the `getCustomTransformers` callback below.
805+
const transformers = getCustomTransformers(instance.loaderOptions, result.getProgram(), result.getProgram);
806+
customTransformers.set(project, transformers);
807+
}
808+
}
809+
792810
return result;
793811
},
794812
resolveModuleNames,
795813
resolveTypeReferenceDirectives,
796814
diagnostics,
797815
...createWatchFactory(filePathKeyMapper, compiler),
816+
getCustomTransformers: function (project: string) {
817+
return customTransformers.get(project);
818+
},
798819
// Overrides
799820
writeFile: (name, text, writeByteOrderMark) => {
800821
const key = filePathKeyMapper(name);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { lib } from './lib';
2+
3+
console.log(lib.one, lib.two, lib.three);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3+
* This devtool is neither made for production nor for readable output files.
4+
* It uses "eval()" calls to create a separate source file in the browser devtools.
5+
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6+
* or disable the default devtool with "devtool: false".
7+
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8+
*/
9+
/******/ (() => { // webpackBootstrap
10+
/******/ "use strict";
11+
/******/ var __webpack_modules__ = ({
12+
13+
/***/ "./app.ts":
14+
/*!****************!*\
15+
!*** ./app.ts ***!
16+
\****************/
17+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18+
19+
eval("\nexports.__esModule = true;\nvar lib_1 = __webpack_require__(/*! ./lib */ \"./lib/index.ts\");\n/*transform was here*/ console.log(lib_1.lib.one, lib_1.lib.two, lib_1.lib.three);\n\n\n//# sourceURL=webpack:///./app.ts?");
20+
21+
/***/ }),
22+
23+
/***/ "./lib/index.ts":
24+
/*!**********************!*\
25+
!*** ./lib/index.ts ***!
26+
\**********************/
27+
/***/ ((__unused_webpack_module, exports) => {
28+
29+
eval("\nexports.__esModule = true;\nexports.lib = void 0;\n/*transform was here*/ exports.lib = {\n one: 1,\n two: 2,\n three: 3\n};\n\n\n//# sourceURL=webpack:///./lib/index.ts?");
30+
31+
/***/ })
32+
33+
/******/ });
34+
/************************************************************************/
35+
/******/ // The module cache
36+
/******/ var __webpack_module_cache__ = {};
37+
/******/
38+
/******/ // The require function
39+
/******/ function __webpack_require__(moduleId) {
40+
/******/ // Check if module is in cache
41+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
42+
/******/ if (cachedModule !== undefined) {
43+
/******/ return cachedModule.exports;
44+
/******/ }
45+
/******/ // Create a new module (and put it into the cache)
46+
/******/ var module = __webpack_module_cache__[moduleId] = {
47+
/******/ // no module.id needed
48+
/******/ // no module.loaded needed
49+
/******/ exports: {}
50+
/******/ };
51+
/******/
52+
/******/ // Execute the module function
53+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
54+
/******/
55+
/******/ // Return the exports of the module
56+
/******/ return module.exports;
57+
/******/ }
58+
/******/
59+
/************************************************************************/
60+
/******/
61+
/******/ // startup
62+
/******/ // Load entry module and return exports
63+
/******/ // This entry module can't be inlined because the eval devtool is used.
64+
/******/ var __webpack_exports__ = __webpack_require__("./app.ts");
65+
/******/
66+
/******/ })()
67+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export declare const lib: {
2+
one: number;
3+
two: number;
4+
three: number;
5+
};

test/comparison-tests/projectReferencesWithCustomTransformer/expectedOutput-4.9/lib/index.js

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/comparison-tests/projectReferencesWithCustomTransformer/expectedOutput-4.9/lib/index.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"program":{"fileNames":["../../../node_modules/typescript/lib/lib.d.ts","../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../../node_modules/typescript/lib/lib.scripthost.d.ts","./index.ts"],"fileInfos":["2dc8c927c9c162a773c6bb3cdc4f3286c23f10eedc67414028f9cb5951610f60",{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},"28ead8445f54a115ea5f778da4f4f80579fbae42ac6ccc3493626084ed335839"],"options":{"composite":true,"newLine":1,"skipLibCheck":true,"sourceMap":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[6,1,3,2,5,4],"emitSignatures":[[6,"82b9c263edd140802d0afbd57d557b2c41db16c5ad9a744bca8c71ad5b10f66f"]],"latestChangedDtsFile":"./index.d.ts"},"version":"4.9.3"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
asset bundle.js 2.6 KiB [emitted] (name: main)
2+
asset lib/tsconfig.tsbuildinfo 1.17 KiB [compared for emit]
3+
asset lib/index.js.map 188 bytes [compared for emit]
4+
asset lib/index.js 152 bytes [compared for emit]
5+
asset lib/index.d.ts 84 bytes [compared for emit]
6+
./app.ts 131 bytes [built] [code generated]
7+
./lib/index.ts 119 bytes [built] [code generated]
8+
webpack compiled successfully
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3+
* This devtool is neither made for production nor for readable output files.
4+
* It uses "eval()" calls to create a separate source file in the browser devtools.
5+
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6+
* or disable the default devtool with "devtool: false".
7+
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8+
*/
9+
/******/ (() => { // webpackBootstrap
10+
/******/ "use strict";
11+
/******/ var __webpack_modules__ = ({
12+
13+
/***/ "./app.ts":
14+
/*!****************!*\
15+
!*** ./app.ts ***!
16+
\****************/
17+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
18+
19+
eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nvar lib_1 = __webpack_require__(/*! ./lib */ \"./lib/index.ts\");\n/*transform was here*/ console.log(lib_1.lib.one, lib_1.lib.two, lib_1.lib.three);\n\n\n//# sourceURL=webpack:///./app.ts?");
20+
21+
/***/ }),
22+
23+
/***/ "./lib/index.ts":
24+
/*!**********************!*\
25+
!*** ./lib/index.ts ***!
26+
\**********************/
27+
/***/ ((__unused_webpack_module, exports) => {
28+
29+
eval("\nexports.__esModule = true;\nexports.lib = void 0;\n/*transform was here*/ exports.lib = {\n one: 1,\n two: 2,\n three: 3\n};\n\n\n//# sourceURL=webpack:///./lib/index.ts?");
30+
31+
/***/ })
32+
33+
/******/ });
34+
/************************************************************************/
35+
/******/ // The module cache
36+
/******/ var __webpack_module_cache__ = {};
37+
/******/
38+
/******/ // The require function
39+
/******/ function __webpack_require__(moduleId) {
40+
/******/ // Check if module is in cache
41+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
42+
/******/ if (cachedModule !== undefined) {
43+
/******/ return cachedModule.exports;
44+
/******/ }
45+
/******/ // Create a new module (and put it into the cache)
46+
/******/ var module = __webpack_module_cache__[moduleId] = {
47+
/******/ // no module.id needed
48+
/******/ // no module.loaded needed
49+
/******/ exports: {}
50+
/******/ };
51+
/******/
52+
/******/ // Execute the module function
53+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
54+
/******/
55+
/******/ // Return the exports of the module
56+
/******/ return module.exports;
57+
/******/ }
58+
/******/
59+
/************************************************************************/
60+
/******/
61+
/******/ // startup
62+
/******/ // Load entry module and return exports
63+
/******/ // This entry module can't be inlined because the eval devtool is used.
64+
/******/ var __webpack_exports__ = __webpack_require__("./app.ts");
65+
/******/
66+
/******/ })()
67+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export declare const lib: {
2+
one: number;
3+
two: number;
4+
three: number;
5+
};

test/comparison-tests/projectReferencesWithCustomTransformer/expectedOutput-transpile-4.9/lib/index.js

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/comparison-tests/projectReferencesWithCustomTransformer/expectedOutput-transpile-4.9/lib/index.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"program":{"fileNames":["../../../node_modules/typescript/lib/lib.d.ts","../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../../node_modules/typescript/lib/lib.scripthost.d.ts","./index.ts"],"fileInfos":["2dc8c927c9c162a773c6bb3cdc4f3286c23f10eedc67414028f9cb5951610f60",{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"7fac8cb5fc820bc2a59ae11ef1c5b38d3832c6d0dfaec5acdb5569137d09a481","affectsGlobalScope":true},{"version":"097a57355ded99c68e6df1b738990448e0bf170e606707df5a7c0481ff2427cd","affectsGlobalScope":true},"28ead8445f54a115ea5f778da4f4f80579fbae42ac6ccc3493626084ed335839"],"options":{"composite":true,"newLine":1,"skipLibCheck":true,"sourceMap":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[6,1,3,2,5,4],"emitSignatures":[[6,"82b9c263edd140802d0afbd57d557b2c41db16c5ad9a744bca8c71ad5b10f66f"]],"latestChangedDtsFile":"./index.d.ts"},"version":"4.9.3"}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
asset bundle.js 2.64 KiB [emitted] (name: main)
2+
asset lib/tsconfig.tsbuildinfo 1.17 KiB [compared for emit]
3+
asset lib/index.js.map 188 bytes [compared for emit]
4+
asset lib/index.js 152 bytes [compared for emit]
5+
asset lib/index.d.ts 84 bytes [compared for emit]
6+
./app.ts 167 bytes [built] [code generated]
7+
./lib/index.ts 119 bytes [built] [code generated]
8+
webpack compiled successfully
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!*.js.map
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export declare const lib: {
2+
one: number;
3+
two: number;
4+
three: number;
5+
};

test/comparison-tests/projectReferencesWithCustomTransformer/lib/index.js

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/comparison-tests/projectReferencesWithCustomTransformer/lib/index.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const lib = {
2+
one: 1,
3+
two: 2,
4+
three: 3
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true,
4+
"sourceMap": true,
5+
"types": []
6+
},
7+
"files": [
8+
"./index.ts"
9+
]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"types": []
4+
},
5+
"files": [
6+
"./app.ts"
7+
],
8+
"references": [
9+
{ "path": "./lib" }
10+
]
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"use strict";
2+
exports.__esModule = true;
3+
var ts = require("typescript");
4+
var transformer = function (context) {
5+
var visitor = function (node) {
6+
if (node.kind == ts.SyntaxKind.FirstStatement || ts.isExpressionStatement(node)) {
7+
return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, "transform was here")
8+
}
9+
return ts.visitEachChild(node, visitor, context);
10+
};
11+
return function (node) { return ts.visitNode(node, visitor); };
12+
};
13+
exports["default"] = transformer;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
var path = require('path');
2+
var wasHereTransformer = require('./wasHereTransformer').default;
3+
4+
module.exports = {
5+
mode: 'development',
6+
entry: './app.ts',
7+
output: {
8+
filename: 'bundle.js'
9+
},
10+
resolve: {
11+
extensions: ['.ts', '.js']
12+
},
13+
module: {
14+
rules: [
15+
{
16+
test: /\.ts$/,
17+
loader: 'ts-loader',
18+
options: {
19+
projectReferences: true,
20+
getCustomTransformers: (program) => ({
21+
before: [wasHereTransformer]
22+
})
23+
}
24+
}
25+
]
26+
}
27+
}
28+
29+
// for test harness purposes only, you would not need this in a normal project
30+
module.exports.resolveLoader = { alias: { 'ts-loader': require('path').join(__dirname, "../../../index.js") } }
31+

0 commit comments

Comments
 (0)