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

Remove the language module dependency on TypeScript #368

Merged
merged 3 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/purple-kings-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@mdx-js/language-service": minor
---

Remove the dependency on an injected TypeScript module instance.
2 changes: 1 addition & 1 deletion packages/language-server/lib/language-server-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function plugin({modules}) {
)

config.languages ||= {}
config.languages.mdx ||= getLanguageModule(modules.typescript, plugins)
config.languages.mdx ||= getLanguageModule(plugins)

config.services ||= {}
config.services.markdown = createMarkdownService()
Expand Down
64 changes: 49 additions & 15 deletions packages/language-service/lib/language-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,44 @@ import remarkMdx from 'remark-mdx'
import remarkParse from 'remark-parse'
import {unified} from 'unified'

/**
* A TypeScript compatible script snapshot that wraps a string of text.
*
* @implements {IScriptSnapshot}
*/
export class ScriptSnapshot {
/**
* @param {string} text
* The text to wrap.
*/
constructor(text) {
this.text = text
}

/**
* Not implemented.
*
* @returns {undefined}
*/
getChangeRange() {}

/**
* @returns {number}
*/
getLength() {
return this.text.length
}

/**
* @param {number} start
* @param {number} end
* @returns {string}
*/
getText(start, end) {
return this.text.slice(start, end)
}
}

/**
* @param {string} propsName
*/
Expand Down Expand Up @@ -228,11 +266,10 @@ function processExports(mdx, node, mapping, esm) {
/**
* @param {string} fileName
* @param {IScriptSnapshot} snapshot
* @param {typeof import('typescript')} ts
* @param {Processor} processor
* @returns {VirtualFile[]}
*/
function getVirtualFiles(fileName, snapshot, ts, processor) {
function getVirtualFiles(fileName, snapshot, processor) {
const mdx = snapshot.getText(0, snapshot.getLength())
/** @type {Mapping[]} */
const jsMappings = []
Expand All @@ -248,17 +285,17 @@ function getVirtualFiles(fileName, snapshot, ts, processor) {
fileName: fileName + '.jsx',
languageId: 'javascriptreact',
typescript: {
scriptKind: ts.ScriptKind.JSX
scriptKind: 2
},
mappings: jsMappings,
snapshot: ts.ScriptSnapshot.fromString(fallback)
snapshot: new ScriptSnapshot(fallback)
},
{
embeddedFiles: [],
fileName: fileName + '.md',
languageId: 'markdown',
mappings: [],
snapshot: ts.ScriptSnapshot.fromString(mdx)
snapshot: new ScriptSnapshot(mdx)
}
]
}
Expand Down Expand Up @@ -417,7 +454,7 @@ function getVirtualFiles(fileName, snapshot, ts, processor) {
}
}
],
snapshot: ts.ScriptSnapshot.fromString(node.value)
snapshot: new ScriptSnapshot(node.value)
})

break
Expand Down Expand Up @@ -525,17 +562,17 @@ function getVirtualFiles(fileName, snapshot, ts, processor) {
fileName: fileName + '.jsx',
languageId: 'javascriptreact',
typescript: {
scriptKind: ts.ScriptKind.JSX
scriptKind: 2
},
mappings: jsMappings,
snapshot: ts.ScriptSnapshot.fromString(esm)
snapshot: new ScriptSnapshot(esm)
},
{
embeddedFiles: [],
fileName: fileName + '.md',
languageId: 'markdown',
mappings: [markdownMapping],
snapshot: ts.ScriptSnapshot.fromString(markdown)
snapshot: new ScriptSnapshot(markdown)
}
)

Expand All @@ -545,15 +582,13 @@ function getVirtualFiles(fileName, snapshot, ts, processor) {
/**
* Create a [Volar](https://volarjs.dev) language module to support MDX.
*
* @param {typeof import('typescript')} ts
* The TypeScript module.
* @param {PluggableList} [plugins]
* A list of remark syntax plugins. Only syntax plugins are supported.
* Transformers are unused.
* @returns {LanguagePlugin}
* A Volar language module to support MDX.
*/
export function getLanguageModule(ts, plugins) {
export function getLanguageModule(plugins) {
const processor = unified().use(remarkParse).use(remarkMdx)
if (plugins) {
processor.use(plugins)
Expand All @@ -570,7 +605,7 @@ export function getLanguageModule(ts, plugins) {
const length = snapshot.getLength()

return {
embeddedFiles: getVirtualFiles(fileName, snapshot, ts, processor),
embeddedFiles: getVirtualFiles(fileName, snapshot, processor),
fileName,
languageId: 'mdx',
mappings: [
Expand Down Expand Up @@ -615,7 +650,6 @@ export function getLanguageModule(ts, plugins) {
mdxFile.embeddedFiles = getVirtualFiles(
mdxFile.fileName,
snapshot,
ts,
processor
)
},
Expand All @@ -632,7 +666,7 @@ export function getLanguageModule(ts, plugins) {
...host,
getCompilationSettings: () => ({
// Default to the JSX automatic runtime, because that’s what MDX does.
jsx: ts.JsxEmit.ReactJSX,
jsx: 4,
// Set these defaults to match MDX if the user explicitly sets the classic runtime.
jsxFactory: 'React.createElement',
jsxFragmentFactory: 'React.Fragment',
Expand Down
Loading
Loading