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

WIP: Refactor loader dependencies #119

Closed
wants to merge 4 commits into from
Closed

WIP: Refactor loader dependencies #119

wants to merge 4 commits into from

Conversation

RianFuro
Copy link

@RianFuro RianFuro commented Jan 15, 2021

Closes #118
Very WIP, I still need to clean up the resulting mess.
However, the loader roughly looks like I wanted it to, so I wanted to get some early feedback.

I basically moved all the logic that wasn't about loading a file to the parser class, which eliminated the weird Core in-between altogether. As a result, the parser is now a mess, so that needs to be cleaned up still.
Also, the parser still deals with absolute file paths, since I just pulled out the sources hash from the loader. That needs to be changed too, since a file might not necessarily come from disk as far as the parser is concerned.

TODOs:

  • clean up code
  • find new hashing structure for source chunks
  • flatten out the nested parser instances; should be possible with just one instance

Isolates the file loader so it does no longer depend on the parser.
This frees the loader to only care aout loading files, which makes it
easier to inject custom loaders via the provided interface.

Since the loader is now only a single function that is extracted
immediately, it's been reduced to a function instead of a class.
@RianFuro RianFuro marked this pull request as draft January 15, 2021 20:18
The previous used version of babel had a bug with transpiling async
methods on classes. See:

babel/babel#6806

Update of babel dependencies fixes the problem
@madyankin
Copy link
Owner

Hey @RianFuro, thanks for the PR! I think I'll be able to take a look at it at the end of the week

Since the parser shouldn't have to deal with file system operations, the
loader plugin now has to provide a unique id for an import, which can
just be an absolute path for the default implementation.
Copy link
Owner

@madyankin madyankin left a comment

Choose a reason for hiding this comment

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

I love the overall direction of the PR, looking forward to see the further updates

@@ -1,112 +1,32 @@
// Copied from https://github.com/css-modules/css-modules-loader-core
Copy link
Owner

Choose a reason for hiding this comment

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

I think we can move the loader and parser files to the src directory directly. The directory was just a copy-and-paste from the library as a hot fix and unnecessary now.

import fs from "fs";
import path from "path";

import Parser from "./parser";

class Core {
Copy link
Owner

Choose a reason for hiding this comment

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

I love to see the Core is gone

(err) => console.log(err)
);
async fetchImport(importNode, relativeTo, depNr) {
const file = importNode.selector.match(importRegexp)[1].replace(/^["']|["']$/g, ""),
Copy link
Owner

Choose a reason for hiding this comment

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

Let's split the declarations into separate statements everywhere for the readability sake

class Core {
constructor(plugins) {
this.plugins = plugins || Core.defaultPlugins;
export function resolveRelativeImport(importee, importer, projectRoot) {
Copy link
Owner

Choose a reason for hiding this comment

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

It seems to be an internal function. Let's not export it then

Copy link
Author

Choose a reason for hiding this comment

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

ah, of course. good catch :)

@@ -31,11 +32,11 @@
"postcss": "^8.0.0"
},
"devDependencies": {
"@babel/cli": "7.12.10",
Copy link
Owner

Choose a reason for hiding this comment

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

👍

}),
tokens = this.tokensByFile[fileRelativePath];

try {
Copy link
Owner

Choose a reason for hiding this comment

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

This seems to be cleaner now 👍

}

export default {
resolveId: (importee, importer, projectRoot) => {
Copy link
Owner

Choose a reason for hiding this comment

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

Nice idea to use resolveId, it may be really useful in the future

@RianFuro
Copy link
Author

looking forward to see the further updates

I was about to wrap this up, but to be honest with the last 2 changes I got a little uncomfortable. I'm sure I made a logical mistake at least once during the work on my last commit, but the tests passed regardless.

So I think I will take some extra time to extend the test suite against the original implementation, then move those over here so I can hand the pr off with some confidence :)

@madyankin
Copy link
Owner

I think I will take some extra time to extend the test suite against the original implementation

Yeah, this is what I wanted to ask you to do

@madyankin
Copy link
Owner

Could you also update the docs according to the changes?

@RianFuro
Copy link
Author

Could you also update the docs according to the changes?

Sure thing.

Comment on lines -59 to -64
let relativeDir = path.dirname(relativeTo),
rootRelativePath = path.resolve(relativeDir, newPath),
fileRelativePath = path.resolve(
path.join(this.root, relativeDir),
newPath
);
Copy link
Author

Choose a reason for hiding this comment

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

@madyankin
Btw, do you have a bit of insight on the old code? I'm not quite sure about the distinction between rootRelativePath and fileRelativePath here. They are equal as long as this.root is unset and I don't see why they need to be be different in the alternative case... so while refactoring I got rid of the distinction.
But since I don't completely trust the test suite anymore, I'm not sure if that's a correct step to take. Any idea?

Copy link
Owner

@madyankin madyankin Jan 25, 2021

Choose a reason for hiding this comment

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

I believe I had the insight a couple of years ago or so, but I'm not quite sure now.

AFAIR, this is useful when you have CSS modules placed in some other location and want to resolve them properly, e.g., in Rails or Django frameworks.

These files were in the css-modules-loader-core package without tests. Given I copied them here as a hotfix, I hadn't enough time to cover them with.

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Providing custom Loader implementation
2 participants