Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 

239 wiersze
11 KiB

  1. "use strict";
  2. var __assign = (this && this.__assign) || function () {
  3. __assign = Object.assign || function(t) {
  4. for (var s, i = 1, n = arguments.length; i < n; i++) {
  5. s = arguments[i];
  6. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  7. t[p] = s[p];
  8. }
  9. return t;
  10. };
  11. return __assign.apply(this, arguments);
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. var fs = require("fs");
  15. var path = require("path");
  16. var TypeScriptInstance_1 = require("./TypeScriptInstance");
  17. var VueProgram = /** @class */ (function () {
  18. function VueProgram() {
  19. }
  20. VueProgram.loadProgramConfig = function (typescript, configFile, compilerOptions) {
  21. var extraExtensions = ['vue'];
  22. var parseConfigHost = {
  23. fileExists: typescript.sys.fileExists,
  24. readFile: typescript.sys.readFile,
  25. useCaseSensitiveFileNames: typescript.sys.useCaseSensitiveFileNames,
  26. readDirectory: function (rootDir, extensions, excludes, includes, depth) {
  27. return typescript.sys.readDirectory(rootDir, extensions.concat(extraExtensions), excludes, includes, depth);
  28. }
  29. };
  30. var tsconfig = typescript.readConfigFile(configFile, typescript.sys.readFile).config;
  31. tsconfig.compilerOptions = tsconfig.compilerOptions || {};
  32. tsconfig.compilerOptions = __assign({}, tsconfig.compilerOptions, compilerOptions);
  33. var parsed = typescript.parseJsonConfigFileContent(tsconfig, parseConfigHost, path.dirname(configFile));
  34. parsed.options.allowNonTsExtensions = true;
  35. return parsed;
  36. };
  37. /**
  38. * Search for default wildcard or wildcard from options, we only search for that in tsconfig CompilerOptions.paths.
  39. * The path is resolved with thie given substitution and includes the CompilerOptions.baseUrl (if given).
  40. * If no paths given in tsconfig, then the default substitution is '[tsconfig directory]/src'.
  41. * (This is a fast, simplified inspiration of what's described here: https://github.com/Microsoft/TypeScript/issues/5039)
  42. */
  43. VueProgram.resolveNonTsModuleName = function (moduleName, containingFile, basedir, options) {
  44. var baseUrl = options.baseUrl ? options.baseUrl : basedir;
  45. var discardedSymbols = ['.', '..', '/'];
  46. var wildcards = [];
  47. if (options.paths) {
  48. Object.keys(options.paths).forEach(function (key) {
  49. var pathSymbol = key[0];
  50. if (discardedSymbols.indexOf(pathSymbol) < 0 &&
  51. wildcards.indexOf(pathSymbol) < 0) {
  52. wildcards.push(pathSymbol);
  53. }
  54. });
  55. }
  56. else {
  57. wildcards.push('@');
  58. }
  59. var isRelative = !path.isAbsolute(moduleName);
  60. var correctWildcard;
  61. wildcards.forEach(function (wildcard) {
  62. if (moduleName.substr(0, 2) === wildcard + "/") {
  63. correctWildcard = wildcard;
  64. }
  65. });
  66. if (correctWildcard) {
  67. var pattern = options.paths
  68. ? options.paths[correctWildcard + "/*"]
  69. : undefined;
  70. var substitution = pattern
  71. ? options.paths[correctWildcard + "/*"][0].replace('*', '')
  72. : 'src';
  73. moduleName = path.resolve(baseUrl, substitution, moduleName.substr(2));
  74. }
  75. else if (isRelative) {
  76. moduleName = path.resolve(path.dirname(containingFile), moduleName);
  77. }
  78. return moduleName;
  79. };
  80. VueProgram.isVue = function (filePath) {
  81. return path.extname(filePath) === '.vue';
  82. };
  83. VueProgram.createProgram = function (typescript, programConfig, basedir, files, watcher, oldProgram) {
  84. var host = typescript.createCompilerHost(programConfig.options);
  85. var realGetSourceFile = host.getSourceFile;
  86. // We need a host that can parse Vue SFCs (single file components).
  87. host.getSourceFile = function (filePath, languageVersion, onError) {
  88. // first check if watcher is watching file - if not - check it's mtime
  89. if (!watcher.isWatchingFile(filePath)) {
  90. try {
  91. var stats = fs.statSync(filePath);
  92. files.setMtime(filePath, stats.mtime.valueOf());
  93. }
  94. catch (e) {
  95. // probably file does not exists
  96. files.remove(filePath);
  97. }
  98. }
  99. // get source file only if there is no source in files register
  100. if (!files.has(filePath) || !files.getData(filePath).source) {
  101. files.mutateData(filePath, function (data) {
  102. data.source = realGetSourceFile(filePath, languageVersion, onError);
  103. });
  104. }
  105. var source = files.getData(filePath).source;
  106. // get typescript contents from Vue file
  107. if (source && VueProgram.isVue(filePath)) {
  108. var resolved = VueProgram.resolveScriptBlock(source.text);
  109. source = typescript.createSourceFile(filePath, resolved.content, languageVersion, true, resolved.scriptKind);
  110. }
  111. return source;
  112. };
  113. // We need a host with special module resolution for Vue files.
  114. host.resolveModuleNames = function (moduleNames, containingFile) {
  115. var resolvedModules = [];
  116. for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
  117. var moduleName = moduleNames_1[_i];
  118. // Try to use standard resolution.
  119. var resolvedModule = typescript.resolveModuleName(moduleName, containingFile, programConfig.options, {
  120. fileExists: function (fileName) {
  121. if (fileName.endsWith('.vue.ts')) {
  122. return (host.fileExists(fileName.slice(0, -3)) ||
  123. host.fileExists(fileName));
  124. }
  125. else {
  126. return host.fileExists(fileName);
  127. }
  128. },
  129. readFile: function (fileName) {
  130. // This implementation is not necessary. Just for consistent behavior.
  131. if (fileName.endsWith('.vue.ts') && !host.fileExists(fileName)) {
  132. return host.readFile(fileName.slice(0, -3));
  133. }
  134. else {
  135. return host.readFile(fileName);
  136. }
  137. }
  138. }).resolvedModule;
  139. if (resolvedModule) {
  140. if (resolvedModule.resolvedFileName.endsWith('.vue.ts') &&
  141. !host.fileExists(resolvedModule.resolvedFileName)) {
  142. resolvedModule.resolvedFileName = resolvedModule.resolvedFileName.slice(0, -3);
  143. }
  144. resolvedModules.push(resolvedModule);
  145. }
  146. else {
  147. // For non-ts extensions.
  148. var absolutePath = VueProgram.resolveNonTsModuleName(moduleName, containingFile, basedir, programConfig.options);
  149. if (VueProgram.isVue(moduleName)) {
  150. resolvedModules.push({
  151. resolvedFileName: absolutePath,
  152. extension: '.ts'
  153. });
  154. }
  155. else {
  156. resolvedModules.push({
  157. // If the file does exist, return an empty string (because we assume user has provided a ".d.ts" file for it).
  158. resolvedFileName: host.fileExists(absolutePath)
  159. ? ''
  160. : absolutePath,
  161. extension: '.ts'
  162. });
  163. }
  164. }
  165. }
  166. return resolvedModules;
  167. };
  168. return typescript.createProgram(programConfig.fileNames, programConfig.options, host, oldProgram // re-use old program
  169. );
  170. };
  171. VueProgram.getScriptKindByLang = function (lang) {
  172. if (lang === 'ts') {
  173. return TypeScriptInstance_1.ScriptKind.TS;
  174. }
  175. else if (lang === 'tsx') {
  176. return TypeScriptInstance_1.ScriptKind.TSX;
  177. }
  178. else if (lang === 'jsx') {
  179. return TypeScriptInstance_1.ScriptKind.JSX;
  180. }
  181. else {
  182. // when lang is "js" or no lang specified
  183. return TypeScriptInstance_1.ScriptKind.JS;
  184. }
  185. };
  186. VueProgram.resolveScriptBlock = function (content) {
  187. // We need to import vue-template-compiler lazily because it cannot be included it
  188. // as direct dependency because it is an optional dependency of fork-ts-checker-webpack-plugin.
  189. // Since its version must not mismatch with user-installed Vue.js,
  190. // we should let the users install vue-template-compiler by themselves.
  191. var parser;
  192. try {
  193. // tslint:disable-next-line
  194. parser = require('vue-template-compiler');
  195. }
  196. catch (err) {
  197. throw new Error('When you use `vue` option, make sure to install `vue-template-compiler`.');
  198. }
  199. var script = parser.parseComponent(content, {
  200. pad: 'space'
  201. }).script;
  202. // No <script> block
  203. if (!script) {
  204. return {
  205. scriptKind: TypeScriptInstance_1.ScriptKind.JS,
  206. content: '/* tslint:disable */\nexport default {};\n'
  207. };
  208. }
  209. var scriptKind = VueProgram.getScriptKindByLang(script.lang);
  210. // There is src attribute
  211. if (script.attrs.src) {
  212. // import path cannot be end with '.ts[x]'
  213. var src = script.attrs.src.replace(/\.tsx?$/i, '');
  214. return {
  215. scriptKind: scriptKind,
  216. // For now, ignore the error when the src file is not found
  217. // since it will produce incorrect code location.
  218. // It's not a large problem since it's handled on webpack side.
  219. content: '/* tslint:disable */\n' +
  220. '// @ts-ignore\n' +
  221. ("export { default } from '" + src + "';\n") +
  222. '// @ts-ignore\n' +
  223. ("export * from '" + src + "';\n")
  224. };
  225. }
  226. // Pad blank lines to retain diagnostics location
  227. // We need to prepend `//` for each line to avoid
  228. // false positive of no-consecutive-blank-lines TSLint rule
  229. var offset = content.slice(0, script.start).split(/\r?\n/g).length;
  230. var paddedContent = Array(offset).join('//\n') + script.content.slice(script.start);
  231. return {
  232. scriptKind: scriptKind,
  233. content: paddedContent
  234. };
  235. };
  236. return VueProgram;
  237. }());
  238. exports.VueProgram = VueProgram;