Skip to content

[Feature]: Design of JavaScript Redirect #548

@fi3ework

Description

@fi3ework

What problem does this feature solve?

subtask of #140

Background: The relationship of alias/externals in bundle and bundleless mode

  • bundle mode: use resolve.alias
  • bundleless mode: use output.external to rewrite the external path, redirect is also implemented via external functionality.

Currently supported features in bundle and bundleless mode:

bundle bundleless
rewrite path N/A
rewrite import extension N/A
resolve.aliasStrategy

Modern.js Module related implementation

  • autoExtension: true: controls output file extensions
  • redirect.alias: controls whether to rewrite alias path
  • redirect.autoExtension: rewrite import extension in output code, it will force add the extension as well (use autoExtension as default value)

Proposal of Rslib

redirect only works for bundleless mode

The main principle to is to align the concept and configuration of alias in bundle mode and externals in bundleless mode to reduce the cognitive cost of users

redirect.externalsStrategy

  • type: 'prefer-tsconfig' | 'prefer-externals'
  • default value: 'prefer-tsconfig'

Just like resolve.externalsStrategy in bundle mode, for bundleless mode, Rslib will automatically load tsconfig.compilerOptions.paths as alias and apply. While in bundleless mode, all path rewrite is performed via externals.

'prefer-tsconfig' and 'prefer-externals' perform the same as resolve.externalsStrategy about the strategy.

redirect.relativeImportExtensions

  • type: boolean
  • default value: true

Rename redirect.autoExtension in Modern.js Module (aligned with typescript), relativeImportExtensions changes the extension in the output code which pointing to other output files that will be determined by autoExtension.

main files

Since only CommonJS only support the main files (https://nodejs.org/api/modules.html#all-together). By default:

  • For ESM output, patching the main file path to index.mjs (if exists).
  • For CJS output, patching the main file path to index.cjs (if exists).
    For CommonJS output, do not patch the main file path, leave the path as it is. (I'm not quite sure, maybe we could add the main files directly 🤔)

Examples overview

.
└── src
    ├── index.ts
    ├── foo.ts
    └── utils
        ├── index.ts
        └── add.ts

ESM output

  • import foo from './foo' -> import foo from './foo.mjs'
  • import foo from './foo.ts' -> import foo from './foo.mjs'
  • import foo from './foo.js' -> import foo from './foo.mjs'
  • import foo from './utils' -> import foo from './utils/index.mjs'
  • import foo from './utils/index' -> import foo from './utils/index.mjs'

CommonJS output

  • import foo from './foo' -> import foo from './foo.js'
  • import foo from './foo.ts' -> import foo from './foo.js'
  • import foo from './foo.js' -> import foo from './foo.js'
  • import foo from './utils' -> import foo from './utils'
  • import foo from './utils/index' -> import foo from './utils/index.js'

Compares with Modern.js Module

Modern.js Module Rslib
redirect.alias Removed. I believe there are few situations that require disabling the alias. If we really need to do so in the future, we can use redirect.externalsStrategy = false as an alternative.
redirect.autoExtension changed to redirect.rewriteRelativeImportExtensions
redirect.externalsStrategy

What does the proposed API look like?

/

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions