Skip to content

Conversation

@ringods
Copy link
Contributor

@ringods ringods commented Jun 16, 2020

Closes: #1136

The code has too many places where locations are calculated into a package inside the node_modules folder. The assumption is made here that the the node_modules folder is in the current working directory (process.cwd()). But with Yarn workspaces, this is not always the case: the node_modules can be one or two levels higher in the folder structure.

Summary of changes:

  • Replace hardcoded path calculations with a function using require.resolve.

@ringods ringods requested a review from raphaelokon as a code owner June 16, 2020 20:25
@ringods ringods self-assigned this Jun 16, 2020
@ringods ringods marked this pull request as draft June 16, 2020 20:25
@ringods ringods force-pushed the feature/yarn-workspaces branch from 988136b to a22809e Compare July 13, 2020 16:18
@ringods ringods requested a review from sghoweri July 13, 2020 16:21
@ringods
Copy link
Contributor Author

ringods commented Jul 13, 2020

@sghoweri @bmuenzenmeyer loaduikits iterates over the node_modules folder for folder names containing uikit-. If there are 3 found, they are checked against the config to verify if the uikit is configured and enabled.

const uikits = findModules(nodeModulesPath, isUIKitModule) // [1]

if (!configEntry) {
logger.warning(
`Could not find uikit with name uikit-${kit.name} defined within patternlab-config.json, or it is not enabled.`
);
return;
}

In Yarn v2, you can only load dependencies which are explicitly in your package.json file. So I'm thinking of updating the code and doing it the other way around: reading the enabled uikits and then require-ing them directly. I would error if a uikit is in the PL config, but not defined as a dependency.

If I do it this way, am I covering the same behaviour then?

@bmuenzenmeyer
Copy link
Member

In Yarn v2, you can only load dependencies which are explicitly in your package.json file. So I'm thinking of updating the code and doing it the other way around: reading the enabled uikits and then require-ing them directly. I would error if a uikit is in the PL config, but not defined as a dependency.

If I do it this way, am I covering the same behaviour then?

yes all future work should read the config explictly and look for those only - the node_module scanning has lead to false-positives like uikit-polyfills

@ringods
Copy link
Contributor Author

ringods commented Jul 14, 2020

@bmuenzenmeyer I moved my resolver code from the cli package to core. After that, the require of this code in cli fails:

https://github.com/pattern-lab/patternlab-node/pull/1225/checks?check_run_id=868619630#step:4:48

I don't understand what I'm missing. Any idea?

@ringods ringods force-pushed the feature/yarn-workspaces branch 2 times, most recently from e0cdb11 to 201014d Compare July 26, 2020 13:10
@ringods
Copy link
Contributor Author

ringods commented Jul 26, 2020

@bmuenzenmeyer in commit 04df565, you can see the rewritten version to load the uikits. Without too much effort, the packagename can be added as a uikit config property to cover the requirements covered in #1137.

@ringods
Copy link
Contributor Author

ringods commented Aug 6, 2020

package property is added in ceccfd8, hereby copying the functionality offered in #1137

Copy link
Contributor

@JosefBredereck JosefBredereck left a comment

Choose a reason for hiding this comment

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

When those 3 things are resolved or clearified. I'm appy to approve this PR.

Comment on lines +33 to +41
if ('package' in uikitConfig) {
try {
uikitLocation = resolvePackageFolder(uikitConfig.package);
} catch (ex) {
logger.warning(
`Could not find uikit with package name ${uikitConfig.package}. Did you add it to the 'dependencies' section in your 'package.json' file?`
);
return;
}
Copy link
Contributor

@JosefBredereck JosefBredereck Aug 18, 2020

Choose a reason for hiding this comment

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

Please provide an example patternlab-config.json for that or change the given ones. The user shouldn't get warnings for a freshly installed pattern-lab after we merge this.

Most Important

  • packages/core/patternlab-config.json (used within getDefaultConfig)
  • packages/edition-node/patternlab-config.json
  • packages/edition-node-gulp/patternlab-config.json
  • packages/edition-twig/patternlab-config.json

Less Important or Internal

  • packages/core/test/util/patternlab-config.json
  • packages/cli/test/fixtures/patternlab-config.json
  • packages/development-edition-engine-handlebars/patternlab-config.json
  • packages/development-edition-engine-react/patternlab-config.json
  • packages/development-edition-engine-twig/patternlab-config.json

Copy link
Contributor Author

Choose a reason for hiding this comment

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

packages/core/test/util/patternlab-config.json is left as is intentionally because it is used in the tests for checking the warning messages.

Question back: packages/development-edition-engine-react/patternlab-config.json doesn't have a uikits block, but does point to ./node_modules/@pattern-lab/uikit-workshop files inside the paths section. With my change, this won't work in Yarn v2. I don't know if this is anything specific to React but I would need some help here on what to do.

Copy link
Contributor

Choose a reason for hiding this comment

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

Leave it out then. I'm not shure which engines are used anymore. Some feel depreacated / outdated anyway.

Comment on lines +9 to +27
const resolveFileInPackage = (packageName, ...pathElements) => {
return require.resolve(path.join(packageName, ...pathElements));
};

/**
* @func resolveDirInPackage
* Resolves a file inside a package
*/
const resolveDirInPackage = (packageName, ...pathElements) => {
return path.dirname(resolveFileInPackage(packageName, ...pathElements));
};

/**
* @func resolvePackageFolder
* Resolves the location of a package on disc
*/
const resolvePackageFolder = packageName => {
return path.dirname(resolveFileInPackage(packageName, 'package.json'));
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a question for this. The whole concept is working without process.cwd() is that correct?
When it tries to resolve the given files/directories it will walk from the resolver location through the filesystem or where would it start?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Patternlab loads files from installed NodeJS packages. It starts loading via whatever resolver a package manager could configure inside the Node runtime. In my case, I want to support Yarn v2 with PnP active eventually. In such a setup, no node_modules folder is used at all and every package is stored as a zip file. Here is an example how files inside a package are to be found:

https://yarnpkg.com/features/pnp#packages-are-stored-inside-zip-archives-how-can-i-access-their-files

Copy link
Contributor

Choose a reason for hiding this comment

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

If it does not interfere with other resolvers like npm or yarn v1 everything is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@JosefBredereck if uikit resolution works via require.resolve, the updated code ought to work under any other setup. If it doesn't it is a bug and needs to be fixed, which I'm glad to provide a fix for.

@JosefBredereck JosefBredereck marked this pull request as ready for review August 18, 2020 06:17
@JosefBredereck
Copy link
Contributor

Also, you will need to update the branch from dev or the merging will be blocked.

@ringods
Copy link
Contributor Author

ringods commented Aug 18, 2020

@JosefBredereck will process your requests next week. I'm on holiday this week. ;-)

@ringods ringods force-pushed the feature/yarn-workspaces branch from 7ed5244 to e694c37 Compare August 19, 2020 05:10
@ringods ringods force-pushed the feature/yarn-workspaces branch from e694c37 to 4b18d43 Compare August 19, 2020 05:19
@ringods ringods requested a review from JosefBredereck August 19, 2020 05:21
@ringods
Copy link
Contributor Author

ringods commented Aug 19, 2020

@JosefBredereck can you review again? Please focus on the uikits loading for now. I will submit a new PR to update:

  • core/src/lib/starterkit_manager.js
  • core/src/lib/pattern_engines.js

so these also use the new resolver instead of calculating paths into node_modules themselves.

Copy link
Contributor

@JosefBredereck JosefBredereck left a comment

Choose a reason for hiding this comment

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

Good changes. Also, I like that you keep the old way in place and notify the user to update the config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow uikit plugins to be used across multiple uikit definitions

4 participants