Skip to content

outDir option does not copy the ts files #6435

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

Closed
varghesep opened this issue Jan 11, 2016 · 8 comments
Closed

outDir option does not copy the ts files #6435

varghesep opened this issue Jan 11, 2016 · 8 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@varghesep
Copy link

The tsconfig.json file in my project looks like below. I have outDir set to wwwroot/app. This option copies the js files and the map files. See the picture.

But this outDir option does not copy the sources (ts files from where js files are generated) to the wwwroot/app directory, so the debugging can't be done in IE or any browser.

Is this a bug, or should I set some other option to make it work? Or should I use gulp task to copy the source files?

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "module": "system",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "classic",
    "outDir": "wwwroot/app"
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

ts_files

@kitsonk
Copy link
Contributor

kitsonk commented Jan 11, 2016

It is not designed to copy the source files. If you want the source files available, you should do as you suggested and copy them external to the tsc compiler.

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Jan 11, 2016
@mhegazy mhegazy closed this as completed Jan 11, 2016
@JohnGalt1717
Copy link

Here's the issue with the way typescript is working in Visual Studio 2015 right now with and without the outDir when working with ASPNET5 (sorry, core!)

  1. If you follow best practices and put your .ts files in a separate directory outside of the wwwroot then your .js and .js.map files are in that directory. Which would be fine, use gulp and watch and copy them into the final location. Except then the .js.map points to the wrong location and debugging doesn't work properly. And I have yet to find any rewrite that I can do the relative paths with properly in gulp. Thus this is a no-go.
  2. If you use outDir and you have any other dependencies that are in a different relative sub folder because it comes from another solution (i.e. your api generating typescript interfaces for objects) then outDir goes and creates a silly pathing under whatever you put in outDir.

Oddly, if you use gulp and use outdir instead of outDir then you get the pathing you would expect and it works normally, but then you have to use gulp to compile typescript instead of Visual Studio, and then watch for changes to .ts files to try and get it to compile on save, which is a mess and it doesn't error in a useful way (i.e. they're not in the error window) and doesn't stop execution of your app in debug when there is an error so you're wondering why your typescript changes had no effect.

In short this is a mess right now that needs to be fixed because as it stands the only viable alternative is to put your typescript files in the wwwroot which is a bad solution.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 27, 2016

@JohnGalt1717, i d not think your commments are related to the OP.

For outDir computation, if you only specify --outDir the output structure generated by the compiler is mapped to the input, this is based on a common path calculation, which is the longest common prefix of all your input files. Obviouslly this changes with the input files, so to tell the compiler what is the root of your source tree that you want mapped in the output, use --rootDir.

For map files, you do not need to move them along with the js files. use --mapRoot to tell your debugger where to find them, this can be a local path, or a UNC file path, or even a web address.

If you do move the map files, but now the reference to the sources files are wrong, use --sourceRoot to specify the location of the sources. again this can be a local file path, or a web address.

hope that helps.

@JohnGalt1717
Copy link

Here's my structure:

/wwwroot/app <= this is the destination for the js and map files. (with full hierarchy of ./controllers, ./directives etc.)

/scripts/ <= this is the source of the ts files. (with a full hierarchy of ./controllers, ./directives etc.)

using Vs.net 2015 Update 1 with ASPNET 5 RC1 Update 1 please explain how these options can compile the .ts files from the /scripts/ folder into the /wwwroot/app folder properly with the .map files pointing to the right .ts files so that everything will work in IE and Chrome to debug into the .ts files.

And note that the /scripts/*.ts files have a reference at the top that points to something in ../..//scripts/Interfaces.ts and it shouldn't be copied over at all because it's out of the project and it shouldn't effect the pathing that is created in the /wwwroot/app folder.

Anyone doing strong typing from their API to their angular or other app using ts (huge win for testability and reliability by doing this so everyone should be doing this) will have a similar structure so it needs to be supported.

If you use outdir instead of outDir using gulp and TSC it will compile them into the right spots and even the map files will be right. However this isn't recognized by VS.net as a valid param in the tsconfig file and thus can't be used (it just ignores it and compiles to the same directory)

@mhegazy
Copy link
Contributor

mhegazy commented Jan 27, 2016

/wwwroot/app <= this is the destination for the js and map files. (with full hierarchy of ./controllers, ./directives etc.)

/scripts/ <= this is the source of the ts files. (with a full hierarchy of ./controllers, ./directives etc.)

using Vs.net 2015 Update 1 with ASPNET 5 RC1 Update 1 please explain how these options can compile the .ts files from the /scripts/ folder into the /wwwroot/app folder properly with the .map files pointing to the right .ts files so that everything will work in IE and Chrome to debug into the .ts files.

set config to be:

{
    "compilerOptions": {
        "outDir": "./wwwroot/app", // put output in /wwwroot/app
        "rootDir": "./scripts" // all inputs are under /scripts
    }
}

And note that the /scripts/*.ts files have a reference at the top that points to something in ../..//scripts/Interfaces.ts and it shouldn't be copied over at all because it's out of the project and it shouldn't effect the path that is created in the /wwwroot/app folder.

That is the problem here. interfaces.ts should be interfaces.d.ts, to tell the compiler that there is no output for it. if it is a .ts file, the compiler has to generate a file for it, and it does not know where to put it at this point, since it does not fit under the rootDir.

Having said that, if gulp is working fine for you, i do not see why you can not use it. TypeScript compiler is not meant to be a build system. Similarly VS is an IDE, it has build integration with MSBuild, but you can use any other build system that works for you with the Task Runner Explorer.

@JohnGalt1717
Copy link

This creates a folder under /wwwroot/app with the project name/src/project name/scripts/ instead of them being deployed in the /wwwroot/app folder itself.

This is the issue endlessly and useing outdir instead of outDir is just a hack because it isn't even supported.

Further, there is no guidance on how gulp should be setup for typescript to work properly and get compile on save, and incremental compile instead of always compile and if you setup watches it fails for bizzare reasons etc.

It shouldn't be this hard to use a basic tool like typescript in aspnetcore. Hence why I went back to using msbuild and vs.net's settings for it, but then it's borked completely.

The problem with using .d.ts is that it isn't just definitions and if I make it add definitions then in that project I get endless compile failures because of everything being defined twice.

@mhegazy
Copy link
Contributor

mhegazy commented Jan 27, 2016

This creates a folder under /wwwroot/app with the project name/src/project name/scripts/ instead of them being deployed in the /wwwroot/app folder itself.

you are not using rootDir, this has been my comment from the beginning :) rootDir changed the behavior of outDir.

Further, there is no guidance on how gulp should be setup for typescript to work properly and get compile on save, and incremental compile instead of always compile and if you setup watches it fails for bizzare reasons etc.

if you use gulp/grunt/etc.. you can not use compile on save. gulp has a watch mode, and that would be my recommendation here.

It shouldn't be this hard to use a basic tool like typescript in aspnetcore. Hence why I went back to using msbuild and vs.net's settings for it, but then it's borked completely.

I agree, and i agree the documentation is not compete here. can you share a setup that we can look at and see what issues are happening and how we can make it better, and hopefully write a sample in the process.

The problem with using .d.ts is that it isn't just definitions and if I make it add definitions then in that project I get endless compile failures because of everything being defined twice.

I think these should be compiled twice. i.e. once for your interfaces.ts and once for your other scripts, this way you have two outputs. The fix for issue #4714 should make this possible. but again, i would appreciate a repro i can look at.

@JohnGalt1717
Copy link

Except I did use rootDir. I copied exactly what you put in the tsconfig file and got those results.

Gulp watch causes tsc to fail on compile. Hence I can't use it.

here's my tsconfig.json file that is in the /scripts folder:

{ "compilerOptions": { "noImplicitAny": false, "noEmitOnError": true, "removeComments": true, "sourceMap": true, "target": "es5", "module": "amd", "outdir": "../wwwroot/app" }, "exclude": [ "node_modules", "wwwroot" ] }

(this is the sort of working version. Add the outDir and rootDir as you specified)

Just put any old typescript file in the scripts folder

Here's my gulp:

`///
"use strict";

var gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin"),
uglify = require("gulp-uglify"),
watch = require("gulp-watch"),
less = require("gulp-less"),
livereload = require("gulp-livereload"),
debug = require('gulp-debug'),
inject = require('gulp-inject'),
tsc = require('gulp-typescript'),
tslint = require('gulp-tslint'),
sourcemaps = require('gulp-sourcemaps'),
del = require('del'),
Config = require('./gulpfile.config'),
cache = require('gulp-cached'),
tsProject = tsc.createProject('./scripts/tsconfig.json');

var config = new Config();
var replace = require("gulp-replace");
var gutil = require('gulp-util');

var project = require("./project.json");
var paths = {
webroot: "./wwwroot/"
};

var environment = {
// The names of the different environments.
development: "Debug",
beta: "Beta",
qa: "QA",
demo: "Demo",
production: "Release",
// Gets the current hosting environment the application is running under. This comes from the environment variables.
current: function () { return gutil.env.ASPNET_ENV || this.development },
// Are we running under the development environment.
isDevelopment: function () { return this.current() === this.development; },
// Are we running under the staging environment.
isBeta: function () { return this.current() === this.beta; },
isQA: function () { return this.current() === this.qa; },
isDemo: function () { return this.current() === this.demo; },
// Are we running under the production environment.
isProduction: function () { return this.current() === this.production; }
};

paths.js = paths.webroot + "js//*.js";
paths.minJs = paths.webroot + "js/
/.min.js";
paths.css = paths.webroot + "css/__/
.css";
paths.minCss = paths.webroot + "css/*/.min.css";
paths.concatJsDest = paths.webroot + "js/site.min.js";
paths.concatCssDest = paths.webroot + "css/site.min.css";

