Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2088: unbreak automatic reinstall of linked dependencies on change #2091

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 14 additions & 2 deletions snowpack/src/commands/dev.ts
Expand Up @@ -96,6 +96,8 @@ interface FoundFile {
isResolve: boolean;
}

import {installDependencies} from '../sources/local';

const FILE_BUILD_RESULT_ERROR = `Build Result Error: There was a problem with a file build result.`;

/**
Expand Down Expand Up @@ -1119,7 +1121,7 @@ export async function startServer(commandOptions: CommandOptions): Promise<Snowp
const quickETagCheck = req.headers['if-none-match'];
const quickETagCheckUrl = reqUrl.replace(/\/$/, '/index.html');
if (quickETagCheck && quickETagCheck === knownETags.get(quickETagCheckUrl)) {
logger.debug(`optimized etag! sending 304...`);
logger.debug(`optimized etag for ${quickETagCheckUrl}! sending 304...`);
res.writeHead(304, {'Access-Control-Allow-Origin': '*'});
res.end();
return;
Expand Down Expand Up @@ -1341,10 +1343,20 @@ export async function startServer(commandOptions: CommandOptions): Promise<Snowp
.filter(([_, packageManifest]) => packageManifest && !packageManifest['_id']) // only watch symlinked deps for now
.map(([fileLoc]) => `${path.dirname(fileLoc!)}/**`),
);

let working : Promise<any> | null = null; // only one installl at a time
function onDepWatchEvent() {
hmrEngine.broadcastMessage({type: 'reload'});
knownETags.clear();
if (!working)
// FIXME: If one changes, reinstall _all_. Inefficient?
working = installDependencies(config)
.then(() => {
hmrEngine.broadcastMessage({type: 'reload'})
working = null;
});
}
const depWatcher = chokidar.watch([...symlinkedFileLocs], {
ignored: config.exclude,
cwd: '/', // we’re using absolute paths, so watch from root
persistent: true,
ignoreInitial: true,
Expand Down
2 changes: 1 addition & 1 deletion snowpack/src/sources/local-install.ts
Expand Up @@ -18,7 +18,7 @@ interface InstallRunOptions {
shouldPrintStats: boolean;
}

interface InstallRunResult {
export interface InstallRunResult {
importMap: ImportMap;
newLockfile: ImportMap | null;
stats: DependencyStatsOutput | null;
Expand Down
7 changes: 4 additions & 3 deletions snowpack/src/sources/local.ts
Expand Up @@ -6,7 +6,7 @@ import {ImportMap, InstallOptions as EsinstallOptions} from 'esinstall';
import {existsSync, promises as fs} from 'fs';
import * as colors from 'kleur/colors';
import path from 'path';
import {run as installRunner} from './local-install';
import {InstallRunResult, run as installRunner} from './local-install';
import {logger} from '../logger';
import {getInstallTargets} from '../scan-imports';
import {CommandOptions, PackageSource, PackageSourceLocal, SnowpackConfig} from '../types';
Expand All @@ -26,14 +26,15 @@ const DEV_DEPENDENCIES_DIR = path.join(PROJECT_CACHE_DIR, process.env.NODE_ENV |
* your entire source app for dependency install targets, installs them,
* and then updates the "hash" file used to check node_modules freshness.
*/
async function installDependencies(config: SnowpackConfig) {
export async function installDependencies(config: SnowpackConfig)
: Promise <InstallRunResult | null> {
const installTargets = await getInstallTargets(
config,
config.packageOptions.source === 'local' ? config.packageOptions.knownEntrypoints : [],
);
if (installTargets.length === 0) {
logger.info('Nothing to install.');
return;
return null;
}
// 2. Install dependencies, based on the scan of your final build.
const installResult = await installRunner({
Expand Down