diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 247a204e9bdb2..733e3158593df 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -493,8 +493,8 @@ namespace ts { * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ - export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}): ParsedCommandLine { - const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath); + export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine { + const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName); const options = extend(existingOptions, optionsFromJsonConfigFile); return { @@ -523,7 +523,7 @@ namespace ts { for (const extension of supportedExtensions) { const filesInDirWithExtension = host.readDirectory(basePath, extension, exclude); for (const fileName of filesInDirWithExtension) { - // .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension, + // .ts extension would read the .d.ts extension files too but since .d.ts is lower priority extension, // lets pick them when its turn comes up if (extension === ".ts" && fileExtensionIs(fileName, ".d.ts")) { continue; @@ -547,10 +547,15 @@ namespace ts { } } - export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string): { options: CompilerOptions, errors: Diagnostic[] } { + export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } { const options: CompilerOptions = {}; const errors: Diagnostic[] = []; + if (configFileName && getBaseFileName(configFileName) === "jsconfig.json") { + options.module = ModuleKind.CommonJS; + options.allowJs = true; + } + if (!jsonOptions) { return { options, errors }; } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 808ee6da8046d..9b2457d091692 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -340,7 +340,7 @@ namespace ts { if (sys.watchDirectory && configFileName) { const directory = ts.getDirectoryPath(configFileName); directoryWatcher = sys.watchDirectory( - // When the configFileName is just "tsconfig.json", the watched directory should be + // When the configFileName is just "tsconfig.json", the watched directory should be // the current direcotry; if there is a given "project" parameter, then the configFileName // is an absolute file name. directory == "" ? "." : directory, diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 7cc3a6c96a67c..e2ec5cc159f8f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -120,7 +120,7 @@ namespace ts.server { if (!resolution) { const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName); if (moduleResolutionIsValid(existingResolution)) { - // ok, it is safe to use existing module resolution results + // ok, it is safe to use existing module resolution results resolution = existingResolution; } else { @@ -145,8 +145,8 @@ namespace ts.server { } if (resolution.resolvedModule) { - // TODO: consider checking failedLookupLocations - // TODO: use lastCheckTime to track expiration for module name resolution + // TODO: consider checking failedLookupLocations + // TODO: use lastCheckTime to track expiration for module name resolution return true; } @@ -483,7 +483,7 @@ namespace ts.server { openFileRootsConfigured: ScriptInfo[] = []; // a path to directory watcher map that detects added tsconfig files directoryWatchersForTsconfig: ts.Map = {}; - // count of how many projects are using the directory watcher. If the + // count of how many projects are using the directory watcher. If the // number becomes 0 for a watcher, then we should close it. directoryWatchersRefCount: ts.Map = {}; hostConfiguration: HostConfiguration; @@ -564,11 +564,11 @@ namespace ts.server { // We check if the project file list has changed. If so, we update the project. if (!arrayIsEqualTo(currentRootFiles && currentRootFiles.sort(), newRootFiles && newRootFiles.sort())) { // For configured projects, the change is made outside the tsconfig file, and - // it is not likely to affect the project for other files opened by the client. We can + // it is not likely to affect the project for other files opened by the client. We can // just update the current project. this.updateConfiguredProject(project); - // Call updateProjectStructure to clean up inferred projects we may have + // Call updateProjectStructure to clean up inferred projects we may have // created for the new files this.updateProjectStructure(); } @@ -792,8 +792,8 @@ namespace ts.server { * @param info The file that has been closed or newly configured */ closeOpenFile(info: ScriptInfo) { - // Closing file should trigger re-reading the file content from disk. This is - // because the user may chose to discard the buffer content before saving + // Closing file should trigger re-reading the file content from disk. This is + // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. info.svc.reloadFromFile(info.fileName); @@ -891,8 +891,8 @@ namespace ts.server { } /** - * This function is to update the project structure for every projects. - * It is called on the premise that all the configured projects are + * This function is to update the project structure for every projects. + * It is called on the premise that all the configured projects are * up to date. */ updateProjectStructure() { @@ -946,7 +946,7 @@ namespace ts.server { if (rootFile.defaultProject && rootFile.defaultProject.isConfiguredProject()) { // If the root file has already been added into a configured project, - // meaning the original inferred project is gone already. + // meaning the original inferred project is gone already. if (!rootedProject.isConfiguredProject()) { this.removeProject(rootedProject); } @@ -1026,10 +1026,16 @@ namespace ts.server { // the newly opened file. findConfigFile(searchPath: string): string { while (true) { - const fileName = ts.combinePaths(searchPath, "tsconfig.json"); - if (this.host.fileExists(fileName)) { - return fileName; + const tsconfigFileName = ts.combinePaths(searchPath, "tsconfig.json"); + if (this.host.fileExists(tsconfigFileName)) { + return tsconfigFileName; + } + + const jsconfigFileName = ts.combinePaths(searchPath, "jsconfig.json"); + if (this.host.fileExists(jsconfigFileName)) { + return jsconfigFileName; } + const parentPath = ts.getDirectoryPath(searchPath); if (parentPath === searchPath) { break; @@ -1053,9 +1059,9 @@ namespace ts.server { } /** - * This function tries to search for a tsconfig.json for the given file. If we found it, + * This function tries to search for a tsconfig.json for the given file. If we found it, * we first detect if there is already a configured project created for it: if so, we re-read - * the tsconfig file content and update the project; otherwise we create a new one. + * the tsconfig file content and update the project; otherwise we create a new one. */ openOrUpdateConfiguredProjectForFile(fileName: string) { const searchPath = ts.normalizePath(getDirectoryPath(fileName)); @@ -1180,7 +1186,7 @@ namespace ts.server { return { succeeded: false, error: rawConfig.error }; } else { - const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath); + const parsedCommandLine = ts.parseJsonConfigFileContent(rawConfig.config, this.host, dirPath, /*existingOptions*/ {}, configFilename); Debug.assert(!!parsedCommandLine.fileNames); if (parsedCommandLine.errors && (parsedCommandLine.errors.length > 0)) { @@ -1259,7 +1265,7 @@ namespace ts.server { info = this.openFile(fileName, /*openedByClient*/ false); } else { - // if the root file was opened by client, it would belong to either + // if the root file was opened by client, it would belong to either // openFileRoots or openFileReferenced. if (info.isOpen) { if (this.openFileRoots.indexOf(info) >= 0) { diff --git a/src/services/shims.ts b/src/services/shims.ts index 3dc28763b1769..9ca3f19244d89 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -946,7 +946,8 @@ namespace ts { }; } - const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizeSlashes(fileName))); + const normalizedFileName = normalizeSlashes(fileName); + const configFile = parseJsonConfigFileContent(result.config, this.host, getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); return { options: configFile.options,