[FEATURE] Introduce TypeScript processing 95/49895/16
authorFrank Naegler <frank.naegler@typo3.org>
Fri, 9 Sep 2016 14:32:43 +0000 (16:32 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Mon, 10 Oct 2016 13:41:06 +0000 (15:41 +0200)
This patch introduce a grunt TypeScript processor and linter.

Resolves: #77900
Releases: master
Change-Id: I642db25c84946a97687e1aaa9e1c5e0599618073
Reviewed-on: https://review.typo3.org/49895
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Marco Bresch <marco.bresch@starfinanz.de>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
.gitignore
Build/Gruntfile.js
Build/package.json
Build/tsconfig.json [new file with mode: 0644]
Build/tslint.json [new file with mode: 0644]
Build/typings.json [new file with mode: 0644]
Build/typings/no-def/jquery.minicolors.d.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/TypeScript/ColorPicker.ts [new file with mode: 0644]
typo3/sysext/backend/Resources/Public/JavaScript/ColorPicker.js
typo3/sysext/backend/Resources/Public/JavaScript/ColorPicker.js.map [new file with mode: 0644]
typo3/sysext/core/Documentation/Changelog/master/Feature-77900-IntroduceTypeScriptForTheCore.rst [new file with mode: 0644]

index b7d8a1e..030272e 100644 (file)
@@ -27,6 +27,9 @@ nbproject
 # Ignore build stuff
 Build/bower_components/*
 Build/node_modules/*
+Build/JavaScript
+Build/typings/*
+!Build/typings/no-def*
 .cache
 .sass-cache
 .session
@@ -44,3 +47,6 @@ typo3conf/*
 fileadmin/*
 uploads/*
 /.htaccess
+# TypeScript stuff
+.baseDir.ts
+.tscache
index 86ad6df..5c2e6a2 100644 (file)
@@ -132,6 +132,28 @@ module.exports = function(grunt) {
                                src: '<%= paths.workspaces %>Public/Css/*.css'
                        }
                },
+               ts: {
+                       default : {
+                               tsconfig: true,
+                               options: {
+                                       verbose: false
+                               }
+                       }
+               },
+               tslint: {
+                       options: {
+                               configuration: 'tslint.json',
+                               force: false
+                       },
+                       files: {
+                               src: [
+                                       '<%= paths.sysext %>*/Resources/Private/TypeScript/**/*.ts'
+                               ]
+                       }
+               },
+               typings: {
+                       install: {}
+               },
                watch: {
                        options: {
                                livereload: true
@@ -139,12 +161,27 @@ module.exports = function(grunt) {
                        less: {
                                files: '<%= paths.less %>**/*.less',
                                tasks: 'css'
+                       },
+                       ts: {
+                               files: '<%= paths.sysext %>*/Resources/Private/TypeScript/**/*.ts',
+                               tasks: 'scripts'
                        }
                },
                copy: {
                        options: {
                                punctuation: ''
                        },
+                       ts_files: {
+                               files: [{
+                                       expand: true,
+                                       cwd: '<%= paths.root %>Build/JavaScript/typo3/sysext/',
+                                       src: ['**/*.js', '**/*.js.map'],
+                                       dest: '<%= paths.sysext %>',
+                                       rename: function(dest, src) {
+                                               return dest + src.replace('Resources/Private/TypeScript', 'Resources/Public/JavaScript');
+                                       }
+                               }]
+                       },
                        core_icons: {
                                files: [{
                                        expand: true,
@@ -303,6 +340,10 @@ module.exports = function(grunt) {
        grunt.loadNpmTasks('grunt-svgmin');
        grunt.loadNpmTasks('grunt-postcss');
        grunt.loadNpmTasks('grunt-contrib-copy');
+       grunt.loadNpmTasks('grunt-copy');
+       grunt.loadNpmTasks("grunt-ts");
+       grunt.loadNpmTasks('grunt-tslint');
+       grunt.loadNpmTasks('grunt-typings');
 
        /**
         * grunt default task
@@ -331,10 +372,23 @@ module.exports = function(grunt) {
         *
         * this task does the following things:
         * - npm install
+        * - typings install
         * - bower install
         * - copy some bower components to a specific destinations because they need to be included via PHP
         */
-       grunt.registerTask('update', ['npm-install', 'bower_install', 'bowercopy']);
+       grunt.registerTask('update', ['npm-install', 'typings', 'bower_install', 'bowercopy']);
+
+       /**
+        * grunt scripts task
+        *
+        * call "$ grunt scripts"
+        *
+        * this task does the following things:
+        * - 1) Check all TypeScript files (*.ts) with TSLint which are located in sysext/<EXTKEY>/Resources/Private/TypeScript/*.ts
+        * - 2) Compiles all TypeScript files (*.ts) which are located in sysext/<EXTKEY>/Resources/Private/TypeScript/*.ts
+        * - 3) Copy all generated JavaScript and Map files to public folders
+        */
+       grunt.registerTask('scripts', ['tslint', 'ts', 'copy:ts_files']);
 
        /**
         * grunt build task
@@ -347,6 +401,7 @@ module.exports = function(grunt) {
         * - compile less files
         * - uglify js files
         * - minifies svg files
+        * - compiles TypeScript files
         */
-       grunt.registerTask('build', ['update', 'copy', 'css', 'uglify', 'svgmin']);
+       grunt.registerTask('build', ['update', 'scripts', 'copy', 'css', 'uglify', 'svgmin']);
 };
index 397c7b7..cf0bd29 100644 (file)
     "grunt-contrib-less": "~1.4.0",
     "grunt-contrib-uglify": "2.0.0",
     "grunt-contrib-watch": "~1.0.0",
+    "grunt-copy": "*",
     "grunt-npm-install": "^0.3.1",
     "grunt-postcss": "^0.8.0",
     "grunt-svgmin": "4.0.0",
+    "grunt-ts": "^5.5.1",
+    "grunt-tslint": "^3.2.1",
+    "grunt-typings": "^0.1.5",
     "jasmine-core": "^2.4.1",
     "karma": "^1.3.0",
     "karma-chrome-launcher": "^2.0.0",
@@ -33,6 +37,9 @@
     "karma-safari-launcher": "^1.0.0",
     "phantomjs-prebuilt": "^2.1.7",
     "requirejs": "^2.2.0",
-    "tagsort": "1.4.0"
+    "tagsort": "1.4.0",
+    "tslint": "^3.15.1",
+    "typescript": "^1.8.10",
+    "typings": "^1.3.3"
   }
 }
diff --git a/Build/tsconfig.json b/Build/tsconfig.json
new file mode 100644 (file)
index 0000000..cb611a9
--- /dev/null
@@ -0,0 +1,172 @@
+{
+    "compilerOptions": {
+        "target": "es5",
+        "module": "amd",
+        "removeComments": false,
+        "pretty": true,
+        "baseUrl": ".",
+        "paths": {
+            "TYPO3/CMS/About/*": [
+                "../../typo3/sysext/about/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Backend/*": [
+                "../../typo3/sysext/backend/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Belog/*": [
+                "../../typo3/sysext/belog/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Beuser/*": [
+                "../../typo3/sysext/beuser/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Compatibility7/*": [
+                "../../typo3/sysext/compatibility7/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/ContextHelp/*": [
+                "../../typo3/sysext/context_help/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Core/*": [
+                "../../typo3/sysext/core/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Cshmanuel/*": [
+                "../../typo3/sysext/cshmanuel/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/CssStyledContent/*": [
+                "../../typo3/sysext/css_styled_content/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Documentation/*": [
+                "../../typo3/sysext/documentation/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Extbase/*": [
+                "../../typo3/sysext/extbase/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Extensionmanager/*": [
+                "../../typo3/sysext/extensionmanager/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Feedit/*": [
+                "../../typo3/sysext/feedit/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Felogin/*": [
+                "../../typo3/sysext/felogin/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Filelist/*": [
+                "../../typo3/sysext/filelist/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Filemetadata/*": [
+                "../../typo3/sysext/filemetadata/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Fluid/*": [
+                "../../typo3/sysext/fluid/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/FluidStyledContent/*": [
+                "../../typo3/sysext/fluid_styled_content/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Form/*": [
+                "../../typo3/sysext/form/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Frontend/*": [
+                "../../typo3/sysext/frontend/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Func/*": [
+                "../../typo3/sysext/func/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Impexp/*": [
+                "../../typo3/sysext/impexp/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/IndexedSearch/*": [
+                "../../typo3/sysext/indexed_search/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Info/*": [
+                "../../typo3/sysext/info/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/InfoPagetsconfig/*": [
+                "../../typo3/sysext/info_pagetsconfig/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Install/*": [
+                "../../typo3/sysext/install/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Lang/*": [
+                "../../typo3/sysext/lang/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Linkvalidator/*": [
+                "../../typo3/sysext/linkvalidator/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Lowlevel/*": [
+                "../../typo3/sysext/lowlevel/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Opendocs/*": [
+                "../../typo3/sysext/opendocs/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Recordlist/*": [
+                "../../typo3/sysext/recordlist/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Recycler/*": [
+                "../../typo3/sysext/recycler/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Reports/*": [
+                "../../typo3/sysext/reports/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Rsaauth/*": [
+                "../../typo3/sysext/rsaauth/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Rtehtmlarea/*": [
+                "../../typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Saltedpasswords/*": [
+                "../../typo3/sysext/saltedpassword/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Scheduler/*": [
+                "../../typo3/sysext/scheduler/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Setup/*": [
+                "../../typo3/sysext/setup/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Sv/*": [
+                "../../typo3/sysext/sv/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/SysAction/*": [
+                "../../typo3/sysext/sys_action/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/SysNote/*": [
+                "../../typo3/sysext/sys:note/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/T3editor/*": [
+                "../../typo3/sysext/t3editor/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/T3skin/*": [
+                "../../typo3/sysext/t3skin/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Taskcenter/*": [
+                "../../typo3/sysext/taskcenter/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Tstemplate/*": [
+                "../../typo3/sysext/tetemplate/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Version/*": [
+                "../../typo3/sysext/version/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Viewpage/*": [
+                "../../typo3/sysext/viewpage/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/WizardCrpages/*": [
+                "../../typo3/sysext/wizard_crpages/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/WizardSortpages/*": [
+                "../../typo3/sysext/wizard_sortpages/Resources/Public/JavaScript/"
+            ],
+            "TYPO3/CMS/Workspaces/*": [
+                "../../typo3/sysext/workspaces/Resources/Public/JavaScript/"
+            ]
+        },
+        "rootDir": "../../",
+        "outDir": "./JavaScript/"
+    },
+    "filesGlob": [
+        "typings/index.d.ts",
+        "../../typo3/sysext/*/Resources/Private/TypeScript/**/*.ts",
+        "!node_modules/**"
+    ],
+    "files": [
+        "typings/index.d.ts",
+        "../../typo3/sysext/backend/Resources/Private/TypeScript/ColorPicker.ts"
+    ]
+}
\ No newline at end of file
diff --git a/Build/tslint.json b/Build/tslint.json
new file mode 100644 (file)
index 0000000..208d322
--- /dev/null
@@ -0,0 +1,10 @@
+{
+       "// extends": "@see https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts",
+       "extends": "tslint:recommended",
+       "rules": {
+               "interface-name": false,
+               "no-console": false,
+               "quotemark": [true, "single", "avoid-escape"],
+               "typedef": [true, "call-signature", "arrow-call-signature", "arrow-parameter", "property-declaration", "variable-declaration", "parameter", "member-variable-declaration"]
+       }
+}
diff --git a/Build/typings.json b/Build/typings.json
new file mode 100644 (file)
index 0000000..03fb060
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "globalDependencies": {
+    "bootstrap": "registry:dt/bootstrap#3.3.5+20160619023404",
+    "d3": "registry:dt/d3#0.0.0+20160727131401",
+    "jquery": "registry:dt/jquery#1.10.0+20160704162008",
+    "jqueryui": "registry:dt/jqueryui#1.11.0+20160727153854",
+    "moment": "registry:dt/moment#2.11.1+20160829143156",
+    "nprogress": "registry:dt/nprogress#0.0.0+20160316155526",
+    "require": "registry:dt/require#2.1.20+20160316155526"
+  }
+}
diff --git a/Build/typings/no-def/jquery.minicolors.d.ts b/Build/typings/no-def/jquery.minicolors.d.ts
new file mode 100644 (file)
index 0000000..5d43cd3
--- /dev/null
@@ -0,0 +1,4 @@
+declare module "TYPO3/CMS/Core/Contrib/jquery.minicolors" {
+  var noTypeInfoYet: any; // any var name here really
+  export = noTypeInfoYet;
+}
diff --git a/typo3/sysext/backend/Resources/Private/TypeScript/ColorPicker.ts b/typo3/sysext/backend/Resources/Private/TypeScript/ColorPicker.ts
new file mode 100644 (file)
index 0000000..9c6cf9b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/// <amd-dependency path="TYPO3/CMS/Core/Contrib/jquery.minicolors">
+import $ = require('jquery');
+
+/**
+ * Module: TYPO3/CMS/Backend/ColorPicker
+ * contains all logic for the color picker used in FormEngine
+ * @exports TYPO3/CMS/Backend/ColorPicker
+ */
+class ColorPicker {
+  /**
+   * The selector for the color picker elements
+   */
+  private selector: string;
+
+  /**
+   * The constructor, set the class properties default values
+   */
+  constructor() {
+    this.selector = '.t3js-color-picker';
+  }
+
+  /**
+   * Initialize the color picker for the given selector
+   */
+  public initialize(): void {
+    (<any> $(this.selector)).minicolors({
+      format: 'hex',
+      position: 'bottom left',
+      theme: 'bootstrap',
+    });
+  }
+}
+// Create an instance and return it
+export = new ColorPicker();
index f7a502b..cd1d1e6 100644 (file)
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: TYPO3/CMS/Backend/ColorPicker
- * contains all logic for the color picker used in FormEngine
- */
-define(['jquery', 'TYPO3/CMS/Core/Contrib/jquery.minicolors'], function($) {
-
-       /**
-        * @type {{selector: string}}
-        * @exports TYPO3/CMS/Backend/ColorPicker
-        */
-       var ColorPicker = {
-               selector: '.t3js-color-picker'
-       };
-
-       /**
-        * Initialize ColorPicker elements
-        */
-       ColorPicker.initialize = function() {
-               $(function () {
-                       $(ColorPicker.selector).minicolors({
-                               theme: 'bootstrap',
-                               format: 'hex',
-                               position: 'bottom left'
-                       });
-               });
-       };
-
-       return ColorPicker;
+define(["require", "exports", 'jquery', "TYPO3/CMS/Core/Contrib/jquery.minicolors"], function (require, exports, $) {
+    "use strict";
+    /**
+     * Module: TYPO3/CMS/Backend/ColorPicker
+     * contains all logic for the color picker used in FormEngine
+     * @exports TYPO3/CMS/Backend/ColorPicker
+     */
+    var ColorPicker = (function () {
+        /**
+         * The constructor, set the class properties default values
+         */
+        function ColorPicker() {
+            this.selector = '.t3js-color-picker';
+        }
+        /**
+         * Initialize the color picker for the given selector
+         */
+        ColorPicker.prototype.initialize = function () {
+            $(this.selector).minicolors({
+                format: 'hex',
+                position: 'bottom left',
+                theme: 'bootstrap',
+            });
+        };
+        return ColorPicker;
+    }());
+    return new ColorPicker();
 });
+//# sourceMappingURL=ColorPicker.js.map
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/ColorPicker.js.map b/typo3/sysext/backend/Resources/Public/JavaScript/ColorPicker.js.map
new file mode 100644 (file)
index 0000000..8bb06d6
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"file":"ColorPicker.js","sourceRoot":"","sources":["../../../../../../../../../typo3/sysext/backend/Resources/Private/TypeScript/ColorPicker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;;;IAKH;;;;OAIG;IACH;QAME;;WAEG;QACH;YACE,IAAI,CAAC,QAAQ,GAAG,oBAAoB,CAAC;QACvC,CAAC;QAED;;WAEG;QACI,gCAAU,GAAjB;YACS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAE,CAAC,UAAU,CAAC;gBAClC,MAAM,EAAE,KAAK;gBACb,QAAQ,EAAE,aAAa;gBACvB,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;QACL,CAAC;QACH,kBAAC;IAAD,CAAC,AAvBD,IAuBC;IAED,OAAS,IAAI,WAAW,EAAE,CAAC"}
\ No newline at end of file
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-77900-IntroduceTypeScriptForTheCore.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-77900-IntroduceTypeScriptForTheCore.rst
new file mode 100644 (file)
index 0000000..57a4d04
--- /dev/null
@@ -0,0 +1,92 @@
+.. include:: ../../Includes.txt
+
+===================================================
+Feature: #77900 - Introduce TypeScript for the core
+===================================================
+
+See :forge:`77900`
+
+Description
+===========
+
+The TYPO3 core has introduced TypeScript for the internal JavaScript handling.
+
+
+Why we use TypeScript in the core?
+==================================
+
+TypeScript is a free and open source programming language developed and maintained by Microsoft. It is a strict superset of JavaScript, and adds optional static typing and class-based object-oriented programming to the language.
+
+With TypeScript it is possible to compile JavaScript. TypeScript supports definition files which can contain type information of existing JavaScript libraries.
+
+At the moment the core uses AMD modules for any JavaScript logic in the backend, but what is in 5 years? maybe we want switch to CommonJS, with TypeScript we can recompile all modules with a simple change in a configuration file.
+
+But the main reason to switch to TypeScript is the strict typing and oop structure of the language. We can make use of Interfaces, which is still a missing feature in JavaScript.
+
+
+Coding Guidelines & Best practice
+=================================
+
+:typescript:`/// <amd-dependency path="x" />` informs the compiler about a non-TS module dependency that needs to be injected in the resulting module's require call.
+
+The amd-dependency has a property name which allows passing an optional name for an amd-dependency: :typescript:`/// <amd-dependency path="x" name="fooBar" />`
+
+An example:
+
+:typescript:`/// <amd-dependency path="TYPO3/CMS/Core/Contrib/jquery.minicolors" name="minicolors">`
+
+will be compiled to:
+
+:js:`define(["require", "exports", "TYPO3/CMS/Core/Contrib/jquery.minicolors"], function (require, exports, minicolors) {`
+
+A very simple example is the `EXT:backend/Resources/Private/TypeScript/ColorPicker.ts` file.
+
+TypeScript Linter
+=================
+
+The most rules for TypeScript are defined in the rulesets which are checked by the TypeScript Linter.
+The core provides a configuration file and grunt tasks to ensure a better code quality. For this reason we introduce a new grunt task, which first run the Linter on each TypeScript file before starting the compiler.
+So if your TypeScript does not follow the rules, the task will fail. The idea is to write clean code, else it will not be compiled.
+
+Additional Rules
+================
+
+For the core we have defined some additional rules which you should know, because not all of them can be checked by the Linter yet:
+
+#. Always define types and return types, also if TypeScript provides a default type. [checked by Linter]
+#. Variable scoping: Prefer :js:`let` instead of :js:`var`. [checked by Linter]
+#. Optional properties in interfaces are possible but a bad style, this is not allowed for the core. [NOT checked by Linter]
+#. An interface will never extend a class. [NOT checked by Linter]
+#. Iterables: Use :js:`for (i of list)` if possible instead of :ts:`for (i in list)` [NOT checked by Linter]
+#. The :js:`implements` keyword is required for any usage, also if TypeScript does not require it. [NOT checked by Linter]
+#. Any class or interface must be declared with "export" to ensure re-use or export an instance of the object for existing code which can't be updated now. [NOT checked by Linter]
+
+
+Contribution workflow
+=====================
+
+.. code-block:: shell
+
+       # Change to Build directory
+       cd Build
+
+       # Install dependencies
+       npm install
+
+       # Install typings for the core
+       grunt typings
+
+       # Check with Linter and compile ts files from sysext/*/Resources/Private/TypeScript/*.ts
+       grunt scripts
+
+       # File watcher, the watch task also check for *.ts files
+       grunt watch
+
+The grunt task compiles each TypeScript file (*.ts) to a JavaScript file (*.js) and produces an AMD module.
+
+
+Impact
+======
+
+All AMD modules must be ported to TypeScript to ensure a future proof concept of JavaScript handling.
+The goal is to migrate all AMD modules to a TypeScript file until CMS 8 LTS is released.