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

Esinstall: Allow resolution of inner package files #1689

Merged
merged 2 commits into from
Nov 30, 2020

Conversation

drwpow
Copy link
Collaborator

@drwpow drwpow commented Nov 24, 2020

Changes

Before

esinstall('react/LICENSE');

// [ERROR] Package " node_modules/react/LICENSE" not found. Have you installed it?

After

esinstall('react/LICENSE');

// ✅

Testing

Tested in local build setup. Tested against:

Docs

@vercel
Copy link

vercel bot commented Nov 24, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/pikapkg/snowpack/ogu613izn
✅ Preview: https://snowpack-git-drwpow-resolve-package-files.pikapkg.vercel.app

@@ -302,7 +303,8 @@ export async function install(
const aliasEntry = findMatchingAliasEntry(installAlias, specifier);
return aliasEntry && aliasEntry.type === 'package' ? aliasEntry.to : specifier;
})
.sort(),
.map((specifier) => specifier.replace(/(\/|\\)+$/, '')) // remove trailing slash from end of specifier (easier for Node to resolve)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes a small but important problem: when using import maps, a . will resolve to preact/ when using path.join(). This makes esinstall generate preact/.js rather than preact.js.

Here, if a slash is the very last character(s), we simply remove it. Shouldn’t affect Node generation, and it seems to produce more consistently-named files on esinstall’s end

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

const ext = path.basename(resolvedResult.loc).replace(/[^.]+/, '');
targetName += ext;
proxiedName += ext;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes another bug where for non-JS assets, the extension was often stripped (e.g. when installing bulma, esinstall would create an extensionless web_modules/bulma file that was supposed to be web_modules/bulma.sass.

While this probably isn’t a perfect solution, I think it’s better, as it more closely matches the JS behavior. Also of note: we don’t add extensions if there aren’t any.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the thinking here makes sense, but resolvedResult.loc should already be a fully resolved file location. If we want to fix/handle this, the fix should live inside of resolveWebDependency()

Copy link
Collaborator Author

@drwpow drwpow Nov 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So resolvedResult.loc is correct, and there‘s nothing to change there. That‘s why we correctly get the extension from there.

I was just making a change here where getWebDependencyName() and sanitizePackageName() were producing bad extensions for targetName and proxiedName for assets. Because we were adding asset handling here, I felt it safer to make the change here than in those 2 functions. But happy for you to make the call.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, makes sense!

Copy link
Owner

@FredKSchott FredKSchott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woo! 🎉 left a couple comments

@@ -302,7 +303,8 @@ export async function install(
const aliasEntry = findMatchingAliasEntry(installAlias, specifier);
return aliasEntry && aliasEntry.type === 'package' ? aliasEntry.to : specifier;
})
.sort(),
.map((specifier) => specifier.replace(/(\/|\\)+$/, '')) // remove trailing slash from end of specifier (easier for Node to resolve)
.sort((a, b) => a.localeCompare(b, undefined, {numeric: true})),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious, why is this needed?

Copy link
Collaborator Author

@drwpow drwpow Nov 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I default to localeCompare() more out of habit these days (it‘s recommended to do in browsers; probably doesn‘t make a difference in Node). But mainly I thought it‘d be a nice QoL improvement here to add {numeric: true}.

Whereas before it would sort file1.js, file10.js, file2.js, now it will sort file1.js, file2.js, file10.js.

@@ -302,7 +303,8 @@ export async function install(
const aliasEntry = findMatchingAliasEntry(installAlias, specifier);
return aliasEntry && aliasEntry.type === 'package' ? aliasEntry.to : specifier;
})
.sort(),
.map((specifier) => specifier.replace(/(\/|\\)+$/, '')) // remove trailing slash from end of specifier (easier for Node to resolve)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

const ext = path.basename(resolvedResult.loc).replace(/[^.]+/, '');
targetName += ext;
proxiedName += ext;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the thinking here makes sense, but resolvedResult.loc should already be a fully resolved file location. If we want to fix/handle this, the fix should live inside of resolveWebDependency()

@@ -6,6 +6,7 @@ const PROCESS_MODULE_NAME = 'process';
export function rollupPluginNodeProcessPolyfill(env = {}): Plugin {
const injectPlugin = inject({
process: PROCESS_MODULE_NAME,
include: ['*.js', '*.mjs', '*.cjs'],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed for Rollup to not blow up for non-JS assets.

@drwpow
Copy link
Collaborator Author

drwpow commented Nov 30, 2020

Snapshots seem to be failing due to minification differences; don‘t seem to be related to this PR at all.

Copy link
Owner

@FredKSchott FredKSchott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@drwpow drwpow merged commit c6abea7 into main Nov 30, 2020
@drwpow drwpow deleted the drwpow/resolve-package-files branch November 30, 2020 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants