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

Add support for cross-mount imports #1355

Merged
merged 1 commit into from
Oct 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions snowpack/src/build/import-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import url from 'url';
import {ImportMap, SnowpackConfig} from '../types/snowpack';
import {findMatchingAliasEntry, getExt, relativeURL, replaceExt} from '../util';
import {defaultFileExtensionMapping} from './file-urls';
import {defaultFileExtensionMapping, getUrlForFile} from './file-urls';

const cwd = process.cwd();

Expand All @@ -14,8 +14,7 @@ interface ImportResolverOptions {
}

/** Perform a file disk lookup for the requested import specifier. */
export function getImportStats(dirLoc: string, spec: string): fs.Stats | false {
const importedFileOnDisk = path.resolve(dirLoc, spec);
export function getImportStats(importedFileOnDisk: string): fs.Stats | false {
try {
return fs.statSync(importedFileOnDisk);
} catch (err) {
Expand Down Expand Up @@ -66,18 +65,20 @@ export function createImportResolver({
}

if (spec.startsWith('/')) {
const importStats = getImportStats(cwd, spec.substr(1));
const importStats = getImportStats(path.resolve(cwd, spec.substr(1)));
return resolveSourceSpecifier(spec, importStats, config);
}
if (spec.startsWith('./') || spec.startsWith('../')) {
const importStats = getImportStats(path.dirname(fileLoc), spec);
return resolveSourceSpecifier(spec, importStats, config);
const importedFileLoc = path.resolve(path.dirname(fileLoc), spec);
const importStats = getImportStats(importedFileLoc);
const newSpec = getUrlForFile(importedFileLoc, config) || spec;
return resolveSourceSpecifier(newSpec, importStats, config);
}
const aliasEntry = findMatchingAliasEntry(config, spec);
if (aliasEntry && aliasEntry.type === 'path') {
const {from, to} = aliasEntry;
let result = spec.replace(from, to);
const importStats = getImportStats(cwd, result);
const importStats = getImportStats(path.resolve(cwd, result));
result = resolveSourceSpecifier(result, importStats, config);
// replace Windows backslashes at the end, after resolution
result = relativeURL(path.dirname(fileLoc), result);
Expand Down
51 changes: 33 additions & 18 deletions snowpack/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import {
openInBrowser,
parsePackageImportSpecifier,
readFile,
relativeURL,
replaceExt,
resolveDependencyManifest,
updateLockfileHash,
Expand Down Expand Up @@ -795,26 +796,40 @@ export async function startServer(commandOptions: CommandOptions): Promise<Serve
},
(spec) => {
// Try to resolve the specifier to a known URL in the project
const resolvedImportUrl = resolveImportSpecifier(spec);
if (resolvedImportUrl) {
// Ignore "http://*" imports
if (url.parse(resolvedImportUrl).protocol) {
return resolvedImportUrl;
}
// Support proxy file imports
const extName = path.extname(resolvedImportUrl);
if (
extName &&
(responseExt === '.js' || responseExt === '.html') &&
extName !== '.js'
) {
return resolvedImportUrl + '.proxy.js';
}
return resolvedImportUrl;
let resolvedImportUrl = resolveImportSpecifier(spec);
// Handle an import that couldn't be resolved
if (!resolvedImportUrl) {
missingPackages.push(spec);
return spec;
}
// Ignore "http://*" imports
if (url.parse(resolvedImportUrl).protocol) {
return spec;
}
// Ignore packages marked as external
if (config.installOptions.externalPackage?.includes(resolvedImportUrl)) {
return spec;
}
// Handle normal "./" & "../" import specifiers
const importExtName = path.posix.extname(resolvedImportUrl);
const isProxyImport =
importExtName &&
(responseExt === '.js' || responseExt === '.html') &&
importExtName !== '.js';
const isAbsoluteUrlPath = path.posix.isAbsolute(resolvedImportUrl);
if (isProxyImport) {
resolvedImportUrl = resolvedImportUrl + '.proxy.js';
}

missingPackages.push(spec);
return spec;
// When dealing with an absolute import path, we need to honor the baseUrl
if (isAbsoluteUrlPath) {
resolvedImportUrl = relativeURL(path.posix.dirname(reqPath), resolvedImportUrl);
}
// Make sure that a relative URL always starts with "./"
if (!resolvedImportUrl.startsWith('.') && !resolvedImportUrl.startsWith('/')) {
resolvedImportUrl = './' + resolvedImportUrl;
}
return resolvedImportUrl;
},
);

Expand Down
2 changes: 1 addition & 1 deletion test-dev/__snapshots__/dev.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ exports[`snowpack dev smoke: js 1`] = `
* When you're ready to start on your site, clear the file. Happy hacking!
**/

import confetti from '/web_modules/canvas-confetti.js';
import confetti from '../web_modules/canvas-confetti.js';

confetti.create(document.getElementById('canvas'), {
resize: true,
Expand Down
2 changes: 1 addition & 1 deletion test/build/config-mount/__snapshots__
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Array [
]
`;

exports[`snowpack build config-mount: build/__snowpack__/env.js 1`] = `"export default {\\"MODE\\":\\"production\\",\\"NODE_ENV\\":\\"production\\"};"`;
exports[`snowpack build config-mount: build/__snowpack__/env.js 1`] = `"export default {\\"MODE\\":\\"production\\",\\"NODE_ENV\\":\\"production\\",\\"SSR\\":false};"`;

exports[`snowpack build config-mount: build/a/index.js 1`] = `"console.log('a');"`;

Expand Down
12 changes: 11 additions & 1 deletion test/build/resolve-imports/__snapshots__
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Array [
"_dist_/index.js",
"_dist_/sort.js",
"_dist_/test-mjs.js",
"robots.txt",
"robots.txt.proxy.js",
"TEST_WMU/@css/package-b/style.css",
"TEST_WMU/@css/package-b/style.css.proxy.js",
"TEST_WMU/@fortawesome/fontawesome-free/svgs/solid/ad.svg",
Expand Down Expand Up @@ -94,6 +96,9 @@ exports[`snowpack build resolve-imports: build/_dist_/index.html 1`] = `
import styles from './components/style.css.proxy.js'; // relative import
import styles_ from './components/style.css.proxy.js'; // relative import
console.log(styles, styles_);
// Importing across mounted directories
import robotsTxtRef from '../robots.txt.proxy.js';
console.log(robotsTxtRef);
</script>
<!-- exception test 1: comments should be ignored -->
<!-- <script type=\\"module\\" src=\\"preact\\"></script> -->
Expand Down Expand Up @@ -148,7 +153,10 @@ import styles from './components/style.css.proxy.js'; // relative import
import styles_ from './components/style.css.proxy.js'; // relative import
console.log(styles, styles_);
import adSvg from '../TEST_WMU/@fortawesome/fontawesome-free/svgs/solid/ad.svg.proxy.js';
console.log(adSvg);"
console.log(adSvg);
// Importing across mounted directories
import robotsTxtRef from '../robots.txt.proxy.js';
console.log(robotsTxtRef);"
`;

exports[`snowpack build resolve-imports: build/_dist_/sort.js 1`] = `"export default (arr) => arr.sort();"`;
Expand Down Expand Up @@ -233,3 +241,5 @@ exports[`snowpack build resolve-imports: build/TEST_WMU/import-map.json 1`] = `
}
}"
`;

exports[`snowpack build resolve-imports: build/robots.txt.proxy.js 1`] = `"export default \\"/robots.txt\\";"`;
1 change: 1 addition & 0 deletions test/build/resolve-imports/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
THIS IS A ROBOTS.TXT TEST FILE
1 change: 1 addition & 0 deletions test/build/resolve-imports/snowpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = {
},
mount: {
'./src': '/_dist_',
'./public': '/',
},
devOptions: {
fallback: '_dist_/index.html',
Expand Down
4 changes: 4 additions & 0 deletions test/build/resolve-imports/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
import styles from './components/style.css'; // relative import
import styles_ from '@app/components/style.css'; // relative import
console.log(styles, styles_);

// Importing across mounted directories
import robotsTxtRef from '../public/robots.txt';
console.log(robotsTxtRef);
</script>

<!-- exception test 1: comments should be ignored -->
Expand Down
4 changes: 4 additions & 0 deletions test/build/resolve-imports/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ console.log(styles, styles_);

import adSvg from '@fortawesome/fontawesome-free/svgs/solid/ad.svg';
console.log(adSvg);

// Importing across mounted directories
import robotsTxtRef from '../public/robots.txt';
console.log(robotsTxtRef);