Skip to content

Commit 00f0f84

Browse files
committed
Merge pull request #215 from TypeStrong/implement-VSPROJ-support
Merge PR #215 - Implement Visual Studio Project support
2 parents 987b03f + fa8c4cf commit 00f0f84

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3006
-1966
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
# Releases
22

33
## Next
4+
5+
## v4.0.0
6+
* 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)
7+
* FEAT: Now includes a custom TypeScript targets file to easily disable the internal Visual Studio TypeScript build.
8+
* DOCS: New detailed instructions on how to disable TypeScript build within Visual Studio while keeping TypeScript Build project properties pane functional.
9+
* DOCS: Several documentation improvements and clarifications.
410
* FIX: report error on wrong `module` option. (https://github.com/TypeStrong/grunt-ts/pull/212)
11+
* FIX: Corrected an issue where the grunt-ts transforms module might transform itself. #SkyNet
12+
* CHORE: Added unit test for ///ts:ref= transform.
13+
* CHORE: Removed dependency on tslint-path-formatter and upgraded grunt-tslint dev dependency to 2.0.0.
514

615
## v3.0.0
716
* **Breaking Change**: the default bundled typescript compiler is now `1.4.1`

Gruntfile.js

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ module.exports = function (grunt) {
3030
},
3131
tslint: {
3232
options: {
33-
configuration: grunt.file.readJSON('tslint.json'),
34-
formatter: 'tslint-path-formatter'
33+
configuration: grunt.file.readJSON('tslint.json')
3534
},
3635
source: {
3736
src: ['tasks/**/*.ts']
@@ -151,6 +150,14 @@ module.exports = function (grunt) {
151150
fast: 'never'
152151
}
153152
},
153+
files_showWarningIfFilesIsUsedWithVs: {
154+
test: true,
155+
files: [{ src: ['test/multifile/a/**/*.ts'], dest: 'test/multifile/a' }],
156+
vs: 'test/vsproj/testproject.csproj',
157+
options: {
158+
fast: 'never'
159+
}
160+
},
154161
files_showWarningIfFilesIsUsedWithWatch: {
155162
//note this should not actually watch.
156163
files: [{ src: ['test/multifile/a/**/*.ts'], dest: 'test/multifile/a' }],
@@ -257,6 +264,36 @@ module.exports = function (grunt) {
257264
target: 'es5'
258265
}
259266
},
267+
vsproj_test: {
268+
test: true,
269+
vs: 'test/vsproj/testproject.csproj'
270+
},
271+
vsproj_test_config: {
272+
test: true,
273+
vs: {
274+
project: 'test/vsproj/testproject.csproj',
275+
config: 'Release'
276+
}
277+
},
278+
vsproj_ignoreFiles_test: {
279+
test: true,
280+
src: 'test/vsproj/ignoreFiles/**/*.ts',
281+
vs: {
282+
project: 'test/vsproj/testproject.csproj',
283+
ignoreFiles: true
284+
}
285+
},
286+
vsproj_ignoreSettings_test: {
287+
test: true,
288+
vs: {
289+
project: 'test/vsproj/testproject.csproj',
290+
ignoreSettings: true
291+
},
292+
outDir: 'test/vsproj/ignoreSettings',
293+
options: {
294+
target: 'es6'
295+
}
296+
},
260297
warnbothcomments: {
261298
test: true,
262299
src: ['test/abtest/**/*.ts'],
@@ -355,6 +392,14 @@ module.exports = function (grunt) {
355392
fast: 'always'
356393
}
357394
},
395+
refTransform: {
396+
test: true,
397+
src: ['test/references-transform/**/*.ts','test/references*.d.ts'],
398+
options: {
399+
fast: 'always',
400+
noImplicitAny: true
401+
}
402+
},
358403
customcompiler: {
359404
test: true,
360405
src: ['test/customcompiler/ts/**/*.ts'],

README.md

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
## TypeScript Compilation Task for GruntJS
66

7-
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).
7+
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).
88

99
## Getting Started
1010

@@ -37,6 +37,7 @@ A more extensive sample `Gruntfile.js` is available [here](https://github.com/Ty
3737
* 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.
3838
* Allows the developer to [select a custom TypeScript compiler version](#compiler) for their project, or even use a custom (in-house) version.
3939
* 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.
40+
* Supports [Visual Studio Projects](#vs) as a compile target for identifying TypeScript files, setting up compile configuration, or both.
4041
* 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:
4142
* External module [import transforms](#import-transform) by file name, aliasing, directories, indexed directories, and re-exported imports.
4243
* Internal module [reference maintenance](#references)
@@ -99,9 +100,9 @@ For file ordering, look at [JavaScript Generation](#javascript-generation).
99100
|[src](#src)|target|`string` or `string[]` - glob of TypeScript files to compile.|
100101
|[target](#target)|option|`'es5'` (default), `'es3'`, or `'es6'` - targeted ECMAScript version|
101102
|[verbose](#verbose)|option|`true`, `false` (default) - logs `tsc` command-line options to console|
103+
|[vs](#vs)|target|`string` referencing a `.csproj` or `.vbproj` file or, `{}` (object) (see [Visual Studio Projects](#vs) for details)|
102104
|[watch](#watch)|target|`string` - will watch for changes in the specified directory or below|
103105

104-
105106
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`.
106107

107108

@@ -262,7 +263,10 @@ grunt.initConfig({
262263
````
263264
**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).
264265

265-
*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.
266+
*Note:* It is not supported to use `reference` with `files`.
267+
268+
*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.
269+
266270

267271
#### src
268272

@@ -278,6 +282,54 @@ grunt.initConfig({
278282
});
279283
````
280284

285+
#### vs
286+
287+
Grunt-ts can use the TypeScript compilation settings from a Visual Studio project file (.csproj or .vbproj).
288+
289+
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.
290+
291+
````javascript
292+
grunt.initConfig({
293+
ts: {
294+
default: {
295+
vs: 'test/vsproj/testproject.csproj'
296+
}
297+
}
298+
});
299+
````
300+
301+
If more control is desired, you may pass the `vs` target property as an object literal with the following properties:
302+
303+
* `project`: (`string`, mandatory) the relative path (from the `gruntfile.js`) to the Visual Studio project file.
304+
* `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).
305+
* `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.
306+
* `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.
307+
308+
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.
309+
310+
**Note:** Using the `vs` target property with `files` is not supported.
311+
312+
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.
313+
314+
````javascript
315+
grunt.initConfig({
316+
ts: {
317+
CompileMyLibsOnly: {
318+
src: 'MyProject/lib/**/*.ts',
319+
out: 'built/mylibs.js',
320+
vs: {
321+
project: 'MyProject/MyProject.csproj',
322+
ignoreFiles: true,
323+
config: 'Release'
324+
}
325+
}
326+
}
327+
});
328+
````
329+
330+
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).
331+
332+
281333
#### watch
282334

283335
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.
@@ -705,9 +757,25 @@ grunt.initConfig({
705757

706758
### Transforms
707759

708-
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.
760+
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.
761+
762+
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.
763+
764+
For example, if you put this in your code:
765+
766+
```typescript
767+
///ts:ref=mylibrary
768+
```
769+
770+
The next time grunt-ts runs, it might change that line to this:
771+
772+
```typescript
773+
///ts:ref=mylibrary
774+
/// <reference path='../path/to/mylibrary.d.ts'/> ///ts:ref:generated
775+
```
776+
777+
**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!
709778

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

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

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

874+
**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.
875+
806876
##### Examples
807877

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

893963
### Development
894964

895-
You will probably be working and testing a particular feature. Modify `tasksToTest` in our `Gruntfile.js` and run:
965+
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.
896966

897-
```bash
898-
$ grunt dev
899-
```
967+
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.
900968

901-
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).
902969

903970
### Additional commands
904971
Update the current `grunt-ts` to be the last known good version (dogfood). Commit message should be `Update LKG`.

custom.TypeScript.targets

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<CfgPropertyPagesGuidsAddCSharp>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddCSharp>
4+
<CfgPropertyPagesGuidsAddVB>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddVB>
5+
<CfgPropertyPagesGuidsAddTypeScript>{d4683cae-88c4-4b85-863d-ac8014f3ba36}</CfgPropertyPagesGuidsAddTypeScript>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<ProjectCapability Include="TypeScript" />
9+
</ItemGroup>
10+
<PropertyGroup>
11+
<TypeScriptEnabled>true</TypeScriptEnabled>
12+
</PropertyGroup>
13+
</Project>

defs/csproj2ts/csproj2ts.d.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
declare module 'csproj2ts' {
2+
interface TypeScriptSettings extends TypeScriptConfiguration {
3+
VSProjectDetails?: VSProjectDetails;
4+
files?: string[];
5+
}
6+
interface VSProjectParams {
7+
ProjectFileName?: string;
8+
MSBuildExtensionsPath32?: string;
9+
VisualStudioVersion?: string;
10+
TypeScriptVersion?: string;
11+
ActiveConfiguration?: string;
12+
}
13+
interface VSProjectDetails extends VSProjectParams {
14+
DefaultProjectConfiguration?: string;
15+
DefaultVisualStudioVersion?: string;
16+
TypeScriptDefaultPropsFilePath?: string;
17+
TypeScriptDefaultConfiguration?: TypeScriptConfiguration;
18+
}
19+
interface TypeScriptConfiguration {
20+
AdditionalFlags?: string;
21+
Charset?: string;
22+
CodePage?: string;
23+
CompileOnSaveEnabled?: boolean;
24+
EmitBOM?: boolean;
25+
GeneratesDeclarations?: boolean;
26+
MapRoot?: string;
27+
ModuleKind?: string;
28+
NoEmitOnError?: boolean;
29+
NoImplicitAny?: boolean;
30+
NoLib?: boolean;
31+
NoResolve?: boolean;
32+
OutFile?: string;
33+
OutDir?: string;
34+
PreserveConstEnums?: boolean;
35+
RemoveComments?: boolean;
36+
SourceMap?: boolean;
37+
SourceRoot?: string;
38+
SuppressImplicitAnyIndexErrors?: boolean;
39+
Target?: string;
40+
}
41+
var xml2jsReadXMLFile: (fileName: string) => Promise<any>;
42+
var getTypeScriptSettings: (projectInfo: VSProjectParams) => Promise<TypeScriptSettings>;
43+
var normalizePath: (path: string, settings: TypeScriptSettings) => string;
44+
var getTypeScriptDefaultsFromPropsFileOrDefaults: (settings: TypeScriptSettings) => Promise<TypeScriptConfiguration>;
45+
var programFiles: () => string;
46+
}

defs/tsd.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/// <reference path="lodash/lodash.d.ts" />
44
/// <reference path="gruntjs/gruntjs.d.ts" />
55
/// <reference path="es6-promises/es6-promises.d.ts" />
6+
/// <reference path="csproj2ts/csproj2ts.d.ts" />

docs/DisableVisualStudioBuild.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# How to disable the Visual Studio TypeScript Build
2+
*but keep the TypeScript Project Properties Pane Working...*
3+
4+
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:
5+
6+
* First, make sure your project has TypeScript support enabled by opening the project properties and confirming that the TypeScript Build properties pane is selectable.
7+
* Next, make sure your project folder has grunt-ts installed, and confirm that running grunt with the appropriate configuration will compile your project correctly.
8+
* Exit Visual Studio (Targets are only read once, so unloading the project is not sufficient).
9+
* Make sure that your project is backed-up or fully checked-in to Source Control.
10+
* Edit the .csproj or .vbproj file for which you wish to disable VS TypeScript building.
11+
* Search for the line containing the text "Microsoft.TypeScript.targets". Delete or comment-out the entire line.
12+
* At that spot, add one of these lines:
13+
14+
**If grunt-ts is installed in node_modules under the Project folder:**
15+
```xml
16+
<Import Project="$(ProjectDir)\node_modules\grunt-ts\custom.TypeScript.targets" Condition="Exists('$(ProjectDir)\node_modules\grunt-ts\custom.TypeScript.targets')" />
17+
```
18+
19+
**If grunt-ts is installed in node_modules under the Solution folder:**
20+
```xml
21+
<Import Project="$(SolutionDir)\node_modules\grunt-ts\custom.TypeScript.targets" Condition="Exists('$(SolutionDir)\node_modules\grunt-ts\custom.TypeScript.targets')" />
22+
```
23+
24+
**If grunt-ts is installed elsewhere**
25+
Modify one of the previous examples to point to the `custom.TypeScript.targets` file.
26+
27+
* If you have multiple projects in your solution, you must edit each .csproj or .vbproj.
28+
* Reload Visual Studio and confirm that the TypeScript Build pane still appears in the project properties.
29+
* Then, introduce an error in a TypeScript file such as a mismatched parenthesis.
30+
* 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).
31+
32+
33+
34+

0 commit comments

Comments
 (0)