-
-
Notifications
You must be signed in to change notification settings - Fork 211
feat: check postcss versions to avoid using PostCSS 7 #527
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
feat: check postcss versions to avoid using PostCSS 7 #527
Conversation
LGTM @alexander-akait can you start CI? |
src/index.js
Outdated
// Check postcss versions to avoid using PostCSS 7 | ||
if (!isCheckedPostCSSVersion && postcss().version.startsWith("7.")) { | ||
isCheckedPostCSSVersion = true; | ||
const pkg = readPackageJson(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will add one more fs call for each css
file, reduce perf very well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand, fs
call will be only once and only for postcss 7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can solve it on two ways:
- webpack already reads
package.json
, need look where we store it - using
this.fs
, so each call will be cacheable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it is invalid, in monorepos you can have multiple packages with different versions of postcss
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexander-akait can you show examples of such repositories? I'm talking about the mono repository.
Previous discussion about this problem #507 |
We will positive false/false positive for monorepos and will spam warnings, it is bad, also we need more strong check here, we can read |
Anyway we will run this check only for PostCSS 7 case, which will be rare case. Should we add deep search and check for |
To be honest, this is not an easy task, you can see the algorithm in npm/yarn/pnpm and found it is not easy. Also it is not make sense for yarn PnP/pnpm (will be failed by default) and npm v7 (automatically install peer deps) |
A lot of PostCSS 7 downloads is coming from plugins. The real number is much smaller. Right now using PostCSS 7 is insecure because of vulnerability. It forced migration.
We do not need to cover all cases here. We just need to prevent popular error. Edge cases can be fixed by:
I think npm 7 do not install peer dependencies for old dependencies on npm 6→7 migration. It will help only for new project or during installing new |
https://github.blog/2021-02-02-npm-7-is-now-generally-available/#peer-dependencies |
Yeap. As I understand, npm 7 will not fix old missed peer dependencies. |
Please help me understand what to do next. Add a warning and an environment variable? Or do you want to do this task more thoroughly in another PR? |
I understand your excitement, but it's okay, we just need to discuss a little more and as soon as we come to a decision I immediately ping you |
npm 7 install them by default, no matter whether it is old or new Anyway the main problem is not npm/yarn/pnpm, searching package.json is the main problem. I think we should use, simplified, but covered most of cases: const cwd = process.cwd();
let dir = cwd;
for (;;) {
try {
// `this` - is loader context
if (this.fs.statSync(path.join(dir, 'package.json')).isFile()) break;
} catch (e) {}
const parent = path.dirname(dir);
if (dir === parent) {
dir = undefined;
break;
}
dir = parent;
} It's just that from my experience these things usually create more problems than they solve... Package manager output is the place where you need read warnings/errors. All of these workarounds are trying to train the developer to be attentive, but if you do not read errors from your tty, you may need to learn more.. Just my opinion. |
yarn output is full on warnings about deprecated nested dependencies, which you can't fix. They hide important warning which you can fix. We know that people ignore this warning. Speaking about “the right way” will not solve the problem. Another way to fix the problem, is to catch errors from PostCSS and show warning about missed dependency before re-throwing the error. |
Sounds very good, I like it |
@shlyk a new plan:
|
OK |
@ai and @alexander-akait, please check it out. |
src/index.js
Outdated
postcssFactory().version.startsWith("7.") | ||
) { | ||
// For caching reasons, we use the readFileSync function from the context, not the function from the `fs` module. | ||
const pkg = readPackageJson(this.fs.readFileSync); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to check that pacjage.json
exists first (print nothing on no file).
Otherwise, it will throw Can’t read file error if package.json was in a different place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, done.
src/index.js
Outdated
// not the functions from the `fs` module. | ||
if ( | ||
!hasExplicitDependencyOnPostCSS && | ||
isFileExists(PACKAGE_JSON_PATH, this.fs.existsSync) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Run postcssFactory().version.startsWith("7.")
before isFileExists
to avoid unnecessary file check for PostCSS 8 users
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also changed it to call statSync(...).isFile()
instead of existsSync()
, because existsSync()
is not available in this version of Webpack.
src/utils.js
Outdated
@@ -408,10 +409,24 @@ function normalizeSourceMapAfterPostcss(map, resourceContext) { | |||
return newMap; | |||
} | |||
|
|||
function isFileExists(filePath, existsSync = fs.existsSync) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need default value for any cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I removed the default value. They don't seem to be needed here.
@alexander-akait we are ready for your review |
src/index.js
Outdated
} from "./utils"; | ||
|
||
let hasExplicitDependencyOnPostCSS = false; | ||
|
||
const PACKAGE_JSON_PATH = path.resolve(process.cwd(), "package.json"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cwd can be src
(i.e. src/package.json
), but it is invalid I provided example above with recusing searching
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be possible to use iterators to search for a file (from similar solutions), but it seems that this is not essential here. I took your solution, especially since there is a similar solution in the Webpack source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also use null
and undefined
to cache calls. For some, this may seem implicit. I can try to make it more explicit, if necessary.
@alexander-akait and @ai, are we doing something extra? Any other questions? |
LGTM. @alexander-akait let’s merge =^_^= |
I'm a little busy now, tomorrow I will merge and do release 👍 |
Codecov Report
@@ Coverage Diff @@
## master #527 +/- ##
==========================================
- Coverage 97.04% 94.93% -2.12%
==========================================
Files 5 5
Lines 271 296 +25
Branches 88 96 +8
==========================================
+ Hits 263 281 +18
- Misses 8 14 +6
- Partials 0 1 +1
Continue to review full report at Codecov.
|
@shlyk Can you accept CLA (link in github actions checks)? |
@alexander-akait done. |
You need to use the same email in commits, can you add it? |
@alexander-akait done. |
@alexander-akait, it looks like something needs to be done. Is there anything I can do to help? |
@shlyk You still have commits without email (look at your commits above), can you fix it? |
This PR contains a:
Motivation / Use-Case
Added code that helps the developer understand that it is necessary to use an explicit version of PostCSS. Closes #507.
Breaking Changes
No breaking changes.
Additional Info
cc @ai