miracle2k / webassets

Asset management for Python web development.
BSD 2-Clause "Simplified" License
923 stars 259 forks source link

Autoprefixer not working properly #497

Open NixBiks opened 6 years ago

NixBiks commented 6 years ago

In my flask application I have a setup like this

assets = Environment(app)
assets.load_path = [os.path.join(app.root_path, 'assets')]
assets.config['AUTOPREFIXER_BIN'] = os.path.join(app.root_path, os.pardir, 'node_modules', '.bin', 'postcss')

css_all = Bundle(
    'scss/all.scss',
    filters=['autoprefixer'],
    output='packed.css',
)
assets.register('css_all', css_all)

where I first installed autoprefixer by

npm install postcss-cli autoprefixer

Now this is all working fine and dandy - at least one would think. But if scss/all.scss contains

:fullscreen a {
  display: flex; 
}

then packed.css will output

:fullscreen a {
  display: flex; }

/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztFQUVFO0FBQ0Y7RUFDRSxjQUFjLEVBQUUiLCJmaWxlIjoic3RkaW4iLCJzb3VyY2VzQ29udGVudCI6WyIvKiohXHJcbiogQ3VzdG9tIHNhc3NcclxuKi9cbjpmdWxsc2NyZWVuIGEge1xuICBkaXNwbGF5OiBmbGV4OyB9XG4iXX0= */

instead of the expected output:

:-webkit-full-screen a {
    display: -webkit-box;
    display: flex
}
:-moz-full-screen a {
    display: flex
}
:-ms-fullscreen a {
    display: -ms-flexbox;
    display: flex
}
:fullscreen a {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex
}

Any suggestions?

NixBiks commented 6 years ago

Just realised changing

css_all = Bundle(
    'scss/all.scss',
    filters=['autoprefixer'],
    output='packed.css',
)

to

css_all = Bundle(
    'scss/all.scss',
    filters=['autoprefixer6'],
    output='packed.css',
)

fixes the issue. At least the output now are

:-webkit-full-screen a {
  display: -webkit-box;
  display: flex; }
:-moz-full-screen a {
  display: flex; }
:-ms-fullscreen a {
  display: -ms-flexbox;
  display: flex; }
:fullscreen a {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex; }

/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztFQUVFO0FBQ0Y7RUFDRSxjQUFjLEVBQUUiLCJmaWxlIjoic3RkaW4iLCJzb3VyY2VzQ29udGVudCI6WyIvKiohXHJcbiogQ3VzdG9tIHNhc3NcclxuKi9cbjpmdWxsc2NyZWVuIGEge1xuICBkaXNwbGF5OiBmbGV4OyB9XG4iXX0= */

Still the question is: why this last part with sourceMappingURL?

dfee commented 6 years ago

Wow – I didn't understand what you were talking about, but was trying to get autoprefixer to spit out anything beyond this in my compiled template:

autoprefix

Options:
  --info    Show target browsers and used prefixes
  --version Show version number
  --help    Show help

Usage:
  autoprefixer --info

Turns out that while autoprefixer is currently (at time of writing) at version 8.0.0, the filter you supply should indeed be autoprefixer6 and not autoprefixer as mentioned in the docs ... at least that compiles something.

Is autoprefixer6 completely undocumented? Anyway, it feels like it's an anti-pattern to be using webassets at all in the day of modern JS / webpack / etc. but if anyone else comes across this I hope it's helpful.

ghost commented 4 years ago

Anyway, it feels like it's an anti-pattern to be using webassets at all in the day of modern JS / webpack / etc.

I'm just reading this thread, a year later (because the documentation is still wrong). I disagree. Webpack is just another tool like webassets. A more popular tool indeed, but also, in my opinion, way more complicated than what it should be.

What webassets need is an update to its documentation (and a new release!). I might start working on the first one.

PS: Thank you for the tip!

ghost commented 4 years ago

I take back my words. The lack of support for sourcemaps it's a serious problem.

krassowski commented 3 years ago

Here is a working solution for modern autoprefixer. First, install autoprefixer 9 because postcss command line interface has not yet caught up with autoprefixer 10 (https://github.com/postcss/autoprefixer/issues/1358):

npm install autoprefixer@^9 postcss-cli@^8 postcss@^8

Then, define custom filter:

from subprocess import Popen, PIPE

def css_prefixer(_in, out, **kw):
    # probably can be simplified...
    cat = Popen(['cat'], stdin=PIPE, stdout=PIPE)
    postcss = Popen(['npx', 'postcss', '--use', 'autoprefixer'], stdin=cat.stdout, stdout=PIPE, stderr=PIPE)
    cat.stdin.write(_in.read().encode('utf-8'))
    cat.stdout.close()
    cat.terminate()
    postcss.wait()
    postcss_error = postcss.stderr.read().decode('utf-8')
    if postcss_error:
        raise ValueError(postcss_error)
    output = postcss.stdout.read().decode('utf-8')
    assert output
    out.write(output)

# Bundle(..., filters=[css_prefixer])

Now the seemingly useless use of cat above is actually required, because the postcss does not implement the pipe interface correctly (https://github.com/postcss/postcss-cli/issues/119).

It's not surprising that the JS ecosystem is breaking fast and breaking a lot, but as long as they provide a CLI it is possible to easily use the newest version.