alphagov / govuk-frontend

GOV.UK Frontend contains the code you need to start building a user interface for government platforms and services.
https://frontend.design-system.service.gov.uk/
MIT License
1.16k stars 320 forks source link

Path to sass-mq is dependent on specific node_modules location #636

Closed penx closed 6 years ago

penx commented 6 years ago

This line is causing us an issue:

https://github.com/alphagov/govuk-frontend/blob/ad2022ef044d2e67768199479e215f641e36cc5f/dist/components/globals/helpers/_media-queries.scss#L14

This assumes that sass-mq is installed in a node_modules folder relative to the root folder used by the Sass build system.

This isn't always the case, e.g.

  1. If Sass is configured to resolve links relative to file location rather than parent project root
  2. If the parent project uses a different version of sass-mq to govuk-frontend, npm won't flatten this dependency and the version needed by govuk-frontend actually lives in ./node_modules/govuk-frontend/node_modules/sass-mq govuk-frontend
  3. if used in a monorepo (lerna, yarn workspaces) then node_modules are hoisted in to a parent directory.

I suspect this can be fixed by swapping it with @import "sass-mq/mq", which will leave node to deal with the module resolution.

NickColley commented 6 years ago

Thanks for raising! Do you have an example of the build where this fails for us to reproduce? It may help us fix this quicker. 😄

penx commented 6 years ago

@marksy was having this issue, I think on this branch, though perhaps he can confirm

https://github.com/penx/govuk-react/tree/feature/sassExtract

penx commented 6 years ago

failing that I could try create a simple example if that would help?

penx commented 6 years ago

@nickcolley @igloosi I have created a failing example with instructions here https://github.com/penx/govuk-monorepo-example

penx commented 6 years ago

Note that Webpack sass-loader provides a mechanism to load dependencies from node_modules:

@import "~sass-mq/mq";

However this doesn't seem to be a standard Sass convention, but personally I think it is preferred to importing from an assumed relative path to node_modules.

NickColley commented 6 years ago

@penx thanks so much for the failing example! 🙌

kr8n3r commented 6 years ago

the proposed change in #637 should fix that https://github.com/alphagov/govuk-frontend/pull/637/files#diff-b47fe464b7770f8ba6b5ce3bf61eceb9R14

kr8n3r commented 6 years ago

the other options would be to expose that path in config options @penx or @marksy can you forsee any issues with that when you include it in your project?

penx commented 6 years ago

@igloosi that may work, but would require the parent project to know where the package was hoisted to (which could potentially vary) rather than defer this resolution to node.

Any reason for this instead of Eyeglass?

penx commented 6 years ago

failing that we could have the govuk-frontend Sass => JS variables conversion go in to its own project that wasn't a monorepo and do the conversion as part of its build, then have govuk-react depend on this interim package

NickColley commented 6 years ago

@penx (while we try and find other solutions) is it possible to avoid hoisting node_modules? Or avoiding yarn?

penx commented 6 years ago

@nickcolley using a monorepo is pretty core to the current architecture of govuk-react, and I am pretty certain other monorepo approaches (lerna + npm) would have the same issue, but if we move the conversion to another repo then this may work, unless I'm missing something @marksy?

NickColley commented 6 years ago

I think I'm maybe misunderstanding but is hoisting node_modules required for a monorepo approach?

Looks to have more context on hoisting: https://yarnpkg.com/blog/2018/02/15/nohoist/

penx commented 6 years ago

Good point, I thought it was, which led me to find this:

https://yarnpkg.com/blog/2018/02/15/nohoist/

So we could probably use that.

Related, I thought lerna hoisted by default but apparently it doesn't

https://github.com/lerna/lerna/blob/master/doc/hoist.md

Also in the above link

some tooling does not follow the module resolution spec closely, and instead assumes or requires that dependencies are present specificially in the local node_modules directory. To work around this, it is possible to symlink packages from their hoisted top-level location, to individual package node_modules directory. Lerna does not yet do this automatically, and it is recommended instead to work with tool maintainers to migrate to more compatible patterns

I think it would still be good to have hoisting support in the medium term though could see why this may be low priority 😀

penx commented 6 years ago

Interestingly I seem to have the same issue when not in a monorepo!

https://github.com/penx/govuk-frontend-js

git clone git@github.com:penx/govuk-frontend-js.git
cd govuk-frontend-js
node build.js

Error: Can not determine imported file for url './node_modules/sass-mq/mq.scss' imported in govuk-frontend-js/node_modules/@govuk-frontend/globals/helpers/_media-queries.scss

kr8n3r commented 6 years ago

@penx this will be fixed in the next release of Frontend

kr8n3r commented 6 years ago

relased in https://github.com/alphagov/govuk-frontend/releases/tag/v0.0.29-alpha