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

Option to emit referenced files. #190

Open
Lenne231 opened this Issue Aug 25, 2015 · 17 comments

Comments

Projects
None yet
@Lenne231

It would be nice if there would be an option to emit referenced files, so that tsProject.src() streams them as well. This would make the configuration much simpler, match the behavior of the tsc command line tool and we would only have to define the entry files.

This could be implemented using preProcessFile(...).

Additionally it would be nice to be able to reference other files like css or less files, i.e. /// <reference path="../assets/mycomponent.less" /> and tsProject.src('less'). This way we could reference styles that should be integrated in our build. This would be very useful for single page applications but would require TypeScript to allow referencing other files than *.ts and expose these files over preProcessFile.

@ivogabe

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Aug 25, 2015

Owner

I've been thinking about adding a resolve method that can be used like this:

return tsProject.src()
    .pipe(tsProject.resolve())
    .pipe(ts(tsProject))
    .pipe(gulp.dest('release'));

The resolve function would add the referenced & imported files to the file stream. Would that be sufficient for you?

For the second request, I'm not a big fan of adding non standard features. I think your proposed syntax doesn't have enough use cases, also because lots of users don't use reference comments any more, they use ES6 imports and/or tsconfig.json instead.

Owner

ivogabe commented Aug 25, 2015

I've been thinking about adding a resolve method that can be used like this:

return tsProject.src()
    .pipe(tsProject.resolve())
    .pipe(ts(tsProject))
    .pipe(gulp.dest('release'));

The resolve function would add the referenced & imported files to the file stream. Would that be sufficient for you?

For the second request, I'm not a big fan of adding non standard features. I think your proposed syntax doesn't have enough use cases, also because lots of users don't use reference comments any more, they use ES6 imports and/or tsconfig.json instead.

@ivogabe ivogabe added the Suggestion label Aug 25, 2015

@Lenne231

This comment has been minimized.

Show comment
Hide comment
@Lenne231

Lenne231 Aug 25, 2015

Yes, that would be sufficient. Does resolve need the dependency on tsproject or would ts.resolve() work as well? I could think of something like

gulp.task('default', function () {
  var tsResult = gulp.src('src/main.ts')
    .pipe(ts.resolve())
    .pipe(ts({
        noImplicitAny: true
      }));
  return tsResult.js.pipe(gulp.dest('built/local'));
});

as well.

Why is .pipe(tsproject.resolve()) better than ts.createProject('tsconfig.json', { emitReferencedFiles: true }) or tsproject.resolvedSrc().pipe(...)? Is there a use case where we need the unresolved files in the stream?

The second request is not really a request at gulp-typescript, this needs to be supported by TypeScript first. I'm also not a fan of using reference to reference TypeScript files and would always prefer import for code files, but i would like to be able to use reference to define the CSS files my Code depends on and create CSS bundles based on this information. You can do this today using webpack and Code Splitting (http://webpack.github.io/docs/stylesheets.html).

Yes, that would be sufficient. Does resolve need the dependency on tsproject or would ts.resolve() work as well? I could think of something like

gulp.task('default', function () {
  var tsResult = gulp.src('src/main.ts')
    .pipe(ts.resolve())
    .pipe(ts({
        noImplicitAny: true
      }));
  return tsResult.js.pipe(gulp.dest('built/local'));
});

as well.

Why is .pipe(tsproject.resolve()) better than ts.createProject('tsconfig.json', { emitReferencedFiles: true }) or tsproject.resolvedSrc().pipe(...)? Is there a use case where we need the unresolved files in the stream?

The second request is not really a request at gulp-typescript, this needs to be supported by TypeScript first. I'm also not a fan of using reference to reference TypeScript files and would always prefer import for code files, but i would like to be able to use reference to define the CSS files my Code depends on and create CSS bundles based on this information. You can do this today using webpack and Code Splitting (http://webpack.github.io/docs/stylesheets.html).

@Lenne231

This comment has been minimized.

Show comment
Hide comment
@Lenne231

Lenne231 Aug 26, 2015

I think this should work with incremental compilation as well. But we would need a way to watch all files, including the referenced files. There is currently no way to watch all files defined in the tsconfig.json file #191. If this works, ts.createProject('tsconfig.json', { emitReferencedFiles: true }) makes much more sense than .pipe(tsproject.resolve()).

I think this should work with incremental compilation as well. But we would need a way to watch all files, including the referenced files. There is currently no way to watch all files defined in the tsconfig.json file #191. If this works, ts.createProject('tsconfig.json', { emitReferencedFiles: true }) makes much more sense than .pipe(tsproject.resolve()).

