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

#1393: Only use public API of 'compiler.inputFileSystem' #1437

Merged

Conversation

DorianGrey
Copy link
Contributor

@DorianGrey DorianGrey commented Apr 17, 2018

R: @jeffposnick @philipwalton

Fixes #1393.

Description of what's changed/fixed.
The issue linked above provides a more detailed explanation about the source of this problem.
Short version: The InjectManifest version of workbox-webpack-plugin currently relies on an internal function _readFile of the filesystem API. This only works under specific circumstances, and is unreliable in a more general case (e.g. in case of a decorated filesystem version).

Changes included in this PR:

  • Use the public readFile function of webpack's filesystem API. Requires an explicit binding for this.
  • Omit the encoding in readFileFn of readFileWrapper - it cannot be provided explicitly in this case.

@coveralls
Copy link

coveralls commented Apr 17, 2018

Coverage Status

Coverage increased (+0.003%) to 87.302% when pulling c85cce2 on DorianGrey:1393-use-public-filesystem-api into b719ce3 on GoogleChrome:master.

@DorianGrey DorianGrey force-pushed the 1393-use-public-filesystem-api branch from 38f009d to c85cce2 Compare April 27, 2018 07:44
@jeffposnick
Copy link
Contributor

Thanks for the contribution, @DorianGrey!

I'm generally on board with this change, but would like to CC: in @goldhand (who wrote the original _readFile code) to see if there is any feedback, and @raejin as an FYI, as they've been helpful with feedback on webpack dev server issues in the past.

I don't want to block on either of those folks as I'm not sure that they'll have time to provide feedback, so I'll also run a few quick sanity checks.

(Longer-term, I think it would make sense to specifically add some tests that cover alternative filesystems; see #1456)

@@ -28,7 +28,7 @@
*/
function readFileWrapper(readFileFn, filePath) {
return new Promise((resolve, reject) => {
readFileFn(filePath, 'utf8', (error, data) => {
Copy link

Choose a reason for hiding this comment

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

Would the utf8 encoding option cause any problem? This seems like the only different in calling the readFile API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes - it causes a runtime error, since the method from the public API only expects two parameters, the file path and the callback. See the API of the CachedInputFileSystem for an example: https://github.com/webpack/enhanced-resolve/blob/master/lib/CachedInputFileSystem.js#L238

Copy link

Choose a reason for hiding this comment

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

@DorianGrey Clarification on my question, it seems like the delegated callsite (https://github.com/webpack/enhanced-resolve/blob/master/lib/CachedInputFileSystem.js#L78-L80) omitted the utf8 encoding option, which we are doing here. I'm wondering what the implication of omitting the encoding option.

Copy link
Contributor

Choose a reason for hiding this comment

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

A few data points:

The one usage of readFileWrapper is to read in the swSrc, and the results of that are then used as part of a ES2015 template string to construct the final swDest file.

If the native fs.readFile() is called in two-parameter mode, without specifying the encoding, then it returns the contents as a Buffer rather than a string. But, using the Buffer within the final ES2015 template string will automatically call toString() on in, and the default encoding for that stringification is utf-8. So, we should have the same end result for the fs.readFile() case as well.

Copy link

Choose a reason for hiding this comment

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

👍 Awesome, thank you for the detailed explanation and references to the source code.

@philipwalton
Copy link
Member

I'm not as familiar with this issue, but this change looks fine to me. @jeffposnick if you're fine with merging, +1 from me.

@@ -28,7 +28,7 @@
*/
function readFileWrapper(readFileFn, filePath) {
return new Promise((resolve, reject) => {
readFileFn(filePath, 'utf8', (error, data) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

A few data points:

The one usage of readFileWrapper is to read in the swSrc, and the results of that are then used as part of a ES2015 template string to construct the final swDest file.

If the native fs.readFile() is called in two-parameter mode, without specifying the encoding, then it returns the contents as a Buffer rather than a string. But, using the Buffer within the final ES2015 template string will automatically call toString() on in, and the default encoding for that stringification is utf-8. So, we should have the same end result for the fs.readFile() case as well.

@jeffposnick jeffposnick merged commit eff3540 into GoogleChrome:master May 1, 2018
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.

[workbox-webpack-plugin#InjectManifest] Relying on private _readFile is unstable
5 participants