Skip to content
This repository has been archived by the owner on Feb 9, 2023. It is now read-only.

Make postcss-brunch both compiler and optimizer #33

Closed
wants to merge 1 commit into from

Conversation

kuon
Copy link

@kuon kuon commented Nov 16, 2016

Fix #31 and stay consistent.

@lydell
Copy link
Contributor

lydell commented Nov 16, 2016

Doesn't this mean that PostCSS is run twice for .css files?

@kuon
Copy link
Author

kuon commented Nov 16, 2016

No it is run only once.

@lydell
Copy link
Contributor

lydell commented Nov 16, 2016

Would you mind explaining how that works? I think it is important for people to understand their build tools.

@kuon
Copy link
Author

kuon commented Nov 16, 2016

Actually, while it runs only once on each CSS file, it also run on the assembled css file (optimize), so in fact it will run twice on the same CSS code, yeah.

I just noticed that it was the case before: #2

Having both works with brunch 2.9, I think this plugin should really use only optimize, but it was changed back and forth by @paulmillr but it's unclear why. I thought having both functions would make things working without breaking stuff.

But, as I wrote here brunch/sass-brunch#125 I think we should write a test suite that run sass, postcss, autoprefixer/cssnext... to ensure all those plugins play nicely.

@paulmillr
Copy link
Member

I don't like this. We need a more generic api which is built into Brunch for stuff which is reused my many plugins.

@kuon
Copy link
Author

kuon commented Nov 16, 2016

I don't like it either, but we need to fix this without breaking stuff.

What do you recommend?

@paulmillr
Copy link
Member

Don't know. Maybe let's get into discussing the new API ASAP.

I was thinking that postcss could pass postcssTokens or so through Brunch File interface (which is basically a JS object passed to compile() or optimize() plugin functions).

This way stuff from sass, etc would be passed through without parsing the output twice.

@kuon
Copy link
Author

kuon commented Nov 16, 2016

But what is wrong with droping compile() and have postcss only as an optimizer?

@paulmillr
Copy link
Member

I don't remember the exact reason but we've dropped this decision because it broke something.

@shvaikalesh

@lydell
Copy link
Contributor

lydell commented Nov 16, 2016

#24 contains some information on the drawbacks (in some case) on using this as an optimizer.

@kuon
Copy link
Author

kuon commented Nov 16, 2016

Ok, I get what the whole "optimizer" problem is.

The real solution is to allow compiler chaining I guess.

@kuon
Copy link
Author

kuon commented Nov 16, 2016

I did a bit of digging, and this is getting more and more complicated.

We need a way to compile a file, and if it produces a file with an extension another compiler support, that other compiler should be called (with a check to avoid cycling).

While I was able to chain compilers, I was unable to generate a proper source map.

@jacksonrayhamilton
Copy link

I'd like to help move this issue forward. Chaining compilers sounds like an intuitive solution to this. @kuon, can you share your attempt at chaining so we can work on merging it into Brunch?

In an effort to get this package to work with sass-brunch, I branched it off the last version that worked with sass-brunch as suggested here, then added a quick fix to pass the source map along. See here. Does that help?

@kuon
Copy link
Author

kuon commented Jan 5, 2017

I tried to work a bit on this issue on the brunch source code:
https://gist.github.com/kuon/69366b9d448406a7b79e488c83f76fb4

But I realised I needed a distinct step, thus brunch/brunch#1565

I currently got a bit tired of this issue and switched to webpack.

@shvaikalesh
Copy link
Contributor

I've implemented chaining in brunch/brunch#1571. All we need is to release current masters of preprocessors and add .targetExtension = 'css'.

@kuon
Copy link
Author

kuon commented Jan 5, 2017

@shvaikalesh great! I'd like to keep using brunch as webpack is a bit over engineered, but I was on a tight schedule. I hope this will get it fixed.

@caleb531
Copy link

caleb531 commented Feb 12, 2017

I'm using sass-brunch with postcss-brunch and autoprefixer on one of my projects. I've upgraded to the latest brunch (2.10.6) and sass-brunch (2.10.2), but the latest postcss-brunch (2.0.5) breaks autoprefixing (I'm currently using @jacksonrayhamilton's patched version of postcss-brunch, which restores autoprefixing for me; see https://github.com/jacksonrayhamilton/postcss-brunch/tree/sass-support-and-sourcemap-fix).

I also noticed that this particular issue was closed because brunch/sass-brunch#135 was merged in, except that the required postcss-brunch changes (mentioned in the PR's HOWEVER note) have not yet made it into postcss-brunch.

@paulmillr @shvaikalesh I'd really love to get autoprefixing working again, and I'm willing to help however I can, so what's the current status of all this?

Thanks,
Caleb

@paulmillr
Copy link
Member

@caleb531 the only thing different in 2.10.2 is newer version of node-sass. It would be great to have the problem traced back to the project. Otherwise it's unwise to change from param, since it also affects other plugins.

@caleb531
Copy link

@paulmillr @shvaikalesh FWIW:

I can confirm that adding an optimize(file) function in addition to compile(file) (or replacing compile with optimize altogether) fixes autoprefixing for CSS compiled from sass-brunch. I've tried applying these changes to the latest release (v2.0.5) and to the tip of master for postcss-brunch (b5a0946) with the same success.

I've ready through #24 and I respect the rationale for keeping postcss-brunch as a compiler instead of an optimizer. I agree that breaking things like CSS modules for the purpose of enabling support for preprocessors (like sass-brunch) is not a fair compromise.

However, I'm still really wanting to see postcss-brunch play nicely with preprocessor plugins (as I really don't like referencing a patched version of this package for new Brunch projects). Allow me to throw out a few ideas:

  1. I'm not deeply familiar with the brunch plugin API, but I wonder if there is a way to dynamically determine when to run this package as a compiler or optimizer
  • Depending on the plugin that's passing data to postcss-brunch, if that can be known
  • or depending on the npm packages currently installed, like sass-brunch (this may not be an ideal heuristic, but I imagine it should work)
  1. Provide a configuration option the user can specify in their brunch config which determines whether to optimize or compile. I realize this isn't as automatic as users might expect from a brunch plugin, but considering that the choice between compiler and optimizer seems very use case-specific, I think it's worth considering:
     plugins: {
         postcss: {
           optimize: true,
           processors: [
             require('autoprefixer')({
               browsers: ['> 0.1%']
             })
           ]
         }
     }

Thoughts?

@lydell
Copy link
Contributor

lydell commented Mar 11, 2017

@caleb531 The real fix is to add targetExtension to sass-brunch. However, postcss-brunch and/or brunch is broken, causing errors to be thrown when combined with postcss-brunch. See brunch/sass-brunch#135 (which was reverted in brunch/sass-brunch@aa56632). Welcome to the wonderful world of broken brunch plugins.

@caleb531
Copy link

@lydell thanks for the clarification. I tried adding targetExtension in my project's installed version of sass-brunch, and I can confirm that I do receive an error. However, I'm able to fix this by adding to postcss-brunch the required file.map.toJSON ("HOWEVER") check described in brunch/sass-brunch#135:

diff --git a/index.js b/index.js
index 6c49ab4..bfe011b 100644
--- a/index.js
+++ b/index.js
@@ -60,7 +60,7 @@ class PostCSSCompiler {
 			file.data = '';
 		}
 		if (file.map) {
-			opts.map.prev = file.map.toJSON();
+			opts.map.prev = file.map.toJSON ? file.map.toJSON() : file.map;
 		}
 
 		return this.processor.process(file.data, opts).then(result => {

With both the above check in postcss-brunch and the addition of targetExtension in sass-brunch, autoprefixer works again. Therefore, what's stopping us from adding the toJSON check to postcss-brunch (and pushing a new release) so sass-brunch can add targetExtension without producing errors? Does making these changes break something else? I just want to understand this complex issue so I can help to fix it however I'm able.

@caleb531
Copy link

@lydell On second thought, I realize that the proposed toJSON check is merely a monkey-patch which doesn't address the real issue (i.e. why the check is even necessary). From what I've gathered, file.map should always be a SourceMapGenerators object, so I concede that this is a bug in brunch core.

For anyone trying to make sense of this tangled web of issues, here's what needs to happen (as I understand it) to get postcss-brunch working properly:

  1. Fix file.map issue in brunch core so that a toJSON check in postcss-brunch isn't required (maybe related to [2.10.x] Chains of plugins has issues brunch#1648?)
  2. Add targetExtension to sass-brunch (which should compile without errors at this point)

@PragTob
Copy link

PragTob commented Mar 13, 2017

Thanks for the writeup @caleb531 ! I'm trying to race this around and get postcss, brunch and sass to play nicely with each other... apparently that's a super hard task. I'll try to check out the fork you mentioned although that's less than ideal... might be I'll see if I have more success moving it all to webpack (for reasons I really NEED autoprefixer, in case someone understands this wrong: ❤️ to all maintainers and thanks for all your work :) )

@PragTob
Copy link

PragTob commented Mar 15, 2017

If you get here, as mentioned earlier by @caleb531 the fork in the dependencies as follows works for me:

"postcss-brunch": "jacksonrayhamilton/postcss-brunch#27ae06f"

@caleb531
Copy link

@PragTob Yes, that fork works, but it's based on an older version of postcss-brunch. If you'd like to patch autoprefixer for the most recent versions of postcss-brunch and sass-brunch, see my newly-created forks:

https://github.com/caleb531/sass-brunch
https://github.com/caleb531/postcss-brunch

I applied exactly the same changes I described above (the file.map check for postcss-brunch, and the targetExtension for sass-brunch). @PragTob, please try them and let me know if they fix autoprefixer for you. :)

@caleb531
Copy link

caleb531 commented Mar 15, 2017

Well, this issue has become somewhat more complicated.

Apparently, the latest commit in sass-brunch (brunch/sass-brunch@7ffb2e6) has rendered the plugin unable to load (see the sass-brunch issue I just created). Needless to say, I needed to revert this commit in my fork (in addition to committing my aforementioned file.map and targetExtension patches) in order to get the very latest postcss-brunch and sass-brunch playing nicely again.

EDIT: The aforementioned sass-brunch issue is actually a bug in brunch core, for which there is already a pull request. As on now, that pull request has been merged into master, with a new brunch release coming later today. :)

@PragTob
Copy link

PragTob commented Mar 16, 2017

Sadly, the forks with their respective latest latest versions don't seem to invoke auroprefixer so I'm back tot he old fork for now :|

@caleb531
Copy link

caleb531 commented Mar 16, 2017

@PragTob Don't fret! Perhaps you missed my revised comment above, but in short, try my forks with brunch 2.10.9 (released yesterday), which fixes a bug that was preventing sass-brunch from loading. I just tried it on one of my Brunch projects, and autoprefixer totally works for me.

"devDependencies": {
  "brunch": "^2.10.9",
  "postcss-brunch": "github:caleb531/postcss-brunch",
  "sass-brunch": "github:caleb531/sass-brunch"
}

@PragTob
Copy link

PragTob commented Mar 16, 2017

@caleb531 ah dang... I read the comment, but before the edit and when I got back here didn't read it again - will try it again - thanks :D

@caleb531
Copy link

Once again, this issue has gotten more complicated.

I discovered today that the switch from optimizer to compiler for postcss-brunch breaks the watching of sass partials by sass-brunch. That is, when I make a change to a sass partial (e.g. _foo.scss) that's included in a main sass file (e.g. main.scss) and then save that partial file, brunch will not recompile styles for the project. Only when I save the main sass file will the styles be recompiled.

I've created a test project to demonstrate this. After running npm install, here are the steps to reproduce:

  1. Run brunch watch; you'll get the standard "compiled everything" message:
info: compiled main.scss into main.css in 671 ms
  1. Save any changes to _foo.scss; notice this time you'll get a generic compile message, meaning that main.scss wasn't actually compiled:
info: compiled in 70 ms
  1. Save any changes to main.scss; the styles will actually compile this time:
info: compiled main.scss into main.css in 80 ms

Here's the full source code if you want to try it yourself:
sass-postcss-brunch-watch-test.zip

Regardless, because I only ever use a preprocessor (like sass-brunch) with postcss-brunch, I'm updating my fork to make postcss-brunch an optimizer again until we find an acceptable solution to this particular bug.

@paulmillr or @shvaikalesh: What do you make of this? Should I open up a separate issue? (and if so, for which project?)

@shvaikalesh
Copy link
Contributor

Hey Caleb. Greatly appreciate the report: indeed, dependencies are not merged correctly for compiler chains. No extra issue is necessary, will fix soon.

@caleb531
Copy link

@shvaikalesh: Just checking in—any updates on resolving the dependency-merging bug? Is there an existing GitHub issue I can subscribe to? (for that particular bug)

Oh, and thanks for all of the work you do on Brunch! :)
Caleb

@shvaikalesh
Copy link
Contributor

brunch/brunch#1664

This PR will fix things as soon it is competed and merged.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

7 participants