GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Support ES6 import and export declarations by ahejlsberg · Pull Request #1983 · microsoft/TypeScript

Conversation

@ahejlsberg

@ahejlsberg Anders Hejlsberg (ahejlsberg) commented Feb 9, 2015

Copy link
Copy Markdown
Member

This PR adds support for ES6 import and export declarations. Supported import forms include:

import defaultBinding from "foo";  // Import foo's default export
import * as foo from "foo";        // Make a single binding for the entire namespace
import { a, b as x } from "foo";   // Make local bindings for individually imported members

Supported export forms include:

export { a, b as x };             // Export local entities
export { a, b as x } from "foo";  // Re-export individual members of foo without local bindings
export * from "foo";              // Re-export all members of foo without local bindings

The following export forms are not yet implemented:

export default class {...}
export default function(...) {...}
export default someExpression;

ES6 modules are very similar to TypeScript's external modules. ES6 modules permit individual entities to be exported using an export modifier and additionally support an optional export default in each module. The export default corresponds to TypeScript's export =, except that in ES6 a module can have both individual exports and a default export.

Given the following external module utils.ts:

export function foo(s: string) {}
export function bar(s: string) {}
export default function(x: number) {}

here are some ways it might be imported:

import * as utils from "utils";  // Namespace import
utils.foo("hello");
utils.bar("world");
import { foo, bar as baz } from "utils";  // Individual named imports
foo("hello");
baz("world");
import func from "utils";  // Import of default export
func(42);
import func, { foo, bar } from "utils";  // Combination
func(42);
foo("hello");
bar("world");

When ES6 modules are compiled down-level for ES3 or ES5 (which is currently the only supported way), a module cannot have both individual exports and a default export.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Sheetal Nandi (sheetalkamat) and others added 30 commits January 27, 2015 14:42
@sheetalkamat
Rename existing import declaration to ImportEqualsDeclaration
e058189
@sheetalkamat
Types for the new es6 style import statement parsing
5bd8271
@sheetalkamat
Parse import ModuleSpecifier;
4f1b908
@sheetalkamat
Parsing for import * as ImportedBinding
fdd7032
@sheetalkamat
Parsing for NamedImports
5eb0094
NamedImports :
{ }
{ ImportsList }
{ ImportsList , }

ImportsList :
ImportSpecifier
ImportsList , ImportSpecifier

ImportSpecifier :
ImportedBinding
IdentifierName as ImportedBinding

Conflicts:
	src/compiler/parser.ts
@sheetalkamat
Parsing for default binding import syntax
69fef6e
@sheetalkamat
Rename bindings to namedBindings in ImportClause
d296a10
@sheetalkamat
Code review feedback
b0f2265
@sheetalkamat
Some refactoring of how import specifiers are parsed as per code revi…
fc91272
…ew feedback
@sheetalkamat
Tests for more combination of import specifier list
89d0146
@sheetalkamat
More test cases for incorrect named modules specification
484144b
@sheetalkamat
Rename ImportStatement to ImportDeclaration
c521fe4
@sheetalkamat
Do not create Name of the importSpecifier if it isnt identifier, to a…
d85581b
…void creating missing symbols

Missing symbols are defined when the declaration doesnt have name,
so if we created node for missing identifier it would end up binding symbol with name (Missing)
@sheetalkamat
Change the name of defaultBinding to name and make ImportClause as De…
62ed618
…claration

This helps binder to use it directly to bind the default binding
@sheetalkamat
New Import declaration syntax makes the source file external module
a9575a5
@ahejlsberg
Adding new import nodes to forEachChild
36c9cf0
@ahejlsberg
Process ES6 imports when creating program
35583e6
@ahejlsberg
Support ES6 imports in binder
c6a6619
@ahejlsberg
Resolve ES6 imports in type checker
6d0db0f
@ahejlsberg
Cleaning up a few things
930d11b
@ahejlsberg
Always bind children of import clause
89f58d0
@ahejlsberg
Merge branch 'master' into es6importcheck
7bd14a7
Conflicts:
	src/compiler/checker.ts
@ahejlsberg
Correctly set position of import declaration nodes
7e187ef
@ahejlsberg
CommonJS emit for ES6 import declarations
69bd059
@ahejlsberg
Accepting new baselines
acaea1c
@ahejlsberg
AMD emit for ES6 import declarations
c8cc195
@ahejlsberg
Accepting new baselines
e30fc41
@ahejlsberg
Formatting fixes
69d47ef
@ahejlsberg
Checking of ES6 import declarations
e47f64c
@ahejlsberg
Accepting new baselines
a075525
@ahejlsberg
Accepting new baselines
e52ddcb
@RyanCavanaugh

Ryan Cavanaugh (RyanCavanaugh) commented Feb 13, 2015

Copy link
Copy Markdown
Member

Notes from the design meeting

If we rewrite references to an imported function func to _ref.func, then rewritten calls to func() will have a this of _ref instead of the default. Potential fix is to rewrite invocations as (0, _ref.func)(args) instead of _ref.func(args) (note that (_ref.func)(args) is not a sufficient fix).

Brian notes that this will be undefined in any ES6 module, so we may not need to really care.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 13, 2015

Copy link
Copy Markdown
Member Author

Sheetal Nandi (@sheetalkamat) That should be an error. We currently put all external symbols of a module into scope, but we should exclude those that came from an export declaration. I will fix.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ahejlsberg
Re-exported symbols should not be in scope
c601210
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 13, 2015

Copy link
Copy Markdown
Member Author

Ryan Cavanaugh (@RyanCavanaugh) Regarding effects of rewriting on this, the same thing happens today with the rewrite we do when referencing exported members of another declaration of the same internal module. It happens everywhere in the compiler, for example. Doesn't appear to be a problem, at least I haven't seen anyone report an issue for it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Anders Hejlsberg (ahejlsberg) added 2 commits February 15, 2015 08:25
@ahejlsberg
Support for 'export *' declarations
a8152b6
@ahejlsberg
Accepting new baselines
cc52dce
@ahejlsberg

Anders Hejlsberg (ahejlsberg) commented Feb 15, 2015

Copy link
Copy Markdown
Member Author

Latest commit adds support for export * declarations, including binding, checking, and down-level emit for CommonJS and AMD. Mohamed Hegazy (@mhegazy) Sheetal Nandi (@sheetalkamat) The commit does not include .d.ts emit support.

An example:

// a.ts
export var x = 1;
export var y = 2;
export function foo() {
    console.log("Hello from a");
}
// b.ts
export function foo() {
    console.log("Hello from b");
}
export { foo as bar };
export * from "./a";
// t.ts
import * as a from "./a";
import * as b from "./b";
a.foo();  // Hello from a
b.foo();  // Hello from b
b.bar();  // Hello from b
console.log(a.x);  // 1
console.log(b.x);  // 1

This generates the following when compiled with -m commonjs:

// a.js
exports.x = 1;
exports.y = 2;
function foo() {
    console.log("Hello from a");
}
exports.foo = foo;
// b.js
function foo() {
    console.log("Hello from b");
}
exports.foo = foo;
exports.bar = foo;
var _a = require("./a");
for (var _b in _a) if (!exports.hasOwnProperty(_b)) exports[_b] = _a[_b];
// t.js
var a = require("./a");
var b = require("./b");
a.foo();
b.foo();
b.bar();
console.log(a.x);
console.log(b.x);
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vladima
vladima reviewed Feb 16, 2015
View reviewed changes
Comment thread src/compiler/checker.ts Outdated

@vladima Vladimir Matveev (vladima) Feb 16, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to have a situation when name does not appear in current file but exists on the top level in some another file (like window or name)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@JsonFreeman Jason Freeman (JsonFreeman) Feb 16, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ahejlsberg Anders Hejlsberg (ahejlsberg) Feb 16, 2015

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should probably check globals as well. Will fix.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ahejlsberg
Include globals in check for existing identifiers
7cca651
vladima
vladima reviewed Feb 16, 2015
View reviewed changes
Comment thread src/compiler/checker.ts

@vladima Vladimir Matveev (vladima) Feb 16, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identifiers can be incomplete after incremental parsing so 'compile on save' will be broken. that is why we use a separate table nameTable in part of SourceFile that belongs to services layer. We can pull initializeNameTable function that builds nameTable on demand down to the base compiler.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ahejlsberg Anders Hejlsberg (ahejlsberg) Feb 16, 2015

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should do that.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Feb 16, 2015
define parameter not generated for a referenced AND used external module class. #2038
Closed
CyrusNajmabadi
CyrusNajmabadi reviewed Feb 21, 2015
View reviewed changes
Comment thread src/compiler/parser.ts Outdated

@CyrusNajmabadi Cyrus Najmabadi (CyrusNajmabadi) Feb 21, 2015

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the new import and export node types should be in this list.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Anders Hejlsberg (ahejlsberg) added 2 commits February 23, 2015 11:15
@ahejlsberg
Merge branch 'master' into es6Import
f0f4ca6
Conflicts:
	src/compiler/diagnosticInformationMap.generated.ts
	src/compiler/diagnosticMessages.json
	src/compiler/emitter.ts
	tests/baselines/reference/APISample_compile.js
	tests/baselines/reference/APISample_compile.types
	tests/baselines/reference/APISample_linter.js
	tests/baselines/reference/APISample_linter.types
	tests/baselines/reference/APISample_transform.js
	tests/baselines/reference/APISample_transform.types
	tests/baselines/reference/APISample_watcher.js
	tests/baselines/reference/APISample_watcher.types
	tests/baselines/reference/recursiveClassReferenceTest.js.map
	tests/baselines/reference/recursiveClassReferenceTest.sourcemap.txt
@ahejlsberg
Addressing CR feedback
27529f1
@mhegazy Mohamed Hegazy (mhegazy) mentioned this pull request Feb 23, 2015
Merge and re-export module in external module declaration #2019
Closed
@jbrantly James Brantly (jbrantly) mentioned this pull request Feb 23, 2015
Create "Global / External-agnostic" declaration files without exposing internal definitions #2018
Closed
Anders Hejlsberg (ahejlsberg) added a commit that referenced this pull request Feb 23, 2015
@ahejlsberg
Merge pull request #1983 from Microsoft/es6Import
4aae41b
Support ES6 import and export declarations
@ahejlsberg
Anders Hejlsberg (ahejlsberg) merged commit 4aae41b into master Feb 23, 2015
@Vadorequest

Vadorequest (Vadorequest) commented Feb 28, 2015

Copy link
Copy Markdown

Super nice. Thanks!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Mar 4, 2015
Complete support for ES6 modules #2197
Merged
ES6 Modules #2242
Closed
@mhegazy
Mohamed Hegazy (mhegazy) deleted the es6Import branch June 18, 2015 06:57
@parisk Paris Kasidiaris (parisk) mentioned this pull request Sep 16, 2016
I now need to fork to use an arbitrary commit in vscode xtermjs/xterm.js#270
Closed
@daslicht

Marc Wensauer (daslicht) commented Nov 12, 2016

Copy link
Copy Markdown

how to import templates like this with the es6 syntax, please:
var template = require("./file.handlebars");
https://github.com/pcardune/handlebars-loader#your-js-making-use-of-the-templates

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aluanhaddad

Aluan Haddad (aluanhaddad) commented Nov 12, 2016 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Marc Wensauer (@daslicht) First, you need a loader that interpolates them into a named module export, usually this is the export named default.
Then you need an ambient wildcard module declaration so that TypeScript understand that the paths are legal module import targets. That part looks like

declare module '*.handlebars' {
  // export matching the shape produced by the loader.
}

In your case, it looks like using ES2015 module syntax is not supported, and you are stuck with export = and import = as I noticed you commented on pcardune/handlebars-loader#115

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@daslicht

Marc Wensauer (daslicht) commented Nov 17, 2016 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
First, you need a loader that interpolates them into a named module export, usually this is the export named default.

Any example on that ? please?

I am trying to use handlebars in an TypeScript setup

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aluanhaddad

Aluan Haddad (aluanhaddad) commented Nov 17, 2016 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Marc Wensauer (@daslicht) say I were using SystemJS to load and bundle my application. In that case I would have a setup like this (simplified)

systemjs.config.js

SystemJS.config({
  meta: {
    '*.handlebars': {
      loader: 'text-loader-plugin'
    }
  }
});

If I were using webpack it would look like this (simplified)

webpack.config.js

module.exports = {
  loaders: [
    {
      test: /\.handlebars$/,
      loader: 'text-loader-plugin'
    }
  ]
};

The plugin would sort of look like this (changed and simplified for exposition)

text-loader-plugin.js

export default function (path) {
  const content = load(path); // XHR or fs.readFile
  return { 
    'default': content 
  };
}

Then in my TypeScript project I would have a file like globals.d.ts with the following declaration

globals.d.ts

declare module '*.handlebars' {
  export default '';
}

Then I would use it like this

app/home.ts

import template from 'app/home.handlebars';
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@daslicht

Marc Wensauer (daslicht) commented Nov 17, 2016 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

OK, thank you !, I keep trying, my approach was using the handlebars-loader:
https://github.com/pcardune/handlebars-loader

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

11 participants

@ahejlsberg @JsonFreeman @RyanCavanaugh @Vadorequest @daslicht @aluanhaddad @yuit @CyrusNajmabadi @vladima @sheetalkamat @msftclas
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.