Git Product home page Git Product logo

Comments (8)

helmturner avatar helmturner commented on July 22, 2024 1

So sorry, just now realizing this code is pulled from the node algorithm, and the issue is an upstream one (and, apparently, expected behavior? 🙄)

Edit: thanks for the quick reply. This actually explains why I was having issues with another bundler—that's what got me searching for this package in the first place lol.

Edit-edit: I promise this wasn't an XY problem—I actually did (mis-)read the spec first...

from import-meta-resolve.

wooorm avatar wooorm commented on July 22, 2024 1

From what I gather, the “spec” was I think just a random idea years ago. Then folks implemented it. And figured out that it was super complex to do everything. And decided to rip things out.

Personally, I feel like conditions do a good job already at pointing to one file or another. And whether files currently exist or not isn’t something that should be related to the public API of a package.

You may like https://github.com/wooorm/package-exports, which attempt to lint package exports!

from import-meta-resolve.

wooorm avatar wooorm commented on July 22, 2024

I am under the impression that this is exactly how node works?

The code here is manually picked from node. I don't think they have that.

from import-meta-resolve.

helmturner avatar helmturner commented on July 22, 2024

Nice! That would have saved me a headache. Although I noticed the rule that would have caught this says 'Many tools don't support this... Heh, including node!

I reckon most folks want this for simulating the 'CJS' semantics of guessing extensions, but this actually has a valid use-case in a cross-platform environment. I left my 2 cents on their issue, but I'll just have to go back to the drawing board on my end 🤷

from import-meta-resolve.

wooorm avatar wooorm commented on July 22, 2024

ok, well a) don’t restore extension guessing, b) you’re talking about “conditionally resolve”, and that’s something that conditions already do? c) you can use asterisks as well.

"./prefix-*-suffix": {
  "native": "./path/to/folder/*.native.js",
  "default": "./path/to/folder/*.default.js"
}

(prefix and suffix here just an example. depends on your actual files what values to use)

from import-meta-resolve.

wooorm avatar wooorm commented on July 22, 2024

This sounds more like you have a question on how best to expose your package’s API. That’s fine. But then I need you to provide me the input files. Then I can help you.

from import-meta-resolve.

helmturner avatar helmturner commented on July 22, 2024

I appreciate your offer to help, especially considering I didn't even open an issue in the right repo 😅

I think I know an approach, but it's not elegant. There's really not a good way to achieve what I'm aiming for.

I've got two apps which share a multiple cross-platform internal packages. One, the UI library, is compiled before consumption. In effect, this just means that all built files end with .js—however there are still .native.js and/or .web.js files with the same name. I'll focus on the non-transpiled modules, because it includes the additional complexity of having both tsx vs ts files (in addition to the platform extensions)

Many of the package modules are pure react, using only platform-agnostic APIs. For these files, I would like just to have a single .ts or .tsx module that resolves the same on both platforms.

Some of the modules, however, have unique implementations for each platform. For these, I would like to have *.native.* files only resolved by Metro, and *.web.* files only resolved by webpack. A third version, without the platform extension, exports a type that (through some type magic) is different depending on the importing package's configuration.

Setting aside the wisdom of extension guessing, this is the exports map I hoped to use:

"exports": {
    ".": {
      "types": [
        "./src/index.ts",
        "./src/index.tsx"
      ],
      "browser": [
        "./src/index.web.ts",
        "./src/index.web.tsx",
        "./src/index.ts",
        "./src/index.tsx"
      ],
      "ios": [
        "./src/index.ios.ts",
        "./src/index.ios.tsx",
        "./src/index.ts",
        "./src/index.tsx"
      ],
      "android": [
        "./src/index.android.ts",
        "./src/index.android.tsx",
        "./src/index.ts",
        "./src/index.tsx"
      ],
      "native": [
        "./src/index.native.ts",
        "./src/index.native.tsx",
        "./src/index.ts",
        "./src/index.tsx"
      ],
      "default": [
        "./src/index.ts",
        "./src/index.tsx"
      ]
    },
    "./*": {
      "types": [
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ],
      "browser": [
        "./src/*.web.ts",
        "./src/*/index.web.ts",
        "./src/*.web.tsx",
        "./src/*/index.web.tsx",
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ],
      "ios": [
        "./src/*.ios.ts",
        "./src/*/index.ios.ts",
        "./src/*.ios.tsx",
        "./src/*/index.ios.tsx",
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ],
      "android": [
        "./src/*.android.ts",
        "./src/*/index.android.ts",
        "./src/*.android.tsx",
        "./src/*/index.android.tsx",
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ],
      "native": [
        "./src/*.native.ts",
        "./src/*/index.native.ts",
        "./src/*.native.tsx",
        "./src/*/index.native.tsx",
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ],
      "default": [
        "./src/*.ts",
        "./src/*/index.ts",
        "./src/*.tsx",
        "./src/*/index.tsx"
      ]
    }
}

and here is an example of the file tree:

packages/app/src
├── providers.tsx # Should be resolved the same regardless of platform, including types
├── fonts
│   ├── Inter.web.ts # Should be exclusively resolved by Webpack
│  ├── Inter.native.ts # Should be exclusively resolved by Metro
│  └── Inter.ts # Should be exclusively resolved by Typescript
└── index.ts # Should be resolved the same regardless of platform, including types

Now, TypeScript is smart enough to know that if I import *.js and there's a matching *.ts or *.tsx, then that's the right target... but I think that only helps if I transpile the package first, not if it is bundled by the consumer.

Unless you see something I'm missing, the only option is to 1) transpile all packages and 2) explicitly export all modules with a .native/.web split. Well, the only option without writing a custom resolution plugin for every bundler...

EDIT: To add an additional wrinkle, Metro Bundler does not respect platform extensions when using the exports field. So I may have no option but to ditch it for main exports...

from import-meta-resolve.

wooorm avatar wooorm commented on July 22, 2024

Can you post all the files you have in src/, and in dest/?
This is all very theoretical currently.

I would recommend taking some time to think about what you want to expose.
Similar to how you don’t export every variable from a file, not every file is a public interface.

from import-meta-resolve.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.