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

Node module resolution for CSS import #70693

Merged

Conversation

penx
Copy link
Contributor

@penx penx commented Mar 18, 2019

@msftclas
Copy link

msftclas commented Mar 18, 2019

CLA assistant check
All CLA requirements met.

// and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
// convention, if an import path starts with ~ then use node module resolution
// *unless* it starts with "~/" as this refers to the user's home directory.
if (ref[0] === '~' && ref[1] !== '/') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this can be unit tested, I guess I'd need to mock require.resolve, I don't see an equivalent test for
https://github.com/Microsoft/vscode-languageserver-node/blob/master/server/src/resolve.ts

@@ -8,6 +8,14 @@ import { endsWith, startsWith } from '../utils/strings';
import * as url from 'url';
import { WorkspaceFolder } from 'vscode-languageserver';

function getModuleNameFromPath(path: string) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add unit tests for this fairly easily, but that would lead me to put it in its own module, which in turn makes me wonder if there's an existing util in vscode that already does this that I could use instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the unit tests for this part of the code (completion.test.ts) only seem to be testing the public API rather than internal functions so I'm not going to add unit tests for now. Happy to take direction on this if you want unit tests adding!

@penx penx force-pushed the feature/node-module-resolution-for-css-import branch from 386069f to a2c0729 Compare March 19, 2019 14:31
Alasdair McLeay added 4 commits March 20, 2019 18:05
extract resolvePathToModule and ensure we resolve to package root
if require.resolve fails, defer to default behaviour -url.resolve(base, ref)
@penx penx force-pushed the feature/node-module-resolution-for-css-import branch from a2c0729 to 2e9bd07 Compare March 20, 2019 18:06
@penx
Copy link
Contributor Author

penx commented Mar 20, 2019

@octref previous build issues were not related to this PR. All solved now after rebase off master.

Please let me know if you'd like any changes

@octref
Copy link
Contributor

octref commented Apr 1, 2019

You are also in this thread: sass/sass#2350.

I'm not sure if VS Code should add such url resolving mechanism. It's not part of css or sass language, and only comes from some webpack plugins that you have configured. Ping @aeschli

@penx
Copy link
Contributor Author

penx commented Apr 10, 2019

some webpack plugins that you have configured

sass-loader and css-loader are the standard webpack loaders for styling and the behaviour this PR supports is for their default behaviour without any additional configuration.

https://webpack.js.org/loaders#styling

These loaders are used by many config-less uses of webpack, e.g. when using create-react-app

I agree that this isn't in the underlying spec for Sass, however I suspect that a very large number of people using VSCode to write Sass are using sass-loader under the hood. Even more so, I think it's safe to assume that near to 100% of vscode users that encounter @import "~something"; in a Sass file would be expecting this to be using node module resolution when compiled.

If you're still against this being the default behaviour of "Go to definition" in VSCode then perhaps it can be behind a config option instead? I personally would find this very useful, and I use what I believe are fairly standard build setups for writing CSS/Sass.

@minkir014
Copy link

Can't you provide autocompletion also??

@penx
Copy link
Contributor Author

penx commented May 31, 2019

Waiting for @aeschli to confirm this feature can be merged first!

@minkir014
Copy link

@penx This feature is needed too much. if you can do that please post another PR.

@aeschli aeschli merged commit df9b668 into microsoft:master Jun 4, 2019
@aeschli
Copy link
Contributor

aeschli commented Jun 4, 2019

@penx Thanks, sorry for the delay!

@aeschli
Copy link
Contributor

aeschli commented Jun 4, 2019

Tests would be very appreciated. I created a first link tests: ae6be63
Would be great if you can add one for your feature.

To run, cd extensions/css-language-features && yarn test

@minkir014
Copy link

@penx This PR has finally been merged. Please start another PR that provides variables completion across files.

@aeschli aeschli self-assigned this Jun 5, 2019
@aeschli
Copy link
Contributor

aeschli commented Jun 5, 2019

I had to rewrite the code as we can't use require: The code is webpackaged and webpack is very against require. See 8f72934
@penx You want to look at my changes and fix it if I misunderstood how this works.

@penx
Copy link
Contributor Author

penx commented Jul 12, 2019

@aeschli sorry for the delay in responding, yes unfortunately what you have written assumes that join(documentFolder, 'node_modules', _moduleName, 'package.json'); will resolve the correct location on disk, but this will not work in many cases. e.g. nested dependencies, npm link, peerDependencies, yarn PnP, yarn portal.

See:

require is exactly what we want here as we want to know where node resolves the module to on disk.

Is it possible that we do something like if(require) or if(webpacked) and use require only in safe environments?

@aeschli
Copy link
Contributor

aeschli commented Jul 12, 2019

I you find a way to trick webpack, I'm happy to take a PR.

@penx
Copy link
Contributor Author

penx commented Jul 12, 2019

@aeschli ok I should be able to look in to this, is there a way I can replicate the issue? Is there a particular build task I need to run to get the webpacked version that was causing the issue?

@penx
Copy link
Contributor Author

penx commented Jul 12, 2019

From what I understand, the development build I was using is not webpacked, but when you do a production/distribution build it is.

If I run yarn gulp -- vscode-darwin I guess this should produce a Mac OS X application that I can test, though on my branch this results in

Error: ModuleDependencyWarning: Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Which I guess is the issue you encountered when you merged my PR.

@aeschli
Copy link
Contributor

aeschli commented Jul 12, 2019

You can manually invoke webpack by calling
npx webpack-cli --config=extension.webpack.config.js
in extensions/css-language-features

@penx
Copy link
Contributor Author

penx commented Aug 22, 2019

I'm still thinking about this but have had limited time. From some initial tests I think the current implementation only works if you're editing an scss file that's in the same directory as the node_modules folder you want to jump in to, which is rarely the case.

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

Successfully merging this pull request may close these issues.

Ctrl+click (go to file) doesn't work for saas-loader ~ imports (node_modules)
5 participants