Skip to content

Possible loader chaining problem / possible yarn problem#48515

@izaakschroeder

Description

@izaakschroeder

Version

v20.3.1

Platform

Darwin Kernel Version 22.5.0: Mon Apr 24 20:52:24 PDT 2023; root:xnu-8796.121.2~5/RELEASE_ARM64_T6000 arm64

Subsystem

esm, loaders

What steps will reproduce the bug?

  • Have Yarn 3+ installed
    • corepack enable
    • yarn set version berry
    • yarn set version 4
  • Write a custom loader that uses the load hook
    • Within that hook use await import(someFile);
    • Within someFile import a package that requires another loader to resolve

Reproducible repo: https://github.com/izaakschroeder/loader-chain-issue

Run the following:

yarn cd packages/demo yarn demo

/packages/banana-loader/loader.mjs:

import*aspathfrom'node:path';importmodulefrom'node:module';import{fileURLToPath}from'node:url'constDEFAULT_EXTENSIONS=['.banana'];constcompile=async(code,filepath)=>{// We are second loader in chain so we have PnP injected yay all this worksconstpnpApi=module.findPnpApi(filepath);constpackageLocator=pnpApi.findPackageLocator(filepath);constpackageInformation=pnpApi.getPackageInformation(packageLocator);constconfigFile=path.join(packageInformation.packageLocation,'banana.config.mjs');// This fails complaining that "banana-config" cannot be resolved// This confuses me because shouldn't PnP be active at this point? If the previous// code works then how can this not? And specifically importing `configFile`// itself is OK, only the import WITHIN it fails.constconfigModule=awaitimport(configFile);if(configModule.default.magic!==42){thrownewError('Bad banana');}returncode;}exportconstload=async(url,context,nextLoad)=>{if(DEFAULT_EXTENSIONS.some((ext)=>url.endsWith(ext))){const{source, responseURL, format}=awaitnextLoad(url,{...context,format: 'module'});constcode=awaitcompile(source.toString('utf8'),fileURLToPath(responseURL));return{ format,source: code,shortCircuit: true,};}returnnextLoad(url,context);}

/packages/demo/banana.config.mjs:

import{createConfig}from"banana-config";exportdefaultcreateConfig();

/packages/demo/test.banana:

console.log('Hello world');

/packages/banana-config/config.mjs:

exportconstcreateConfig=()=>{return{magic: 42};};

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior? Why is that the expected behavior?

Using await import(...) should respect the existing loader chain.

What do you see instead?

Module resolution fails inside an import'd module.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    esmIssues and PRs related to the ECMAScript Modules implementation.loadersIssues and PRs related to ES module loaders

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions