4.3.1
2.1.5
<template>
<q-layout>
<div slot="header" class="toolbar">
<q-toolbar-title :padding="0">
Quasar Framework v{{quasarVersion}}
</q-toolbar-title>
</div>
<!--
Replace following "div" with
"<router-view class="layout-view">" component
if using subRoutes
-->
<div class="layout-view">
<div class="logo-container non-selectable no-pointer-events">
<div class="logo" :style="position">
<img src="~assets/quasar-logo.png">
<p class="caption text-center">
<span class="desktop-only">Move your mouse!!!.</span>
<span class="touch-only">Touch screen and move.</span>
</p>
</div>
</div>
</div>
</q-layout>
</template>
<script lang="ts">
import * as Quasar from 'quasar';
import { Utils } from 'quasar';
import * as Vue from 'vue';
import Component from 'vue-class-component';
const moveForce = 30;
const rotateForce = 40;
@Component({
})
export default class Index extends Vue {
rotateX: number;
rotateY: number;
moveY: number;
moveX: number;
quasarVersion: string;
...
}
</script>
<style lang="stylus">
....
</style>
tslint.json
๊ตฌ์ฑ:
{
"rules": {
"class-name": true,
"curly": true,
"eofline": false,
"expr" : true,
"forin": true,
"indent": [true, "spaces"],
"label-position": true,
"label-undefined": true,
"max-line-length": [true, 140],
"no-arg": true,
"no-bitwise": true,
"no-console": [true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-empty": true,
"no-eval": true,
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-trailing-comma": true,
"no-trailing-whitespace": true,
"no-unused-expression": false,
"no-unused-variable": true,
"no-unreachable": true,
"no-use-before-declare": true,
"one-line": [true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"quotemark": [true, "single"],
"radix": false,
"semicolon": [false],
"triple-equals": [true, "allow-null-check"],
"variable-name": false,
"whitespace": [true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}
์ ์ฒด ํ์ผ์ ๋ฆฐํธํ๋ ค๊ณ ์๋ํ์ง๋ง ์คํจํฉ๋๋ค.
eslint์ ์ ์ฌํ๊ฒ ์คํฌ๋ฆฝํธ ํ๊ทธ ๋ด๋ถ์ ์ฝ๋๋ง ํ์ธํฉ๋๋ค.
@nrip-monotype, vue-loader
๊ตฌ์ฑํ์ฌ Vue ๋จ์ผ ํ์ผ ๊ตฌ์ฑ ์์์ ํจ๊ป TSLint๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์นํฉ ์๋ฅผ ๋ค์ด 2 Iํฉ๋๋ค (ํ ๋ฒ ๋ด ๊ฐ์ง๊ณ ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ๊ณ
module: {
rules: [
{
enforce: 'pre',
test: /\.ts$/,
loader: 'tslint-loader',
exclude: /(node_modules)/,
options: {
configFile: 'tslint.json'
}
},
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true,
isolatedModules: true
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
ts: 'ts-loader!tslint-loader'
}
}
},
}
}
}
@romandragan , ๊ทํ์ ์ ์์ ํจ๊ณผ๊ฐ ์์ง๋ง no-consecutive-blank-lines
๋ฌธ์ ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋งํฌ์
์์๊ฐ ๋น ์ค๋ก ๋์ฒด๋๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
<template>
<span class='hello'>hello world</span>
</tempalte>
<script lang="ts">
return {};
</script>
<style>
.hello { background-color: pink }
</style>
tslint๋ ๋ค์๊ณผ ๊ฐ์ด ํ์ํฉ๋๋ค.
return {};
"no-consecutive-blank-lines": [true, 3]
ํ๋ฉด ์คํจํ์ง๋ง "no-consecutive-blank-lines": [true, 4]
๋ ์ฑ๊ณตํฉ๋๋ค... ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์๋์ง ์์ญ๋๊น? (์ ํ ๋ฐ ํํ ๊ณต๋ฐฑ์ ์ ๊ฑฐํ๋ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ์ ์ฝ์...)
@lucastheisen , ๋์๊ฒ๋ ๊ฐ์ ๋ฌธ์ ๐ ํด๊ฒฐ์ฑ ์ ์ฐพ๋ ์ค...
@romandragan ์ ์ค์ ์ด ์ ์๊ฒ typeCheck
ํ๋๊ทธ๊ฐ vue-loader์์ ์๋ํ์ง ์๋๋ค๋ ๊ฒ์
๋๋ค. vue-loader ์ธ๋ถ์์ ์ ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
>
module: {
rules: [
{
enforce: 'pre',
test: /\.ts$/,
loader: 'tslint-loader',
exclude: /(node_modules)/,
options: {
configFile: 'tslint.json'
}
},
{
test: /\.ts$/,
exclude: /node_modules|vue\/src/,
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
transpileOnly: true,
isolatedModules: true,
typeCheck: true // This is ok.
}
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
ts: 'ts-loader!tslint-loader' // Can't append `?typeCheck` here.
}
}
},
}
}
}
vue-loader์์ ์ ํ ๊ฒ์ฌ ๊ท์น์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
ERROR in ./app.ts
(10,29): error TS2307: Cannot find module './components/sidebar.vue'.
ERROR in ./~/ts-loader!./~/tslint-loader?formatter=verbose&typeCheck!./~/vue-loader/lib/selector.js?type=script&index=0!./components/sidebar.vue
Module build failed: Error:
Invalid source file: /absolute/path/to/sidebar.vue. Ensure that the files supplied to lint have a .ts, .tsx, .js or .jsx extension.
@lucastheisen ๋ฐ @romandragan๊ณผ ๋์ผํ no-consecutive-blank-lines
๊ฐ์์ฑ์ด ๋ฐ์ํฉ๋๋ค.
์ด ๊ตฌ์ฑ์ ์ฌ์ฉํ ๋ ERROR in Entry module not found: Error: Can't resolve 'ts-loader!tslint-loader'
๋ฉ๋๋ค.
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
ts: 'ts-loader!tslint-loader'
}
}
},
@ARomancev , ์ด๋ค ๋ฒ์ ์ ์นํฉ์ ์ฌ์ฉํ๊ณ ์์ต๋๊น? ts-loader
๋ฐ tslint-loader
npm ๋ชจ๋์ด ์ค์น๋์ด ์์ต๋๊น?
@romandragan , ๋ค์์ ๋ค์์ ์ฌ์ฉํ๋ npm ๊ตฌ์ฑ์
๋๋ค.
```
"tslint": "^5.1.0",
"ts-loader": "^2.0.3",
"์นํฉ": "^2.4.1",
And this is the webpack config:
{
test: /\.tsx?$/,
enforce: 'pre',
loader: 'tslint-loader'
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
appendTsSuffixTo: [/\.vue$/]
}
},
```
ts-loader์ tslint-loader๋ ๋ชจ๋ *.ts ํ์ผ์์ ์ฌ๋ฐ๋ฅธ lint๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ์ค์น๋๊ณ ์ ๋๋ก ์๋ํฉ๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก .vue ํ์ผ์์ TypeScript ๋ก์ง์ ๋ถ๋ฆฌํ๊ณ vue ๋ก๋์์ tslint-loader
๋ฅผ ์ ๊ฑฐํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด no-consecutive-blank-lines
์ฌ๋ผ์ง๋๋ค.
@romandragan ์ด๊ฒ์ ์๋ํ์ง๋ง <script>
ํ๊ทธ ์์ ์ฝ๋๋ฅผ ๋ฆฐํธํ๋ ๊ฒ๋ ์ข์ ๊ฒ์
๋๋ค. ์ด๊ฒ์ ํธ์ง๊ธฐ ์ง์์ ํ์ํ๋ฉฐ ์ ์ฒด ์นํฉ์ ํตํ๋ ๊ฒ๋ณด๋ค tslint
๋ช
๋ น์ ๊ฐ๋ณ์ ์ผ๋ก ์คํํ๋ ๊ฒ์ด ํจ์ฌ ์ฝ์ต๋๋ค. ํ๋ฆ.
@adidahiya ์ด ๊ธฐ๋ฅ์ ๋ํ ๊ณํ์ด ์์ต๋๊น?
๋๋ eslint ํ๋ฌ๊ทธ์ธ๊ณผ ๊ฐ์ tslint์ ํ๋ฌ๊ทธ์ธ ์์คํ
์ง์ ๊ณํ์ด ์์ต๋๊น?
Webpack์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ .vue
ํ์ผ์ด ์๋ํ๊ณ fork-ts-checker-webpack-plugin ์์ no-consecutive-blank-lines
๋ฌธ์ ์์ด typechecker ์์ค์์ linting๋ฉ๋๋ค. ์ฌ๊ธฐ์์ PR์ ๋ณผ ์ ์์ต๋๋ค(ํ
์คํธ ๋ธ๋์น์์ npm install
๋ฅผ ๋ณด๊ณ ์ง๊ธ ๋ฐ๋ก ์ฌ์ฉ ํ์ธ์ . PR ์ค๋ ๋ ์๋จ ์ฐธ์กฐ):
๋ํ VSCode ํธ์ง๊ธฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ TSLint Vue ํ์ฅ์ ํ์ธํ์ญ์์ค.
tslint์์ ํ๋ฌ๊ทธ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ pull ์์ฒญ์ ๋ง๋ค๊ณ "vue" ๋จ์ผ ํ์ผ ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ ์ ์๋ ์ฒซ ๋ฒ์งธ ํ๋ฌ๊ทธ์ธ์ ์์ฑํ์ต๋๋ค.
https://github.com/palantir/tslint/pull/3596
https://github.com/Toilal/tslint-plugin-vue
์ด๊ฒ์ ์งํ์ค์ธ ์์
์ด์ง๋ง ์์ ๋กญ๊ฒ ์๋ํ์ญ์์ค. npm install git+https://https://github.com/Toilal/tslint-plugin-vue
๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํ๊ณ tslint.json
plugins: 'vue'
๋ฅผ ์ถ๊ฐํ์ฌ ํ์ฑํํ ์ ์์ต๋๋ค. ํ์ฌ -p/--project
์ต์
์์๋ ์๋ํ์ง ์์ผ๋ฏ๋ก -c/--config
์ต์
์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
์๋
ํ์ธ์ ์ฌ๋ฌ๋ถ, ํ์ฌ ๋ค๋ฅธ ๋์ ์๋ฃจ์
์ ํ์ผ ์์ ๋ถ๋ถ์์ ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ์ด๋ํ๊ณ ์ด ๊ท์น์ ๊ณ ๋ คํ์ง ์๋๋ก ๋ง์ง๋ง ์ค์ /* tslint:disable:no-consecutive-blank-lines */
๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค.
์๋ ์ด๋ฏธ์ง๋ฅผ ํ์ธํ์ธ์
Vue-loader ๋ ์ค์ ๋ก vue ํ์ผ์์ JavaScript ๋๋ TypeScript๋ฅผ ์ถ์ถํ ์ ์์ผ๋ฏ๋ก vue ํ์ผ์ ๊ตฌ๋ฌธ ๋ถ์ํ๋ ๊ฒ์ webpack์์ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ typeCheck๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ ํ์ผ ์ด๋ฆ์ด ".vue"๋ก ๋๋๊ธฐ ๋๋ฌธ์ TSLint๋ ์ฌ์ ํ "์๋ชป๋ ์์ค ํ์ผ"์ ๋ฐ์์ํต๋๋ค...
๋ํ vue-loader๋ TypeScript์ ๊ด๋ จ์ด ์๋ ์ค์ ์ญ์ ํ์ง ์๊ณ ์ฌ๋ฐ๋ฅธ ์ค ๋ฒํธ๋ฅผ ์ ์งํ๊ธฐ ์ํด ์ง์ฐ๊ธฐ ๋๋ฌธ์ vue ํ์ผ์ ์์ ๋๋ ๋ ๋ถ๋ถ์ ์ฐ์์ ์ธ ๋น ์ค์ ํ์ฉํ์ฌ TSLint๊ฐ ์ฐ์์ ์ธ ๋น ์ค์ ๋ํด ๋ถํํ์ง ์๋๋ก ํ ์ ์์ต๋๋ค.
์ ๋ ํ์ฌ ์นํฉ ์์ด ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฆฐํฐ๋ฅผ ์์
์ค์
๋๋ค. https://github.com/ajafff/wotan
์ด๊ฒ์ ํ์ฌ ๊ฐ๋
์ฆ๋ช
์ด๋ฉฐ TSLint์ ํตํฉ๋๊ฑฐ๋ ํตํฉ๋์ง ์์ ์ ์์ต๋๋ค. ์ฒ์๋ถํฐ ์์ ํ ๋ค์ ์์ฑํ์ผ๋ฉฐ TSLint์ ๊ฑฐ์ ํธํ๋์ง ์์ต๋๋ค.
ํ๋ก์ธ์(ESLint ํ๋ก์ธ์์ ์ ์ฌ)๋ฅผ ์ฌ์ฉํ์ฌ ํ์ผ์ ๋ณํํ๋ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. vue ํ๋ก์ธ์๋ SFC์์ TypeScript ์ฝ๋๋ฅผ ์ถ์ถํ๊ณ linter๋ ์ฝ๋๋ง ๋ฆฐํธํ ๋ค์ ํ๋ก์ธ์๋ ์ค๋ฅ๋ฅผ ์๋ณธ ํ์ผ์ ์ฌ๋ฐ๋ฅธ ์์น์ ๋งคํํฉ๋๋ค. ์ด๊ฒ์ ์ ํ ๊ฒ์ฌ์์๋ ์๋ํฉ๋๋ค.
์ฌ๊ธฐ์์ vue ํ์ผ ๋ฆฐํธ์ ์ํ ์ถ๋ ฅ์ ๋ณผ ์ ์์ต๋๋ค.
https://github.com/ajafff/wotan/blob/master/baselines/integration/processors/vue/default/hello.vue.lint#L29
๋ํ ์๋ ์์ ์ ํ์ฉํฉ๋๋ค. ์์ ๋์ผํ ํ์ผ์ด ์๋์ผ๋ก ์์ ๋จ: https://github.com/ajafff/wotan/blob/master/baselines/integration/processors/vue/default/hello.vue#L28
https://github.com/ajafff/wotan/issues/32 ์์ ํ๋ฉด ์ค์ ์ฝ๋์์ ์ฌ์ฉํด ๋ณผ ์ ์๋๋ก ๋ฆด๋ฆฌ์ค๋ฅผ ๊ฒ์ํ๊ฒ ์ต๋๋ค.
vue ํ๋ก์ธ์๋ ๋ฉ์ธ ํ๋ก์ ํธ์ ์ผ๋ถ๊ฐ ์๋์ง๋ง ํ๋ก์ธ์์ ๋ํ ๋ณ๋์ ํจํค์ง๋ฅผ ๊ฒ์ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
๋ช
๋ น์ค tslint๊ฐ ๋ด Vue ํ์ผ์ TS ๋ถ๋ถ์ ๋ฆฐํธํ๋๋ก tsconfig.json
์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์๋ ์ฌ๋์ด ์์ต๋๊น? VS Code์์๋ ์ ์๋ํ์ง๋ง ๋ช
๋ น์ค๋ ์๋ํ๊ณ ์ถ์ต๋๋ค.
์๊ฐ๋ณด๋ค ์๊ฐ์ด ์กฐ๊ธ ๋ ๊ฑธ๋ ธ์ง๋ง ์ฌ๊ธฐ ์์ต๋๋ค: https://www.npmjs.com/package/@fimbul/wotan
Linter ๋ฐํ์( @fimbul/wotan
)์ ์ฌ์ฉํ์ฌ TSLint ๊ท์น์ ์คํํ ์๋ ์์ต๋๋ค. @fimbul/heimdall
๋ง ํ์ํฉ๋๋ค. https://github.com/fimbullinter/wotan/tree/master/packages/heimdall#readme ์ฐธ์กฐ
Vue ํ์ผ์ ๋ฆฐํธํ๋ ค๋ฉด @fimbul/ve
(์คํ ์์, 've'์ 'u' ์์): https://github.com/fimbullinter/wotan/tree/master/packages/ve#readme
tslint๊ฐ linting vue/html ํ์ผ์ ์ง์ํ๋ ์ผ์ ์ด ์์ต๋๊น? @๋์
์ด๊ฒ์ ๊ตฌํํ๋ ๊ฒ์ ์ปค๋ฎค๋ํฐ์ ๋ชซ์ด์ง๋ง VueJS ์์ฑ์๋ vue-cli์ ๋ง์ง๋ง ๋ฒ์ (ํ์ฌ ์ํ ๋ฒ์ ) ๋์ ESLint TypeScript ํ๋ฌ๊ทธ์ธ์ ์ ํธํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ์ด๋ฏธ [email protected]
๊ตฌํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์:
$ npm install -g @vue/cli
$ vue create project-name
๊ทธ๋ฆฌ๊ณ TSLint๋ฅผ ๋ฆฐํฐ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด ์ค๋ ๋์ ๋ชจ๋ ์ฌ๋๋ค์๊ฒ ๋ ์ข์ ์์์ ๊ฐ์ง๊ณ ๋์์์ต๋๋ค.
์ต์ ๋ฒ์ ์ wotan ์ tslint.json
์ ๋ฐ๋ผ TSLint ๊ท์น์ ์คํํ ์ ์์ผ๋ฉฐ ํ๋ก์ธ์์ ๋ํ ์ง์์ ์ถ๊ฐํฉ๋๋ค. ์ฆ, ๊ตฌ์ฑ์ ๋ณ๊ฒฝํ ํ์๊ฐ ์์ผ๋ฉฐ ์ง๊ธ Vue ํ์ผ ๋ฆฐํธ๋ฅผ ์์ํ ์ ์์ต๋๋ค.
sh
yarn add -D @fimbul/wotan @fimbul/ve @fimbul/valtyr
# or
npm install --save-dev @fimbul/wotan @fimbul/ve @fimbul/valtyr
.fimbullinter.yaml
์ ์ถ๊ฐํ๊ณ ๋ค์ ์ฝํ
์ธ ๋ฅผ ์ถ๊ฐํฉ๋๋ค.yaml
modules: "@fimbul/valtyr"
valtyr:
overrides:
- files: "*.vue"
processor: "@fimbul/ve"
sh
wotan # finds tsconfig.json and lints the whole project with type information according to your tslint.json
wotan 'src/**/*.vue' -f verbose # lint all Vue files, use TSLint's verbose formatter
wotan -p tsconfig.json -c tslint.json --fix # lint the whole project with tslint.json and fix failures
@romandragan
vue-loader๋ฅผ ๊ตฌ์ฑํ์ฌ Vue ๋จ์ผ ํ์ผ ๊ตฌ์ฑ ์์์ ํจ๊ป TSLint๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ฃจ์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ Webpack ํน์ ์๋ฃจ์ ์ผ ๋ฟ์ ๋๋ค. ๋น๋ ๋๊ตฌ์ ์์กดํ์ง ์๋ ์ผ๋ฐ ์๋ฃจ์ ์ด ์์ผ๋ฉด Fusebox (๋๋ ๋ค๋ฅธ ๋น๋ ๋๊ตฌ)๋ก ์ปดํ์ผ๋ Vue ํ์ผ์ tslintํ ์ ์์ต๋๋ค.
์นํฉ์ ์ํ ๋ ๋ค๋ฅธ ์๋ฃจ์ ์ ๋๋ค.
vue-loader์์ ์ ๊ณตํ๋ "ํ์ผ"์์ ๋ชจ๋ ๊ณต๋ฐฑ์ ํธ๋ฆฌ๋ฐํ ๋ค์ ๋ฆฐํฐ์ ๊ณต๋ฐฑ์ ์ถ๊ฐํ๋ ๊ฐ๋จํ ๋ก๋๋ฅผ ๋ง๋ค์์ต๋๋ค.
webpack.config.js:
test:/\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'ts': [
'vue-ts-loader',
'tslint-loader',
path.resolve('./path/to/remove-whitespace-ts-loader.js')
],....
๊ทธ๋ฐ ๋ค์ remove-whitespace-ts-loader:
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Szymon Sasin
*/
module.exports = function(source) {
let result = source.replace(/^\s+|\s+$/g, '')
result += '\r\n'
return result;
}
_์ฝ๋ ํ์์ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ชจ๋ ๋์์ ํ์ํฉ๋๋ค_
๊ทธ๊ฒ์ ์ ์๋ํ๊ณ ์์ค๋ฅผ ์์ ํ์ง ์๋๋ก ํ์ฉํฉ๋๋ค, ๊ฐ์ฌํฉ๋๋ค
๊ทธ๋ฅ ๊ฐ์ ์ ์ฅ์ธ๋ฐ, PR๋ก ํ์ง ์์ผ๋ฉด ํด๊ฒฐ๋์ง ์๋ ๊ฑด๊ฐ์?
no-consecutive-blank-lines
๊ฐ ์ด ์ค์ ์์ ์๋ํ์ง ์๋ ๊ฒ ์ธ์(์ฌ์ฉ์ ์ง์ ๋ก๋๋ก ํด๊ฒฐํ ์ ์์ด์ผ ํจ), ์ต๊ทผ webpack ๋ฐ vue-loader ๋ฒ์ ์์๋ typeCheck: true
tslint
์ด ํ์ฅ์ ๋ง์กฑํ์ง ์๊ธฐ ๋๋ฌธ์ typeCheck: true
*.vue
ํ์ผ์ ๋ํด ์๋ํฉ๋๋ค( appendTsSuffixTo
). ์ด ๋ฐ๋ชจ ํ๋ก์ ํธ ๋ ๊ฐ์ง๊ณ ๋ ์ ์๋ ๊ฐ๋จํ ์๋ฅผ ์ ๊ณตํฉ๋๋ค.
ํ์
์ฌ๊ธฐ์ ๋ ๋ง์ ์์์ด ์์ต๋๊น? ๐ค
๋๊ตฐ๊ฐ cli๋ฅผ ์ฌ์ฉํ์ฌ .vue ํ์ผ์ lintํ๋ ค๋ ๊ฒฝ์ฐ vue-tslint๋ฅผ ์๋ํ ์ ์์ต๋๋ค. ์๋ฒฝํ์ง๋ ์์ง๋ง ์๋ํฉ๋๋ค ...
@romandragan ์ ์๋ฃจ์
์ ์ด์ ๋ชจ๋ฒ ์ฌ๋ก๊ฐ ์๋๋๋ค(์ด์ ์๋ \.ts$
๊ท์น์ use
์ tslint-loader
๋ฅผ ์ถ๊ฐํ์ธ์. ์ด์ vue-loader
๋ ์ผ๋ฐ์ ์ผ๋ก ํ
ํ๋ฆฟ ํ์ผ์ ์ฒ๋ฆฌํ์ฌ ํด๋น ํ์ฅ์ ๋ํ Webpack ๊ตฌ์ฑ์ ๋ค๋ฅธ ์น์
์ ์์ํฉ๋๋ค. ์ ํ๋ฌ๊ทธ์ธ ๊ตฌ์ฑ ์์ vue-loader
๊ท์น ์ถ์ถํฉ๋๋ค \.ts$
ํ๊ณ ์คํธ๋ฆฌ๋ฐ <script lang="ts">
์ด ๊ท์น์ ํตํด ๋ธ๋ก์.
Vue CLI๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ถ๊ฐ
config.module.rule('ts')
.use('tslint-loader')
.loader('tslint-loader');
vue.config.js
์ chainWebpack
์ต์
์ ๋ํ ๋ช
์ธ์ ์๋ฅผ ๋ค์ด,
vue.config.js
module.exports = {
chainWebpack: (config) => {
config.devtool('source-map');
config.module.rule('ts')
.use('tslint-loader')
.loader('tslint-loader');
},
pluginOptions: {
apollo: {
enableMocks: true,
enableEngine: true
}
}
}
์ด๊ฒ์ ๋๋ฅผ ์ํด ์ผํ์ต๋๋ค.
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
module.exports = (baseConfig, env, defaultConfig) => {
defaultConfig.resolve.extensions.push('.ts', '.tsx', '.vue', '.css', '.less', '.scss', '.sass', '.html')
defaultConfig.module.rules.push( {
test: /\.ts$/,
exclude: /(node_modules)/,
use: [
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/]
// transpileOnly: true,
}
},
{
loader: 'tslint-loader',
options: {
configFile: 'tslint.json',
emitErrors: true,
}
}
]
})
defaultConfig.module.rules.push({ test: /\.less$/, loaders: [ 'style-loader', 'css-loader', 'less-loader' ] })
defaultConfig.module.rules.push({ test: /\.scss$/, loaders: [ 'style-loader', 'css-loader', 'sass-loader' ] })
defaultConfig.module.rules.push({ test: /\.styl$/, loader: 'style-loader!css-loader!stylus-loader' })
defaultConfig.plugins.push(new ForkTsCheckerWebpackPlugin())
return defaultConfig
}
#4379์ ๋ฐ๋ผ Vue ๊ด๋ จ ํด๊ฒฐ ๋ฐฉ๋ฒ์ TSLint ์ฝ์ด์ ์ฐฉ๋ฅํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ํ ๋ก ์ด๋ ๊ตฌ์ฒด์ ์ธ ์ ์์ด ์๊ณ ESLint(#4534)์ ์ฐฌ์ฑํ์ฌ TSLint๊ฐ ๊ณง ์ฌ์ฉ ์ค๋จ๋๋ค๋ ์ ์ ๊ฐ์ํ ๋ ์ด ๋ฌธ์ ์ ๊ด๋ จ Vue ๊ด๋ จ ๋ณด๊ณ ์๋ฅผ ์ ๋ฆฌ ๋ชฉ์ ์ผ๋ก ์ข ๋ฃํ๊ฒ ์ต๋๋ค.
์ด๊ฒ์ด ์ฌ์ ํ typescript-eslint ์์ ๋ฌธ์ ๋ผ๋ฉด ๊ฑฐ๊ธฐ์ ๋ฌธ์ ๋ฅผ ์ ์ถํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํ์ด์ ๋น๋๋ค!
./node_modules/.bin/wotan 'src/ */ .vue' -f ์์ธ
์ถฉ๋:
Error: ENOENT: no such file or directory, open '/home/andrew/PycharmProjects/djangochat/fe/src/components/App.vue.ts'
at Object.openSync (fs.js:451:3)
at detectEncoding (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:67:17)
at walk (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:49:20)
at Rule.AbstractRule.applyWithFunction (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/language/rule/abstractRule.js:39:9)
at Rule.apply (/home/andrew/PycharmProjects/djangochat/fe/node_modules/tslint/lib/rules/encodingRule.js:33:21)
at R.apply (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/bifrost/src/index.js:30:40)
at Linter.applyRules (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/linter.js:209:31)
at Linter.getFindings (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/linter.js:125:25)
at Runner.lintFiles (/home/andrew/PycharmProjects/djangochat/fe/node_modules/@fimbul/wotan/src/runner.js:159:43)
at lintFiles.next (<anonymous>) {
errno: -2,
syscall: 'open',
code: 'ENOENT',
path: '/home/andrew/PycharmProjects/djangochat/fe/src/components/App.vue.ts'
}
@akoidan tslint๊ฐ ์๋ wotan ํ๋ก์ ํธ์์ ๊ทธ๋ฐ ๋ฌธ์ ๋ฅผ ์ ๊ธฐํ์ญ์์ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ฌ๊ธฐ์ ๋ ๋ง์ ์์์ด ์์ต๋๊น? ๐ค