diff --git a/CHANGELOG.md b/CHANGELOG.md index 99a7a60d..693e7c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ + +## [0.20.1](https://github.com/NativeScript/nativescript-dev-webpack/compare/0.20.0...0.20.1) (2019-02-18) + + +### Bug Fixes + +* add a typescript module resolution when searching for the main Angular module location ([#800](https://github.com/NativeScript/nativescript-dev-webpack/issues/800)) ([e2714f2](https://github.com/NativeScript/nativescript-dev-webpack/commit/e2714f2)) + + +### Features + +* allow angular resolver configuration via webpack.config ([4f3e8a6](https://github.com/NativeScript/nativescript-dev-webpack/commit/4f3e8a6)) +* backwards compatible angular resolver options ([c9fc731](https://github.com/NativeScript/nativescript-dev-webpack/commit/c9fc731)) + + + -# [0.20.0](https://github.com/NativeScript/nativescript-dev-webpack/compare/0.18.3...0.20.0) (2019-02-08) +# [0.20.0](https://github.com/NativeScript/nativescript-dev-webpack/compare/0.19.2...0.20.0) (2019-02-08) ### Bug Fixes diff --git a/host/resolver.ts b/host/resolver.ts index 30d8c7a0..6cff232c 100644 --- a/host/resolver.ts +++ b/host/resolver.ts @@ -1,13 +1,10 @@ import { parse, join } from "path"; import { statSync } from "fs"; -export function getResolver(platforms: string[], explicitResolve: string[] = []) { - const platformSpecificExt = [".ts", ".js", ".scss", ".less", ".css", ".html", ".xml", ".vue", ".json"]; - const nsPackageFilters = [ - 'nativescript', - 'tns', - 'ns' - ]; +export function getResolver(platforms: string[], explicitResolve?: string[], nsPackageFilters?: string[], platformSpecificExt?: string[]) { + explicitResolve = explicitResolve || []; + nsPackageFilters = nsPackageFilters || ['nativescript', 'tns', 'ns']; + platformSpecificExt = platformSpecificExt || [".ts", ".js", ".scss", ".less", ".css", ".html", ".xml", ".vue", ".json"]; return function (path: string) { const nmIndex = path.lastIndexOf('node_modules'); @@ -16,7 +13,7 @@ export function getResolver(platforms: string[], explicitResolve: string[] = []) const subPath = path.substr(nmIndex + 'node_modules'.length).replace(/\\/g, '/'); const shouldResolve = explicitResolve.length && explicitResolve.some(packageName => subPath.indexOf(packageName) !== -1); const pathParts = subPath.split(/[/\-_]/); - + if (!shouldResolve && pathParts.every(p => nsPackageFilters.every(f => f !== p))) { return path; } diff --git a/templates/webpack.angular.js b/templates/webpack.angular.js index f5a97343..d244b5d6 100644 --- a/templates/webpack.angular.js +++ b/templates/webpack.angular.js @@ -51,7 +51,7 @@ module.exports = env => { const externals = nsWebpack.getConvertedExternals(env.externals); const appFullPath = resolve(projectRoot, appPath); const appResourcesFullPath = resolve(projectRoot, appResourcesPath); - + const tsConfigName = "tsconfig.tns.json"; const entryModule = `${nsWebpack.getEntryModule(appFullPath)}.ts`; const entryPath = `.${sep}${entryModule}`; const entries = { bundle: entryPath }; @@ -73,7 +73,7 @@ module.exports = env => { // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes // fixes https://github.com/NativeScript/nativescript-cli/issues/4024 if (env.externals && env.externals.indexOf("@angular/core") > -1) { - const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule)); + const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule), tsConfigName); if (appModuleRelativePath) { const appModuleFolderPath = dirname(resolve(appFullPath, appModuleRelativePath)); // include the lazy loader inside app module @@ -87,7 +87,7 @@ module.exports = env => { hostReplacementPaths: nsWebpack.getResolver([platform, "tns"]), platformTransformers: ngCompilerTransformers.map(t => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule))), mainPath: resolve(appPath, entryModule), - tsConfigPath: join(__dirname, "tsconfig.tns.json"), + tsConfigPath: join(__dirname, tsConfigName), skipCodeGeneration: !aot, sourceMap: !!sourceMap, additionalLazyModuleResources: additionalLazyModuleResources diff --git a/utils/ast-utils.ts b/utils/ast-utils.ts index a98c53de..88660b86 100644 --- a/utils/ast-utils.ts +++ b/utils/ast-utils.ts @@ -14,19 +14,62 @@ // example of a working workaround by searching for content in each parent. // 4) Always test your transformer both single and in combinations with the other ones. -import { dirname, join } from "path"; +import { dirname, join, relative } from "path"; import * as ts from "typescript"; import { readFileSync, existsSync } from "fs"; import { collectDeepNodes } from "@ngtools/webpack/src/transformers"; -export function getMainModulePath(entryFilePath) { +export function getMainModulePath(entryFilePath: string, tsConfigName: string) { try { - return findBootstrappedModulePath(entryFilePath); + // backwards compatibility + tsConfigName = tsConfigName || "tsconfig.tns.json"; + + const tsModuleName = findBootstrappedModulePath(entryFilePath); + const result = tsResolve(tsModuleName, entryFilePath, tsConfigName); + + return result; } catch (e) { return null; } } +/** + * Returns the real path to the ts/d.ts of the specified `moduleName` relative to the specified `containingFilePath`. (e.g. `~/app/file` -> `./app/file.ts`) + * @param moduleName The name of the module to be resolved (e.g. `~/config.js`, `lodash`, `./already-relative.js`, `@custom-path/file`). + * @param containingFilePath An absolute path to the file where the `moduleName` is imported. The relative result will be based on this file. + * @param tsConfigName The name of the tsconfig which will be used during the module resolution (e.g. `tsconfig.json`). + * We need this config in order to get its compiler options into account (e.g. resolve any custom `paths` like `~` or `@src`). + */ +function tsResolve(moduleName: string, containingFilePath: string, tsConfigName: string) { + let result = moduleName; + try { + const parseConfigFileHost: ts.ParseConfigFileHost = { + getCurrentDirectory: ts.sys.getCurrentDirectory, + useCaseSensitiveFileNames: false, + readDirectory: ts.sys.readDirectory, + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + onUnRecoverableConfigFileDiagnostic: undefined + }; + + const tsConfig = ts.getParsedCommandLineOfConfigFile(tsConfigName, ts.getDefaultCompilerOptions(), parseConfigFileHost); + + const compilerOptions: ts.CompilerOptions = tsConfig.options || ts.getDefaultCompilerOptions(); + const moduleResolutionHost: ts.ModuleResolutionHost = { + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile + }; + + const resolutionResult = ts.resolveModuleName(moduleName, containingFilePath, compilerOptions, moduleResolutionHost); + + if (resolutionResult && resolutionResult.resolvedModule && resolutionResult.resolvedModule.resolvedFileName) { + result = relative(dirname(containingFilePath), resolutionResult.resolvedModule.resolvedFileName); + } + } catch (err) { } + + return result; +} + export function findBootstrapModuleCall(mainPath: string): ts.CallExpression | null { const source = getSourceFile(mainPath);