我有一个简单的自定义 Webpack 加载器,它从文件生成 TypeScript 代码.txt
:
txt-loader.js
module.exports = function TxtLoader(txt) {
console.log(`TxtLoader invoked on ${this.resourcePath} with content ${JSON.stringify(txt)}`)
if (txt.indexOf('Hello') < 0) {
throw new Error(`No "Hello" found`)
}
return `export const TEXT: string = ${JSON.stringify(txt)}`
}
在现实生活中,我正在对输入进行一些解析;在此示例中,假设文件必须包含Hello
有效的文本。
这个加载器让我可以像这样导入文本文件:
索引.ts
import { TEXT } from './hello.txt'
console.log(TEXT)
这一切都很好,除了一件事:(webpack watch
和它的表亲webpack serve
)。第一次编译很好:
$ /tmp/webpack-loader-repro/node_modules/.bin/webpack watch
TxtLoader invoked on /tmp/webpack-loader-repro/hello.txt with content "Hello world!\n"
asset main.js 250 bytes [compared for emit] [minimized] (name: main)
./index.ts 114 bytes [built] [code generated]
./hello.txt 97 bytes [built] [code generated]
webpack 5.64.3 compiled successfully in 3952 ms
但后来我更改了hello.txt
文件:
$ touch hello.txt
突然奇怪的事情发生了:
TxtLoader invoked on /tmp/webpack-loader-repro/index.ts with content "import { TEXT } from './hello.txt'\n\nconsole.log(TEXT)\n"
TxtLoader invoked on /tmp/webpack-loader-repro/custom.d.ts with content "declare module '*.txt'\n"
[webpack-cli] Error: The loaded module contains errors
at /tmp/webpack-loader-repro/node_modules/webpack/lib/dependencies/LoaderPlugin.js:108:11
at /tmp/webpack-loader-repro/node_modules/webpack/lib/Compilation.js:1930:5
at /tmp/webpack-loader-repro/node_modules/webpack/lib/util/AsyncQueue.js:352:5
at Hook.eval [as callAsync] (eval at create (/tmp/webpack-loader-repro/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
at AsyncQueue._handleResult (/tmp/webpack-loader-repro/node_modules/webpack/lib/util/AsyncQueue.js:322:21)
at /tmp/webpack-loader-repro/node_modules/webpack/lib/util/AsyncQueue.js:305:11
at /tmp/webpack-loader-repro/node_modules/webpack/lib/Compilation.js:1392:15
at /tmp/webpack-loader-repro/node_modules/webpack/lib/HookWebpackError.js:68:3
at Hook.eval [as callAsync] (eval at create (/tmp/webpack-loader-repro/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)
at Cache.store (/tmp/webpack-loader-repro/node_modules/webpack/lib/Cache.js:107:20)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
似乎 Webpack 决定在我的加载器中抛出比配置中指定的更多的文件。
如果我删除加载程序中抛出的异常并返回一些任意有效的 TypeScript 代码,生成main.js
的代码看起来完全一样。所以看起来这些额外的操作是完全多余的。但我不认为正确的解决方案是让我的装载机吞下这些异常。
加载器配置如下:
webpack.config.js
const path = require('path')
module.exports = {
mode: 'production',
entry: './index.ts',
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
},
{
test: /\.txt$/,
use: [
{
loader: 'ts-loader',
// Tell TypeScript that the input should be parsed as TypeScript,
// not JavaScript: <https://stackoverflow.com/a/47343106/14637>
options: { appendTsSuffixTo: [/\.txt$/] },
},
path.resolve('txt-loader.js'),
],
},
],
},
}
最后,这些是将它们放在一起的必要位:
自定义.d.ts
declare module '*.txt'
tsconfig.json
{}
包.json
{
"name": "webpack-loader-repro",
"license": "MIT",
"private": true,
"devDependencies": {
"ts-loader": "9.2.6",
"typescript": "4.5.2",
"webpack": "5.64.3",
"webpack-cli": "4.9.1"
},
"dependencies": {}
}
对于那些想在家尝试的人,克隆这个最小的复制项目。
这是 Webpack 中的错误吗?在 ts-loader 中?在我的配置中?