Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing #37

Open
jamiebuilds opened this issue Jul 1, 2019 · 0 comments
Open

Importing #37

jamiebuilds opened this issue Jul 1, 2019 · 0 comments

Comments

@jamiebuilds
Copy link
Owner

Specifiers

Standard Library Packages

The import bare syntax is reserved for packages in the standard library.

import time
import math

Community Packages

Packages outside of the standard library will always be scoped.

import facebook/react
import jamiebuilds/unstated

Local Packages

Packages can also exist within a local project, and will follow the same scoping rules as community packages.

import mycompany/api
import mycompany/utils

Local Modules

import ./sibling
import ../parent
import ../../grandparent
import ../../path/to/cousin

Scoping rules

Bare Namespace

When importing a module with import ./mod the name mod becomes a namespace containing all of the modules exports

import ./mod
# mod.foo
# mod.bar
# mod.baz

Renamed Namespaces

You can rename namespaces using import ./mod as other.

import ./mod as other
# other.foo (mod.foo)
# other.bar (mod.bar)
# other.baz (mod.baz)

Renaming is useful to avoid clashes

Destructuring Exports

Alternatively, you can pick the exports you need without putting them on a namespace.

import ./mod as { foo, bar, baz }
# foo
# bar
# baz

Just like normal destructuring, you can also use ...rest to put any remaining exports onto a namespace.

import ./mod as { foo, ...rest }
# foo
# rest.bar
# rest.baz

Also like normal destructuring, you can also rename within destructuring.

import ./mod as { foo as bam, bar as bat }
# bam (foo)
# bat (bat)

Spread Exports

Inversely, you can spread all exports into the local scope.

import ./mod as ...
# foo
# bar
# baz

This can be extremely useful for DSLs where you want lots of things in scope:

import css as ...

let rule = css(
  display(.block),
  fontFamily(.sansSerif),
)

Default Exports

Modules can also have "default" exports by naming an export the same thing as the file name.

# foo.ghost:
let foo = fn () {} # because `foo` matches `foo.ghost` it gets special treatment (see below)
let bar = fn () {}
let baz = fn () {}

# other.ghost:
import ./foo                 # in scope: foo, foo.foo, foo.bar
import ./foo as bat          # in scope: bat (foo), bat.foo, bat.bar
import ./foo as { foo, bar } # in scope: foo, bar
import ./foo as { ...bat }   # in scope: bat.foo, bat.bar, bat.baz
import ./foo as ...          # in scope: foo, bar, baz

I want to have a concept of default exports because I don't want to end up with imports like this:

import ./foo
# foo.foo

import ./foo as { foo }
# foo

import ./bar # named "bar" just so you don't repeat "foo.foo"
# bar.foo

I think that it is okay to use the filename for this because I already consider the filename as part of the public API of a module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant