1
1
// @ts -check
2
2
const path = require ( 'path' ) ;
3
+ const process = require ( 'process' ) ;
3
4
const logger = require ( 'loglevel' ) ;
4
5
const {
5
6
getLanguageNames,
@@ -13,6 +14,7 @@ const {
13
14
const { getHighestBuiltinLanguageId } = require ( './storeUtils' ) ;
14
15
const unzipDir = path . resolve ( __dirname , '../lib/extensions' ) ;
15
16
const requireMain = createRequire ( require . main . filename ) ;
17
+ const requireCwd = createRequire ( path . join ( process . cwd ( ) , 'index.js' ) ) ;
16
18
17
19
/**
18
20
* @param {string } packageJsonPath
@@ -105,7 +107,7 @@ async function mergeCache(cache, key, value) {
105
107
* @param {Host } host
106
108
*/
107
109
async function getExtensionPackageJsonPath ( specifier , host ) {
108
- const absolute = path . isAbsolute ( specifier ) ? specifier : requireMain . resolve ( path . join ( specifier , 'package.json' ) ) ;
110
+ const absolute = path . isAbsolute ( specifier ) ? specifier : requireResolveExtension ( specifier ) ;
109
111
const ext = path . extname ( absolute ) ;
110
112
if ( ext . toLowerCase ( ) === '.vsix' || ext . toLowerCase ( ) === '.zip' ) {
111
113
const outDir = path . join ( unzipDir , path . basename ( absolute , ext ) ) ;
@@ -137,6 +139,33 @@ async function getExtensionPackageJsonPath(specifier, host) {
137
139
}
138
140
}
139
141
142
+ /**
143
+ * We want to resolve the extension from the context of the user’s gatsby-config,
144
+ * but this turns out to be difficult. Ideally, gatsby and this plugin are installed
145
+ * in the same node_modules directory as the extension, but gatsby could be invoked
146
+ * globally, and this plugin could be npm linked. If both of those things happen, we
147
+ * can also try resolving from the current working directory. One of these will
148
+ * probably always work.
149
+ * @param {string } specifier
150
+ */
151
+ function requireResolveExtension ( specifier ) {
152
+ return (
153
+ tryResolve ( require ) ||
154
+ tryResolve ( requireMain ) ||
155
+ tryResolve ( requireCwd ) ||
156
+ require . resolve ( path . join ( specifier , 'package.json' ) )
157
+ ) ; // If none work, throw the best error stack
158
+
159
+ /** @param {NodeRequire } req */
160
+ function tryResolve ( req ) {
161
+ try {
162
+ return req . resolve ( path . join ( specifier , 'package.json' ) ) ;
163
+ } catch ( _ ) {
164
+ return undefined ;
165
+ }
166
+ }
167
+ }
168
+
140
169
/**
141
170
* @param {string[] } extensions
142
171
* @param {Host } host
0 commit comments