OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

ts-morph error: Module '"vue"' has no exported member 'computed'

  • Thread starter Thread starter wang
  • Start date Start date
W

wang

Guest
I wrote my own component library based on element-puls. When generating types, I got an error. All exports related to vue could not be found. Module '"vue"' has no exported member 'onMounted'. Module '"vue"' has no exported member 'ref'. Module '"vue"' has no exported member 'computed'.

Code:
import {
    projRoot,
    pkgRoot,
    buildOutput,
    excludeFiles,
    epRoot
} from '@hfn-components/build-utils'
import {resolve, relative} from "path";
import { Project } from "ts-morph";
import * as vueCompiler from "vue/compiler-sfc";
import glob from "fast-glob";
import {readFileSync} from 'fs'
import type { CompilerOptions, SourceFile } from 'ts-morph'
import consola from 'consola'
const TSCONFIG_PATH = resolve(projRoot,"tsconfig.json")
const outDir = resolve(buildOutput, "types");


export const generateTypesDefinitions = async () => {
  const compilerOptions: CompilerOptions = {
    emitDeclarationOnly: true,
    outDir,
    baseUrl: projRoot,
    preserveSymlinks: true,
    skipLibCheck: true,
    noImplicitAny: false,
  }

  const project = new Project({
    compilerOptions,
    tsConfigFilePath: TSCONFIG_PATH,
    skipAddingFilesFromTsConfig: true,
  })

  const sourceFiles = await addSourceFiles(project)
  consola.success('Added source files')

  typeCheck(project)
  consola.success('Type check passed!')

  await project.emit({
    emitOnlyDtsFiles: true,
  })

  const tasks = sourceFiles.map(async (sourceFile) => {
    consola.log(sourceFile.getFilePath())
    // const relativePath = relative(pkgRoot, sourceFile.getFilePath())
  })
}



// await addSourceFiles(project);
async function addSourceFiles(project:Project) {
  project.addSourceFileAtPath(resolve(projRoot, 'typings/env.d.ts'))
  const globSourceFile = "**/*.{js?(x),ts?(x),vue}";
  console.log('---',globSourceFile)
  const filePaths = excludeFiles(
    await glob([globSourceFile, '!hfn-components/**/*'], {
      cwd: pkgRoot, 
      absolute: true, 
      onlyFiles: true, 
    })
  );
  const epPaths = excludeFiles(
    await glob(globSourceFile, {
      cwd: epRoot, 
      onlyFiles: true, 
    })
  );
  console.log("filePaths", filePaths);
  console.log("epPaths",epPaths)
  const sourceFiles: SourceFile[] = []
  await Promise.all([
      ...filePaths.map((file) => {
        if (file.endsWith(".vue")) {
          const content = readFileSync(file, "utf-8");
          const sfc = vueCompiler.parse(content);
          const { script, scriptSetup } = sfc.descriptor;
          if (script || scriptSetup) {
            console.log()
            let content = script?.content ?? "";
            if (scriptSetup) {
              const compiled = vueCompiler.compileScript(sfc.descriptor, {
                id: "xxx",
              });
              content += compiled.content;
            }
            console.log(content)
            const lang = scriptSetup?.lang || script?.lang || "js";
            const source = project.createSourceFile(
                `${relative(process.cwd(), file)}.${lang}`,
                content
            );
            sourceFiles.push(source)
          }
        } else {
          const source = project.addSourceFileAtPath(file);
          sourceFiles.push(source)
        }
      }),
      ...epPaths.map(async (file) => {
        const content = readFileSync(resolve(epRoot, file), "utf-8");
        sourceFiles.push(project.createSourceFile(resolve(pkgRoot, file), content))
      }),
    ]);

    return sourceFiles
}



function typeCheck (project: Project){
  const diagnostics = project.getPreEmitDiagnostics()
  if (diagnostics.length > 0) {
    consola.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
    const err = new Error('Failed to generate dts.')
    consola.error(err)
    throw err
  }
}

My vue file uses setup syntax sugar, version 3.4.29

