textlint
textlint copied to clipboard
Supports rules that are ECMAScript Modules
Currently, textlint can not load a rule that is ECMAScript Modules(ESM).
It means that textlint-module-loader.ts use Dynamic Import instead of require
to load a rule module.
This issue aim to support to load a rule that is written by ESM. It is not that rewrite textlint to ESM.
- Current:
require()
in CJS can not load ESM, It only load CJS - Next(This issue):
import()
in CJS can load ESM and CJS
TODO
- [ ] How to treat
export default { linter, fixter }
?-
import(rule)
→.default.default
issue still exists? - https://github.com/secretlint/secretlint/pull/187
- Adding an option to interpret __esModule as Babel does · Issue #40891 · nodejs/node
- https://github.com/endojs/endo/pull/1149
- Should we still use default export? (named export does not cause this issue)
-
- [ ] Update to TypeScript 4.7
- require TS 4.7 to use
import()
in CJS. - Use native dynamic import() · Issue #197 · secretlint/secretlint
- require TS 4.7 to use
import(rule)
return Promise<NameSpace>
So. const default = interop(await import(rule)).default
Edit: const default = interop(await import(rule).default)
is correct
- Refactor Config
- Inject config into TextlintEngine from outside like constructor DI
- Or. No use class. instaed of it, use async function
- constructor does not support async
- It means that we need to make config loading async
- https://github.com/textlint/textlint/blob/d4c5075b5a7bcbf875d7cee122de7dc5253d325e/packages/textlint/src/config/config.ts#L388
- Probably, we need to based on https://github.com/textlint/editor/tree/master/packages/%40textlint/config-loader
- use dynamic import for loading rule/plugin
Change to Async:
- Config Loading
- textlintrc.mjs supports require Async API: https://github.com/davidtheclark/cosmiconfig/pull/283
- Rule/Preset/Filter/Plugin Loading
- Need to use Dynamic Import to load a module written in ESM
flowchart LR
A[Load Config File] --> B[Load Modules]
We will introduce new API like createTextlint
for supporting Async APIs.
v13 continue to support current TextLintEngine
and TextFixEngine
for backward compatible.
- #902
New createTextlint
support ESM rules/plugins.
In other hands, TextLintEngine
and TextFixEngine
can not support ESM rules/plugins.
https://github.com/textlint/textlint/blob/60cea514f7eaefbff4411087d16a51daf68f12a4/packages/textlint/src/index.ts
API | Description | Behavior | Target Platform | Current Status | Next Status |
---|---|---|---|---|---|
cli | Command LIne Interface | Async | Node.js | ✅ | ✅ (Use createTextlint internally) |
textlint | TextLintCore alias | Async | Node.js/CommonJS | ❌ Deprecated | ❌ Deprecated |
TextLintCore | Old API. It is Procedural API. Lint Only Single File. Recommended to use @texltint/kernel module instead of It. | Async | Node.js/CommonJS | ❌ Deprecated | ❌ Deprecated |
TextLintEngine | Lint Engine API. It load .textlintrc automaticaly | ◉ Loading is Sync ◉ Linting is Async |
Node.js/CommonJS | ✅ Recommended | ❌ Deprecated |
TextFixEngine | Fix Engine API. It load .textlintrc automaticaly | ◉ Loading is Sync ◉ Fixing is Async |
Node.js/CommonJS | ✅ Recommended | ❌ Deprecated |
createLinter | Combine TextLintEngine and TextFixEngine. Support Async APIs. | ◉ Loading is Async ◉ Linting/Fixing is Async |
Node.js/CommonJS and ESM | None | ✅ Recommended |
We have two config
- .textlintrc config file
- CLI options - It override textlintrc
It is just idea that we can implement these as separated loader and merge these.

type Loader = (_:unknown) => Promise<Config>;
const config = mergeConfig({
await configFileLoader(),
await cliLoader()
});
createTextlint({
config
});
// OR
createTextlint({
loaders: [configFileLoader(), cliLoader()]
});