How to autoprefix css files generated by less, in

2019-04-29 18:57发布

问题:

I've got Webstorm 7 (on Win7) compiling my .less files into minified css with sourcemaps (using lessc on nodejs v0.10.26, run from a File Watcher in Webstorm), and I can then run autoprefixer on that generated css to automatically insert vendor prefixes.

What I'm not sure how to do, is combine the two steps. Is it possible to chain File Watchers in Webstorm?

Possible approaches:

  • Create a batch script that is called from the file watcher, then calls less and autoprefixer in sequence.
  • Create a node.js script/module that calls less, then autoprefixer.
  • Have the less transpiler output the css with a custom extension (e.g., .unprefixedcss), then have a File Watcher specifically for that extension.
  • Something I'm missing?

回答1:

There is a plugin for less which does this job without adding a watcher: https://github.com/less/less-plugin-autoprefix

After installation you can add --autoprefix="…" to your arguments for the output in webstorms file watcher.



回答2:

yes, it's possible to chain file watchers. The autoprefixer file watcher will listen to css changes and run after less. The first and secong approaches will work too



回答3:

I tried the batch script approach with a python script, called from a single File Watcher:

#!/usr/bin/env python

"""
less-prefixed.py

Chains less and autoprefixer, to produce a minified, vendor-prefixed css file.
"""

# TODO: move config data to a config file
# TODO: delete the intermediate files generated by less

import argparse
import os
import subprocess
from pprint import pprint as pp

# Config data
node_folder = r'C:/Users/ClementMandragora/AppData/Roaming/npm'
less_script = os.path.join(node_folder, 'lessc.cmd')
autoprefixer_script = os.path.join(node_folder, 'autoprefixer.cmd')

parser = argparse.ArgumentParser()
parser.add_argument("--file-name", help="filename, not including the extension", required=True)
parser.add_argument("--working-dir", help="the directory to do the work in", required=True)
args = parser.parse_args()

print('\nArgs:')
pp(vars(args))
print('')

os.chdir(args.working_dir)
print('CWD: {c}\n'.format(c=os.getcwd() + '\n'))

print('Running less-css...')

# Compile and minify the less file to css.
# Include a sourcemap.
exitcode = subprocess.Popen([
    less_script,
    '--no-color',
    '-x',
    '--source-map={n}.css.map'.format(n=args.file_name),
    '{n}.less'.format(n=args.file_name),  # source
    '{n}.min.css'.format(n=args.file_name)  # dest
], cwd=args.working_dir).wait()

assert exitcode is 0, 'Nonzero return code from less! Got: {r}'.format(r=exitcode)
print('less compilation completed.\nRunning autoprefixer...')

# Run autoprefixer over the result from lessc.
exitcode = subprocess.Popen([
    autoprefixer_script,
    '-o',
    '{n}.prefixed.min.css'.format(n=args.file_name),  # dest
    '{n}.min.css'.format(n=args.file_name)  # source
], cwd=args.working_dir).wait()

assert exitcode is 0, 'Nonzero return code from autoprefixer! Got: {r}'.format(r=exitcode)

print('autoprefixer completed.\nFinal filename is {n}.prefixed.min.css'.format(n=args.file_name))

It worked, but seemed unwieldy.

Next attempt was having multiple file watchers; it turns out that have autoprefixer watch for changes to css files, then generate another css file, results in a loop.

So I created a custom File Type in Webstorm for files matching *.min.css (the output of the less transpiler), then created a File Watcher for that extension. The other differences from the default/included less File Watcher are:

  • Program: C:\Users\ClementMandragora\AppData\Roaming\npm\autoprefixer.cmd
  • Arguments: -o $FileNameWithoutExtension$.prefixed.css $FileName$
  • Output paths to refresh: $FileNameWithoutExtension$.prefixed.css:$FileNameWithoutExtension$.prefixed.css.map

It wasn't initially clear to me that the 'Output paths to refresh' also signal Webstorm to parent the generated files under the main *.less file, reducing project clutter. (I'm keeping source and output in the same folder.)