1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const chalk_1 = require("chalk");
|
4 | const TsconfigPaths = require("tsconfig-paths");
|
5 | const path = require("path");
|
6 | const Options = require("./options");
|
7 | const Logger = require("./logger");
|
8 | const getInnerRequest = require("enhanced-resolve/lib/getInnerRequest");
|
9 | class TsconfigPathsPlugin {
|
10 | constructor(rawOptions = {}) {
|
11 | this.source = "described-resolve";
|
12 | this.target = "resolve";
|
13 | const options = Options.getOptions(rawOptions);
|
14 | this.extensions = options.extensions;
|
15 | const colors = new chalk_1.default.constructor({ enabled: options.colors });
|
16 | this.log = Logger.makeLogger(options, colors);
|
17 | const context = options.context || process.cwd();
|
18 | const loadFrom = options.configFile || context;
|
19 | const loadResult = TsconfigPaths.loadConfig(loadFrom);
|
20 | if (loadResult.resultType === "failed") {
|
21 | this.log.logError(`Failed to load tsconfig.json: ${loadResult.message}`);
|
22 | }
|
23 | else {
|
24 | this.log.logInfo(`tsconfig-paths-webpack-plugin: Using config file at ${loadResult.configFileAbsolutePath}`);
|
25 | this.baseUrl = options.baseUrl || loadResult.baseUrl;
|
26 | this.absoluteBaseUrl = options.baseUrl
|
27 | ? path.resolve(options.baseUrl)
|
28 | : loadResult.absoluteBaseUrl;
|
29 | this.matchPath = TsconfigPaths.createMatchPathAsync(this.absoluteBaseUrl, loadResult.paths);
|
30 | }
|
31 | }
|
32 | apply(resolver) {
|
33 | const { baseUrl } = this;
|
34 | if (!baseUrl) {
|
35 |
|
36 | this.log.logWarning("tsconfig-paths-webpack-plugin: Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin");
|
37 | return;
|
38 | }
|
39 |
|
40 |
|
41 |
|
42 | if (!resolver.fileSystem) {
|
43 | this.log.logWarning("tsconfig-paths-webpack-plugin: No file system found on resolver." +
|
44 | " Please make sure you've placed the plugin in the correct part of the configuration." +
|
45 | " This plugin is a resolver plugin and should be placed in the resolve part of the Webpack configuration.");
|
46 | return;
|
47 | }
|
48 |
|
49 | if (resolver.getHook && typeof resolver.getHook === "function") {
|
50 | resolver
|
51 | .getHook(this.source)
|
52 | .tapAsync({ name: "TsconfigPathsPlugin" }, createPluginCallback(this.matchPath, resolver, this.absoluteBaseUrl, resolver.getHook(this.target), this.extensions));
|
53 | }
|
54 | else {
|
55 |
|
56 | resolver.plugin(this.source, createPluginLegacy(this.matchPath, resolver, this.absoluteBaseUrl, this.target, this.extensions));
|
57 | }
|
58 | }
|
59 | }
|
60 | exports.TsconfigPathsPlugin = TsconfigPathsPlugin;
|
61 | function createPluginCallback(matchPath, resolver, absoluteBaseUrl, hook, extensions) {
|
62 | const fileExistAsync = createFileExistAsync(resolver.fileSystem);
|
63 | const readJsonAsync = createReadJsonAsync(resolver.fileSystem);
|
64 | return (request, resolveContext, callback) => {
|
65 | const innerRequest = getInnerRequest(resolver, request);
|
66 | if (!innerRequest ||
|
67 | (innerRequest.startsWith(".") || innerRequest.startsWith(".."))) {
|
68 | return callback();
|
69 | }
|
70 | matchPath(innerRequest, readJsonAsync, fileExistAsync, extensions, (err, foundMatch) => {
|
71 | if (err) {
|
72 | return callback(err);
|
73 | }
|
74 | if (!foundMatch) {
|
75 | return callback();
|
76 | }
|
77 | const newRequest = Object.assign({}, request, { request: foundMatch, path: absoluteBaseUrl });
|
78 |
|
79 |
|
80 |
|
81 | const createInnerContext = require("enhanced-resolve/lib/createInnerContext");
|
82 | return resolver.doResolve(hook, newRequest, `Resolved request '${innerRequest}' to '${foundMatch}' using tsconfig.json paths mapping`, createInnerContext(Object.assign({}, resolveContext)), (err2, result2) => {
|
83 |
|
84 |
|
85 | if (err2) {
|
86 | return callback(err2);
|
87 | }
|
88 |
|
89 | if (result2 === undefined) {
|
90 | return callback(null, null);
|
91 | }
|
92 | callback(null, result2);
|
93 | });
|
94 | });
|
95 | };
|
96 | }
|
97 | function createPluginLegacy(matchPath, resolver, absoluteBaseUrl, target, extensions) {
|
98 | const fileExistAsync = createFileExistAsync(resolver.fileSystem);
|
99 | const readJsonAsync = createReadJsonAsync(resolver.fileSystem);
|
100 | return (request, callback) => {
|
101 | const innerRequest = getInnerRequest(resolver, request);
|
102 | if (!innerRequest ||
|
103 | (innerRequest.startsWith(".") || innerRequest.startsWith(".."))) {
|
104 | return callback();
|
105 | }
|
106 | matchPath(innerRequest, readJsonAsync, fileExistAsync, extensions, (err, foundMatch) => {
|
107 | if (err) {
|
108 | return callback(err);
|
109 | }
|
110 | if (!foundMatch) {
|
111 | return callback();
|
112 | }
|
113 | const newRequest = Object.assign({}, request, { request: foundMatch, path: absoluteBaseUrl });
|
114 |
|
115 |
|
116 |
|
117 | const createInnerCallback = require("enhanced-resolve/lib/createInnerCallback");
|
118 | return resolver.doResolve(target, newRequest, `Resolved request '${innerRequest}' to '${foundMatch}' using tsconfig.json paths mapping`, createInnerCallback(function (err2, result2) {
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 | if (arguments.length > 0) {
|
125 | return callback(err2, result2);
|
126 | }
|
127 |
|
128 | callback(null, null);
|
129 | }, callback));
|
130 | });
|
131 | };
|
132 | }
|
133 | function createReadJsonAsync(filesystem) {
|
134 |
|
135 | return (path2, callback2) => {
|
136 | filesystem.readJson(path2, (err, json) => {
|
137 |
|
138 | if (err || !json) {
|
139 | callback2();
|
140 | return;
|
141 | }
|
142 | callback2(undefined, json);
|
143 | });
|
144 | };
|
145 | }
|
146 | function createFileExistAsync(filesystem) {
|
147 | return (path2, callback2) => {
|
148 | filesystem.stat(path2, (err, stats) => {
|
149 |
|
150 | if (err) {
|
151 | callback2(undefined, false);
|
152 | return;
|
153 | }
|
154 | callback2(undefined, stats ? stats.isFile() : false);
|
155 | });
|
156 | };
|
157 | }
|