Repository: gohugoio/hugo (language: go)

Issue:
Unable to import mounted CSS into SCSS.
<!-- Please answer these questions before submitting your issue. Thanks! -->

Hi, Hugo seems doesn't able to load mounted CSS file into SCSS, but normal CSS files are OK.

### What version of Hugo are you using (`hugo version`)?

<pre>
$ hugo version
hugo v0.109.0-47b12b83e636224e5e601813ff3e6790c191e371+extended linux/amd64 BuildDate=2022-12-23T10:38:11Z VendorInfo=gohugoio
</pre>

### Does this issue reproduce with the latest release?

Yep.

### Log

```
Template changed WRITE         "/home/razonyang/Projects/razonyang/hugo-lab/layouts/index.html"
WARN 2022/12/31 14:13:30 tingle.js/tingle.css
WARN 2022/12/31 14:13:30 tingle.js/tingle.js
ERROR 2022/12/31 14:13:30 Rebuild failed: TOCSS-DART: failed to transform "main.scss" (text/x-scss): "/home/razonyang/Projects/razonyang/hugo-lab/assets/main.scss:2:8": Can't find stylesheet to import.
```

### Reproduce steps

```toml
// config.toml
[[module.imports]]
path = "github.com/robinparisi/tingle"

[[module.imports.mounts]]
source = "src"
target = "assets/tingle.js"
```

```go
// layouts/index.html
<html>
    <head>
        {{- range resources.Match "tingle.js/*" }}
          {{- warnf "%v" .Name }}
        {{- end }}
        {{ $css := resources.Get "main.scss" }}
        {{ $css = $css | toCSS (dict "includePaths" (slice "node_modules") "transpiler" "dartsass") }}
        <link href="{{ $css.RelPermalink }}" rel="stylesheet">
    </head>
    <body>
        <h1 class="text-red">RED HEADING</h1>
    </body>
</html>
```

```scss
// assets/main.scss
@import "foo/bar";
@import "tingle.js/tingle"; # Comment this line works as expected.

// assets/foo/bar.css
.text-red {
    color: red;
}
```

> Full example located at https://github.com/razonyang/hugo-lab/tree/scss-import-css. `cd exampleSite && hugo server`.

Both `libsass` and `dartsass` are not working.



Discussion / hints:
your module imports contains remapped path, try using `module.imports` instead of `theme` in your config file:

```diff
-- theme = 'github.com/razonyang/hugo-lab'
++ [[module.imports]]
++  path = "github.com/razonyang/hugo-lab"
```

https://github.com/razonyang/hugo-lab/blob/scss-import-css/exampleSite/config.toml#L4


> your module imports contains remapped path, try using `module.imports` instead of `theme` in your config file:

Thanks, but doesn't help, same error reached.

I think the `theme` has the same effect as `module.imports`, see https://gohugo.io/hugo-modules/theme-components/


turns out, if we explicitly write the full path with the extension, it does resolves correctly.

```scss
@import "foo/bar";
@import "tingle.js/tingle.css";
```
@pamubay Thanks, I've tried this before, but SASS just replace it with `@import "tingle.js/tingle.css";` (loaded as an external style file) instead of importing/appending the CSS content, you'll still get 404 NOT FOUND of that CSS file, which is unexpected.

What I wish is that append the CSS content like `@import "foo/bar"` does.
From the top of my head:

1. `libsass` does not support ordinary CSS imports at all (there is a many year old bug about it)
2. For import resolution with /assets, the logic is fairly simple, see https://github.com/gohugoio/hugo/blob/master/resources/resource_transformers/tocss/dartsass/transform.go#L163


This works:

config.toml

```
[[module.imports.mounts]]
source = "src/tingle.css"
target = "assets/tingle.js/tingle.scss" # mount with scss extension
```

main.scss

```
@import "foo/bar";
@import "tingle.js/tingle";
```

See:

- https://sass-lang.com/documentation/at-rules/import#importing-css
- https://sass-lang.com/documentation/at-rules/import#plain-css-imports

If the import URL ends with `.css`, Sass will compile to a plain CSS import.

If it does not end with `.css` it should imported just like a Sass file.

I think we need to change the import resolver.


@razonyang 

In your initial comment, you wrote:

```text
// assets/main.scss
@import "foo/bar";
@import "tingle.js/tingle"; # Comment this line works as expected.
```

Did you mean this instead?

```text
// assets/main.scss
@import "foo/bar";  # Comment this line works as expected.
@import "tingle.js/tingle";
```


