UNPKG

3.44 kBJavaScriptView Raw
1const { logInfo, logError } = require('./log');
2const { query } = require('../configs/utils');
3const fs = require('fs');
4const path = require('path');
5const chokidar = require('chokidar');
6const glob = require('fast-glob');
7
8const rootDir = process.cwd();
9
10function getPackageJson(dir) {
11 const packageJsonFile = path.resolve(dir, './package.json');
12 if (!fs.existsSync(packageJsonFile)) { return; }
13 return require(packageJsonFile);
14}
15
16function createWatcher(package, packageRootDir, isWatching) {
17 return new Promise(resolve => {
18 let isReady = false;
19 const packageJson = getPackageJson(packageRootDir);
20 if (!packageJson) { logError(`Unable to find the "package.json" file for "${package}".`); return; }
21 const localRootDirsPattern = `${path.join(rootDir, './node_modules')}/**/${package}`.replace(/\\/g, '/');
22 const localRootDirs = glob.sync(localRootDirsPattern, { absolute: true, onlyDirectories: true });
23
24 const rootFiles = packageJson.files || ['dist'];
25 const mandatoryFiles = [
26 'package.json',
27 'license.*', // TODO: This doesn't seem to be matching...?
28 packageJson.main || '',
29 ];
30
31 const watchedItems = rootFiles.concat(mandatoryFiles)
32 .filter(item => item != null)
33 .map(file => path.join(packageRootDir, file));
34
35 const watcher = chokidar.watch(watchedItems, {
36 awaitWriteFinish: true,
37 });
38
39 const copyFile = file => {
40 const relativeFile = path.relative(packageRootDir, file);
41 localRootDirs.forEach(localRootDir => {
42 const destFile = path.join(localRootDir, relativeFile);
43 const destPath = path.dirname(destFile);
44 if (!fs.existsSync(destPath)) { fs.mkdirSync(destPath); }
45 if (fs.existsSync(destFile) && fs.statSync(destFile).mtime >= fs.statSync(file).mtime) { return; }
46 fs.copyFileSync(file, destFile);
47 });
48 if (isReady) { logInfo(`\t${package}: Copied file "${relativeFile}"`); }
49 };
50
51 const removeFile = file => {
52 const relativeFile = path.relative(packageRootDir, file);
53 localRootDirs.forEach(localRootDir => {
54 const destFile = path.join(localRootDir, relativeFile);
55 if (!fs.existsSync(destFile)) { return; }
56 fs.unlinkSync(destFile);
57 });
58 if (isReady) { logInfo(`\t${package}: Removed file "${relativeFile}"`); }
59 };
60
61 logInfo(`\t${isWatching ? 'Watching' : 'Copying'} files for package "${package}"`);
62 watcher
63 .on('add', copyFile)
64 .on('change', copyFile)
65 .on('unlink', removeFile)
66 .on('ready', () => {
67 isReady = true;
68 resolve(watcher);
69 });
70 });
71}
72
73function stopWatcher(watcher) {
74 if (!watcher) { return; }
75 watcher.close();
76}
77
78module.exports = async (shouldWatchFiles) => {
79 logInfo('Pulling in dependencies for this package...');
80 const packageJson = getPackageJson(rootDir);
81 if (!packageJson) { logError('Unable to find "package.json" for this package.'); return; }
82 if (typeof (packageJson.pull) != 'object') { logError('There are no packages to pull for this package.'); return; }
83 const watchers = await Promise.all(Object.keys(packageJson.pull).map(key => createWatcher(key, packageJson.pull[key], shouldWatchFiles)));
84 if (shouldWatchFiles && watchers.every(watcher => watcher != null)) { await query('Press enter to stop...\n'); }
85 watchers.map(stopWatcher);
86};