This is reproduce demo https://github.com/178220709/ts-loader-error
I have a exist vue project(vue2 webpack2 babel), and I want writer TypeScript in new vue file.
So I add some lib ,and use ts-loader .
In one sense, I successe, I can writer ts in *.ts file like this
<script lang="ts" src="./app3.ts"></script>
But if I add lang="ts"
<script type="ts" lang="ts"></script>
Even this is a empty script tag,will show this error:
webpack: Compiling...
Hash: 46dbdca8c10d668d6ea2
Version: webpack 2.2.1
Time: 89ms
chunk {0} ums/test/app.js (ums/test/app) 0 bytes {1} [initial]
chunk {1} assets/js/vendors.js (vendors) 487 kB [entry]
[80] ./~/ts-loader!./~/vue-loader/lib/selector.js?type=script&index=0!./src/pages/ums/test/app.vue 574 bytes {1} [built] [failed] [1 error]
[84] ./src/pages/ums/test/app.vue 1.34 kB {1} [built]
[86] ./~/vue-loader/lib/template-compiler.js?{"id":"data-v-4823cd5b"}!./~/vue-loader/lib/selector.js?type=template&index=0!./src/pages/ums/test/app.vue 586 bytes {1} [built]
+ 91 hidden modules
ERROR in ./~/ts-loader!./~/vue-loader/lib/selector.js?type=script&index=0!./src/pages/ums/test/app.vue
Module build failed: Error: Could not find file: 'D:\code\demo\vue\mut-ts-demo\src\pages\ums\test\app.vue'.
at getValidSourceFile (D:\code\demo\vue\mut-ts-demo\node_modules\typescript\lib\typescript.js:81080:23)
at Object.getEmitOutput (D:\code\demo\vue\mut-ts-demo\node_modules\typescript\lib\typescript.js:81446:30)
at getEmit (D:\code\demo\vue\mut-ts-demo\node_modules\ts-loader\dist\index.js:99:43)
at Object.loader (D:\code\demo\vue\mut-ts-demo\node_modules\ts-loader\dist\index.js:27:11)
@ ./src/pages/ums/test/app.vue 3:2-103
@ ./src/pages/ums/test/app.js
@ multi (webpack)-dev-server/client?http://127.0.0.1:4053 webpack/hot/dev-server ./src/pages/ums/test/app.js
Child html-webpack-plugin for "ums\test.html":
chunk {0} ums/test.html 367 bytes [entry]
+ 1 hidden modules
webpack: Failed to compile.
D:\code\demo\vue\mut-ts-demo\src\pages\ums\test\app.vue is the right path.
this is my webpack config
resolve: {
extensions: ['.js', '.ts','.vue'],
alias: {
assets: join(__dirname, '/src/assets'),
}
},
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
use: [{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}]
},
{
test: /\.vue$/,
use: [{
loader: 'vue-loader',
options: {
esModule: true
}
}]
},
{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
presets: ['es2015', "stage-3"]
}
}],
exclude: /node_modules/
},
anyone can help me ?
Thanks!
ts-loader anyway generate error message and sequence ts-loader(target es6) -> babel-loader don't work. Please fix it asap.
I'm afraid i don't use vue and so can't comment. Perhaps @herringtondarkholme can help
The entry file must be ts, too. That will make building pass.
I don't know the root cause. But since ts-loader is hacking vue's extension, it probably affects webpack's resolver.
I just remembered. ts-loader will build all scripts in component by resolving the entry file. So that when vue-loader asks ts-loader for script, ts-loader can find out the matching script and answer vue-loader.
However, if entry file is not ts, ts-loader does not have the chance to build script. So webpack cannot find the script.
You might ask why not just build the requested component script instead of building all scripts. The answer is TypeScript needs resolve all dependency before emitting and checking.
So you have to make the entry file into TypeScript.
Thanks @herringtondarkholme!
So how to solve this problem? I have similar errors and the entry file is a typescript file.
If someone would like to contribute a Vue example setup I'll happily add it to our collection of examples. It may help all those struggling folk. Though this may help: https://github.com/vuejs/vue-cli/issues/263
Adding appendTsSuffixTo to ts-loader options for tsx files fixed my problem:
{
test: /\.tsx?$/,
include: paths.appSrc,
use: [
{
loader: require.resolve('babel-loader'),
options: {
compact: true,
},
},
{
loader: require.resolve('ts-loader'),
options: {
appendTsSuffixTo: [/\.vue$/],
}
}
],
},
Adding appendTsSuffixTo to vue-loader options for ts files fixed my problem:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
ts: [
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
}
}]
},
options: {
esModule: true
}
}
}
"vue-loader": "^14.2.1",
{ test: /.vue$/, loader: 'vue-loader', options: { loaders: { ts: [ { loader: 'ts-loader', options: { appendTsSuffixTo: [/.vue$/] } }] }, options: { esModule: true } } }
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction,
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

