1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
10 | if (k2 === undefined) k2 = k;
|
11 | var desc = Object.getOwnPropertyDescriptor(m, k);
|
12 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
13 | desc = { enumerable: true, get: function() { return m[k]; } };
|
14 | }
|
15 | Object.defineProperty(o, k2, desc);
|
16 | }) : (function(o, m, k, k2) {
|
17 | if (k2 === undefined) k2 = k;
|
18 | o[k2] = m[k];
|
19 | }));
|
20 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
21 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
22 | }) : function(o, v) {
|
23 | o["default"] = v;
|
24 | });
|
25 | var __importStar = (this && this.__importStar) || function (mod) {
|
26 | if (mod && mod.__esModule) return mod;
|
27 | var result = {};
|
28 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
29 | __setModuleDefault(result, mod);
|
30 | return result;
|
31 | };
|
32 | Object.defineProperty(exports, "__esModule", { value: true });
|
33 | exports.NgccProcessor = void 0;
|
34 | const child_process_1 = require("child_process");
|
35 | const crypto_1 = require("crypto");
|
36 | const fs_1 = require("fs");
|
37 | const path = __importStar(require("path"));
|
38 | const benchmark_1 = require("./benchmark");
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | class NgccProcessor {
|
47 | constructor(compilerNgcc, propertiesToConsider, compilationWarnings, compilationErrors, basePath, tsConfigPath, inputFileSystem, resolver) {
|
48 | this.compilerNgcc = compilerNgcc;
|
49 | this.propertiesToConsider = propertiesToConsider;
|
50 | this.compilationWarnings = compilationWarnings;
|
51 | this.compilationErrors = compilationErrors;
|
52 | this.basePath = basePath;
|
53 | this.tsConfigPath = tsConfigPath;
|
54 | this.inputFileSystem = inputFileSystem;
|
55 | this.resolver = resolver;
|
56 | this._processedModules = new Set();
|
57 | this._logger = new NgccLogger(this.compilationWarnings, this.compilationErrors, compilerNgcc.LogLevel.info);
|
58 | this._nodeModulesDirectory = this.findNodeModulesDirectory(this.basePath);
|
59 | }
|
60 |
|
61 | process() {
|
62 |
|
63 | if (process.env.BAZEL_TARGET) {
|
64 | return;
|
65 | }
|
66 |
|
67 | const corePackage = this.tryResolvePackage('@angular/core', this._nodeModulesDirectory);
|
68 | if (corePackage && isReadOnlyFile(corePackage)) {
|
69 | return;
|
70 | }
|
71 |
|
72 |
|
73 |
|
74 | let skipProcessing = false;
|
75 | let runHashFilePath;
|
76 | const runHashBasePath = path.join(this._nodeModulesDirectory, '.cli-ngcc');
|
77 | const projectBasePath = path.join(this._nodeModulesDirectory, '..');
|
78 | try {
|
79 | let ngccConfigData;
|
80 | try {
|
81 | ngccConfigData = (0, fs_1.readFileSync)(path.join(projectBasePath, 'ngcc.config.js'));
|
82 | }
|
83 | catch {
|
84 | ngccConfigData = '';
|
85 | }
|
86 | const relativeTsconfigPath = path.relative(projectBasePath, this.tsConfigPath);
|
87 | const tsconfigData = (0, fs_1.readFileSync)(this.tsConfigPath);
|
88 | const { lockFileData, lockFilePath } = this.findPackageManagerLockFile(projectBasePath);
|
89 |
|
90 | const runHash = (0, crypto_1.createHash)('sha256')
|
91 | .update(lockFileData)
|
92 | .update(lockFilePath)
|
93 | .update(ngccConfigData)
|
94 | .update(tsconfigData)
|
95 | .update(relativeTsconfigPath)
|
96 | .digest('hex');
|
97 |
|
98 |
|
99 | runHashFilePath = path.join(runHashBasePath, runHash + '.lock');
|
100 |
|
101 | if ((0, fs_1.existsSync)(runHashFilePath)) {
|
102 | skipProcessing = true;
|
103 | }
|
104 | }
|
105 | catch {
|
106 |
|
107 | }
|
108 | if (skipProcessing) {
|
109 | return;
|
110 | }
|
111 | const timeLabel = 'NgccProcessor.process';
|
112 | (0, benchmark_1.time)(timeLabel);
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 | const originalProcessTitle = process.title;
|
119 | try {
|
120 | const { status, error } = (0, child_process_1.spawnSync)(process.execPath, [
|
121 | this.compilerNgcc.ngccMainFilePath,
|
122 | '--source' ,
|
123 | this._nodeModulesDirectory,
|
124 | '--properties' ,
|
125 | ...this.propertiesToConsider,
|
126 | '--first-only' ,
|
127 | '--create-ivy-entry-points' ,
|
128 | '--async',
|
129 | '--tsconfig' ,
|
130 | this.tsConfigPath,
|
131 | '--use-program-dependencies',
|
132 | ], {
|
133 | stdio: ['inherit', process.stderr, process.stderr],
|
134 | });
|
135 | if (status !== 0) {
|
136 | const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || '';
|
137 | throw new Error(errorMessage + `NGCC failed${errorMessage ? ', see above' : ''}.`);
|
138 | }
|
139 | }
|
140 | finally {
|
141 | process.title = originalProcessTitle;
|
142 | }
|
143 | (0, benchmark_1.timeEnd)(timeLabel);
|
144 |
|
145 | if (runHashFilePath) {
|
146 | try {
|
147 | if (!(0, fs_1.existsSync)(runHashBasePath)) {
|
148 | (0, fs_1.mkdirSync)(runHashBasePath, { recursive: true });
|
149 | }
|
150 | (0, fs_1.writeFileSync)(runHashFilePath, '');
|
151 | }
|
152 | catch {
|
153 |
|
154 | }
|
155 | }
|
156 | }
|
157 |
|
158 | processModule(moduleName, resolvedModule) {
|
159 | var _a, _b;
|
160 | const resolvedFileName = resolvedModule.resolvedFileName;
|
161 | if (!resolvedFileName ||
|
162 | moduleName.startsWith('.') ||
|
163 | this._processedModules.has(resolvedFileName)) {
|
164 |
|
165 | return;
|
166 | }
|
167 | const packageJsonPath = this.tryResolvePackage(moduleName, resolvedFileName);
|
168 |
|
169 |
|
170 | if (!packageJsonPath || isReadOnlyFile(packageJsonPath)) {
|
171 |
|
172 | this._processedModules.add(resolvedFileName);
|
173 | return;
|
174 | }
|
175 | const timeLabel = `NgccProcessor.processModule.ngcc.process+${moduleName}`;
|
176 | (0, benchmark_1.time)(timeLabel);
|
177 | this.compilerNgcc.process({
|
178 | basePath: this._nodeModulesDirectory,
|
179 | targetEntryPointPath: path.dirname(packageJsonPath),
|
180 | propertiesToConsider: this.propertiesToConsider,
|
181 | compileAllFormats: false,
|
182 | createNewEntryPointFormats: true,
|
183 | logger: this._logger,
|
184 | tsConfigPath: this.tsConfigPath,
|
185 | });
|
186 | (0, benchmark_1.timeEnd)(timeLabel);
|
187 |
|
188 |
|
189 | (_b = (_a = this.inputFileSystem).purge) === null || _b === void 0 ? void 0 : _b.call(_a, packageJsonPath);
|
190 | this._processedModules.add(resolvedFileName);
|
191 | }
|
192 | invalidate(fileName) {
|
193 | this._processedModules.delete(fileName);
|
194 | }
|
195 | |
196 |
|
197 |
|
198 | tryResolvePackage(moduleName, resolvedFileName) {
|
199 | try {
|
200 | const resolvedPath = this.resolver.resolveSync({}, resolvedFileName, `${moduleName}/package.json`);
|
201 | return resolvedPath || undefined;
|
202 | }
|
203 | catch {
|
204 |
|
205 |
|
206 | const packageJsonPath = path.resolve(resolvedFileName, '../package.json');
|
207 | return (0, fs_1.existsSync)(packageJsonPath) ? packageJsonPath : undefined;
|
208 | }
|
209 | }
|
210 | findNodeModulesDirectory(startPoint) {
|
211 | let current = startPoint;
|
212 | while (path.dirname(current) !== current) {
|
213 | const nodePath = path.join(current, 'node_modules');
|
214 | if ((0, fs_1.existsSync)(nodePath)) {
|
215 | return nodePath;
|
216 | }
|
217 | current = path.dirname(current);
|
218 | }
|
219 | throw new Error(`Cannot locate the 'node_modules' directory.`);
|
220 | }
|
221 | findPackageManagerLockFile(projectBasePath) {
|
222 | for (const lockFile of ['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json']) {
|
223 | const lockFilePath = path.join(projectBasePath, lockFile);
|
224 | try {
|
225 | return {
|
226 | lockFilePath,
|
227 | lockFileData: (0, fs_1.readFileSync)(lockFilePath),
|
228 | };
|
229 | }
|
230 | catch { }
|
231 | }
|
232 | throw new Error('Cannot locate a package manager lock file.');
|
233 | }
|
234 | }
|
235 | exports.NgccProcessor = NgccProcessor;
|
236 | class NgccLogger {
|
237 | constructor(compilationWarnings, compilationErrors, level) {
|
238 | this.compilationWarnings = compilationWarnings;
|
239 | this.compilationErrors = compilationErrors;
|
240 | this.level = level;
|
241 | }
|
242 |
|
243 | debug() { }
|
244 | info(...args) {
|
245 |
|
246 | process.stderr.write(`\n${args.join(' ')}\n`);
|
247 | }
|
248 | warn(...args) {
|
249 | this.compilationWarnings.push(args.join(' '));
|
250 | }
|
251 | error(...args) {
|
252 | this.compilationErrors.push(new Error(args.join(' ')));
|
253 | }
|
254 | }
|
255 | function isReadOnlyFile(fileName) {
|
256 | try {
|
257 | (0, fs_1.accessSync)(fileName, fs_1.constants.W_OK);
|
258 | return false;
|
259 | }
|
260 | catch {
|
261 | return true;
|
262 | }
|
263 | }
|