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 'import.meta' by DanielRosenwasser · Pull Request #23327 · microsoft/TypeScript

Conversation

@DanielRosenwasser

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) commented Apr 10, 2018 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

Fixes #22861. This PR introduces support for import.meta, a meta-property described here.

Here are some details on the implementation.

The ImportMeta Interface

The type of import.meta is the global ImportMeta type which is defined in lib.es5.d.ts:

interface ImportMeta {
}

This interface is extremely limited. Adding well-known properties for Node or browsers requires interface merging and possibly a global augmentation depending on the context.

For example, one might want to say that __dirname is always available on import.meta:

// node.d.ts
interface ImportMeta {
    __dirname: string;
}

Any user of the above .d.ts file will be able to get completions for import.meta.__dirname which has the type string.

Alternatively, you might be in a bind and just need to say "yes, I know import.meta will have this property, and I only need to use it in one file":

// declaring a property ad-hoc/offhandedly
declare global  {
    interface ImportMeta {
        mySuperCoolProperty: string;
    }
}

import.meta.mySuperCoolProperty // Has type 'string', not 'any'.

An earlier version of this pull request defined ImportMeta as follows:

interface ImportMeta {
    [propertyName: string]: any;
}

However, this interface is extremely lax, and means that you can misspell any property.

Community feedback is appreciated here.

Targets

import.meta is only allowed when targeting ESNext modules and ECMAScript targets.

I think it might make sense to say "this only runs on ESNext modules, but can run on any target", but I'd rather be conservative for now.

Incremental Parsing

import.meta is only valid within a module. This implies one of two things:

  1. It is an error to use import.meta if the current module does not contain a module indicator (i.e. the module has no imports/exports).
  2. import.meta itself is a module indicator (which turns the current file into a module).

I went with choice (2), which implies that a module indicator can occur anywhere within the file. To avoid a full walk of the tree, I use a new NodeFlag called PossiblyContainsImportMeta. Much like NodeFlags.PossiblyContainsDynamicImport, this new flag is set exactly once, and is never unset when re-using an AST.

When the flag is set, we will do a full walk of the AST to find module indicators, but in the common case, we'll run into an import or export declaration.

Sorry, something went wrong.

Uh oh!

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

HerringtonDarkholme, saschanaz, giovannipessiva, and styfle reacted with thumbs up emoji
All reactions
  • 👍 4 reactions
Daniel Rosenwasser (DanielRosenwasser) added 10 commits April 9, 2018 15:26
@DanielRosenwasser
Added tests for 'import.meta'.
8923eec
@DanielRosenwasser
Accepted baselines.
9b8670c
@DanielRosenwasser
Basic parsing/emitting support for 'import.meta'.
9e2bbb6
@DanielRosenwasser
Basic checking for 'import.meta'.
f0081f0
@DanielRosenwasser
Accepted baselines.
910c5d3
@DanielRosenwasser
Added semicolon.
7c0f249
@DanielRosenwasser
Provide an error when using 'import.meta' without setting 'esnext'.
56f4b2e
@DanielRosenwasser
Added tests around ES5, assigning to 'import.meta' and properties, gl…
4f497e6
…obal augmentations.
@DanielRosenwasser
Accepted baselines.
1ea269a
@DanielRosenwasser
'modulekind' -> 'moduleKind'
0feefab
mhegazy
Mohamed Hegazy (mhegazy) reviewed Apr 18, 2018
View reviewed changes
Comment thread src/lib/es5.d.ts Outdated
}

interface ImportMeta {
[propertyName: string]: any;

@mhegazy Mohamed Hegazy (mhegazy) Apr 18, 2018

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.

There is no way to opt out of this one... users who want strict definition can not undo the index signature. consider not adding it and letting say node.d.ts add it.

Sorry, something went wrong.

Uh oh!

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

Jessidhia reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
DanielRosenwasser
Daniel Rosenwasser (DanielRosenwasser) commented Apr 18, 2018
View reviewed changes
Comment thread src/compiler/parser.ts Outdated
}

function walkTreeForExternalModuleIndicators(node: Node): Node {
return isAnExternalModuleIndicatorNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);

@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) Apr 18, 2018

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.

This can accidentally pick up an import/export from an module augmentation as the current file's externalModuleIndicator if we're not careful.

declare module "foo" {
  import * as blah from "blah"
}

import.meta

Sorry, something went wrong.

Uh oh!

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

All reactions
Daniel Rosenwasser (DanielRosenwasser) added 2 commits April 24, 2018 12:38
@DanielRosenwasser
Make 'ImportMeta' more minimal.
a55febd
@DanielRosenwasser
Accepted baselines.
28f8d75
@DanielRosenwasser
Daniel Rosenwasser (DanielRosenwasser) force-pushed the importDotMeta branch from 331230d to 28f8d75 Compare April 24, 2018 19:40
@e111077

Elliott Marquez (e111077) commented Apr 26, 2018

Copy link
Copy Markdown

Heya, we are using stackblitz to host our documentation demos on our site before Google I/O, and we believe that we are blocked on this issue. Do you know which typescript release this fix would be included in?

CC: Eric Simons (@EricSimons) Justin Fagnani (@justinfagnani)

Relevant issues:
stackblitz/core#378
Polymer/old-docs-site#2537

All reactions

Sorry, something went wrong.

Uh oh!

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

@weswigham

Wesley Wigham (weswigham) commented Apr 26, 2018

Copy link
Copy Markdown
Member

2.9 would be our next feature release, which should be cut sometime near the end of May.

e111077 and giovannipessiva reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

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

@DanielRosenwasser
Merge remote-tracking branch 'origin/master' into importDotMeta
9672116
@e111077 Elliott Marquez (e111077) mentioned this pull request Apr 26, 2018
Stackblitz demos for 3.x elements Polymer/old-docs-site#2537
Merged
mhegazy
Mohamed Hegazy (mhegazy) reviewed Apr 26, 2018
View reviewed changes
Comment thread src/compiler/parser.ts Outdated
// and possibly nested import statements in the future).
// Ideally the first few statements will be an import/export anyway.
sourceFile.externalModuleIndicator =
!(sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ?

@mhegazy Mohamed Hegazy (mhegazy) Apr 26, 2018

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.

i think this should be:

sourceFile.externalModuleIndicator = forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || getImportMetaNode(sourceFile);

function isAnExternalModuleIndicatorNode(node: Node) {
    return hasModifier(node, ModifierFlags.Export)
        || node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
        || node.kind === SyntaxKind.ImportDeclaration
        || node.kind === SyntaxKind.ExportAssignment
        || node.kind === SyntaxKind.ExportDeclaration
        ? node
        : undefined
}

function isImportMetaNode(node: Node) { 
    return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta";
}

function walkTreeForExternalModuleIndicators(node: Node): Node {
    return isImportMetaNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
}

function getImportMetaNode(node: SourceFile) { 
    return (sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ? walkTreeForExternalModuleIndicators(node) : undefined;
} 

Sorry, something went wrong.

Uh oh!

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

All reactions
@mhegazy

Mohamed Hegazy (mhegazy) commented Apr 26, 2018

Copy link
Copy Markdown
Contributor

Please take a look at the checklist in https://github.com/Microsoft/TypeScript/wiki/Release-Activities#new-syntax-introduced.

we need to add colorization support as well.

All reactions

Sorry, something went wrong.

Uh oh!

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

mhegazy
Mohamed Hegazy (mhegazy) approved these changes Apr 26, 2018
View reviewed changes
@DanielRosenwasser
Look for top-level imports/exports before diving into the tree.
bc0d3e1
@DanielRosenwasser Daniel Rosenwasser (DanielRosenwasser) mentioned this pull request Apr 28, 2018
'import.meta'/'new.target' should have some special colorization microsoft/TypeScript-TmLanguage#609
Closed
Daniel Rosenwasser (DanielRosenwasser) added 2 commits April 27, 2018 17:51
@DanielRosenwasser
Check for both 'module' and 'target'.
161535b
@DanielRosenwasser
Specify ESNext module in test.
12a3e39
@DanielRosenwasser

Daniel Rosenwasser (DanielRosenwasser) commented Apr 28, 2018

Copy link
Copy Markdown
Member Author

We can get this in first and discuss relaxing the restriction after.

All reactions

Sorry, something went wrong.

Uh oh!

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

@DanielRosenwasser
Daniel Rosenwasser (DanielRosenwasser) merged commit 443c1c7 into master Apr 28, 2018
@DanielRosenwasser
Daniel Rosenwasser (DanielRosenwasser) deleted the importDotMeta branch April 28, 2018 03:52
@smockle Clay Miller (smockle) mentioned this pull request Jun 26, 2018
[TypeScript] import.meta causes SyntaxError: Argument expression expected prettier/prettier#4755
Closed
Clay Miller (smockle) added a commit to smockle/contrast that referenced this pull request Jun 26, 2018
@smockle
Replace '@std/esm' with 'esm' and '__dirname' with 'import.meta.url'
593e4a1
microsoft/TypeScript#23327
@ikatyang Ika (ikatyang) mentioned this pull request Jun 27, 2018
Fix: support ImportMeta (fixes #489) eslint/typescript-eslint-parser#490
Merged
@microsoft Microsoft (microsoft) locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

1 more reviewer
@mhegazy Mohamed Hegazy (mhegazy) mhegazy approved these changes
Reviewers whose approvals may not affect merge requirements

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.

4 participants

@DanielRosenwasser @e111077 @weswigham @mhegazy
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.