UNPKG

4.94 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.
5 * This code may only be used under the BSD style license found at
6 * http://polymer.github.io/LICENSE.txt
7 * The complete set of authors may be found at
8 * http://polymer.github.io/AUTHORS.txt
9 * The complete set of contributors may be found at
10 * http://polymer.github.io/CONTRIBUTORS.txt
11 * Code distributed by Google as part of the polymer project is also
12 * subject to an additional IP rights grant found at
13 * http://polymer.github.io/PATENTS.txt
14 */
15Object.defineProperty(exports, "__esModule", { value: true });
16const whatwgUrl = require("whatwg-url");
17const nodeResolve = require("resolve");
18const path_1 = require("path");
19const isWindows = require("is-windows");
20const pathIsInside = require('path-is-inside');
21const isPathSpecifier = (s) => /^\.{0,2}\//.test(s);
22/**
23 * Resolves module specifiers using node module resolution.
24 *
25 * Full URLs - those parsable by the WHATWG URL spec - are returned as-is.
26 * Absolute and relative paths are resolved, even though they are valid
27 * HTML-spec module specifiers, because node resolution supports directories
28 * and omitting extensions. If a specifier doesn't resolve, it's returned as-is.
29 *
30 * @param componentInfo An object describing a "component-style" URL layout. In
31 * this layout, cross-package URLs reach out of the package directory to
32 * sibling packages, rather than into the component directory. When given,
33 * this parameter causes relative paths to be returns for this style.
34 */
35exports.resolve = (specifier, documentPath, componentInfo) => {
36 if (whatwgUrl.parseURL(specifier) !== null) {
37 return specifier;
38 }
39 const importerFilepath = documentPath;
40 const dependencyFilepath = nodeResolve.sync(specifier, {
41 basedir: path_1.dirname(importerFilepath),
42 moduleDirectory: ['bower_components', 'node_modules'],
43 // It's invalid to load a .json or .node file as a module on the web,
44 // but this is what Node's resolution algorithm does
45 // (https://nodejs.org/api/modules.html#modules_all_together), so we
46 // also do it here for completeness. Without including these
47 // extensions the user will probably get a 404. With them, they'll
48 // probably get an invalid MIME type error (which is hopefully more
49 // useful).
50 extensions: ['.js', '.json', '.node'],
51 // Some packages use a non-standard alternative to the "main" field
52 // in their package.json to differentiate their ES module version.
53 packageFilter: (packageJson) => {
54 packageJson.main = packageJson.module ||
55 packageJson['jsnext:main'] || packageJson.main;
56 return packageJson;
57 },
58 });
59 let relativeSpecifierUrl = path_1.relative(path_1.dirname(importerFilepath), dependencyFilepath);
60 if (componentInfo !== undefined) {
61 // Special handling for servers like Polyserve which, when serving a
62 // package "foo", will map the URL "/components/foo" to the root package
63 // directory, so that "foo" can make correct relative path references to
64 // its dependencies.
65 //
66 // Note that Polyserve will only set componentInfo if the particular
67 // request was for a URL path in the components/ directory.
68 const { packageName, rootDir, componentDir } = componentInfo;
69 const importerInRootPackage = !pathIsInside(importerFilepath, componentDir);
70 const dependencyInRootPackage = !pathIsInside(dependencyFilepath, componentDir);
71 if (importerInRootPackage && !dependencyInRootPackage) {
72 // A module from the root package, served from a components/ URL, is
73 // importing a module from a different package. In this case we need
74 // to fix up our relative path specifier, because on disk the
75 // dependency resolves to e.g. "./node_modules/foo", but in URL space
76 // it must resolve to "../foo".
77 //
78 // Note that the case where both the importer and the dependency are
79 // in the root package does not need to be fixed up, since the
80 // relative path works out the same.
81 const rootRelativeImporterPath = path_1.relative(rootDir, importerFilepath);
82 const effectiveImporterFilepath = path_1.join(componentDir, packageName, rootRelativeImporterPath);
83 relativeSpecifierUrl = path_1.relative(path_1.dirname(effectiveImporterFilepath), dependencyFilepath);
84 }
85 }
86 if (isWindows()) {
87 // normalize path separators to URL format
88 relativeSpecifierUrl =
89 relativeSpecifierUrl.replace(/\\/g, '/');
90 }
91 if (!isPathSpecifier(relativeSpecifierUrl)) {
92 relativeSpecifierUrl = './' + relativeSpecifierUrl;
93 }
94 return relativeSpecifierUrl;
95};
96//# sourceMappingURL=resolve-specifier-node.js.map
\No newline at end of file