choojs / bankai

:station: - friendly web compiler
Apache License 2.0
1.09k stars 102 forks source link

Error trying to use sheetify-postcss and @rule #460

Open timsim00 opened 6 years ago

timsim00 commented 6 years ago

Expected Behavior

Successful compile and css using the keyframes rule.

Current Behavior

TypeError: First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object. at Function.Buffer.from (buffer.js:179:11)

Possible Solution

Has someone successfully used css rules with sheetify-postcss?

Context

Trying to use css for animated ellipsis.

Code Sample

package.json

  "browserify": {
    "transform": [
      [
        "sheetify/transform",
        {
          "use": [
            [
              "sheetify-postcss",
              {
                "plugins": [
                  "postcss-animation"
                ]
              }
            ]
          ]
        }
      ]
    ]
  },

Your Environment

OSX, Latest versions of bankai, choo, sheetify, sheetify-postcss

goto-bus-stop commented 6 years ago

could you share your input script file as well? that'll make it a bit easier to reproduce the problem :)

timsim00 commented 6 years ago

Sure, not much to it. Here you go:

const css = require('sheetify')
  const loadingCss = css`
  :host {
    @keyframes blink {
        0% {
          opacity: .2;
        }
        20% {
          opacity: 1;
        }
        100% {
          opacity: .2;
        }
    }

    .saving span {
        animation-name: blink;
        animation-duration: 1.4s;
        animation-iteration-count: infinite;
        animation-fill-mode: both;
    }

    .saving span:nth-child(2) {
        animation-delay: .2s;
    }

    .saving span:nth-child(3) {
        animation-delay: .4s;
    }
  }
  `

Any "@" will cause the above error. Very possible I just don't have this configured correctly.

goto-bus-stop commented 6 years ago

ah; somehow the CSS ends up with the :host { part removed, but with the matching } still there. That causes purify-css to throw, which we should be showing somewhere, but apparently are not. Then we try to set the undefined result from purify-css as the css bundle contents, causing the error you're actually seeing.

timsim00 commented 6 years ago

Thank you for researching. Is there a way to use this css without host?

timsim00 commented 6 years ago

My bad, has nothing to do with the "@" rule. Breaks on all uses of "host".

goto-bus-stop commented 6 years ago

It looks like it's crashing because of the nesting. You need to add the postcss-nesting plugin to make that work. I wonder if we can make it crash less … confusingly, though!

emilbayes commented 6 years ago

Just hit the same issue even with postcss-cssnext which I thought would take care of the nesting. Just adding another datapoint, will try to investigate more myself too :)

emilbayes commented 6 years ago

So here's my tiny app that appear to show the same result:

package.json ```json { "scripts": { "dev": "bankai start index.js" }, "browserify": { "transform": [ [ "sheetify", { "transform": [ [ "sheetify-postcss", { "plugins": [ "postcss-nesting" ] } ] ] } ] ] }, "dependencies": { "choo": "^6.13.0" }, "devDependencies": { "postcss-nesting": "^6.0.0", "bankai": "^9.14.0", "sheetify-postcss": "^1.2.0" } } ```
index.js ```js var choo = require('choo') var html = require('choo/html') var css = require('sheetify') var app = choo() css` :host { & .icon { stroke: red; } } ` app.route('/', _ => html``) app.mount('body') ```

If I add a console.log(style) in the catch of graph-style.js I see that the css has not been transformed with postcss-nesting:

._a0f69f10 {
    & .icon {
      stroke: red;
    }
  }

I therefore tried adding a console.log(opts.transforms) to https://github.com/stackcss/sheetify/blob/addbd3337ec85c299ea48a44bc857818c4b967c3/transform.js#L97 and saw that this would log twice:

[]
[ [ 'sheetify-postcss', { plugins: [ 'postcss-nesting' ] } ] ]

I suspect the reason it is not transformed properly is because there are no registered transforms the first time around? Does this sound plausible @goto-bus-stop ? :)

timsim00 commented 6 years ago

I think host just applies to the parent element, so for my keyframes example I got it working by removing the outer host.

goto-bus-stop commented 6 years ago

@emilbayes it logs twice because bankai already adds the sheetify transform, you can configure it using the top level sheetify key in package.json instead of adding it to the browserify key. whichever sheetify transform runs first will remove all the template tags so the second one doesn't see them.

emilbayes commented 6 years ago

@goto-bus-stop Ah! Using the sheetify key in my package.json actually fixed my problem!

goto-bus-stop commented 6 years ago

Huh that may have been part of the problem in the OP too, but i didn't notice it then. Could be worth adding a warning about this because it is extremely non obvious

emilbayes commented 6 years ago

So adding sheetify as a browserify transform, without explicitly having sheetify as a dependency works because it just happens to be in node_modules due to bankai? Is it overreaching if bankai used the browserify transforms directly? I guess you couldn't have two versions of sheetify at the same time then, but since the first of them to run removes all css already, I guess there's not really a point to having another?

goto-bus-stop commented 6 years ago

Right now bankai adds the sheetify transform using b.transform(sheetify). If you add sheetify to the browserify.transform key in your own package.json, browserify adds sheetify again (or a different version if you also manually installed it and npm could not dedupe it for some reason). Sheetify itself uses the sheetify package.json key to read config.

Is it overreaching if bankai used the browserify transforms directly?

I'm not sure what this means :sweat_smile: