Giter Site home page Giter Site logo

Make a ~ import alias about remix HOT 12 CLOSED

remix-run avatar remix-run commented on May 3, 2024 4
Make a ~ import alias

from remix.

Comments (12)

kentcdodds avatar kentcdodds commented on May 3, 2024 7

Low effort, high impact task maybe? 🙏 😅

from remix.

ryanflorence avatar ryanflorence commented on May 3, 2024 4

I like this because nested routes make imports super annoying, and I generally prefer flat file structures (but the nested routing is worth it).

If we had ~/home/imports then all my frustration would be gone. And it would make moving routes around a lot easier because they don't ever import each other. You could literally just drag/drop a folder into another layout route folder and it would all still work.

What I don't like about these kinds of aliases is that it can break tooling, like editors "go to file" and "go to definition" functionality, or typescript being able to find the types, etc. Pretty sure most of these tools are configurable to understand our alias though, so might still be worth it.

from remix.

kiliman avatar kiliman commented on May 3, 2024 2

I made a simple patch to enable this. The Remix templates create a tsconfig.json file in ./app. The default should be updated to include:

  ...
  "paths": {
    "~/*": ["./*"]
  }

This makes imports from ~/some/path relative to the /app folder.

The only reason the Remix compiler doesn't support this is because the function isBareModuleId() checks to see if the import doesn't start with '.' (relative) or '/' absolute. If not, then it assumes it's a node module.

I simply updated the function like so

function isBareModuleId(id) {
  return !id.startsWith(".") && !id.startsWith('~') && !path.isAbsolute(id);
}

And now both VS Code and esbuild compiles it just fine.

Before

import Json from '../../../../components/Json'
import { getUser } from '../../../../data/db'
import { getSessionFromCache, commitSession } from '../../../../session'
import { getFromCache } from '../../../../utils/cache'

After

import Json from '~/components/Json'
import { getUser } from '~/data/db'
import { getSessionFromCache, commitSession } from '~/session'
import { getFromCache } from '~/utils/cache'

Of course, this doesn't fully support the paths property. That is, it won't support something like @app as the @ sign is still treated like a scoped node module. You'd have to parse tsconfig.json and compare the paths entries to be fully correct, but I think this is a good initial implementation.

from remix.

kentcdodds avatar kentcdodds commented on May 3, 2024 2

Can't wait for this to get released!

from remix.

sergiodxa avatar sergiodxa commented on May 3, 2024 1

I think this can be closed now

from remix.

kentcdodds avatar kentcdodds commented on May 3, 2024

Yep, typescript jest and eslint all have the ability to handle these kinds of aliases without any trouble with a little config. It would just need to be documented. Easy peasy

from remix.

kevinwolfcr avatar kevinwolfcr commented on May 3, 2024

I am wondering if this could be solved adding @esbuild-plugins/tsconfig-paths?

from remix.

kentcdodds avatar kentcdodds commented on May 3, 2024

Sweet! Thanks @kiliman! Here's my patch (this includes a patch for dynamic import support):

diff --git a/node_modules/@remix-run/dev/compiler.js b/node_modules/@remix-run/dev/compiler.js
index 923d122..cbc40ce 100644
--- a/node_modules/@remix-run/dev/compiler.js
+++ b/node_modules/@remix-run/dev/compiler.js
@@ -239,7 +239,7 @@ async function createServerBuild(config, options) {
 }
 
 function isBareModuleId(id) {
-  return !id.startsWith(".") && !path.isAbsolute(id);
+  return !id.startsWith(".") && !id.startsWith('~') && !path.isAbsolute(id);
 }
 
 function getNpmPackageName(id) {
diff --git a/node_modules/@remix-run/dev/compiler/assets.js b/node_modules/@remix-run/dev/compiler/assets.js
index 2e9bf3f..b465ff6 100644
--- a/node_modules/@remix-run/dev/compiler/assets.js
+++ b/node_modules/@remix-run/dev/compiler/assets.js
@@ -37,7 +37,7 @@ async function createAssetsManifest(config, metafile) {
         module: resolveUrl(key),
         imports: resolveImports(output.imports)
       };
-    } else {
+    } else if (output.entryPoint.startsWith("browser-route-module:")) {
       let route = routesByFile.get(entryPointFile);
       invariant['default'](route, `Cannot get route for entry point ${output.entryPoint}`);
       let sourceExports = await routes.getRouteModuleExportsCached(config, route.id);

from remix.

cyberwombat avatar cyberwombat commented on May 3, 2024

So this feature does not work for me - I am using it as part of @shopify/hydrogen but I think Remix is handling this. I have changed my package.json type to "module" which I suspect is the issue though I find very little info online to support the idea that this prevents the alias from working. Anyone try this with "type":"module"?. My tsconfig specifies the alias and Shopify's demo store is built with it but somewhere in my upgrades to ESM it broke.

from remix.

kentcdodds avatar kentcdodds commented on May 3, 2024

You may be interested in the new approach taken by the Epic Stack: https://github.com/epicweb-dev/epic-stack/blob/main/docs/decisions/031-imports.md

It's based on a Node.js standard.

from remix.

cyberwombat avatar cyberwombat commented on May 3, 2024

@kentcdodds

Thanks but shopify hydrogen already makes use of ~ and this only works for # prefix.

from remix.

cyberwombat avatar cyberwombat commented on May 3, 2024

It actually turns out that the code works. Remix just throws errors that are meaningless evidently.

from remix.

Related Issues (20)

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.