vue-loader 15 with TypeScript & webpack causes tslint to fail on .vue files.

Created on 19 May 2018  路  12Comments  路  Source: vuejs/vue-loader

Version

15.0.0

Reproduction link

https://github.com/bobbylight/vue-loader-15-tslint-issue

Steps to reproduce

git clone https://github.com/bobbylight/vue-loader-15-tslint-issue.git
npm install
npm run build

What is expected?

The project builds successfully.

What is actually happening?

tslint fails, seemingly because it is unhappy with "app.vue"'s suffix not being .ts/.tsx/.js/.jsx.


There might be a way to get this working, but I could not figure it out. A similar setup worked in vue-loade 14.x.x (there were differences in the webpack loaders since vue-loader didn't delegate to other loaders in 14).

I think this is the only thing holding me back from updating to vue-loader 15.

Most helpful comment

@JounQin, thanks for the response. I added that (I've updated the sample project) but I'm still getting the same error. Any other ideas?

All 12 comments

You miss appendTsSuffixTo: [/\.vue$/] for ts-loader.

https://github.com/TypeStrong/ts-loader#appendtssuffixto-regexp-default

@JounQin, thanks for the response. I added that (I've updated the sample project) but I'm still getting the same error. Any other ideas?

FYI, maybe it is related to tslint itself https://github.com/palantir/tslint/issues/2099 and I will recommend you to use fork-ts-checker-webpack-plugin which supports tslint + vue together perfectly.

I'm also having problems with this, although it's only throwing a warning. The problem I've got is that exported code from vue-loader has some blank lines and I get the warning "Consecutive blank lines are forbidden" from ts-lint.

Should I open a different issue for this? I have fixed it with a custom loader that trims the code exported by vue-loader, so it should be easy to fix, but maybe it should be configurable (for example, depending on tslint configuration users may want or not a newline at the end of the file).

@NoelDeMartin, yes, that's a known issue with a different issue # I believe.

Are you using Vue-loader 14 or 15? If it's the latter, can you link to your project so I can see what you're doing differently than me?

@bobbylight I have tried your repo and the problem seems to be with the typeCheck option for the tslint-loader. I tried using it in my project and I get the same error. In any case, since you are using typescript, ts-loader should already do type checks, right? I don't think that's necessary for linting, I don't use it and I get type errors from ts-loader.

And I guess you'll find that, but in your app.vue file you are missing the imports, so that would also fail eventually.

typeCheck is also a tslint-loader option to enable type checking for those tslint rules that require it (deprecation, prefer-readonly, etc.).

I removed the typeCheck option for tslint-loader, and you're right - I do get past the file name issue. However, rather than non-script lines being converted to empty lines like you're seeing (and was done in vue-loader 14), I'm getting tslint errors in inappropriate places in my *.vue files - in the <template> and <style> blocks, for example. It appears that the *.vue file is passed as-is to tslint, which won't work for obvious reasons.

The only workaround I see for now is to exclude /\.vue\.ts$/ from tslint-loader, which is a tough pill to swallow since most of my code is in single-file components.

I updated the demo project with this information.

Something else I also have different from you is the rules, you seem to have two different rules for the same files, and I have never used this enforce option either. My settings are the following:

            {
                test: /\.ts$/,
                use: [
                    'babel-loader',
                    {
                        loader: 'ts-loader',
                        options: {
                            appendTsSuffixTo: [/\.vue$/],
                        },
                    },
                    'tslint-loader',
                    'custom-loader?name=vue-tslint-fixer',
                ],
            },

The only thing custom-loader does is what I mentioned of removing empty lines (it works without this, but I get the warning). And I am using babel-loader because I have target: esnext in tsconfig, but I can remove this loader and it also compiles correctly.

Thanks @NoelDeMartin, changing tslint-loader from enforce: 'pre' to a chained loader for .ts files fixes the "entire file linted" issue for me!

We're now on the same page. Remaining issues are:

  • Can't enable no-consecutive-blank-lines (without a custom loader to strip leading/trailing blank lines)
  • I still can't enable typeCheck: true for tslint-loader

IMO, the former sounds like an issue that can be corrected on the vue-loader side (though admittedly I know nothing about webpack loaders, etc. - might be time to learn!), but is easily work-aroundable. The latter definitely sounds like a tslint issue and should be tracked under their existing ticket here:

https://github.com/palantir/tslint/issues/2099

Thanks for the help guys!

This is occurring again, when I update from vue-loader 15.3.0 to vue-loader 15.4.0. I suspect this commit:

https://github.com/vuejs/vue-loader/commit/0c2da0f5bacb8d0c392fd78b1a3ac72f46bc9ee5

As a recap, this is where my loader configuration ended up for .vue and .ts files:

    {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
            {
                loader: 'ts-loader',
                options: {
                    // Needed for <script lang="ts"> to work in *.vue files; see https://github.com/vuejs/vue-loader/issues/109
                    appendTsSuffixTo: [ /\.vue$/ ]
                }
            },
            {
                loader: 'tslint-loader'
                // Enabling the typeCheck option here causes builds to fail:
                // "Ensure that the files supplied to lint have a .ts, .tsx, .d.ts, .js or .jsx extension."
                // Commented out like this, the build runs, but all lines of *.vue files are linted, including
                // <template> and <script> blocks.
                // , options: {
                //     typeCheck: true
                // }
            }
        ]
    }, {
        test: /\.vue$/,
        use: [
            {
                loader: 'vue-loader'
            }
        ]
    }, {

I can't see any way to get tslint to run on my *.vue files at the moment. Any other ideas?

I just remove "typeCheck" option, It works for me

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ryanelian picture ryanelian  路  3Comments

NextSeason picture NextSeason  路  3Comments

Makio64 picture Makio64  路  4Comments

amorphine picture amorphine  路  3Comments

yozman picture yozman  路  4Comments