If I install the @vue/runtime-core dependency, exporting from this dependency will be normal. If I export ref from the @vue/runtime-core dependency, there will be no such error.

<p>I wrote my own component library based on element-puls. When generating types, I got an error. All exports related to vue could not be found.
Module '"vue"' has no exported member 'onMounted'.
Module '"vue"' has no exported member 'ref'.
Module '"vue"' has no exported member 'computed'.</p>
<pre><code>import {
projRoot,
pkgRoot,
buildOutput,
excludeFiles,
epRoot
} from '@hfn-components/build-utils'
import {resolve, relative} from "path";
import { Project } from "ts-morph";
import * as vueCompiler from "vue/compiler-sfc";
import glob from "fast-glob";
import {readFileSync} from 'fs'
import type { CompilerOptions, SourceFile } from 'ts-morph'
import consola from 'consola'
const TSCONFIG_PATH = resolve(projRoot,"tsconfig.json")
const outDir = resolve(buildOutput, "types");


export const generateTypesDefinitions = async () => {
const compilerOptions: CompilerOptions = {
emitDeclarationOnly: true,
outDir,
baseUrl: projRoot,
preserveSymlinks: true,
skipLibCheck: true,
noImplicitAny: false,
}

const project = new Project({
compilerOptions,
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})

const sourceFiles = await addSourceFiles(project)
consola.success('Added source files')

typeCheck(project)
consola.success('Type check passed!')

await project.emit({
emitOnlyDtsFiles: true,
})

const tasks = sourceFiles.map(async (sourceFile) => {
consola.log(sourceFile.getFilePath())
// const relativePath = relative(pkgRoot, sourceFile.getFilePath())
})
}



// await addSourceFiles(project);
async function addSourceFiles(project:Project) {
project.addSourceFileAtPath(resolve(projRoot, 'typings/env.d.ts'))
const globSourceFile = "**/*.{js?(x),ts?(x),vue}";
console.log('---',globSourceFile)
const filePaths = excludeFiles(
await glob([globSourceFile, '!hfn-components/**/*'], {
cwd: pkgRoot,
absolute: true,
onlyFiles: true,
})
);
const epPaths = excludeFiles(
await glob(globSourceFile, {
cwd: epRoot,
onlyFiles: true,
})
);
console.log("filePaths", filePaths);
console.log("epPaths",epPaths)
const sourceFiles: SourceFile[] = []
await Promise.all([
...filePaths.map((file) => {
if (file.endsWith(".vue")) {
const content = readFileSync(file, "utf-8");
const sfc = vueCompiler.parse(content);
const { script, scriptSetup } = sfc.descriptor;
if (script || scriptSetup) {
console.log()
let content = script?.content ?? "";
if (scriptSetup) {
const compiled = vueCompiler.compileScript(sfc.descriptor, {
id: "xxx",
});
content += compiled.content;
}
console.log(content)
const lang = scriptSetup?.lang || script?.lang || "js";
const source = project.createSourceFile(
`${relative(process.cwd(), file)}.${lang}`,
content
);
sourceFiles.push(source)
}
} else {
const source = project.addSourceFileAtPath(file);
sourceFiles.push(source)
}
}),
...epPaths.map(async (file) => {
const content = readFileSync(resolve(epRoot, file), "utf-8");
sourceFiles.push(project.createSourceFile(resolve(pkgRoot, file), content))
}),
]);

return sourceFiles
}



function typeCheck (project: Project){
const diagnostics = project.getPreEmitDiagnostics()
if (diagnostics.length > 0) {
consola.error(project.formatDiagnosticsWithColorAndContext(diagnostics))
const err = new Error('Failed to generate dts.')
consola.error(err)
throw err
}
}

</code></pre>
<p>My vue file uses setup syntax sugar, version 3.4.29</p>
<p>If I install the @vue/runtime-core dependency, exporting from this dependency will be normal. If I export ref from the @vue/runtime-core dependency, there will be no such error.</p>
 

Latest posts

Top