Vue + webpack + TS: 生成声明时找不到.vue.d.ts
Vue + webpack + TS: cannot find .vue.d.ts when generating declaration
我正在开发一个用 Typescript 编写并使用 VueJS 的库。我还在构建部分使用 webpack。
我在生成 TypeScript 声明文件 (.d.ts) 时遇到问题。
首先,让我们谈谈我的源代码。我有 Typescript 文件(显然)和 Vue 组件。每个 Vue 组件由 2 个文件组成:一个 .vue 文件和一个 .ts 文件。
举个例子
我有以下代码:
// index.ts
export { default } from './components/Foobar.vue';
// components/Foobar.vue
<template><p>Hello!</p></template>
<script lang="ts" src="./Foobar.ts"></script>
// components/Foobar.ts
@Component
export default class Foobar extends Vue {
}
构建的输出将是这样的:
lib/
dist/
index.js // my lib
index.d.ts // aggregated .d.ts with dts-bundle
lib/ // all my .d.ts are here !
index.d.ts
components/
Foobar.d.ts
问题是 dts-bundle 无法输出 dist/index.d.ts 因为生成的声明 (dist/lib/**/*.d.ts
) 无效。它们由 ts-loader 生成。
如果我们查看 dist/lib/index.d.ts,我们会发现以下内容:
// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'
问题当然是:/dist/lib/components/Foobar.vue
不 存在。此组件的定义是 Foobar.d.ts
,而不是 Foobar.vue.d.ts
。
将每个声明捆绑在一起时,dts-bundle 失败,因为它找不到 /dist/lib/components/Foobar.vue.d.ts
.
我该如何解决?
我只需要更换这个
// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'
由此
// dist/lib/index.d.ts
export { default } from './components/Foobar'
我认为这是一个非常常见的错误,我只是在我的 webpack 配置上做错了什么。这是我的 webpack 配置:
{
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: 'path/to/index.ts',
output: { /* ... */}
resolve: {
symlinks: true,
extensions: [
'.ts',
'.vue',
'.js',
'.json',
],
modules: [
'node_modules',
]
},
module: {
noParse: /^(vue|vuex)$/,
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'cache-loader',
options: {
cacheDirectory: // cache path
}
},
{
loader: 'vue-loader',
options: {
cacheDirectory: // cache path
}
},
]
},
{
test: /\.ts$/,
use: [
{
loader: 'cache-loader',
options: {
cacheDirectory: // cache path
}
},
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [
/\.vue$/
],
}
}
]
}
// ...
}
plugins: [
new ProgressPlugin(),
new FriendlyErrorsWebpackPlugin({
clearConsole: false
}),
new VueLoaderPlugin(),
new ForkTsCheckerWebpackPlugin({
vue: true,
tslint: 'custom path to my file',
formatter: 'codeframe',
}),
new CopyWebpackPlugin(
[
{
from: 'assets',
to: 'dist',
ignore: [
'.gitkeep',
'.DS_Store'
]
}
]
),
new DtsBundlePlugin({
name: `MyModule`,
main: path.join(LIB_PATH, entry.output.path, 'lib', 'index.d.ts'),
out: path.join(LIB_PATH, entry.output.path, 'index.d.ts'),
verbose,
})
],
}
我正在做一个最小复制回购,我会及时编辑这个问题。
同时,如果我需要提供具体信息,请告诉我。
感谢您的帮助。
好的,我终于搞定了。
vue-loader
用于将 vue monofiles 拆分为不同的 webpack 资产。目标是让 webpack 在 vue monofile 的每个部分(脚本、样式和模板)执行不同的加载器。
在我的例子中,我没有使用“real”vue monofile,因为 typescript 部分在另一个文件中,而不是 .vue 文件。然后用 <script lang="ts" src="./MyComponent.ts"></script>
.
引用
由于 ts-loader 和 vue-loader 的工作方式,这样做会导致声明生成失败。
我所要做的就是使用普通的单文件组件。但是因为我需要让我的 ts 远离我的 .vue(因为打字稿中的一个已知错误),我不得不显式导入我的 ts 模块而不是引用我的 ts 文件,就像这样:
<script lang="ts">
export { default } from './MyComponent.ts';
</script>
希望我说清楚了。
我正在开发一个用 Typescript 编写并使用 VueJS 的库。我还在构建部分使用 webpack。
我在生成 TypeScript 声明文件 (.d.ts) 时遇到问题。
首先,让我们谈谈我的源代码。我有 Typescript 文件(显然)和 Vue 组件。每个 Vue 组件由 2 个文件组成:一个 .vue 文件和一个 .ts 文件。
举个例子
我有以下代码:
// index.ts
export { default } from './components/Foobar.vue';
// components/Foobar.vue
<template><p>Hello!</p></template>
<script lang="ts" src="./Foobar.ts"></script>
// components/Foobar.ts
@Component
export default class Foobar extends Vue {
}
构建的输出将是这样的:
lib/
dist/
index.js // my lib
index.d.ts // aggregated .d.ts with dts-bundle
lib/ // all my .d.ts are here !
index.d.ts
components/
Foobar.d.ts
问题是 dts-bundle 无法输出 dist/index.d.ts 因为生成的声明 (dist/lib/**/*.d.ts
) 无效。它们由 ts-loader 生成。
如果我们查看 dist/lib/index.d.ts,我们会发现以下内容:
// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'
问题当然是:/dist/lib/components/Foobar.vue
不 存在。此组件的定义是 Foobar.d.ts
,而不是 Foobar.vue.d.ts
。
将每个声明捆绑在一起时,dts-bundle 失败,因为它找不到 /dist/lib/components/Foobar.vue.d.ts
.
我该如何解决?
我只需要更换这个
// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'
由此
// dist/lib/index.d.ts
export { default } from './components/Foobar'
我认为这是一个非常常见的错误,我只是在我的 webpack 配置上做错了什么。这是我的 webpack 配置:
{
mode: 'development',
devtool: 'cheap-module-eval-source-map',
entry: 'path/to/index.ts',
output: { /* ... */}
resolve: {
symlinks: true,
extensions: [
'.ts',
'.vue',
'.js',
'.json',
],
modules: [
'node_modules',
]
},
module: {
noParse: /^(vue|vuex)$/,
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'cache-loader',
options: {
cacheDirectory: // cache path
}
},
{
loader: 'vue-loader',
options: {
cacheDirectory: // cache path
}
},
]
},
{
test: /\.ts$/,
use: [
{
loader: 'cache-loader',
options: {
cacheDirectory: // cache path
}
},
{
loader: 'babel-loader'
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [
/\.vue$/
],
}
}
]
}
// ...
}
plugins: [
new ProgressPlugin(),
new FriendlyErrorsWebpackPlugin({
clearConsole: false
}),
new VueLoaderPlugin(),
new ForkTsCheckerWebpackPlugin({
vue: true,
tslint: 'custom path to my file',
formatter: 'codeframe',
}),
new CopyWebpackPlugin(
[
{
from: 'assets',
to: 'dist',
ignore: [
'.gitkeep',
'.DS_Store'
]
}
]
),
new DtsBundlePlugin({
name: `MyModule`,
main: path.join(LIB_PATH, entry.output.path, 'lib', 'index.d.ts'),
out: path.join(LIB_PATH, entry.output.path, 'index.d.ts'),
verbose,
})
],
}
我正在做一个最小复制回购,我会及时编辑这个问题。
同时,如果我需要提供具体信息,请告诉我。
感谢您的帮助。
好的,我终于搞定了。
vue-loader
用于将 vue monofiles 拆分为不同的 webpack 资产。目标是让 webpack 在 vue monofile 的每个部分(脚本、样式和模板)执行不同的加载器。
在我的例子中,我没有使用“real”vue monofile,因为 typescript 部分在另一个文件中,而不是 .vue 文件。然后用 <script lang="ts" src="./MyComponent.ts"></script>
.
由于 ts-loader 和 vue-loader 的工作方式,这样做会导致声明生成失败。
我所要做的就是使用普通的单文件组件。但是因为我需要让我的 ts 远离我的 .vue(因为打字稿中的一个已知错误),我不得不显式导入我的 ts 模块而不是引用我的 ts 文件,就像这样:
<script lang="ts">
export { default } from './MyComponent.ts';
</script>
希望我说清楚了。