gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
73.54k stars 7.38k forks source link

ToCSS includePaths ignores paths from parent directory (../node_modules) #6274

Open 0xjac opened 4 years ago

0xjac commented 4 years ago

Error

When running hugo, it fails with the following error:

hugo -D -s site server     
Building sites … ERROR 2019/08/27 16:56:32 error: failed to transform resource: SCSS processing failed: file "stdin", line 3, col 1: File to import not found or unreadable: bulma/bulma. 
Total in 13 ms
Error: Error building site: logged 1 error(s)

Project Structure (abridged)

project
├── node_modules
│   └── bulma
│       ├── bulma.sass
│       └── sass
│           └── ...
├── package.json
├── package-lock.json
├── README.md
└── site
    └── themes
        └── custom-theme
            ├── assets
            │   └── scss
            │       ├── main.scss
            │       └── variables.scss
            └── layouts
                └── _default
                    └── baseof.html

project/site/themes/custom-theme/assets/scss/main.scss

@charset "utf-8";
@import "variables.scss";
@import "bulma/bulma";

// custom style ...

head

<head>
    {{ $scssOptions := (dict "targetPath" "css/styles.css" "enableSourceMap" false "includePaths" (slice "../node_modules")) }}
    {{ $scssFile:= default "scss/main.scss" .Params.ScssFile}}
    {{ $scss := resources.Get $scssFile }}
    {{ $style := $scss | resources.ToCSS $scssOptions | minify | fingerprint }}
    <link rel="stylesheet" href="{{ $style.Permalink }}">
    <!-- ... -->
</head>

Hugo Versions

cat /etc/lsb-release 
DISTRIB_ID=ManjaroLinux
DISTRIB_RELEASE=18.0.4
DISTRIB_CODENAME=Illyria
DISTRIB_DESCRIPTION="Manjaro Linux"

Notes

I tried playing with various variations of paths in the head (such as node_modules, ./node_modules, absolute path, ...) and in main.scss (such as ./bulma/bulma, ../bulma/bulma, ...) and nothing works. The only way around is to not use incluePaths and instead to hard-code node_modules in the scss file, as in: @import './node_modules/bulma/bulma';.

Note that using includePaths as described in this setup works fine with the following hugo version:

Hugo Static Site Generator v0.55.6-A5D4C82D2/extended linux/amd64 BuildDate: 2019-05-18T08:08:34Z
bep commented 4 years ago

This is possibly a bug introduced by my 0.57 changes. That said, I think you would get a simpler setup/easier to reason about if you use the new module mounts setup.

E.g. (from memory):

[module]

  [[module.mounts]]
    source = "node_modules/bulma"
    target = "assets/scss/bulma"

If you get those paths in line you should not need to add any includePaths.

0xjac commented 4 years ago

@bep Thanks I was looking into it and it does indeed look like the introduction of modules might have interfered with this feature. You suggestions to use modules (which is a really cool new feature btw) works!

Specfically (and for anyone stumbling upon this) the corrrect configuration is:

[module]

  [[module.mounts]]
    source = "static"
    target = "static"

  [[module.mounts]]
    source = "../node_modules/bulma"
    target = "assets/scss/bulma"

I had to mount the static folder explicitly (not sure if that's intentional or not, but it may be because I have a target of static/webfonts as well in my project) and the source path for the node modules has to start with ../ since the folder is located in the parent of the site in my setup. You can check the working setup here.

For me this is a perfectly acceptable solution. I find it much cleaner and explicit than passing the node_modules folder in the head template. That being said, it may be nice to update the SASS/SCSS documentation to let people know of the changes.

bep commented 4 years ago

That being said, it may be nice to update the SASS/SCSS documentation to let people know of the changes.

I agree. It would be cool if you could lend us a hand, now that you know how it works... But I will fix this particular issue, as this was an unintended side effect. But I do agree that using the file mounts is a cleaner and easier to reason about solution. And it gets even cooler when you mount folders inside other GitHub projects ...

bep commented 4 years ago

I tried to create a failing test similar to your setup, but I failed (or succeeded ...). Which means that there is something I'm not seeing in your setup ...

0xjac commented 4 years ago

Hi sorry for the late reply. I can do a simple set up for testing. I am also happy to lend an hand.

Which approach do you prefer:

  1. Prevent adding paths past the root, display an error message and update the doc?
  2. Fix the logic to restore the old behavior?
cyChop commented 4 years ago

Hi @bep. I think I reproduced this case. The quickest way would be to modify Netlify's Victor Hugo's template:

  1. Clone it.
  2. Make Hugo generate the SCSS instead of Webpack.
  3. Include some SCSS import in node_modules.

As a side note, with Hugo 0.67.1, specifying the modules with @0xjac's configuration results in the following error on my build:

`execute of template failed: template: partials/head.html:57:52: executing "partials/head.html" at

: error calling ToCSS: no Resource provided in transformation`
cyChop commented 4 years ago

Hi @bep,

For information, I made minimal cases of this bug at this repo: https://github.com/cyChop/minimal-cases-hugo

About the branches:

The most important code parts and error log are all summarized in the README.

Please let me know if I can help further (maybe the last problem is a support question for the discourse?).

And thank you for Hugo. :)

zbayoff commented 3 years ago

I am also experiencing this issue. My hugo site is stored under the root site/ directory. So I'm trying to use "includePaths" (slice "../node_modules")

and importing the bootstrap sass partial like: @import "bootstrap/scss/functions";

but keep getting the error:

File to import not found or unreadable: bootstrap/scss/functions.

So now I'm relegated to doing @import '../../../../../node_modules/bootstrap/scss/functions';

danisztls commented 2 years ago

An alternative that worked for me is to add dependencies as a git submodule inside /assets. It made things a lot simpler and less bug prone.

jmooring commented 1 year ago

Reproducible example with v0.111.3

git clone --single-branch -b hugo-github-issue-6274 https://github.com/jmooring/hugo-testing hugo-github-issue-6274
cd hugo-github-issue-6274
npm ci
hugo -s site

Workaround / preferred approach:

[[module.mounts]]
source = 'assets'
target = 'assets'

[[module.mounts]]
source = '../node_modules'
target = 'assets/scss'
drjaydenm commented 8 months ago

I just ran into this with a monorepo using a structure where the Hugo project sits alongside a Node package for styling used by multiple apps. If anyone else is looking for a solution to point to their own styling package inside an NPM (or Lerna etc) workspace, you can use the following module mount setup to mount the package in the assets/scss directory. The beauty of this is you can still @use/@import the package using the normal Sass/NPM pathing way e.g. @use '@name/styles-package/grid';

[module]
  [[module.mounts]]
    source = 'assets'
    target = 'assets'
  [[module.mounts]]
    source = '../styles-package'
    target = 'assets/scss/@name/styles-package'

Would be awesome to see proper support for include directories outside the site added, but at least the modules way can work without hardcoding the paths in the SCSS files too :)

Sammy-T commented 8 months ago

I can't even get the module.mounts way to work. It's already cost me enough time, I'm just going to go with the @import 'node_modules/package' way as that's all I can get to work.