Skip to content

Commit

Permalink
support type-only packages (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
FredKSchott committed Jun 19, 2020
1 parent 05727a4 commit a863c8f
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
type InstallResult = 'SUCCESS' | 'ASSET' | 'FAIL';

interface DependencyLoc {
type: 'JS' | 'ASSET';
type: 'JS' | 'ASSET' | 'IGNORE';
loc: string;
}

Expand Down Expand Up @@ -178,7 +178,8 @@ function resolveWebDependency(dep: string): DependencyLoc {
depManifest['browser:module'] ||
depManifest.module ||
depManifest['main:esnext'] ||
depManifest.browser;
depManifest.browser ||
depManifest.main;
// Some packages define "browser" as an object. We'll do our best to find the
// right entrypoint in an entrypoint object, or fail otherwise.
// See: https://github.com/defunctzombie/package-browser-field-spec
Expand All @@ -190,17 +191,29 @@ function resolveWebDependency(dep: string): DependencyLoc {
foundEntrypoint['./'] ||
foundEntrypoint['.'];
}
// If the package was a part of the explicit whitelist, fallback to it's main CJS entrypoint.
if (!foundEntrypoint) {
foundEntrypoint = depManifest.main || 'index.js';
// Sometimes packages don't give an entrypoint, assuming you'll fall back to "index.js".
const isImplicitEntrypoint = !foundEntrypoint;
if (isImplicitEntrypoint) {
foundEntrypoint = 'index.js';
}
if (typeof foundEntrypoint !== 'string') {
throw new Error(`"${dep}" has unexpected entrypoint: ${JSON.stringify(foundEntrypoint)}.`);
}
return {
type: 'JS',
loc: require.resolve(path.join(depManifestLoc || '', '..', foundEntrypoint)),
};
try {
return {
type: 'JS',
loc: require.resolve(path.join(depManifestLoc || '', '..', foundEntrypoint)),
};
} catch (err) {
// Type only packages! Some packages are purely for TypeScript (ex: csstypes).
// If no JS entrypoint was given or found, but a TS "types"/"typings" entrypoint
// was given, assume a TS-types only package and ignore.
if (isImplicitEntrypoint && (depManifest.types || depManifest.typings)) {
return {type: 'IGNORE', loc: ''};
}
// Otherwise, file truly doesn't exist.
throw err;
}
}

function checkIsEsModule(fileLoc: string) {
Expand Down Expand Up @@ -473,7 +486,6 @@ export async function command({cwd, config, lockfile, pkgManifest}: CommandOptio
}

rimraf.sync(dest);
await mkdirp(dest);
const finalResult = await install(
installTargets,
{
Expand Down
2 changes: 2 additions & 0 deletions src/commands/src-file-extension-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default {
mdx: 'js',
svx: 'js',
elm: 'js',
yaml: 'json',
toml: 'json',
php: 'html',
md: 'html',
ejs: 'html',
Expand Down
4 changes: 4 additions & 0 deletions test/integration/dep-types-only/expected-output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- snowpack installing...
⠼ snowpack installing...
✖ No ESM dependencies found!
At least one dependency must have an ESM "module" entrypoint. You can find modern, web-ready packages at https://www.pika.dev

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions test/integration/dep-types-only/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"scripts": {
"TEST": "node ../../../pkg/dist-node/index.bin.js"
},
"snowpack": {
"install": [
"dep-a"
]
},
"dependencies": {
"dep-a": "1.0.0"
}
}

1 comment on commit a863c8f

@vercel
Copy link

@vercel vercel bot commented on a863c8f Jun 19, 2020

Choose a reason for hiding this comment

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

Please sign in to comment.