Meteor-Community-Packages / meteor-postcss

PostCSS for Meteor

Home Page:https://packosphere.com/juliancwirko/postcss

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to Hot Reload CSS Files Referenced in Imports Directory

joncursi opened this issue · comments

I have the following main.css file in my client directory:

client/main.css

@import '../imports/ui/helpers/style/main';

The above import references the following style manifest:

imports/ui/helpers/style/main.scss

// Vendor
@import '../../../../node_modules/normalize.css/normalize.css';

// Libraries
@import './lib/colors';
@import './lib/transitions';
@import './lib/typography';

// Components
@import '../../components/BottomNav/BottomNav';
@import '../../components/LeftDrawer/LeftDrawer';
@import '../../components/TopBar/TopBar';

// Layouts
@import '../../layouts/AppLayout/AppLayout';

When I make changes to any of the files referenced above within the imports/ directory, Meteor does NOT hot reload those styles to the client. Meteor is only able to detect and hot reload if client/main.css ITSELF changes, which seems to run contrary to Meteor is pushing for modularity / files to be co-located within the imports directory.

Here's my package.json config if it helps!

  "postcss": {
    "plugins": {
      "postcss-easy-import": {
        "extensions": [
          ".css",
          ".scss"
        ]
      },
      "postcss-nested": {},
      "postcss-simple-vars": {},
      "autoprefixer": {
        "browsers": [
          "last 2 versions"
        ]
      }
    },
    "parser": "postcss-scss"
  },

Hi, yes postcss import plugin doesn't work well with Meteor auto reload system. For now the best solution will be to use preprocessor for imports and other PostCSS plugins for everything else. This PostCSS package will not work in all cases because Meteor build system limitations. I think we need more elastic build system in Meteor. I hope in the future we will be able to decouple Meteor parts so for example we can use Webpack an Meteor backend only. Just like for example here: https://github.com/juliancwirko/react-redux-webpack-meteor without spliting it into two separated apps. Or maybe we just get something like webpack loaders in Meteor build system. It would be awesome.

Anyway, I'll try to take a look into it. Maybe we can do something with this problem.

One more thing. I've done simple test and it works well for me.
I have something like:

imports/client/test.css

and in client/main.css I have: @import '../imports/client/test.css'

In html I have my class:

<div class="test">test message</div>

Then when I change the color for .test class in imports/client/test.css then it reloads properly.

All with the same PostCSS configuration.

@juliancwirko I think the difference between your example and mine is that I'm using the .scss file extension, not .css. Seems like the pre-processing on .scss files will not kick off until the main.css file changes, which is never (all my changes are to .scss files).

oh, yes, this could be the case. This is probably because .scss has no additional plugin which would handle these files. Ehhh, the build system in Meteor is quite odd, such simple things are so hard to manage :/

I gues for now you need to use fourseven:scss package and postcss package too. You'll be able to handle imports and reloading with fourseven:scss and all PostCSS related stuff should still work.

Hmm, adding fourseven:scss breaks the app (React):

warning.js:44Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of `MeteorDataContainer`.warning @ warning.js:44ReactElementValidator.createElement @ ReactElementValidator.js:221MeteorDataContainer_render @ createContainer.jsx:36ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:687ReactCompositeComponentMixin._renderValidatedComponent @ ReactCompositeComponent.js:707ReactCompositeComponent__renderValidatedComponent @ ReactPerf.js:66ReactCompositeComponentMixin.performInitialMount @ ReactCompositeComponent.js:291ReactCompositeComponentMixin.mountComponent @ ReactCompositeComponent.js:222ReactCompositeComponent_mountComponent @ ReactPerf.js:66ReactReconciler.mountComponent @ ReactReconciler.js:39ReactCompositeComponentMixin.performInitialMount @ ReactCompositeComponent.js:297ReactCompositeComponentMixin.mountComponent @ ReactCompositeComponent.js:222ReactCompositeComponent_mountComponent @ ReactPerf.js:66ReactReconciler.mountComponent @ ReactReconciler.js:39ReactCompositeComponentMixin.performInitialMount @ ReactCompositeComponent.js:297ReactCompositeComponentMixin.mountComponent @ ReactCompositeComponent.js:222ReactCompositeComponent_mountComponent @ ReactPerf.js:66ReactReconciler.mountComponent @ ReactReconciler.js:39ReactCompositeComponentMixin.performInitialMount @ ReactCompositeComponent.js:297ReactCompositeComponentMixin.mountComponent @ ReactCompositeComponent.js:222ReactCompositeComponent_mountComponent @ ReactPerf.js:66ReactReconciler.mountComponent @ ReactReconciler.js:39ReactCompositeComponentMixin.performInitialMount @ ReactCompositeComponent.js:297ReactCompositeComponentMixin.mountComponent @ ReactCompositeComponent.js:222ReactCompositeComponent_mountComponent @ ReactPerf.js:66ReactReconciler.mountComponent @ ReactReconciler.js:39mountComponentIntoNode @ ReactMount.js:103Mixin.perform @ Transaction.js:136batchedMountComponentIntoNode @ ReactMount.js:124Mixin.perform @ Transaction.js:136ReactDefaultBatchingStrategy.batchedUpdates @ ReactDefaultBatchingStrategy.js:63batchedUpdates @ ReactUpdates.js:97ReactMount._renderNewRootComponent @ ReactMount.js:277ReactMount__renderNewRootComponent @ ReactPerf.js:66ReactMount._renderSubtreeIntoContainer @ ReactMount.js:354ReactMount.render @ ReactMount.js:374React_render @ ReactPerf.js:66(anonymous function) @ main.jsx:22maybeReady @ startup_client.js:26loadingCompleted @ startup_client.js:38
invariant.js:38Uncaught Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `MeteorDataContainer`.

Hmm, this is weird. The stack trace doesn't show anything about this package.
It looks like something related to React usage.

Hello everyone! I had exactly the same issue with hot reload. As a workaround I use .styl.js extension instead of .styl and hot reload works well in this case.. For sass syntax it could be .scss.js:

      ...
      "postcss-easy-import": {
        "extensions": [
          ".css",
          ".scss.js"
        ]
      },
      ...

P.S. I assume, .scss.css should do the thing as well.

@priezz so if you use .js extension so why not just using .css and for example scss or sugarss parser? When using PostCSS only you can write scss or stylus like code in files with .css extension. The problem is when you have large codebase written in for example .scss files and you want to integrate it. But when you write your own files it is better to just use .css extension.

I use sugarss parser (it is buggy, but works in proper conditions :/) to parse Stylus-like files. I do use .js ending to see the changed file name in the server console (I use brilliant gadicc:ecmascript-hot package) - that is the only purpose. Normally it should be .styl.css, of course. I do not like the idea of using just .css because it does not give the understanding of the content inside the file when just looking at the filename.

Ok, I understand. You can also use Stylus compiler and PostCSS side by side. If you need to use both styles. This works for me.

That is what I did before, but Stylus gives some overhead in terms of build time and is not really needed to parse our style files. The only two things I had to do when switched to sugarss were reformatting the code (sugarss always wants space after colon, and I miss it sometimes) and replacement of color management expressions to PostCSS-understandable. For now it looks like a working solution for me and I will stay with it until I am tired with human-unreadable error-messages from sugarss :).

Yeah, personally, I'm slowly getting tired of Meteor's build system ;)

I believe everyone do :) I was extremely happy to find ecmascript-hot to use with React projects. Before that I tried webpack module and it worked rather well but for some reason the built client side was a litte larger and the whole process of development was not so smooth.
I really hope MDG will fix the build system API and performance soon.