diff --git a/package.json b/package.json
index f615f728..e9d7000f 100644
--- a/package.json
+++ b/package.json
@@ -71,10 +71,10 @@
"ts-loader": "4.3.0",
"tslint": "^5.0.0",
"typescript": "^2.6.2",
- "vue": "^2.5.9",
+ "vue": "^2.5.16",
"vue-class-component": "^6.1.1",
"vue-loader": "^15.2.4",
- "vue-template-compiler": "^2.5.9",
+ "vue-template-compiler": "^2.5.16",
"webpack": "^4.0.0"
},
"peerDependencies": {
@@ -92,7 +92,6 @@
"lodash.startswith": "^4.2.1",
"minimatch": "^3.0.4",
"resolve": "^1.5.0",
- "tapable": "^1.0.0",
- "vue-parser": "^1.1.5"
+ "tapable": "^1.0.0"
}
}
diff --git a/src/VueProgram.ts b/src/VueProgram.ts
index fc6a78cd..b1ba72ef 100644
--- a/src/VueProgram.ts
+++ b/src/VueProgram.ts
@@ -3,7 +3,13 @@ import path = require('path');
import ts = require('typescript');
import FilesRegister = require('./FilesRegister');
import FilesWatcher = require('./FilesWatcher');
-import vueParser = require('vue-parser');
+// tslint:disable-next-line
+import vueCompiler = require('vue-template-compiler');
+
+interface ResolvedScript {
+ scriptKind: ts.ScriptKind;
+ content: string;
+}
class VueProgram {
static loadProgramConfig(configFile: string) {
@@ -85,19 +91,6 @@ class VueProgram {
const host = ts.createCompilerHost(programConfig.options);
const realGetSourceFile = host.getSourceFile;
- const getScriptKind = (lang: string) => {
- if (lang === "ts") {
- return ts.ScriptKind.TS;
- } else if (lang === "tsx") {
- return ts.ScriptKind.TSX;
- } else if (lang === "jsx") {
- return ts.ScriptKind.JSX;
- } else {
- // when lang is "js" or no lang specified
- return ts.ScriptKind.JS;
- }
- }
-
// We need a host that can parse Vue SFCs (single file components).
host.getSourceFile = (filePath, languageVersion, onError) => {
// first check if watcher is watching file - if not - check it's mtime
@@ -123,21 +116,8 @@ class VueProgram {
// get typescript contents from Vue file
if (source && VueProgram.isVue(filePath)) {
- let parsed: string;
- let kind: ts.ScriptKind;
- for (const lang of ['ts', 'tsx', 'js', 'jsx']) {
- parsed = vueParser.parse(source.text, 'script', { lang: [lang], emptyExport: false });
- if (parsed) {
- kind = getScriptKind(lang);
- break;
- }
- }
- if (!parsed) {
- // when script tag has no lang, or no script tag given
- parsed = vueParser.parse(source.text, 'script');
- kind = ts.ScriptKind.JS;
- }
- source = ts.createSourceFile(filePath, parsed, languageVersion, true, kind);
+ const resolved = VueProgram.resolveScriptBlock(source.text);
+ source = ts.createSourceFile(filePath, resolved.content, languageVersion, true, resolved.scriptKind);
}
return source;
@@ -201,6 +181,70 @@ class VueProgram {
oldProgram // re-use old program
);
}
+
+ private static getScriptKindByLang(lang: string) {
+ if (lang === "ts") {
+ return ts.ScriptKind.TS;
+ } else if (lang === "tsx") {
+ return ts.ScriptKind.TSX;
+ } else if (lang === "jsx") {
+ return ts.ScriptKind.JSX;
+ } else {
+ // when lang is "js" or no lang specified
+ return ts.ScriptKind.JS;
+ }
+ }
+
+ private static resolveScriptBlock(content: string): ResolvedScript {
+ // We need to import vue-template-compiler lazily because it cannot be included it
+ // as direct dependency because it is an optional dependency of fork-ts-checker-webpack-plugin.
+ // Since its version must not mismatch with user-installed Vue.js,
+ // we should let the users install vue-template-compiler by themselves.
+ let parser: typeof vueCompiler;
+ try {
+ // tslint:disable-next-line
+ parser = require('vue-template-compiler');
+ } catch (err) {
+ throw new Error('When you use `vue` option, make sure to install `vue-template-compiler`.');
+ }
+
+ const { script } = parser.parseComponent(content, {
+ pad: 'line'
+ });
+
+ // No
diff --git a/test/integration/vue/src/attrs/Test.vue b/test/integration/vue/src/attrs/Test.vue
new file mode 100644
index 00000000..046d2f23
--- /dev/null
+++ b/test/integration/vue/src/attrs/Test.vue
@@ -0,0 +1 @@
+
diff --git a/test/integration/vue/src/attrs/test.ts b/test/integration/vue/src/attrs/test.ts
new file mode 100644
index 00000000..5987f2ec
--- /dev/null
+++ b/test/integration/vue/src/attrs/test.ts
@@ -0,0 +1,2 @@
+const a: number = "";
+export default { a }
diff --git a/test/integration/vue/tsconfig-attrs.json b/test/integration/vue/tsconfig-attrs.json
new file mode 100644
index 00000000..2bdc66c5
--- /dev/null
+++ b/test/integration/vue/tsconfig-attrs.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {},
+ "include": [
+ "src/attrs/Test.vue",
+ "src/attrs/NotFound.vue"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/test/unit/VueProgram.spec.js b/test/unit/VueProgram.spec.js
index f0aedaa8..985a3740 100644
--- a/test/unit/VueProgram.spec.js
+++ b/test/unit/VueProgram.spec.js
@@ -47,7 +47,7 @@ describe('[UNIT] VueProgram', function () {
var options = {};
var moduleName = '@/test.vue';
- resolvedModuleName = VueProgram.resolveNonTsModuleName(moduleName, containingFile, basedir, options);
+ var resolvedModuleName = VueProgram.resolveNonTsModuleName(moduleName, containingFile, basedir, options);
expect(resolvedModuleName).to.be.equal('/base/dir/src/test.vue');
options.baseUrl = '/baseurl1';
diff --git a/yarn.lock b/yarn.lock
index b5859ff8..a1593eea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2882,12 +2882,6 @@ parse-glob@^3.0.4:
is-extglob "^1.0.0"
is-glob "^2.0.0"
-parse5@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
- dependencies:
- "@types/node" "*"
-
pascalcase@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
@@ -4210,12 +4204,6 @@ vue-loader@^15.2.4:
vue-hot-reload-api "^2.3.0"
vue-style-loader "^4.1.0"
-vue-parser@^1.1.5:
- version "1.1.6"
- resolved "https://registry.yarnpkg.com/vue-parser/-/vue-parser-1.1.6.tgz#3063c8431795664ebe429c23b5506899706e6355"
- dependencies:
- parse5 "^3.0.3"
-
vue-style-loader@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.0.tgz#7588bd778e2c9f8d87bfc3c5a4a039638da7a863"
@@ -4223,9 +4211,9 @@ vue-style-loader@^4.1.0:
hash-sum "^1.0.2"
loader-utils "^1.0.2"
-vue-template-compiler@^2.5.9:
- version "2.5.13"
- resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.13.tgz#12a2aa0ecd6158ac5e5f14d294b0993f399c3d38"
+vue-template-compiler@^2.5.16:
+ version "2.5.16"
+ resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.16.tgz#93b48570e56c720cdf3f051cc15287c26fbd04cb"
dependencies:
de-indent "^1.0.2"
he "^1.1.0"
@@ -4234,9 +4222,9 @@ vue-template-es2015-compiler@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
-vue@^2.5.9:
- version "2.5.13"
- resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.13.tgz#95bd31e20efcf7a7f39239c9aa6787ce8cf578e1"
+vue@^2.5.16:
+ version "2.5.16"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
watchpack@^1.4.0:
version "1.4.0"