gulp.task("clean:js", function (cb) {
rimraf(paths.concatJsDest, cb);
});

gulp.task("clean:css", function (cb) {
rimraf(paths.concatCssDest, cb);
});

gulp.task("clean", ["clean:js", "clean:css", "clean-ts"]);

gulp.task("min:js", function () {
return gulp.src([paths.js, "!" + paths.minJs], { base: "." })
.pipe(concat(paths.concatJsDest))
.pipe(uglify())
.pipe(gulp.dest("."));
});

gulp.task("min:css", function () {
return gulp.src([paths.css, "!" + paths.minCss])
.pipe(concat(paths.concatCssDest))
.pipe(cssmin())
.pipe(gulp.dest("."));
});

gulp.task("less", function () {
return gulp.src('Styles/*.less')
.pipe(cache('less'))
.pipe(less({ compress: true }))
.pipe(gulp.dest(paths.webroot + '/css'))
.pipe(livereload());
});

gulp.task("html", function () {
return gulp.src('views/*/.html')
.pipe(cache('html'))
.pipe(gulp.dest(paths.webroot + '/app/views'))
.pipe(livereload());
});

/**

  • Lint all custom TypeScript files.
    */
    gulp.task('ts-lint', function () {
    return gulp.src(config.allTypeScript)
    .pipe(cache('ts-lint'))
    .pipe(tslint())
    .pipe(tslint.report('prose'));
    });

/**

  • Compile TypeScript and include references to library and app .d.ts files.
    */
    gulp.task('compileTs', function () {
    var sourceTsFiles = [config.allTypeScript, //path to typescript files
    config.libraryTypeScriptDefinitions]; //reference to library .d.ts files

    var tsResult = gulp.src(sourceTsFiles)
    .pipe(cache('compileTs'))
    .pipe(sourcemaps.init())
    .pipe(tsc(tsProject));

    //tsResult.dts.pipe(gulp.dest(config.tsOutputPath));
    //return tsResult.js.pipe(gulp.dest(config.tsOutputPath));
    return tsResult.js
    .pipe(sourcemaps.write('.', { includeContent: false, sourceRoot: __dirname + "\scripts" }))
    .pipe(gulp.dest(config.tsOutputPath))
    .on("error", function(e) {
    console.log("error: Typescript Compile Failed: " + e);
    });
    });

/**

  • Compile TypeScript and include references to library and app .d.ts files.
    */
    gulp.task('compileTs-nosource', function () {
    var sourceTsFiles = [config.allTypeScript, //path to typescript files
    config.libraryTypeScriptDefinitions]; //reference to library .d.ts files

    var tsResult = gulp.src(sourceTsFiles)
    .pipe(tsc(tsProject));

    //tsResult.dts.pipe(gulp.dest(config.tsOutputPath));
    //return tsResult.js.pipe(gulp.dest(config.tsOutputPath));
    return tsResult.js
    .pipe(gulp.dest(config.tsOutputPath))
    .on("error", function (e) {
    console.log("error: Typescript Compile Failed: " + e);
    });
    });

/**

  • Remove all generated JavaScript files from TypeScript compilation.
    /
    gulp.task('clean-ts', function (cb) {
    var typeScriptGenFiles = [
    config.tsOutputPath + '/__/
    .js', // path to all JS files auto gen'd by editor
    config.tsOutputPath + '/*/.js.map', // path to all sourcemap files auto gen'd by editor
    '!' + config.tsOutputPath + '/lib'
    ];

    // delete the files
    del(typeScriptGenFiles, cb);
    });

gulp.task("cleanRelease", function () {
console.log(process.env);
gulp.src(["wwwroot/app/app.js"])
.pipe(replace("http://localhost:64553/", environment.isBeta ? "https://betaapi.azurewebsites.net/" : environment.isDemo ? "https://demoapi.azurewebsites.net/" : environment.isProduction ? "https://api.azurewebsites.net/" : "https://qaapi.azurewebsites.net/"))
.pipe(gulp.dest("wwwroot/app"));
});

gulp.task('watchTs', function () {
gulp.watch([config.allTypeScript], ['compileTs']);
});

gulp.task("watchLess", function () {
gulp.watch("styles/*/.less", ["less"]);

});

gulp.task("watchHtml", function () {
gulp.watch("views/*/.html", ["html"]);
});

gulp.task("min", ["min:js", "min:css"]);
//gulp.task("default", ["ts-lint", "compile-ts"]);`

Run compile-ts and you'll see what it does. It goes all of the way back to the solution root folder even with rootDir specified.

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants