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

fix: make sure manifest writes don't overlap #56

Merged
merged 3 commits into from
Aug 9, 2017

Conversation

mastilver
Copy link
Contributor

closes #21

@codecov-io
Copy link

codecov-io commented Jul 9, 2017

Codecov Report

Merging #56 into master will decrease coverage by 0.93%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #56      +/-   ##
==========================================
- Coverage     100%   99.06%   -0.94%     
==========================================
  Files           2        2              
  Lines          56      107      +51     
==========================================
+ Hits           56      106      +50     
- Misses          0        1       +1
Impacted Files Coverage Δ
lib/plugin.js 99.05% <100%> (-0.95%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c441207...29ffc01. Read the comment docs.

@mastilver mastilver force-pushed the write-file-from-plugin branch 2 times, most recently from ce697a8 to 36d0f9b Compare July 9, 2017 20:23
@zuzusik
Copy link

zuzusik commented Jul 10, 2017

The main question here - does it really fix #21? I don't see an appropriate test case added here. If it is hard to reproduce maybe we should ask reporters of #21 to test this fix with their local setup?

If it doesn't fix #21 then I don't see why it should be merged. As a step for #33 as supposed here
#33 (comment) ?
Don't think we need this step - we better fix #33 with one monolithic PR

lib/plugin.js Outdated

const shouldUseNodeFs = compiler.outputFileSystem.constructor.name !== 'MemoryFileSystem' ||
this.opts.writeToFileEmit;
if (shouldUseNodeFs) {
Copy link

@zuzusik zuzusik Jul 10, 2017

Choose a reason for hiding this comment

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

As far as I see, the logic used here breaks what was achieved with #28, as it assumes the file should be output to both memory and file system - now when writeToFileEmit is set to true, it will be output only to file system, and not to memory.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍 will fix that

@mastilver
Copy link
Contributor Author

@zuzusik Thank you for reviewing this PR :)

Did you see #49, I think you could be a good help for me

I think I know what's causing the issue, I will try to write a test that reproduce it

lib/plugin.js Outdated

const shouldUseNodeFs = compiler.outputFileSystem.constructor.name !== 'MemoryFileSystem' ||
this.opts.writeToFileEmit;
Copy link

Choose a reason for hiding this comment

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

this indentation looks broken, I think we should stick to 2 spaces everywhere, also I think it is little bit more readable if we put || on the new line:

const shouldUseNodeFs = compiler.outputFileSystem.constructor.name !== 'MemoryFileSystem'
  || this.opts.writeToFileEmit;


var ManifestPlugin = require('../index.js');

function webpackConfig (webpackOpts, opts) {
Copy link

Choose a reason for hiding this comment

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

let's be consistent with style here - we should stick to function<name>(...) {} style as it is used all over the project

I mean - there shouldn't be a space before (

Also it should be fixed in other places in this PR

lib/plugin.js Outdated

const shouldUseNodeFs = compiler.outputFileSystem.constructor.name !== 'MemoryFileSystem' ||
Copy link

Choose a reason for hiding this comment

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

I know that const is much more appropriate here, but this file uses var all over the place (and even 2 previous lines use var)

So I guess we should stick to var and if we want to go with const we should create separate PR in which we do refactor all var to const

Copy link

Choose a reason for hiding this comment

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

Also, as far as I see we do rely on internal implementation of memory-fs here. Not sure if it is a good idea - the class name can be changed at any time without implicating the API, so it wouldn't be a reason for new major version release.

Copy link

Choose a reason for hiding this comment

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

And another question here - what if someone provides custom memory file system which is implemented in the other way?

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 agree it's ugly but that the only way I could find to check if it's really MemoryFileSystem, if you have a better solution feel free to share it ;)

I'm note the only one doing it: https://github.com/gajus/write-file-webpack-plugin/blob/51167a8cf33ee0885805abd1fb85c8306f0eda27/src/index.js#L19

Copy link

@zuzusik zuzusik Jul 10, 2017

Choose a reason for hiding this comment

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

What do you think about this proposal:

var outputFolder = compilation.options.output.path;
var outputFile = path.join(outputFolder, this.opts.fileName);

compiler.outputFileSystem.mkdirp.sync(path.dirname(outputFile));
compiler.outputFileSystem.writeFileSync(outputFile, json);  

if (this.opts.writeToFileEmit) {
  fse.outputFileSync(outputFile, 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.

That would only work when using memory-fs, see: https://github.com/webpack/webpack/blob/master/lib/node/NodeOutputFileSystem.js#L17
It doesn't have writeFileSync

Copy link
Contributor Author

@mastilver mastilver Jul 10, 2017

Choose a reason for hiding this comment

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

this should work thought:

compiler.outputFileSystem.mkdirp.sync(path.dirname(outputFile));
if (isMemoryFs) {
  compiler.outputFileSystem.writeFileSync(outputFile, json);  
}

if (!isMemoryFs || this.opts.writeToFileEmit) {
  fse.outputFileSync(outputFile, json);
}

Copy link

Choose a reason for hiding this comment

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

Your code looks good, should work as expected 👍 I only assume it should use mkdirp.sync

What I want to achieve here is that we can skip compiler.outputFileSystem.constructor.name !== 'MemoryFileSystem' check

Overall impression - it is weird that different FSs used in WebPack have different sets of methods.

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 only assume it should use mkdirp.sync

Damn, I updated it :)

@@ -62,7 +62,7 @@ function webpackCompile(webpackOpts, opts, cb) {
var fs = compiler.outputFileSystem = new MemoryFileSystem();

compiler.run(function(err, stats){
var manifestFile = JSON.parse( fs.readFileSync(manifestPath).toString() );
var manifestFile = JSON.parse(fs.readFileSync(manifestPath).toString());
Copy link

Choose a reason for hiding this comment

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

I'd remove this changes as they are completely unrelated to this PR

@zuzusik
Copy link

zuzusik commented Jul 10, 2017

Also added few style related comments here

lib/plugin.js Outdated
fse.outputFileSync(outputFile, json);
} else {
compiler.outputFileSystem.mkdirpSync(path.dirname(outputFile));
Copy link

Choose a reason for hiding this comment

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

I wonder why mkdirpSync and not mkdirp?
Webpack docs only mention mkdirp here so it might blow up for some custom FS that provides only mkdirp but doesn't provide mkdirpSync

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should be mkdirp.sync

@zuzusik
Copy link

zuzusik commented Jul 10, 2017

@mastilver mastilver force-pushed the write-file-from-plugin branch 2 times, most recently from d334049 to 81bdf52 Compare July 12, 2017 09:39
@mastilver
Copy link
Contributor Author

@zuzusik PR updated, do you mind having another look

@mastilver mastilver force-pushed the write-file-from-plugin branch 2 times, most recently from 4f0347c to 3f9f027 Compare July 16, 2017 12:11
@mastilver
Copy link
Contributor Author

@zuzusik I'm not relying anymore or memory-fslogic

Let me know what you think!

@mastilver mastilver force-pushed the write-file-from-plugin branch 2 times, most recently from 0059180 to 609b6ca Compare July 16, 2017 12:18
@mastilver mastilver changed the title fix: write file directly from the plugin fix: make sure manifest writes don't overlap Jul 16, 2017
@mastilver mastilver added this to the v1.3 milestone Jul 29, 2017
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.

Mangled output
3 participants