Skip to content

tns-core-modules path mapping #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions bin/ns-upgrade-tsconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env node
var path = require("path");
var upgrader = require("../tsconfig-upgrader");

var projectDir = path.dirname(path.dirname(path.dirname(__dirname)));
var tsConfigPath = path.join(projectDir, "tsconfig.json");
upgrader.migrateTsConfig(tsConfigPath, projectDir);
1 change: 1 addition & 0 deletions bin/ns-upgrade-tsconfig.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@node %~dp0\ns-upgrade-tsconfig %*
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{
"name": "nativescript-dev-typescript",
"version": "0.4.1",
"version": "0.4.2",
"description": "TypeScript support for NativeScript projects. Install using `tns install typescript`.",
"scripts": {
"test": "exit 0",
"postinstall": "node postinstall.js",
"preuninstall": "node preuninstall.js"
},
"bin": {
"ns-upgrade-tsconfig": "./bin/ns-upgrade-tsconfig"
},
"nativescript": {
"hooks": [
{
Expand Down
110 changes: 7 additions & 103 deletions postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,126 +3,31 @@ hook.postinstall();

var fs = require("fs");
var path = require("path");

var __migrations = [
inlineSourceMapMigration,
addDomLibs,
addIterableToAngularProjects,
];

var upgrader = require("./tsconfig-upgrader");

var projectDir = hook.findProjectDir();
if (projectDir) {
var tsconfigPath = path.join(projectDir, "tsconfig.json");
if (fs.existsSync(tsconfigPath)) {
migrateTsconfig(tsconfigPath);
upgrader.migrateTsConfig(tsconfigPath, projectDir);
} else {
createTsconfig(tsconfigPath);
}
createReferenceFile();
if (!upgrader.hasModules30(projectDir)) {
createReferenceFile();
}
installTypescript();
}

function createReferenceFile() {
var referenceFilePath = path.join(projectDir, "references.d.ts"),
content = '/// <reference path="./node_modules/tns-core-modules/tns-core-modules.d.ts" /> Needed for autocompletion and compilation.';
content = "/// <reference path=\"./node_modules/tns-core-modules/tns-core-modules.d.ts\" /> Needed for autocompletion and compilation.";

if (!fs.existsSync(referenceFilePath)) {
fs.appendFileSync(referenceFilePath, content);
}
}

function inlineSourceMapMigration(existingConfig, displayableTsconfigPath) {
if (existingConfig.compilerOptions) {
if ("sourceMap" in existingConfig["compilerOptions"]) {
delete existingConfig["compilerOptions"]["sourceMap"];
console.warn("> Deleted \"compilerOptions.sourceMap\" setting in \"" + displayableTsconfigPath + "\".");
console.warn("> Inline source maps will be used when building in Debug configuration from now on.");
}
}
}

function addIterableToAngularProjects(existingConfig) {
var packageJsonPath = path.join(projectDir, "package.json");
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
var dependencies = packageJson.dependencies || [];

var hasAngular = Object.keys(dependencies).includes("nativescript-angular");
var hasRelevantAngularVersion = /[4-9]\.\d+\.\d+/i.test(dependencies["@angular/core"]);
if (hasAngular && hasRelevantAngularVersion) {
console.log("Adding 'es2015.iterable' lib to tsconfig.json...");
addTsLib(existingConfig, "es2015.iterable");
}
}

function addDomLibs(existingConfig) {
function relevantModulesVersion(version) {
return /[3-9]\.\d+\.\d+/i.test(version);
}

function hasRelevantModulesDependency() {
var packageJsonPath = path.join(projectDir, "package.json");
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
var dependencies = packageJson.dependencies || [];

return relevantModulesVersion(dependencies["tns-core-modules"]);
}

function hasRelevantModulesPackage() {
var packageJsonPath = path.join(projectDir, "node_modules", "tns-core-modules", "package.json");
if (!fs.existsSync(packageJsonPath)) {
return false;
}

var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
return relevantModulesVersion(packageJson.version);
}

if (hasRelevantModulesDependency() || hasRelevantModulesPackage()) {
console.log("Adding 'es6' lib to tsconfig.json...");
addTsLib(existingConfig, "es6");
console.log("Adding 'dom' lib to tsconfig.json...");
addTsLib(existingConfig, "dom");
}
}

function addTsLib(existingConfig, libName) {
if (existingConfig.compilerOptions) {
var options = existingConfig.compilerOptions;
if (!options.lib) {
options.lib = [];
}
if (!options.lib.find(function(l) {
return libName.toLowerCase() === l.toLowerCase();
})) {
options.lib.push(libName);
}
}
}

function migrateTsconfig(tsconfigPath) {
var displayableTsconfigPath = path.relative(projectDir, tsconfigPath);

function withTsConfig(action) {
var existingConfig = null;
try {
var existingConfigContents = fs.readFileSync(tsconfigPath);
existingConfig = JSON.parse(existingConfigContents);
} catch (e) {
console.error("Invalid " + displayableTsconfigPath + ": " + e);
return;
}
action(existingConfig);
fs.writeFileSync(tsconfigPath, JSON.stringify(existingConfig, null, 4));
}

withTsConfig(function(existingConfig) {
__migrations.forEach(function(migration) {
migration(existingConfig, displayableTsconfigPath);
});
});
}

function createTsconfig(tsconfigPath) {
var tsconfig = {};

Expand All @@ -134,8 +39,7 @@ function createTsconfig(tsconfigPath) {
noEmitHelpers: true,
noEmitOnError: true,
};
addDomLibs(tsconfig);
addIterableToAngularProjects(tsconfig);
upgrader.migrateProject(tsconfig, tsconfigPath, projectDir);

tsconfig.exclude = ["node_modules", "platforms", "**/*.aot.ts"];

Expand Down
126 changes: 126 additions & 0 deletions tsconfig-upgrader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
var fs = require("fs");
var path = require("path");

var __migrations = [
inlineSourceMapMigration,
addDomLibs,
addIterableToAngularProjects,
addTnsCoreModulesPathMappings,
];

function migrateProject(tsConfig, tsconfigPath, projectDir) {
var displayableTsconfigPath = path.relative(projectDir, tsconfigPath);
__migrations.forEach(function(migration) {
migration(tsConfig, displayableTsconfigPath, projectDir);
});
}
exports.migrateProject = migrateProject;

function migrateTsConfig(tsconfigPath, projectDir) {
var displayableTsconfigPath = path.relative(projectDir, tsconfigPath);

function withTsConfig(action) {
var existingConfig = null;
try {
var existingConfigContents = fs.readFileSync(tsconfigPath);
existingConfig = JSON.parse(existingConfigContents);
} catch (e) {
console.error("Invalid " + displayableTsconfigPath + ": " + e);
return;
}
action(existingConfig);
fs.writeFileSync(tsconfigPath, JSON.stringify(existingConfig, null, 4));
}

withTsConfig(function(existingConfig) {
migrateProject(existingConfig, displayableTsconfigPath, projectDir);
});
}
exports.migrateTsConfig = migrateTsConfig;

function inlineSourceMapMigration(existingConfig, displayableTsconfigPath) {
if (existingConfig.compilerOptions) {
if ("sourceMap" in existingConfig["compilerOptions"]) {
delete existingConfig["compilerOptions"]["sourceMap"];
console.warn("> Deleted \"compilerOptions.sourceMap\" setting in \"" + displayableTsconfigPath + "\".");
console.warn("> Inline source maps will be used when building in Debug configuration from now on.");
}
}
}

function addIterableToAngularProjects(existingConfig, displayableTsconfigPath, projectDir) {
var packageJsonPath = path.join(projectDir, "package.json");
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
var dependencies = packageJson.dependencies || [];

var hasAngular = Object.keys(dependencies).includes("nativescript-angular");
var hasRelevantAngularVersion = /[4-9]\.\d+\.\d+/i.test(dependencies["@angular/core"]);
if (hasAngular && hasRelevantAngularVersion) {
console.log("Adding 'es2015.iterable' lib to tsconfig.json...");
addTsLib(existingConfig, "es2015.iterable");
}
}

function hasModules30(projectDir) {
function relevantModulesVersion(version) {
return /[3-9]\.\d+\.\d+/i.test(version);
}

function hasRelevantModulesDependency() {
var packageJsonPath = path.join(projectDir, "package.json");
var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
var dependencies = packageJson.dependencies || [];

return relevantModulesVersion(dependencies["tns-core-modules"]);
}

function hasRelevantModulesPackage() {
var packageJsonPath = path.join(projectDir, "node_modules", "tns-core-modules", "package.json");
if (!fs.existsSync(packageJsonPath)) {
return false;
}

var packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
return relevantModulesVersion(packageJson.version);
}

return hasRelevantModulesDependency() || hasRelevantModulesPackage();
}
exports.hasModules30 = hasModules30;

function addDomLibs(existingConfig, displayableTsconfigPath, projectDir) {
if (hasModules30(projectDir)) {
console.log("Adding 'es6' lib to tsconfig.json...");
addTsLib(existingConfig, "es6");
console.log("Adding 'dom' lib to tsconfig.json...");
addTsLib(existingConfig, "dom");
}
}

function addTsLib(existingConfig, libName) {
if (existingConfig.compilerOptions) {
var options = existingConfig.compilerOptions;
if (!options.lib) {
options.lib = [];
}
if (!options.lib.find(function(l) {
return libName.toLowerCase() === l.toLowerCase();
})) {
options.lib.push(libName);
}
}
}

function addTnsCoreModulesPathMappings(existingConfig, displayableTsconfigPath, projectDir) {
if (hasModules30(projectDir)) {
console.log("Adding tns-core-modules path mappings lib to tsconfig.json...");
existingConfig["compilerOptions"] = existingConfig["compilerOptions"] || {};
var compilerOptions = existingConfig["compilerOptions"];
compilerOptions["baseUrl"] = ".";
compilerOptions["paths"] = compilerOptions["paths"] || {};
compilerOptions["paths"]["*"] = [
"./node_modules/tns-core-modules/*",
"./node_modules/*"
];
}
}