Skip to content

Implement vsproj support #215

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 21 commits into from
Mar 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Releases

## Next

## v4.0.0
* FEAT: Now supports parsing and compiling directly against the TypeScript files and configuration specified in a Visual Studio project file - .csproj or .vbproj. Visual Studio *not* required and files list/config override-able, ignorable and extend-able. (https://github.com/TypeStrong/grunt-ts/pull/215)
* FEAT: Now includes a custom TypeScript targets file to easily disable the internal Visual Studio TypeScript build.
* DOCS: New detailed instructions on how to disable TypeScript build within Visual Studio while keeping TypeScript Build project properties pane functional.
* DOCS: Several documentation improvements and clarifications.
* FIX: report error on wrong `module` option. (https://github.com/TypeStrong/grunt-ts/pull/212)
* FIX: Corrected an issue where the grunt-ts transforms module might transform itself. #SkyNet
* CHORE: Added unit test for ///ts:ref= transform.
* CHORE: Removed dependency on tslint-path-formatter and upgraded grunt-tslint dev dependency to 2.0.0.

## v3.0.0
* **Breaking Change**: the default bundled typescript compiler is now `1.4.1`
Expand Down
49 changes: 47 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ module.exports = function (grunt) {
},
tslint: {
options: {
configuration: grunt.file.readJSON('tslint.json'),
formatter: 'tslint-path-formatter'
configuration: grunt.file.readJSON('tslint.json')
},
source: {
src: ['tasks/**/*.ts']
Expand Down Expand Up @@ -151,6 +150,14 @@ module.exports = function (grunt) {
fast: 'never'
}
},
files_showWarningIfFilesIsUsedWithVs: {
test: true,
files: [{ src: ['test/multifile/a/**/*.ts'], dest: 'test/multifile/a' }],
vs: 'test/vsproj/testproject.csproj',
options: {
fast: 'never'
}
},
files_showWarningIfFilesIsUsedWithWatch: {
//note this should not actually watch.
files: [{ src: ['test/multifile/a/**/*.ts'], dest: 'test/multifile/a' }],
Expand Down Expand Up @@ -257,6 +264,36 @@ module.exports = function (grunt) {
target: 'es5'
}
},
vsproj_test: {
test: true,
vs: 'test/vsproj/testproject.csproj'
},
vsproj_test_config: {
test: true,
vs: {
project: 'test/vsproj/testproject.csproj',
config: 'Release'
}
},
vsproj_ignoreFiles_test: {
test: true,
src: 'test/vsproj/ignoreFiles/**/*.ts',
vs: {
project: 'test/vsproj/testproject.csproj',
ignoreFiles: true
}
},
vsproj_ignoreSettings_test: {
test: true,
vs: {
project: 'test/vsproj/testproject.csproj',
ignoreSettings: true
},
outDir: 'test/vsproj/ignoreSettings',
options: {
target: 'es6'
}
},
warnbothcomments: {
test: true,
src: ['test/abtest/**/*.ts'],
Expand Down Expand Up @@ -355,6 +392,14 @@ module.exports = function (grunt) {
fast: 'always'
}
},
refTransform: {
test: true,
src: ['test/references-transform/**/*.ts','test/references*.d.ts'],
options: {
fast: 'always',
noImplicitAny: true
}
},
customcompiler: {
test: true,
src: ['test/customcompiler/ts/**/*.ts'],
Expand Down
87 changes: 77 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## TypeScript Compilation Task for GruntJS

Grunt-ts is an npm package that handles TypeScript compilation work in GruntJS build scripts. It provides a [Grunt-compatible wrapper](#support-for-tsc-switches) for the `tsc` command-line compiler, and provides some [additional functionality](#grunt-ts-gruntfilejs-options) that improves the TypeScript development workflow. Grunt-ts is itself written in [TypeScript](./tasks/ts.ts).
Grunt-ts is an npm package that handles TypeScript compilation work in GruntJS build scripts. It provides a [Grunt-compatible wrapper](#support-for-tsc-switches) for the `tsc` command-line compiler, and provides some [additional functionality](#grunt-ts-gruntfilejs-options) that improves the TypeScript development workflow. Grunt-ts even supports compiling against a [Visual Studio project](#vs) directly. Grunt-ts is itself written in [TypeScript](./tasks/ts.ts).

## Getting Started

Expand Down Expand Up @@ -37,6 +37,7 @@ A more extensive sample `Gruntfile.js` is available [here](https://github.com/Ty
* Allows use of all standard GruntJS functionality such as use of customizable task targets, globbing, use of the `files` object (for instantiating multiple independent `tsc` runs in a single target), etc.
* Allows the developer to [select a custom TypeScript compiler version](#compiler) for their project, or even use a custom (in-house) version.
* Supports [most switches](#support-for-tsc-switches) of the `tsc` TypeScript Compiler via options in the gruntfile `ts` task, and also supports switch overrides per-target.
* Supports [Visual Studio Projects](#vs) as a compile target for identifying TypeScript files, setting up compile configuration, or both.
* Provides a [transforms](#transforms) feature that eases code refactoring by taking the burden of relative path maintenance off the developer. If the paths to a set of files changes, grunt-ts will regenerate the relevant sections. This feature supports:
* External module [import transforms](#import-transform) by file name, aliasing, directories, indexed directories, and re-exported imports.
* Internal module [reference maintenance](#references)
Expand Down Expand Up @@ -99,9 +100,9 @@ For file ordering, look at [JavaScript Generation](#javascript-generation).
|[src](#src)|target|`string` or `string[]` - glob of TypeScript files to compile.|
|[target](#target)|option|`'es5'` (default), `'es3'`, or `'es6'` - targeted ECMAScript version|
|[verbose](#verbose)|option|`true`, `false` (default) - logs `tsc` command-line options to console|
|[vs](#vs)|target|`string` referencing a `.csproj` or `.vbproj` file or, `{}` (object) (see [Visual Studio Projects](#vs) for details)|
|[watch](#watch)|target|`string` - will watch for changes in the specified directory or below|


Note: In the above chart, if "where to define" is "target", the property must be defined on a target or on the `ts` object directly. If "where to define" is "options", then the property must be defined on an `options` object on `ts` or on a target under `ts`.


Expand Down Expand Up @@ -262,7 +263,10 @@ grunt.initConfig({
````
**Note:** the TypeScript file identified in the `reference` property *must* be included in the `src` or `files` property in the Grunt target, or `reference` won't work (either directly or via wildcard/glob).

*Warning:* Using the compiler with `out` and `reference` will prevent grunt-ts from using its fast compile feature. Consider using external modules with transforms instead.
*Note:* It is not supported to use `reference` with `files`.

*Warning:* Using the compiler with `out` and `reference` will prevent grunt-ts from using its fast compile feature. Consider using external modules with transforms instead.


#### src

Expand All @@ -278,6 +282,54 @@ grunt.initConfig({
});
````

#### vs

Grunt-ts can use the TypeScript compilation settings from a Visual Studio project file (.csproj or .vbproj).

In the simplest use case, specify a string identifying the Visual Studio project file name in the `vs` target property. Grunt-ts will extract the TypeScript settings *last saved* into the project file and compile the TypeScript files identified in the project in the manner specified by the Visual Studio project's configuration.

````javascript
grunt.initConfig({
ts: {
default: {
vs: 'test/vsproj/testproject.csproj'
}
}
});
````

If more control is desired, you may pass the `vs` target property as an object literal with the following properties:

* `project`: (`string`, mandatory) the relative path (from the `gruntfile.js`) to the Visual Studio project file.
* `config`: (`string`, optional, default = '') the Visual Studio project configuration to use (allows choosing a different project configuration than the one currently in-use/saved in Visual Studio).
* `ignoreFiles`: (`boolean`, optional, default = `false`) Will ignore the files identified in the Visual Studio project. This is useful if you want to keep your command-line build settings synchronized with the project's TypeScript Build settings, but want to specify a custom set of files to compile in your own `src` glob. If not specified or set to false, the TypeScript files referenced in the Visual Studio project will be compiled in addition to any files identified in the `src` target property.
* `ignoreSettings`: (`boolean`, optional, default = `false`) Will ignore the compile settings identified in the Visual Studio project. If specified, grunt-ts will follow its normal behavior and use any TypeScript build settings specified on the target or its defaults.

All features of grunt-ts other than `files`, are compatible with the `vs` target property. If you wish to add more files to the compilation than are referenced in the Visual Studio project, the `src` grunt-ts property can be used; any files found in the glob are *added* to the compilation list (grunt-ts will resolve duplicates). All other target properties and target options specified in the gruntfile.js will **override** the settings in the Visual Studio project file. For example, if you were referencing a Visual Studio project configuration that had source maps enabled, specifying `sourcemap: false` in the gruntfile.js would keep all other Visual Studio build settings, but disable generation of source maps.

**Note:** Using the `vs` target property with `files` is not supported.

Example: Use all compilation settings specified in the "Release" TypeScript configuration from the project, but compile only the TypeScript files in the `lib` subfolder to a single file in the `built` folder.

````javascript
grunt.initConfig({
ts: {
CompileMyLibsOnly: {
src: 'MyProject/lib/**/*.ts',
out: 'built/mylibs.js',
vs: {
project: 'MyProject/MyProject.csproj',
ignoreFiles: true,
config: 'Release'
}
}
}
});
````

If you wish to disable the Visual Studio built-in TypeScript build, but keep the Visual Studio project properties TypeScript Build pane working, follow [these instructions](./docs/DisableVisualStudioBuild.md).


#### watch

Grunt-ts can watch a directory and recompile TypeScript files when any TypeScript or HTML file is changed, added, or removed. Use the `watch` *target* option specifying a target directory that will be watched. All subdirectories are automatically included.
Expand Down Expand Up @@ -705,9 +757,25 @@ grunt.initConfig({

### Transforms

Objective : To allow easier code refactoring by taking the relative path maintenance burden off the developer. If the paths to the files changes `grunt-ts` will regenerate the relevant sections.
Objective: To allow for easier code refactoring by taking relative path maintenance burden off the developer. If the path to a referenced file changes, `grunt-ts` will regenerate the relevant lines.

Transforms begin with a three-slash comment `///` and are prefixed with `ts:`. When grunt-ts is run against your TypeScript file, it will add a new line with the appropriate TypeScript code to reference the file, or it will generate a comment indicating that the file you referenced could not be found.

For example, if you put this in your code:

```typescript
///ts:ref=mylibrary
```

The next time grunt-ts runs, it might change that line to this:

```typescript
///ts:ref=mylibrary
/// <reference path='../path/to/mylibrary.d.ts'/> ///ts:ref:generated
```

**Important Note:** All transforms require the searched-for file to be *included* in the result of the `files`, `src`, or `vs` Grunt globs. Grunt-ts will only search within the results that *Grunt has identified*; it does not go searching through your disk for files!

Transforms begin with a three-slash comment `///` and are prefixed with `ts:`

You can also run transforms without compiling your code by setting `compile: false` in your config. For example:
```javascript
Expand Down Expand Up @@ -803,6 +871,8 @@ export import anotherfile = require('../path/to/dirName/deeper/anotherfile'); //

This will generate the relevant `/// <references path="./path/to/foo" />` code without you having to figure out the relative path.

**Note:** grunt-ts only searches through the enumerated results of the `src` or `files` property in the Grunt target. The referenced TypeScript file *must* be included for compilation (either directly or via wildcard/glob) or the transform won't work. This is so that grunt-ts doesn't go searching through your whole drive for files.

##### Examples

Reference file:
Expand Down Expand Up @@ -892,13 +962,10 @@ It runs `build` followed by `test`. This is also the default task. You should ru

### Development

You will probably be working and testing a particular feature. Modify `tasksToTest` in our `Gruntfile.js` and run:
The easiest/fastest way to work on grunt-ts is to modify `tasksToTest` toward the bottom of the `gruntfile.js`. The `grunt dev` command is set up to compile grunt-ts with your changes and then reload itself; then, your newly-compiled grunt-ts will be used to run whatever tasks are listed in the `tasksToTest` array.

```bash
$ grunt dev
```
Without using `tasksToTest` while working on grunt-ts, the old grunt-ts remains in memory for successive tasks on the same run. This means you might have to run your grunt commands twice; once to compile grunt-ts and once to see how the new grunt-ts works with your code.

It will watch your changes (to `grunt-ts` task as well as examples) and run your tasksToTest after updating the task (if any changes detected).

### Additional commands
Update the current `grunt-ts` to be the last known good version (dogfood). Commit message should be `Update LKG`.
Expand Down
13 changes: 13 additions & 0 deletions custom.TypeScript.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CfgPropertyPagesGuidsAddCSharp>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddCSharp>
<CfgPropertyPagesGuidsAddVB>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddVB>
<CfgPropertyPagesGuidsAddTypeScript>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddTypeScript>
</PropertyGroup>
<ItemGroup>
<ProjectCapability Include="TypeScript" />
</ItemGroup>
<PropertyGroup>
<TypeScriptEnabled>true</TypeScriptEnabled>
</PropertyGroup>
</Project>
46 changes: 46 additions & 0 deletions defs/csproj2ts/csproj2ts.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
declare module 'csproj2ts' {
interface TypeScriptSettings extends TypeScriptConfiguration {
VSProjectDetails?: VSProjectDetails;
files?: string[];
}
interface VSProjectParams {
ProjectFileName?: string;
MSBuildExtensionsPath32?: string;
VisualStudioVersion?: string;
TypeScriptVersion?: string;
ActiveConfiguration?: string;
}
interface VSProjectDetails extends VSProjectParams {
DefaultProjectConfiguration?: string;
DefaultVisualStudioVersion?: string;
TypeScriptDefaultPropsFilePath?: string;
TypeScriptDefaultConfiguration?: TypeScriptConfiguration;
}
interface TypeScriptConfiguration {
AdditionalFlags?: string;
Charset?: string;
CodePage?: string;
CompileOnSaveEnabled?: boolean;
EmitBOM?: boolean;
GeneratesDeclarations?: boolean;
MapRoot?: string;
ModuleKind?: string;
NoEmitOnError?: boolean;
NoImplicitAny?: boolean;
NoLib?: boolean;
NoResolve?: boolean;
OutFile?: string;
OutDir?: string;
PreserveConstEnums?: boolean;
RemoveComments?: boolean;
SourceMap?: boolean;
SourceRoot?: string;
SuppressImplicitAnyIndexErrors?: boolean;
Target?: string;
}
var xml2jsReadXMLFile: (fileName: string) => Promise<any>;
var getTypeScriptSettings: (projectInfo: VSProjectParams) => Promise<TypeScriptSettings>;
var normalizePath: (path: string, settings: TypeScriptSettings) => string;
var getTypeScriptDefaultsFromPropsFileOrDefaults: (settings: TypeScriptSettings) => Promise<TypeScriptConfiguration>;
var programFiles: () => string;
}
1 change: 1 addition & 0 deletions defs/tsd.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/// <reference path="lodash/lodash.d.ts" />
/// <reference path="gruntjs/gruntjs.d.ts" />
/// <reference path="es6-promises/es6-promises.d.ts" />
/// <reference path="csproj2ts/csproj2ts.d.ts" />
34 changes: 34 additions & 0 deletions docs/DisableVisualStudioBuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# How to disable the Visual Studio TypeScript Build
*but keep the TypeScript Project Properties Pane Working...*

If you are using Visual Studio and wish to compile your TypeScript with grunt-ts *only*, you can disable the Visual Studio TypeScript build by performing the following steps:

* First, make sure your project has TypeScript support enabled by opening the project properties and confirming that the TypeScript Build properties pane is selectable.
* Next, make sure your project folder has grunt-ts installed, and confirm that running grunt with the appropriate configuration will compile your project correctly.
* Exit Visual Studio (Targets are only read once, so unloading the project is not sufficient).
* Make sure that your project is backed-up or fully checked-in to Source Control.
* Edit the .csproj or .vbproj file for which you wish to disable VS TypeScript building.
* Search for the line containing the text "Microsoft.TypeScript.targets". Delete or comment-out the entire line.
* At that spot, add one of these lines:

**If grunt-ts is installed in node_modules under the Project folder:**
```xml
<Import Project="$(ProjectDir)\node_modules\grunt-ts\custom.TypeScript.targets" Condition="Exists('$(ProjectDir)\node_modules\grunt-ts\custom.TypeScript.targets')" />
```

**If grunt-ts is installed in node_modules under the Solution folder:**
```xml
<Import Project="$(SolutionDir)\node_modules\grunt-ts\custom.TypeScript.targets" Condition="Exists('$(SolutionDir)\node_modules\grunt-ts\custom.TypeScript.targets')" />
```

**If grunt-ts is installed elsewhere**
Modify one of the previous examples to point to the `custom.TypeScript.targets` file.

* If you have multiple projects in your solution, you must edit each .csproj or .vbproj.
* Reload Visual Studio and confirm that the TypeScript Build pane still appears in the project properties.
* Then, introduce an error in a TypeScript file such as a mismatched parenthesis.
* Finally, press Ctrl+Shift+B to initiate a build. If the build succeeds, you've successfully disabled the TypeScript compilation in Visual Studio. Run Grunt to build your project and it should fail. Fix the error and Grunt should then succeed (assuming it was prior to you making these changes).




Loading