Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Support for alias from jsconfig and eslint issue fix internally for alias #2000

Closed
xettri opened this issue Apr 4, 2024 · 6 comments

Comments

@xettri
Copy link
Contributor

xettri commented Apr 4, 2024

What problem does this feature solve?

jsconfig handling

We would like to have jsconfig support internally like we have with tsconfig.

Example 1:

{
  "compilerOptions": {
    "baseUrl": "./src",
  }
}

if src has folder my-components

import component from 'my-components/some';

Example 2:

{
  "compilerOptions": {
    "paths": {
      "@my-components/*": ["./src/components/*"]
    }
  }
}
import component from '@my-components/some';

Example 3:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@my-components/*": ["./components/*"]
    }
  }
}
import component from '@my-components/some';

Eslint handling @rsbuild/plugin-eslint

Current behaviour: right now eslint does not internally resolve alias
Expected: Eslint with @rsbuild/plugin-eslint should resolve alias from rsbuild.config tsconfig and jsconfig based on configuration and priority

**Let me know if these things already available in build tool I will explore that.

What does the proposed API look like?

I'm in search of a solution in JavaScript projects that handles jsconfig similarly to tsconfig, enabling alias resolution. Additionally, I'm interested in default alias handling within ESLint (@rsbuild/plugin-eslint), ensuring it's not overwritten by external configurations, or exploring ways to prevent such overwrites specifically for aliases.

@xettri xettri changed the title [Feature]: Support for alias from jsconfig alias and eslint issue fix internally for alias [Feature]: Support for alias from jsconfig and eslint issue fix internally for alias Apr 4, 2024
@chenjiahan
Copy link
Member

Compared to jsconfig.json#paths, the package.json#imports is a more standard approach, which is natively supported by Node.js.

Can you trypackage.json#imports and see if it meets your needs?

https://nodejs.org/docs/latest/api/packages.html#imports

@chenjiahan
Copy link
Member

For the ESLint part, should ESLint support aliases?

I understand that eslint-plugin-import may contain implementations related to resolver or tsconfig paths, but ESLint itself does not need to care about aliases.

@xettri
Copy link
Contributor Author

xettri commented Apr 7, 2024

@chenjiahan
I'm looking for built-in support similar to Create React App (CRA) to fix this problem. Specifically, I want the build process to automatically find source files if there's either a tsconfig or jsconfig file present. I've tried some workarounds that are currently working, but I'm hoping for an built-in solution.
One common situation is when you set a baseUrl in your configuration, like "baseUrl": "./src". This means everything inside the src folder can be treated as an alias, which users usually have to set up manually. Let me know if there's a simpler way to do this.

source: {
+  alias: {
+   api: './src/api',
+    components: './src/components',
+    hooks: './src/hooks',
+    // other alias
+  },
},

Hack: This is example how I hack for jsconfig

const root = process.cwd();

const resolve = (...args) => {
  return path.resolve(root, ...args);
};

const getJSConfig = () => {
  if (fs.existsSync(resolve("jsconfig.json"))) {
    const jsconfig = fs.readFileSync(resolve("jsconfig.json"), "utf8");
    return JSON.parse(jsconfig);
  } else {
    return {};
  }
};

const createAlias = (customAlias = {}) => {
  const { compilerOptions } = getJSConfig();
  const alias = { ...customAlias };
  try {
    let baseUrl = root;
    if (compilerOptions) {
      if (
        compilerOptions.baseUrl &&
        fs.existsSync(resolve(root, compilerOptions.baseUrl))
      ) {
        baseUrl = resolve(root, compilerOptions.baseUrl);
        // if only base url exist then create its all folders as alias
        // let src is base url so all its folders will become alias
        getAliasDefaultPaths(baseUrl).forEach((folder) => {
          const aliasPath = resolve(baseUrl, folder);
          if (fs.existsSync(aliasPath)) {
            alias[folder] = aliasPath;
          }
        });
      }
    }
    return alias;
  } catch (e) {
    console.error(e);
  }
  return alias;
};
export default defineConfig({
  source: {
    define: publicEnv,
+    alias: createAlias()
  },
  // other config here
});

Is it possible for a similar solution to be integrated as a built-in feature of rsbuild? This will be helpful who is migrating from CRA to rsbuild.

Following is builtin code in CRA (ejected) file: config/modules.js

image

@chenjiahan
Copy link
Member

How about add this config to the rsbuild.config.* file? It should work:

export default {
  source: {
    tsconfigPath: './jsconfig.json',
  },
};

https://rsbuild.dev/config/source/tsconfig-path

@xettri
Copy link
Contributor Author

xettri commented Apr 8, 2024

@chenjiahan, yes it will work with tsconfigPath: "./jsconfig.json" and source.aliasStrategy = "prefer-tsconfig"(default with tsconfigPath), not sure might be possible issues can be seen as its backed by tsconfig-paths-webpack-plugin.
We can add this solution in doc if possible.

@chenjiahan
Copy link
Member

Sure, I will add e2e case and document for this.

The tsconfigPath is backed by Rspack (see https://www.rspack.dev/config/resolve.html#resolvetsconfigpath), which is functionally equivalent to tsconfig-paths-webpack-plugin,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants