Skip to content

Commit

Permalink
Add an implementation note about sass/libsass#2957 (sass#359)
Browse files Browse the repository at this point in the history
Documentation for @use and @forward themselves will come in a future
PR.

Partially addresses sass#263
  • Loading branch information
Israel-4Ever authored Aug 29, 2019
1 parent e30ed6c commit 871f991
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 87 deletions.
3 changes: 3 additions & 0 deletions data/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ toc:
- Interpolation: /documentation/interpolation
- At-Rules: /documentation/at-rules
:children:
- <code>@use</code>: /documentation/at-rules/use
- <code>@forward</code>: /documentation/at-rules/forward
- <code>@import</code>: /documentation/at-rules/import
- <code>@mixin</code> and <code>@include</code>: /documentation/at-rules/mixin
- <code>@function</code>: /documentation/at-rules/function
Expand Down Expand Up @@ -64,4 +66,5 @@ toc:
:children:
- Dart Sass: /documentation/cli/dart-sass
- Ruby Sass: /documentation/cli/ruby-sass
- Migrator: /documentation/cli/migrator
- JavaScript API: /documentation/js-api
5 changes: 5 additions & 0 deletions source/documentation/at-rules/forward.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: "@forward"
introduction: >
TODO(nweiz): Write this
---
128 changes: 128 additions & 0 deletions source/documentation/at-rules/import.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,48 @@ required to have quotes.

[indented syntax]: ../syntax#the-indented-syntax

<% heads_up do %>
The Sass team discourages the continued use of the `@import` rule. Sass will
[gradually phase it out][] over the next few years, and eventually remove it
from the language entirely. Prefer the [`@use` rule][] instead.

[gradually phase it out]: https://github.com/sass/sass/blob/master/accepted/module-system.md#timeline
[`@use` rule]: use

#### What's Wrong With `@import`?

The `@import` rule has a number of serious issues:

* `@import` makes all variables, mixins, and functions globally accessible.
This makes it very difficult for people (or tools) to tell where anything is
defined.

* Because everything's global, libraries must prefix to all their members to
avoid naming collisions.

* [`@extend` rules][] are also global, which makes it difficult to predict
which style rules will be extended.

[`@extend` rules]: extend

* Each stylesheet is executed and its CSS emitted *every time* it's
`@import`ed, which increases compilation time and produces bloated output.

* There was no way to define private members or placeholder selectors that
were inaccessible to downstream stylesheets.

The new module system and the `@use` rule address all these problems.

#### How Do I Migrate?

We've written a [migration tool][] that automatically converts most
`@import`-based code to `@use`-based code in a flash. Just point it at your
entrypoints and let it run!

[migration tool]: /documentation/cli/migrator

<% end %>
<% example do %>
// foundation/_code.scss
code {
Expand Down Expand Up @@ -414,3 +456,89 @@ for example based on mixin parameters.

@include google-font("Droid Sans")
<% end %>

## Import and Modules

<%= partial '../snippets/module-system-status' %>

Sass's [module system][] integrates seamlessly with `@import`, whether you're
importing a file that contains `@use` rules or loading a file that contains
imports as a module. We want to make the transition from `@import` to `@use` as
smooth as possible.

[module system]: use

### Importing a Module-System File

When you import a file that contains `@use` rules, the importing file has access
to all members (even private members) defined directly in that file, but *not*
any members from modules that file has loaded. However, if that file contains
[`@forward` rules][], the importing file will have access to forwarded members.
This means that you can import a library that was written to be used with the
module system.

[`@forward` rules]: forward

<% heads_up do %>
When a file with `@use` rules is imported, all the CSS transitively loaded by
those is included in the resulting stylesheet, even if it's already been
included by another import. If you're not careful, this can result in bloated
CSS output!
<% end %>

#### Import-Only Files

An API that makes sense for `@use` might not make sense for `@import`. For
example, `@use` adds a namespace to all members by default so you can safely use
short names, but `@import` doesn't so you might need something longer. If you're
a library author, you may be concerned that if you update your library to use
the new module system, your existing `@import`-based users will break.

To make this easier, Sass also supports *import-only files*. If you name a file
`<name>.import.scss`, it will only be loaded for imports, not for `@use`s. This
way, you can retain compatibility for `@import` users while still providing a
nice API for users of the new module system.

<% example(autogen_css: false) do %>
// _reset.scss

// Module system users write `@include reset.list()`.
@mixin list() {
ul {
margin: 0;
padding: 0;
list-style: none;
}
}
---
// _reset.import.scss

// Legacy import users can keep writing `@include reset-list()`.
@forward "reset" as reset-*;
===
// _reset.sass

// Module system users write `@include reset.list()`.
@mixin list()
ul
margin: 0
padding: 0
list-style: none
---
// _reset.import.sass

// Legacy import users can keep writing `@include reset-list()`.
@forward "reset" as reset-*
<% end %>

### Loading a Module That Contains Imports

When you use `@use` (or `@forward`) load a module that uses `@import`, that
module will contain all the public members defined by the stylesheet you load
*and* everything that stylesheet transitively imports. In other words,
everything that's imported is treated as though it were written in one big
stylesheet.

This makes it easy to convert start using `@use` in a stylesheet even before all
the libraries you depend on have converted to the new module system. Be aware,
though, that if they do convert their APIs may well change!
9 changes: 9 additions & 0 deletions source/documentation/at-rules/use.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "@use"
introduction: >
TODO(nweiz): Write this
---

### Load Paths

### Partials
12 changes: 6 additions & 6 deletions source/documentation/cli/dart-sass.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ The `--stdin` flag may not be used with [many-to-many mode][].

This flag tells Sass to parse the input file as the [indented syntax][]. If it's
used in [many-to-many mode][], all input files are parsed as the indented
syntax, although files they [import][] will have their syntax determined as
usual. The inverse, `--no-indented`, can be used to force all input files to be
parsed as [SCSS][] instead.
syntax, although files they [use][] will have their syntax determined as usual.
The inverse, `--no-indented`, can be used to force all input files to be parsed
as [SCSS][] instead.

[import]: ../at-rules/import
[use]: ../at-rules/use

The `--indented` flag is mostly useful when the input file is coming from
[standard input][], so its syntax can't be automatically determined.
Expand All @@ -110,10 +110,10 @@ h1 {
#### `--load-path`

This option (abbreviated `-I`) adds an additional [load path][] for Sass to look
for imports. It can be passed multiple times to provide multiple load paths.
for stylesheets. It can be passed multiple times to provide multiple load paths.
Earlier load paths will take precedence over later ones.

[load path]: ../at-rules/import#load-paths
[load path]: ../at-rules/use#load-paths

```shellsession
$ sass --load-path=node_modules/bootstrap/dist/css style.scss style.css
Expand Down
5 changes: 5 additions & 0 deletions source/documentation/cli/migrator.html.md.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: "Migrator"
introduction: >
TODO(nweiz): Write this
---
6 changes: 3 additions & 3 deletions source/documentation/cli/ruby-sass.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ When compiling whole directories, Sass will ignore [partial files][] whose names
begin with `_`. You can use partials to separate out your stylesheets without
creating a bunch of unnecessary output files.

[partial files]: ../at-rules/import#partials
[partial files]: ../at-rules/use#partials

Many-to-many mode will only compile stylesheets whose dependencies have been
modified more recently than the corresponding CSS file was generated. It will
Expand All @@ -93,10 +93,10 @@ also print status messages when updating stylesheets.
#### `--load-path`

This option (abbreviated `-I`) adds an additional [load path][] for Sass to look
for imports. It can be passed multiple times to provide multiple load paths.
for stylesheets. It can be passed multiple times to provide multiple load paths.
Earlier load paths will take precedence over later ones.

[load path]: ../at-rules/import#load-paths
[load path]: ../at-rules/use#load-paths

```shellsession
$ sass --load-path=node_modules/bootstrap/dist/css style.scss style.css
Expand Down
34 changes: 18 additions & 16 deletions source/documentation/js-api.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ console.log(result.map.toString());

An array of the absolute paths of all Sass files loaded during compilation. If a
stylesheet was loaded from an [importer][] that returned the stylesheet's
contents, the raw strings of that stylesheet's `@import` is included in this
array.
contents, the raw string of the `@use` or `@import` that loaded that stylesheet
is included in this array.

[importer]: #importer

Expand Down Expand Up @@ -188,9 +188,9 @@ provides the same information.
The stylesheet where the error occurred. If the error occurred in a stylesheet
loaded from disk, this is the absolute path of that stylesheet. If the error
occurred in a stylesheet that was loaded from an [importer][] which returned the
stylesheet's contents, this is the raw string of that stylesheet's `@import`. If
it occurred in the contents of the [`data` option][], this is the string
`"stdin"`.
stylesheet's contents, this is the raw string of the `@use` or `@import` that
loaded that stylesheet. If it occurred in the contents of the [`data` option][],
this is the string `"stdin"`.

#### `error.line`

Expand Down Expand Up @@ -741,21 +741,23 @@ h1 {
somewhere else to break it.
<% end %>

This option defines one or more additional handlers for loading files when an
[`@import` rule][] is encountered. It can either be a single JavaScript
function, or an array of functions. These functions are always passed two
arguments:
This option defines one or more additional handlers for loading files when a
[`@use` rule] or an [`@import` rule][] is encountered. It can either be a single
JavaScript function, or an array of functions. These functions are always passed
two arguments:

[`@use` rule]: at-rules/use
[`@import` rule]: at-rules/import

1. The `@import` rule's URL as a string, exactly as it appears in the
1. The `@use` or `@import` rule's URL as a string, exactly as it appears in the
stylesheet.
2. A string identifying for the stylesheet that contained the `@import`. This
identifier's format depends on how that stylesheet was loaded:
2. A string identifying for the stylesheet that contained the `@use` or
`@import`. This identifier's format depends on how that stylesheet was
loaded:
* If the stylesheet was loaded from the filesystem, it's the absolute path of
its file.
* If the stylesheet was loaded from an importer that returned its contents,
it's the URL of the `@import` rule that loaded it.
it's the URL of the `@use` or `@import` rule that loaded it.
* If the stylesheet came from the [`data` option][], it's the string
`"stdin"`.

Expand All @@ -775,7 +777,7 @@ asynchronously pass the result of the import once it's complete.

Imports are resolved by trying, in order:

* Loading a file relative to the file in which the `@import` appeared.
* Loading a file relative to the file in which the `@use` or `@import` appeared.

* Each custom importer.

Expand All @@ -793,7 +795,7 @@ sass.render({
// This importer uses the synchronous API, and can be passed to either
// renderSync() or render().
function(url, prev) {
// This generates a stylesheet from scratch for `@import "big-headers"`.
// This generates a stylesheet from scratch for `@use "big-headers"`.
if (url != "big-headers") return null;

return {
Expand All @@ -807,7 +809,7 @@ h1 {
// This importer uses the asynchronous API, and can only be passed to
// render().
function(url, prev, done) {
// Convert `@import "foo/bar"` to "node_modules/foo/sass/bar".
// Convert `@use "foo/bar"` to "node_modules/foo/sass/bar".
var components = url.split('/');
var innerPath = components.slice(1).join('/');
done({
Expand Down
6 changes: 6 additions & 0 deletions source/documentation/snippets/_module-system-status.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<% impl_status dart: '(unreleased)', libsass: false, ruby: false do %>
Only Dart Sass currently supports `@use`. Users of other implementations must
use the [`@import` rule][] instead.

[`@import` rule]: /documentation/at-rules/import
<% end %>
2 changes: 1 addition & 1 deletion source/documentation/syntax.html.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Syntax
introduction: >
Sass supports two different syntaxes. Each one can import the other, so it's
Sass supports two different syntaxes. Each one can load the other, so it's
up to you and your team which one to choose.
---

Expand Down
1 change: 1 addition & 0 deletions source/documentation/syntax/structure.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ These statements produce CSS. They can be used anywhere except within a
These statements can only be used at the top level of a stylesheet, or nested
within a CSS statement at the top level:

* [Module loads](../at-rules/use), using `@use`.
* [Imports](../at-rules/import), using `@import`.
* [Mixin definitions](../at-rules/mixin) using `@mixin`.
* [Function definitions](../at-rules/function) using `@function`.
Expand Down
Loading

0 comments on commit 871f991

Please sign in to comment.