@jmooring I am not good at English, I mean as same as your [previous comment](https://github.com/gohugoio/hugo/issues/10592#issuecomment-1368267253) pointed out. 

```
// assets/main.scss
@import "foo/bar";  # The nomarl CSS file "foo/bar.css" can be loaded by SASS.
@import "tingle.js/tingle"; # The CSS file "tingle.js/tingle.css" mounted from module are unable to load, but it should.
```

Fix patch:
diff --git a/resources/resource_transformers/tocss/dartsass/transform.go b/resources/resource_transformers/tocss/dartsass/transform.go
index 1a5b81b47c3..fdf4d8ef363 100644
--- a/resources/resource_transformers/tocss/dartsass/transform.go
+++ b/resources/resource_transformers/tocss/dartsass/transform.go
@@ -163,9 +163,9 @@ func (t importResolver) CanonicalizeURL(url string) (string, error) {
 	if strings.Contains(name, ".") {
 		namePatterns = []string{"_%s", "%s"}
 	} else if strings.HasPrefix(name, "_") {
-		namePatterns = []string{"_%s.scss", "_%s.sass"}
+		namePatterns = []string{"_%s.scss", "_%s.sass", "_%s.css"}
 	} else {
-		namePatterns = []string{"_%s.scss", "%s.scss", "_%s.sass", "%s.sass"}
+		namePatterns = []string{"_%s.scss", "%s.scss", "_%s.sass", "%s.sass", "_%s.css", "%s.css"}
 	}
 
 	name = strings.TrimPrefix(name, "_")


Test patch:
diff --git a/resources/resource_transformers/tocss/dartsass/integration_test.go b/resources/resource_transformers/tocss/dartsass/integration_test.go
index e7432f12bc5..aa71101a04e 100644
--- a/resources/resource_transformers/tocss/dartsass/integration_test.go
+++ b/resources/resource_transformers/tocss/dartsass/integration_test.go
@@ -101,14 +101,75 @@ T1: {{ $r.Content | safeHTML }}
 		moo {
 		  color: #fff;
 		}
-		
+
 		moo {
 		  color: #fff;
 		}
-		
+
 		/* foo */`)
 }
 
+// Issue 10592
+func TestTransformImportMountedCSS(t *testing.T) {
+	t.Parallel()
+	if !dartsass.Supports() {
+		t.Skip()
+	}
+
+	files := `
+-- assets/main.scss --
+@import "import-this-file.css";
+@import "foo/import-this-mounted-file.css";
+@import "compile-this-file";
+@import "foo/compile-this-mounted-file";
+a {color: main-scss;}
+-- assets/_compile-this-file.css --
+a {color: compile-this-file-css;}
+-- assets/_import-this-file.css --
+a {color: import-this-file-css;}
+-- foo/_compile-this-mounted-file.css --
+a {color: compile-this-mounted-file-css;}
+-- foo/_import-this-mounted-file.css --
+a {color: import-this-mounted-file-css;}
+-- layouts/index.html --
+{{- $opts := dict "transpiler" "dartsass" }}
+{{- with resources.Get "main.scss" | toCSS $opts }}{{ .Content | safeHTML }}{{ end }}
+-- config.toml --
+disableKinds = ['RSS','sitemap','taxonomy','term','page','section']
+
+[[module.mounts]]
+source = 'assets'
+target = 'assets'
+
+[[module.mounts]]
+source = 'foo'
+target = 'assets/foo'
+	`
+	b := hugolib.NewIntegrationTestBuilder(
+		hugolib.IntegrationTestConfig{
+			T:           t,
+			TxtarString: files,
+			NeedsOsFS:   true,
+		},
+	).Build()
+
+	b.AssertFileContent("public/index.html", `
+		@import "import-this-file.css";
+		@import "foo/import-this-mounted-file.css";
+		a {
+			color: compile-this-file-css;
+		}
+
+		a {
+			color: compile-this-mounted-file-css;
+		}
+
+		a {
+			color: main-scss;
+		}
+	`)
+}
+
 func TestTransformThemeOverrides(t *testing.T) {
 	t.Parallel()
 	if !dartsass.Supports() {
@@ -291,7 +352,7 @@ body {
 	body {
 		background: url(vars.$image) no-repeat center/cover;
 		font-family: vars.$font;
-	  }	  
+	  }
 }
 
 p {
@@ -341,7 +402,7 @@ image = "images/hero.jpg"
 body {
 	body {
 		background: url(vars.$image) no-repeat center/cover;
-	  }	  
+	  }
 }
 
 p {