diff --git a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts index 756e7dc22b..8afd4e22b3 100644 --- a/libs/remix-core-plugin/src/lib/compiler-content-imports.ts +++ b/libs/remix-core-plugin/src/lib/compiler-content-imports.ts @@ -20,7 +20,31 @@ export class CompilerImports extends Plugin { urlResolver: any constructor () { super(profile) - this.urlResolver = new RemixURLResolver() + this.urlResolver = new RemixURLResolver(async () => { + try { + let yarnLock + if (await this.call('fileManager', 'exists', './yarn.lock')) { + yarnLock = await this.call('fileManager', 'readFile', './yarn.lock') + } + + let packageLock + if (await this.call('fileManager', 'exists', './package-lock.json')) { + packageLock = await this.call('fileManager', 'readFile', './package-lock.json') + packageLock = JSON.parse(packageLock) + } + + if (await this.call('fileManager', 'exists', './package.json')) { + const content = await this.call('fileManager', 'readFile', './package.json') + const pkg = JSON.parse(content) + return { deps: { ...pkg['dependencies'], ...pkg['devDependencies'] }, yarnLock, packageLock } + } else { + return {} + } + } catch (e) { + console.error(e) + return {} + } + }) this.previouslyHandled = {} // cache import so we don't make the request at each compilation. } diff --git a/libs/remix-url-resolver/src/resolve.ts b/libs/remix-url-resolver/src/resolve.ts index e3d9c4cf4b..2798943058 100644 --- a/libs/remix-url-resolver/src/resolve.ts +++ b/libs/remix-url-resolver/src/resolve.ts @@ -23,13 +23,17 @@ interface HandlerResponse { cleanUrl: string } +export type getPackages = () => Promise<{ [name: string]: string }> + export class RemixURLResolver { private previouslyHandled: PreviouslyHandledImports gistAccessToken: string protocol: string + getDependencies: getPackages - constructor (gistToken?: string, protocol = 'http:') { + constructor (getDependencies?: getPackages, gistToken?: string, protocol = 'http:') { this.previouslyHandled = {} + this.getDependencies = getDependencies this.setGistToken(gistToken, protocol) } @@ -130,6 +134,36 @@ export class RemixURLResolver { async handleNpmImport (url: string): Promise { // eslint-disable-next-line no-useless-catch try { + if (this.getDependencies) { + try { + const { deps, yarnLock, packageLock } = await this.getDependencies() + for (const pkg of Object.keys(deps)) { + if (url.startsWith(pkg)) { + let version + if (yarnLock) { + // yarn.lock + const regex = new RegExp(`"${pkg}@(.*)"`, 'g') + const yarnVersion = regex.exec(yarnLock) + if (yarnVersion && yarnVersion.length > 1) { + version = yarnVersion[1] + } + } + if (!version && packageLock['dependencies'] && packageLock['dependencies'][pkg] && packageLock['dependencies'][pkg]['version']) { + // package-lock.json + version = packageLock['dependencies'][pkg]['version'] + } + if (!version) { + // package.json + version = deps[pkg] + } + if (version) url = url.replace(pkg, `${pkg}@${version}`) + break + } + } + } catch (e) { + console.log(e) + } + } const req = 'https://unpkg.com/' + url const response: AxiosResponse = await axios.get(req, { transformResponse: [] }) return { content: response.data, cleanUrl: url }