twoslashes / twoslash

Markup for generating rich type information in your documentations ahead of time.
https://twoslash.netlify.app/
MIT License
430 stars 16 forks source link

Cannot find module or it's type declarations #35

Open khawarizmus opened 3 months ago

khawarizmus commented 3 months ago

I am using twoslash with Vitepress and my example codes require me to document my own library. so when I try the following example code:

import { PlainWeekDate } from '../../src'
import { Temporal } from '@js-temporal/polyfill'
//---cut---

const weekDate = PlainWeekDate.from({ yearOfWeek: 2021, weekOfYear: 1, dayOfWeek: 1, }) // [!code highlight]
console.log(weekDate.toString()) // 2021-W01-01
console.log(weekDate.toPlainDate().toString()) // 2021-01-04

const plainDate = Temporal.PlainDate.from({ year: 2021, month: 1, day: 4 }) // [!code highlight]
const weekDate2 = PlainWeekDate.from(plainDate) // [!code highlight]
console.log(weekDate2.toString()) // 2021-W01-01

I get this error

Cannot find module '../../src' or its corresponding type declarations.

twoslash seems to recognise my second import from @js-temporal/polyfill but not the first one which is coming from my own code. What's the best way to fix this?

khawarizmus commented 3 months ago

I have tried the following but it's not working so far

markdown: {
    theme: {
      light: 'vitesse-light',
      dark: 'vitesse-dark',
    },
    codeTransformers: [
      transformerTwoslash({
        twoslashOptions: {
          // tried with both extraFiles and fsMap options but it's doesn't seem to work
          extraFiles: {
            'week-dates': fileContent
          },
          fsMap,
        }
      })
    ]
  },

The file content is being read this way

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// Convert the URL to a path that's compatible with the file system
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Adjust the path to your file as necessary
const filePath = path.resolve(__dirname, '../../dist/index.d.ts');
const fileContent = fs.readFileSync(filePath, 'utf8');
const fsMap = new Map<string, string>();
fsMap.set('week-dates', fileContent);

I am trying to make it work but ideally i don't want to read from the dist folder as it might not be available to Vitepress in deployment

khawarizmus commented 3 months ago

Okay for people who might stumble on this in the future. I have solved it by appending a file extension to the file name. the file name has to be named the same as what we are importing from.

import { defineConfig } from 'vitepress'
import { transformerTwoslash } from '@shikijs/vitepress-twoslash'
import { version } from '../../package.json'
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// Convert the URL to a path that's compatible with the file system
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Adjust the path to your file as necessary
const filePath = path.resolve(__dirname, '../../dist/index.d.ts');
const fileContent = fs.readFileSync(filePath, 'utf8');

// https://vitepress.dev/reference/site-config
export default defineConfig({
  // ...
  markdown: {
    theme: {
      light: 'vitesse-light',
      dark: 'vitesse-dark',
    },
    codeTransformers: [
      transformerTwoslash({
        twoslashOptions: {
          extraFiles: {
            'week-dates.ts': fileContent,
          },
        }
      })
    ]
  },
  //...
})

and in the docs i have this working now

import { PlainWeekDate } from 'week-dates'
import { Temporal } from '@js-temporal/polyfill'
//---cut---

const weekDate = PlainWeekDate.from({ yearOfWeek: 2021, weekOfYear: 1, dayOfWeek: 1, }) // [!code highlight]
console.log(weekDate.toString()) // 2021-W01-01
console.log(weekDate.toPlainDate().toString()) // 2021-01-04

const plainDate = Temporal.PlainDate.from({ year: 2021, month: 1, day: 4 }) // [!code highlight]
const weekDate2 = PlainWeekDate.from(plainDate) // [!code highlight]
console.log(weekDate2.toString()) // 2021-W01-01

However if there is a way to avoid importing from dist that would be very helpful

Also i think we should document this if it is the only way.