@ivogabe

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Aug 26, 2015

Owner

The separate resolve function is more flexible. You don't have to use tsProject.src but you can also use gulp.src, and you can add a preprocessor between resolving and compiling.

The reason it depends on a project is that it allows caching, which will speed up incremental compilation. When it's implemented, it's easy to implement a non caching ts.resolve.

If you want the references to be supported in TypeScript, you can report an issue there, but I'm afraid it doesn't add enough value for them to implement it. A better idea would be to create a gulp plugin that follows comments and one that filters files based on extension. The latter probably exists already, the fist maybe too. Then you can also use jsdoc style comments instead of xml comments (like // @style foo.css).

Owner

ivogabe commented Aug 26, 2015

The separate resolve function is more flexible. You don't have to use tsProject.src but you can also use gulp.src, and you can add a preprocessor between resolving and compiling.

The reason it depends on a project is that it allows caching, which will speed up incremental compilation. When it's implemented, it's easy to implement a non caching ts.resolve.

If you want the references to be supported in TypeScript, you can report an issue there, but I'm afraid it doesn't add enough value for them to implement it. A better idea would be to create a gulp plugin that follows comments and one that filters files based on extension. The latter probably exists already, the fist maybe too. Then you can also use jsdoc style comments instead of xml comments (like // @style foo.css).

@Briareos

This comment has been minimized.

Show comment
Hide comment
@Briareos

Briareos Oct 19, 2015

Giant +1 to this

Giant +1 to this

@edvinv

This comment has been minimized.

Show comment
Hide comment
@edvinv

edvinv Dec 14, 2015

+1 to this

I have many applications that share same common modules and with TS it is very is easy to compile this and to generate only js modules that are imported/referenced from entry point module. So this is a must have features for me to use gulp-typescript.

edvinv commented Dec 14, 2015

+1 to this

I have many applications that share same common modules and with TS it is very is easy to compile this and to generate only js modules that are imported/referenced from entry point module. So this is a must have features for me to use gulp-typescript.

@Briareos

This comment has been minimized.

Show comment
Hide comment
@Briareos

Briareos Dec 14, 2015

@edvinv This might solve your case (it outputs all the modules into a single file) #243 (comment)

@edvinv This might solve your case (it outputs all the modules into a single file) #243 (comment)

@edvinv

This comment has been minimized.

Show comment
Hide comment
@edvinv

edvinv Dec 15, 2015

@Briareos, not sure if it will add also files that are only referenced through import, but not part of the gulp src. The other problem is also that you can’t use –outFile, with commonjs modules.

edvinv commented Dec 15, 2015

@Briareos, not sure if it will add also files that are only referenced through import, but not part of the gulp src. The other problem is also that you can’t use –outFile, with commonjs modules.

@dsebastien

This comment has been minimized.

Show comment
Hide comment
@dsebastien

dsebastien Jan 8, 2016

+1 for the resolve() function idea.
I've described the issue I'm facing over there: typings/typings#69 (comment)

Basically I would like to get the exact same behavior between tsc and gulp-typescript but I can't seem to be able to do so.

I see only a few solutions at the moment:

  • have the typings be placed in the rootDir (currently not supported by the typings CLI)
  • have gulp-typescript mimic what tsc does
  • use some gulp-fu and perform some voodoo magic
  • go back to gulp.src (but then I lose the huge benefit of having a single place to configure my TS transpilation settings

Just for reference, here's my current gulp task:

gulp.task("scripts-typescript", "Transpile TypeScript to ES5, include references to library and app .d.ts files and generate sourcemaps", (callback) =>{
    // references:
    // https://www.npmjs.com/package/gulp-typescript
    const tsProject = ts.createProject("tsconfig.json", {
        typescript: require("typescript") // override the typescript version by that defined in package.json

        // configuration defined in tsconfig.json
        // other overrides here if needed
        // http://json.schemastore.org/tsconfig
        // https://github.com/Microsoft/TypeScript/wiki/Compiler%20Options
    });
    //console.log(tsProject.config.compilerOptions);

    const tsConfigOutDir = tsProject.config.compilerOptions.outDir;
    const tsResult = tsProject.src()
        // Display the files in the stream
        //.pipe(debug({title: "Stream contents:", minimal: true}))
        .pipe(sourcemaps.init())
        .pipe(ts(
            tsProject
        ));

    // Output type definition files
    tsResult.dts.pipe(gulp.dest(tsConfigOutDir));

    // Output js files
    tsResult.js

        // Display the files in the stream
        //.pipe(debug({title: "Stream contents:", minimal: true}))

        .pipe(sourcemaps.write(".", { // use "." to write the sourcemap to a separate file in the same dir
            includeContent: false, // alternative: include the contents and remove sourceRoot. Avoids issues but prevents from editing the sources directly in the browser
            sourceRoot: "/" // use an absolute path because we have scripts in different subpaths
        }))

        // Output files
        .pipe(gulp.dest(tsConfigOutDir))

        // Task result
        .pipe(size({
            title: "scripts-typescript"
        }));
    callback();
});

+1 for the resolve() function idea.
I've described the issue I'm facing over there: typings/typings#69 (comment)

Basically I would like to get the exact same behavior between tsc and gulp-typescript but I can't seem to be able to do so.

I see only a few solutions at the moment:

  • have the typings be placed in the rootDir (currently not supported by the typings CLI)
  • have gulp-typescript mimic what tsc does
  • use some gulp-fu and perform some voodoo magic
  • go back to gulp.src (but then I lose the huge benefit of having a single place to configure my TS transpilation settings

Just for reference, here's my current gulp task:

gulp.task("scripts-typescript", "Transpile TypeScript to ES5, include references to library and app .d.ts files and generate sourcemaps", (callback) =>{
    // references:
    // https://www.npmjs.com/package/gulp-typescript
    const tsProject = ts.createProject("tsconfig.json", {
        typescript: require("typescript") // override the typescript version by that defined in package.json

        // configuration defined in tsconfig.json
        // other overrides here if needed
        // http://json.schemastore.org/tsconfig
        // https://github.com/Microsoft/TypeScript/wiki/Compiler%20Options
    });
    //console.log(tsProject.config.compilerOptions);

    const tsConfigOutDir = tsProject.config.compilerOptions.outDir;
    const tsResult = tsProject.src()
        // Display the files in the stream
        //.pipe(debug({title: "Stream contents:", minimal: true}))
        .pipe(sourcemaps.init())
        .pipe(ts(
            tsProject
        ));

    // Output type definition files
    tsResult.dts.pipe(gulp.dest(tsConfigOutDir));

    // Output js files
    tsResult.js

        // Display the files in the stream
        //.pipe(debug({title: "Stream contents:", minimal: true}))

        .pipe(sourcemaps.write(".", { // use "." to write the sourcemap to a separate file in the same dir
            includeContent: false, // alternative: include the contents and remove sourceRoot. Avoids issues but prevents from editing the sources directly in the browser
            sourceRoot: "/" // use an absolute path because we have scripts in different subpaths
        }))

        // Output files
        .pipe(gulp.dest(tsConfigOutDir))

        // Task result
        .pipe(size({
            title: "scripts-typescript"
        }));
    callback();
});
@blakeembrey

This comment has been minimized.

Show comment
Hide comment
@blakeembrey

blakeembrey Jan 8, 2016

@ivogabe In the linked issue, I narrowed down the bug to the handling of rootDir, which is inconsistent with tsc. You should be able to use the functionality in tsc directly, or you can try using https://github.com/TypeStrong/tsconfig for resolving files too.

@ivogabe In the linked issue, I narrowed down the bug to the handling of rootDir, which is inconsistent with tsc. You should be able to use the functionality in tsc directly, or you can try using https://github.com/TypeStrong/tsconfig for resolving files too.

@JKillian

This comment has been minimized.

Show comment
Hide comment
@JKillian

JKillian Jan 20, 2016

👍 It's a pain to have to maintain a list of all files - it would be nicer if there was a way to get local imports (those beginning with a .) to be emitted as well

👍 It's a pain to have to maintain a list of all files - it would be nicer if there was a way to get local imports (those beginning with a .) to be emitted as well

@dsebastien

This comment has been minimized.

Show comment
Hide comment
@dsebastien

dsebastien Jan 30, 2016

@ivogabe did you already have time to take a look at this one?

@ivogabe did you already have time to take a look at this one?

@ivogabe

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Feb 2, 2016

Owner

The issues with base paths and rootDir should be resolved with #276. Can you test it with that branch?

npm install ivogabe/gulp-typescript#tsconfig-files

This does not resolve files yet.

Owner

ivogabe commented Feb 2, 2016

The issues with base paths and rootDir should be resolved with #276. Can you test it with that branch?

npm install ivogabe/gulp-typescript#tsconfig-files

This does not resolve files yet.

@rashtao

This comment has been minimized.

Show comment
Hide comment

rashtao commented Mar 17, 2016

+1

@zeh

This comment has been minimized.

Show comment
Hide comment
@zeh

zeh Mar 28, 2016

+1 to resolve(). To add some background, my issue is that I'd like gulp-typescript to behave the same as tsc, when I pass a tsconfig.json to it. But currently, it does not include resolved files.

I have this tsconfig file:

{
    "compilerOptions": {
        "inlineSourceMap": true,
        "noImplicitAny": true,
        "target": "es6",
        "module": "es6",
        "outDir": "dist/es6",
        "rootDir": "src",
    },
    "files": [
        "src/MyClass.ts"
    ]
}

My /src/ location includes not only MyClass.ts, but other files referenced from it with import/export clauses. And sure enough, when using tsc, the output inside dist/es6 includes both MyClass.js and any other referenced files.

And then, I want to do the same from gulp. This is the code used to compile it from gulp:

var ts = require('gulp-typescript');

gulp.task('compile-es6', function() {
    var tsProject = ts.createProject('tsconfig.json', {});
    return tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(options.distES6));
});

However, when compiling the project as above, gulp-typescript only outputs Myclass.js.

It seems like resolve() would solve this issue.

As a side note, it's hard for projects to keep a tsconfig.json that is, many times, useless/redundant/misleading, as the source files/destination/options/etc have to be set again in the gulp file.. any options that allows us to use tsconfig are very much welcomed.

zeh commented Mar 28, 2016

+1 to resolve(). To add some background, my issue is that I'd like gulp-typescript to behave the same as tsc, when I pass a tsconfig.json to it. But currently, it does not include resolved files.

I have this tsconfig file:

{
    "compilerOptions": {
        "inlineSourceMap": true,
        "noImplicitAny": true,
        "target": "es6",
        "module": "es6",
        "outDir": "dist/es6",
        "rootDir": "src",
    },
    "files": [
        "src/MyClass.ts"
    ]
}

My /src/ location includes not only MyClass.ts, but other files referenced from it with import/export clauses. And sure enough, when using tsc, the output inside dist/es6 includes both MyClass.js and any other referenced files.

And then, I want to do the same from gulp. This is the code used to compile it from gulp:

var ts = require('gulp-typescript');

gulp.task('compile-es6', function() {
    var tsProject = ts.createProject('tsconfig.json', {});
    return tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(ts(tsProject))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(options.distES6));
});

However, when compiling the project as above, gulp-typescript only outputs Myclass.js.

It seems like resolve() would solve this issue.

As a side note, it's hard for projects to keep a tsconfig.json that is, many times, useless/redundant/misleading, as the source files/destination/options/etc have to be set again in the gulp file.. any options that allows us to use tsconfig are very much welcomed.

@pikilon

This comment has been minimized.

Show comment
Hide comment
@pikilon

pikilon Apr 29, 2016

+1 to resolve(),
I am using gulp-include until we have resolve online

pikilon commented Apr 29, 2016

+1 to resolve(),
I am using gulp-include until we have resolve online

@jephir

This comment has been minimized.

Show comment
Hide comment
@jephir

jephir Aug 25, 2016

If you're bundling your output you may want to use rollup-stream with rollup-plugin-typescript. It handles dependencies and also reads tsconfig.json correctly (no more config duplication).

gulpfile.js

const gulp = require("gulp")
const rollup = require("rollup-stream")
const source = require("vinyl-source-stream")

gulp.task("default", () =>
    rollup("rollup.config.js")
        .pipe(source("server.js"))
        .pipe(gulp.dest("./build/server"))
)

rollup.config.js

import typescript from "rollup-plugin-typescript"

export default {
    entry: "./server.ts",
    format: "cjs",
    plugins: [
        typescript(),
    ],
}

jephir commented Aug 25, 2016

If you're bundling your output you may want to use rollup-stream with rollup-plugin-typescript. It handles dependencies and also reads tsconfig.json correctly (no more config duplication).

gulpfile.js

const gulp = require("gulp")
const rollup = require("rollup-stream")
const source = require("vinyl-source-stream")

gulp.task("default", () =>
    rollup("rollup.config.js")
        .pipe(source("server.js"))
        .pipe(gulp.dest("./build/server"))
)

rollup.config.js

import typescript from "rollup-plugin-typescript"

export default {
    entry: "./server.ts",
    format: "cjs",
    plugins: [
        typescript(),
    ],
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment