UNPKG

3.91 kBJavaScriptView Raw
1'use strict';
2
3const fs = require('fs');
4const pad = require('pad');
5const path = require('path');
6const chalk = require('chalk');
7const yargs = require('yargs');
8const rimraf = require('rimraf');
9const chokidar = require('chokidar');
10const pkg = require('../package.json');
11const utils = require('../utils');
12const logger = utils.logger({ name: 'dev' });
13
14const argv = yargs.argv
15const PACKAGE_ROOT = process.cwd();
16
17start();
18
19async function start() {
20 logger.log(chalk.green('start'));
21
22 const linkPath = checkLinkPath(argv.link);
23 if (!linkPath) return logger.log(chalk.red(`Error: no --link path provided`));
24
25 cleanupLinkPath({ linkPath });
26
27 process.on('exit', cleanupLinkPath.bind(null, { linkPath, exit: true }));
28 process.on('SIGINT', cleanupLinkPath.bind(null, { linkPath, exit: true }));
29 process.on('SIGTERM', cleanupLinkPath.bind(null, { linkPath, exit: true }));
30 process.on('SIGUSR1', cleanupLinkPath.bind(null, { linkPath, exit: true }));
31 process.on('SIGUSR2', cleanupLinkPath.bind(null, { linkPath, exit: true }));
32
33 const binaries = {};
34
35 for (const binary in pkg.bin) {
36 if (pkg.bin.hasOwnProperty(binary)) {
37 let binPath = path.relative(PACKAGE_ROOT, pkg.bin[binary]);
38 binaries[binPath] = binary;
39 }
40 }
41
42 const targetPath = path.join(linkPath, 'node_modules', pkg.name);
43 utils.ensureDirectoryExists(path.join(targetPath, 'index.js'), PACKAGE_ROOT); // creates target folder
44
45 const linker = chokidar.watch('.', { ignored: ['./node_modules', './scripts', /(^|[/\\])\../] });
46
47 linker.on('all', async (event, destPath) => {
48 let relPath = path.relative(PACKAGE_ROOT, destPath);
49 let copyPath = path.resolve(targetPath, relPath);
50 utils.ensureDirectoryExists(relPath, copyPath);
51 fs.copyFileSync(destPath, copyPath);
52
53 logger.log(chalk.blue(pad('copy', 5)), chalk.white(relPath), chalk.blue('→'), chalk.magenta(copyPath));
54
55 if (binaries[destPath]) {
56 let binaryLinkPath = path.join(linkPath, 'node_modules', '.bin', binaries[destPath]);
57 if (fs.existsSync(binaryLinkPath)) {
58 fs.unlinkSync(binaryLinkPath);
59 }
60 fs.symlinkSync(path.relative(path.dirname(binaryLinkPath), copyPath), binaryLinkPath);
61 fs.chmodSync(copyPath, '0755');
62 logger.log(chalk.blue(pad('link', 5)), chalk.white(copyPath), chalk.blue('→'), chalk.magenta(binaryLinkPath));
63 }
64 });
65
66 linker.on('ready', async () => {
67 logger.log(chalk.green('ready'));
68 });
69}
70
71function checkLinkPath(link) {
72 if (!link) return false;
73 let linkPath = path.resolve(PACKAGE_ROOT, link);
74
75 if (!fs.existsSync(linkPath)) {
76 logger.log(chalk.yellow(`warning: link path ${linkPath} does not exist`));
77 return null;
78 }
79
80 let stats = fs.statSync(linkPath);
81
82 if (!stats.isDirectory()) {
83 logger.log(chalk.yellow(`warning: link path must be a directory, provided ${linkPath}`));
84 return null;
85 }
86
87 return linkPath;
88}
89
90let cleaningup = false;
91
92function cleanupLinkPath({ linkPath, exit }) {
93 if (exit) {
94 if (cleaningup) {
95 return;
96 }
97 cleaningup = true;
98 logger.log(chalk.blue('cleanup'));
99 }
100
101 for (const binary in pkg.bin) {
102 if (pkg.bin.hasOwnProperty(binary)) {
103 let unlinkPath = path.join(linkPath, 'node_modules', '.bin', binary);
104 if (fs.existsSync(unlinkPath)) {
105 logger.log(chalk.blue('unlink'), chalk.gray(unlinkPath));
106 fs.unlinkSync(unlinkPath);
107 }
108 }
109 }
110
111 let targetPath = path.join(linkPath, 'node_modules', pkg.name);
112 if (fs.existsSync(targetPath)) {
113 logger.log(chalk.blue('rmdir'), chalk.gray(targetPath));
114 rimraf.sync(targetPath);
115 }
116
117 if (exit) {
118 return process.exit();
119 }
120}