diff --git a/demos/typescript/a.js b/demos/typescript/a.js new file mode 100644 index 000000000..43d8191df --- /dev/null +++ b/demos/typescript/a.js @@ -0,0 +1,6 @@ + + + function foo() { + + return "hello" +} \ No newline at end of file diff --git a/demos/typescript/a.md b/demos/typescript/a.md new file mode 100644 index 000000000..95efab456 --- /dev/null +++ b/demos/typescript/a.md @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/demos/typescript/a.ts b/demos/typescript/a.ts new file mode 100644 index 000000000..386042b48 --- /dev/null +++ b/demos/typescript/a.ts @@ -0,0 +1,5 @@ +console.log("LOAD a.ts") + +function foo() { + return "hello" +} \ No newline at end of file diff --git a/demos/typescript/b.js b/demos/typescript/b.js new file mode 100644 index 000000000..06836dc18 --- /dev/null +++ b/demos/typescript/b.js @@ -0,0 +1,6 @@ +import * as a from "./a.ts" + +export default function foo() { + + return a.foo() +} \ No newline at end of file diff --git a/demos/typescript/c.ts b/demos/typescript/c.ts new file mode 100644 index 000000000..be48bb314 --- /dev/null +++ b/demos/typescript/c.ts @@ -0,0 +1,5 @@ +lively.notify("LOAD c.ts") + +export default function foo(s : string) : string { + return "hello " + s +} \ No newline at end of file diff --git a/src/components/tools/lively-container.js b/src/components/tools/lively-container.js index bad620288..b3c05bcf5 100644 --- a/src/components/tools/lively-container.js +++ b/src/components/tools/lively-container.js @@ -770,7 +770,7 @@ export default class Container extends Morph { // #TODO #babel6refactoring if (lively.modules) { - if (urlString.match(/\.js$/)) { + if (urlString.match(/\.((js)|(ts))$/)) { var m = lively.modules.module(urlString); } } @@ -1205,7 +1205,7 @@ export default class Container extends Morph { lively.error("custom elements require a hyphen in their name!") // see https://html.spec.whatwg.org/multipage/custom-elements.html#prod-potentialcustomelementname } this.openTemplateInstance(url); - } else if (url.match(/\.js$/)) { + } else if (url.match(/\.((js)|(ts))$/)) { this.reloadModule(url); } else { lively.openBrowser(url); @@ -1460,11 +1460,11 @@ export default class Container extends Morph { } this.updateOtherContainers(); - var moduleName = this.getURL().pathname.match(/([^/]+)\.js$/); + var moduleName = this.getURL().pathname.match(/([^/]+)\.((js)|(ts))$/); if (moduleName) { moduleName = moduleName[1]; - const testRegexp = /((test\/.*)|([.-]test)|([.-]spec))\.js/; + const testRegexp = /((test\/.*)|([.-]test)|([.-]spec))\.((js)|(ts))/; if (this.lastLoadingFailed) { console.log("last loading failed... reload") await this.reloadModule(url); // use our own mechanism... @@ -1529,7 +1529,7 @@ export default class Container extends Morph { async onTextChanged() { - if (!this.getURL().pathname.match(/\.js$/)) { + if (!this.getURL().pathname.match(/\.((js)|(ts))$/)) { return } } @@ -2076,7 +2076,7 @@ export default class Container extends Morph { if (codeMirror) { const cmURL = "" + url; - if (cmURL.match(/\.((js)|(py))$/)) { + if (cmURL.match(/\.((js)|(ts)|(py))$/)) { codeMirror.setTargetModule("" + url); // for editing } diff --git a/src/components/widgets/lively-code-mirror.js b/src/components/widgets/lively-code-mirror.js index 2874c8a89..2eaa6bbeb 100644 --- a/src/components/widgets/lively-code-mirror.js +++ b/src/components/widgets/lively-code-mirror.js @@ -1106,6 +1106,8 @@ export default class LivelyCodeMirror extends HTMLElement { mode = "text/jsx"; } else if (filename.match(/\.mjs$/)) { mode = "text/jsx"; + } else if (filename.match(/\.ts$/)) { + mode = "text/typescript"; } else if (filename.match(/\.py$/)) { mode = "text/x-python"; } else if (filename.match(/\.c$/)) { diff --git a/src/external/babel-plugin-var-recorder.js b/src/external/babel-plugin-var-recorder.js index 9f01a209d..ebfb9d3d8 100644 --- a/src/external/babel-plugin-var-recorder.js +++ b/src/external/babel-plugin-var-recorder.js @@ -1,7 +1,7 @@ const moduleNameToVarRecorderName = new Map(); export function getScopeIdForModule(moduleName) { - console.log("[babel-plugin-var-recorder] getScopeIdForModule", moduleName); + // console.log("[babel-plugin-var-recorder] getScopeIdForModule", moduleName); if (!moduleNameToVarRecorderName.has(moduleName)) { var scopeId = (moduleName || "undefined").replace(lively4url, "").replace(/[^a-zA-Z0-9]/g, "_") moduleNameToVarRecorderName.set(moduleName, scopeId); diff --git a/src/plugin-babel.js b/src/plugin-babel.js index 969e611ce..eb3167ce5 100644 --- a/src/plugin-babel.js +++ b/src/plugin-babel.js @@ -672,8 +672,14 @@ async function transformSource(load, babelOptions, config) { var stage3Syntax = [] // console.log(`transformSource ${config.filename} ${babelOptions.babel7level}`) - - if (babelOptions.babel7level == "moduleOptionsNon") { + if (babelOptions.babel7level == "liveTS") { + allPlugins.push(...await basePlugins()) + allPlugins.push(babel7.babelPluginTransformTypeScript) + allPlugins.push(babel7.babelPluginProposalDynamicImport) + allPlugins.push([babel7.babelPluginTransformModulesSystemJS, { + allowTopLevelThis: true + }]) + } else if (babelOptions.babel7level == "moduleOptionsNon") { allPlugins.push(babel7.babelPluginProposalDynamicImport) allPlugins.push([babel7.babelPluginTransformModulesSystemJS, { allowTopLevelThis: true diff --git a/src/systemjs-config.js b/src/systemjs-config.js index b085c72c4..391324038 100644 --- a/src/systemjs-config.js +++ b/src/systemjs-config.js @@ -507,6 +507,15 @@ const liveES7 = { } }; +const liveTS = { + babelOptions: { + plugins: [], + babel7: true, + babel7level: "liveTS" + } +}; + + const babel7base = { babelOptions: { babel7: true, @@ -526,6 +535,7 @@ System.config({ meta: { '*.js': liveES7, '*.mjs': liveES7, + '*.ts': liveTS, 'https://unpkg.com/*.js': moduleOptionsNon, /* FILE-BASED */ /* plugins are not transpiled with other plugins, except for SystemJS-internal plugins */