I set your config in loaders config it's also error, I must to rewrite the loaders will ok but I dont know why should I to cover the default loader option, all config file generate by [email protected]
@Lemenxzy 我不清楚为什么,要覆盖vue默认的loader配置呢?(还是中文言简意赅呀!)
i have a same problem.....
{ test: /.vue$/, loader: 'vue-loader', options: { loaders: { ts: [ { loader: 'ts-loader', options: { appendTsSuffixTo: [/.vue$/] } }] }, options: { esModule: true } } }
module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction, }), cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, transformToRequire: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } }
I set your config in loaders config it's also error, I must to rewrite the loaders will ok but I dont know why should I to cover the default loader option, all config file generate by [email protected]
@Lemenxzy 我不清楚为什么,要覆盖vue默认的loader配置呢?(还是中文言简意赅呀!)
@baixiaoji 这个有点久远忘记了,我印象中是 vue-loader的问题 ,因为 webpack 编译时候的先后顺序问题,好像是这样。话说兄弟 你好眼熟,我之前好像见过你,而且我也在杭州你是谁来着。。。哈哈哈记性不好
Adding appendTsSuffixTo to vue-loader options for ts files fixed my problem:
{ test: /\.vue$/, loader: 'vue-loader', options: { loaders: { ts: [ { loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } }] }, options: { esModule: true } } }
it works, thanks!
{ test: /.vue$/, loader: 'vue-loader', options: { loaders: { ts: [ { loader: 'ts-loader', options: { appendTsSuffixTo: [/.vue$/] } }] }, options: { esModule: true } } }
module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction, }), cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, transformToRequire: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } }
I set your config in loaders config it's also error, I must to rewrite the loaders will ok but I dont know why should I to cover the default loader option, all config file generate by [email protected]
@Lemenxzy 我不清楚为什么,要覆盖vue默认的loader配置呢?(还是中文言简意赅呀!)@baixiaoji 这个有点久远忘记了,我印象中是 vue-loader的问题 ,因为 webpack 编译时候的先后顺序问题,好像是这样。话说兄弟 你好眼熟,我之前好像见过你,而且我也在杭州你是谁来着。。。哈哈哈记性不好
在utils.cssLoaders这个方法的返回里添加也是可以的。3Q
Most helpful comment
The entry file must be ts, too. That will make building pass.
I don't know the root cause. But since ts-loader is hacking vue's extension, it probably affects webpack's resolver.I just remembered. ts-loader will build all scripts in component by resolving the entry file. So that when vue-loader asks ts-loader for script, ts-loader can find out the matching script and answer vue-loader.
However, if entry file is not ts, ts-loader does not have the chance to build script. So webpack cannot find the script.
You might ask why not just build the requested component script instead of building all scripts. The answer is TypeScript needs resolve all dependency before emitting and checking.
So you have to make the entry file into TypeScript.