UNPKG

10.1 kBJavaScriptView Raw
1/*
2 @license
3 Rollup.js v2.75.7
4 Mon, 20 Jun 2022 07:24:02 GMT - commit 057171c2d3bc2092b7f543fc05ead01f12595f12
5
6 https://github.com/rollup/rollup
7
8 Released under the MIT License.
9*/
10'use strict';
11
12Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
13
14const require$$0 = require('path');
15const process = require('process');
16const rollup = require('./rollup.js');
17const mergeOptions = require('./mergeOptions.js');
18const require$$2 = require('os');
19const index = require('./index.js');
20require('perf_hooks');
21require('crypto');
22require('fs');
23require('events');
24require('util');
25require('stream');
26
27class FileWatcher {
28 constructor(task, chokidarOptions) {
29 this.transformWatchers = new Map();
30 this.chokidarOptions = chokidarOptions;
31 this.task = task;
32 this.watcher = this.createWatcher(null);
33 }
34 close() {
35 this.watcher.close();
36 for (const watcher of this.transformWatchers.values()) {
37 watcher.close();
38 }
39 }
40 unwatch(id) {
41 this.watcher.unwatch(id);
42 const transformWatcher = this.transformWatchers.get(id);
43 if (transformWatcher) {
44 this.transformWatchers.delete(id);
45 transformWatcher.close();
46 }
47 }
48 watch(id, isTransformDependency) {
49 var _a;
50 if (isTransformDependency) {
51 const watcher = (_a = this.transformWatchers.get(id)) !== null && _a !== void 0 ? _a : this.createWatcher(id);
52 watcher.add(id);
53 this.transformWatchers.set(id, watcher);
54 }
55 else {
56 this.watcher.add(id);
57 }
58 }
59 createWatcher(transformWatcherId) {
60 const task = this.task;
61 const isLinux = require$$2.platform() === 'linux';
62 const isTransformDependency = transformWatcherId !== null;
63 const handleChange = (id, event) => {
64 const changedId = transformWatcherId || id;
65 if (isLinux) {
66 // unwatching and watching fixes an issue with chokidar where on certain systems,
67 // a file that was unlinked and immediately recreated would create a change event
68 // but then no longer any further events
69 watcher.unwatch(changedId);
70 watcher.add(changedId);
71 }
72 task.invalidate(changedId, { event, isTransformDependency });
73 };
74 const watcher = index.chokidar
75 .watch([], this.chokidarOptions)
76 .on('add', id => handleChange(id, 'create'))
77 .on('change', id => handleChange(id, 'update'))
78 .on('unlink', id => handleChange(id, 'delete'));
79 return watcher;
80 }
81}
82
83const eventsRewrites = {
84 create: {
85 create: 'buggy',
86 delete: null,
87 update: 'create'
88 },
89 delete: {
90 create: 'update',
91 delete: 'buggy',
92 update: 'buggy'
93 },
94 update: {
95 create: 'buggy',
96 delete: 'delete',
97 update: 'update'
98 }
99};
100class Watcher {
101 constructor(configs, emitter) {
102 this.buildDelay = 0;
103 this.buildTimeout = null;
104 this.invalidatedIds = new Map();
105 this.rerun = false;
106 this.running = true;
107 this.emitter = emitter;
108 emitter.close = this.close.bind(this);
109 this.tasks = configs.map(config => new Task(this, config));
110 this.buildDelay = configs.reduce((buildDelay, { watch }) => watch && typeof watch.buildDelay === 'number'
111 ? Math.max(buildDelay, watch.buildDelay)
112 : buildDelay, this.buildDelay);
113 process.nextTick(() => this.run());
114 }
115 async close() {
116 if (this.buildTimeout)
117 clearTimeout(this.buildTimeout);
118 for (const task of this.tasks) {
119 task.close();
120 }
121 await this.emitter.emitAndAwait('close');
122 this.emitter.removeAllListeners();
123 }
124 invalidate(file) {
125 if (file) {
126 const prevEvent = this.invalidatedIds.get(file.id);
127 const event = prevEvent ? eventsRewrites[prevEvent][file.event] : file.event;
128 if (event === 'buggy') {
129 //TODO: throws or warn? Currently just ignore, uses new event
130 this.invalidatedIds.set(file.id, file.event);
131 }
132 else if (event === null) {
133 this.invalidatedIds.delete(file.id);
134 }
135 else {
136 this.invalidatedIds.set(file.id, event);
137 }
138 }
139 if (this.running) {
140 this.rerun = true;
141 return;
142 }
143 if (this.buildTimeout)
144 clearTimeout(this.buildTimeout);
145 this.buildTimeout = setTimeout(async () => {
146 this.buildTimeout = null;
147 try {
148 await Promise.all([...this.invalidatedIds].map(([id, event]) => this.emitter.emitAndAwait('change', id, { event })));
149 this.invalidatedIds.clear();
150 this.emitter.emit('restart');
151 this.emitter.removeAwaited();
152 this.run();
153 }
154 catch (error) {
155 this.invalidatedIds.clear();
156 this.emitter.emit('event', {
157 code: 'ERROR',
158 error,
159 result: null
160 });
161 this.emitter.emit('event', {
162 code: 'END'
163 });
164 }
165 }, this.buildDelay);
166 }
167 async run() {
168 this.running = true;
169 this.emitter.emit('event', {
170 code: 'START'
171 });
172 for (const task of this.tasks) {
173 await task.run();
174 }
175 this.running = false;
176 this.emitter.emit('event', {
177 code: 'END'
178 });
179 if (this.rerun) {
180 this.rerun = false;
181 this.invalidate();
182 }
183 }
184}
185class Task {
186 constructor(watcher, config) {
187 this.cache = { modules: [] };
188 this.watchFiles = [];
189 this.closed = false;
190 this.invalidated = true;
191 this.watched = new Set();
192 this.watcher = watcher;
193 this.skipWrite = Boolean(config.watch && config.watch.skipWrite);
194 this.options = mergeOptions.mergeOptions(config);
195 this.outputs = this.options.output;
196 this.outputFiles = this.outputs.map(output => {
197 if (output.file || output.dir)
198 return require$$0.resolve(output.file || output.dir);
199 return undefined;
200 });
201 const watchOptions = this.options.watch || {};
202 this.filter = rollup.createFilter(watchOptions.include, watchOptions.exclude);
203 this.fileWatcher = new FileWatcher(this, {
204 ...watchOptions.chokidar,
205 disableGlobbing: true,
206 ignoreInitial: true
207 });
208 }
209 close() {
210 this.closed = true;
211 this.fileWatcher.close();
212 }
213 invalidate(id, details) {
214 this.invalidated = true;
215 if (details.isTransformDependency) {
216 for (const module of this.cache.modules) {
217 if (!module.transformDependencies.includes(id))
218 continue;
219 // effective invalidation
220 module.originalCode = null;
221 }
222 }
223 this.watcher.invalidate({ event: details.event, id });
224 }
225 async run() {
226 if (!this.invalidated)
227 return;
228 this.invalidated = false;
229 const options = {
230 ...this.options,
231 cache: this.cache
232 };
233 const start = Date.now();
234 this.watcher.emitter.emit('event', {
235 code: 'BUNDLE_START',
236 input: this.options.input,
237 output: this.outputFiles
238 });
239 let result = null;
240 try {
241 result = await rollup.rollupInternal(options, this.watcher.emitter);
242 if (this.closed) {
243 return;
244 }
245 this.updateWatchedFiles(result);
246 this.skipWrite || (await Promise.all(this.outputs.map(output => result.write(output))));
247 this.watcher.emitter.emit('event', {
248 code: 'BUNDLE_END',
249 duration: Date.now() - start,
250 input: this.options.input,
251 output: this.outputFiles,
252 result
253 });
254 }
255 catch (error) {
256 if (!this.closed) {
257 if (Array.isArray(error.watchFiles)) {
258 for (const id of error.watchFiles) {
259 this.watchFile(id);
260 }
261 }
262 if (error.id) {
263 this.cache.modules = this.cache.modules.filter(module => module.id !== error.id);
264 }
265 }
266 this.watcher.emitter.emit('event', {
267 code: 'ERROR',
268 error,
269 result
270 });
271 }
272 }
273 updateWatchedFiles(result) {
274 const previouslyWatched = this.watched;
275 this.watched = new Set();
276 this.watchFiles = result.watchFiles;
277 this.cache = result.cache;
278 for (const id of this.watchFiles) {
279 this.watchFile(id);
280 }
281 for (const module of this.cache.modules) {
282 for (const depId of module.transformDependencies) {
283 this.watchFile(depId, true);
284 }
285 }
286 for (const id of previouslyWatched) {
287 if (!this.watched.has(id)) {
288 this.fileWatcher.unwatch(id);
289 }
290 }
291 }
292 watchFile(id, isTransformDependency = false) {
293 if (!this.filter(id))
294 return;
295 this.watched.add(id);
296 if (this.outputFiles.some(file => file === id)) {
297 throw new Error('Cannot import the generated bundle');
298 }
299 // this is necessary to ensure that any 'renamed' files
300 // continue to be watched following an error
301 this.fileWatcher.watch(id, isTransformDependency);
302 }
303}
304
305exports.Task = Task;
306exports.Watcher = Watcher;
307//# sourceMappingURL=watch.js.map