metalsmith-postcss2 v2.0.0
metalsmith-postcss2
Metalsmith plugin for PostCSS.
Features
Supports the latest PostCSS
Loading PostCSS config file
Use postcss-load-config to load the PostCSS configuration.
Automatic rename
By default, all file extensions are converted to
.css. See description ofrenameroption.Multi-level SourceMap
Supports SourceMap joins processed in the previous processing step. If you want to omit the previous SourceMap, set the PostCSS
map.prevoption tofalse.Customizable SourceMap location
In the PostCSS configuration file, specify the SourceMap filepath in the PostCSS
map.annotationoption.Reading dependencies
Subsequent Metalsmith plugins can read the metadata of the imported file during the conversion. See description of
dependenciesKeyoption.Available in TypeScript
Type definition is included.
Compliant with PostCSS Runner Guidelines
Install
# This package does not include postcss. You need to install postcss.
npm install postcss
npm install metalsmith-postcss2CLI Usage
The simplest use is with a PostCSS configuration file.
Use PostCSS configuration file
Install via npm and then add the metalsmith-postcss2 key to your metalsmith.json plugin, like so:
metalsmith.json
{
"plugins": {
"metalsmith-postcss2": true
}
}Then create a PostCSS configuration file.
It is a file with a name like postcss.config.js or .postcssrc.*.
postcss.config.js or .postcssrc.js
module.exports = {
map: { inline: false },
plugins: {
'postcss-import': {},
'postcss-preset-env': {},
'cssnano': {}
}
};or
.postcssrc.yaml or .postcssrc.yml
map:
inline: false
plugins:
postcss-import: {}
postcss-preset-env: {}
cssnano: {}or
.postcssrc.json
{
"map": {
"inline": false
},
"plugins": {
"postcss-import": {},
"postcss-preset-env": {},
"cssnano": {}
}
}Or you can include the PostCSS configuration in the package.json file
package.json
{
...
"postcss": {
"map": {
"inline": false
},
"plugins": {
"postcss-import": {},
"postcss-preset-env": {},
"cssnano": {}
}
}
}You can read more about common PostCSS Config here.
Normally you will create a PostCSS configuration file in the same directory as the metalsmith.json file.
Project (Root)
├── metalsmith.json
├── postcss.config.js # <- PostCSS configuration file
└── src
├── main.css
└── dir
└── sub.cssHowever, it is also possible to place the PostCSS configuration file in a subdirectory.
Project (Root)
├── metalsmith.json
├── postcss.config.js # <- PostCSS configuration file
└── src
├── main.css
└── dir
├── .postcssrc.yml # <- PostCSS configuration file in subdirectory
└── sub.cssPostCSS configuration files are searched by tracing the parent directories where the CSS file to be processed is located.
In the above example, sub.css is converted using the settings defined in the closest .postcssrc.yml file.
Project (Root)
├── metalsmith.json
├── postcss.config.js # <- [1] PostCSS configuration file
└── src
├── main.css # Use configuration is [1]
└── dir
├── .postcssrc.yml # <- [2] PostCSS configuration file in subdirectory
└── sub.css # Use configuration is [2]Use with AltCSS
When converting AltCSS such as SASS, SCSS, LESS, Stylus or SugarSS, it is necessary to overwrite the file extension setting.
For SugarSS, the file extension is .sss. Therefore, set as follows:
metalsmith.json
{
"plugins": {
"metalsmith-postcss2": {
"pattern": "**/*.sss"
}
}
}postcss.config.js
module.exports = {
parser: 'sugarss',
plugins: {
// ...
}
};By default, all processed file extensions are renamed to .css.
If you want to stop renaming, set the renamer option to false or null.
metalsmith.json
{
"plugins": {
"metalsmith-postcss2": {
"pattern": "**/*.sss",
"renamer": false
}
}
}Use Metalsmith plugin options
If you need to specify an PostCSS options in metalsmith.json, set the options to the value of the metalsmith-postcss2 key.
{
"plugins": {
"metalsmith-postcss2": {
"plugins": {
"postcss-import": {},
"postcss-preset-env": {},
"cssnano": {}
},
"options": {
"map": { "inline": false }
}
}
}
}However, this is not recommended.
Plugin options are parsed differently than the PostCSS configuration file. It is not fully compatible.
A prominent example of this difference is that it currently does not support the parser option specified as a string.
{
"plugins": {
"metalsmith-postcss2": {
"plugins": {
"postcss-import": {},
"postcss-preset-env": {},
"cssnano": {}
},
"options": {
"parser": "sugarss", // DO NOT WORK! Currently does not support string value
"map": { "inline": false }
}
}
}
}Use the PostCSS configuration file whenever possible.
Javascript Usage
The simplest use is to omit the option. The settings in the PostCSS configuration file are used.
const postcss = require('metalsmith-postcss2');
metalsmith
.use(postcss());If you need to specify an options, set the options value.
const postcss = require('metalsmith-postcss2');
metalsmith
.use(postcss({
pattern: '**/*.sss',
}));If you want to use the files variable or the default options value, you can specify the callback function that generates the options.
const postcss = require('metalsmith-postcss2');
metalsmith
.use(postcss(
(files, metalsmith, defaultOptions) => {
return {
pattern: [...defaultOptions.pattern, '!**/_*', '!**/_*/**'],
};
}
));TypeScript Usage
For compatibility with the Metalsmith CLI, this package exports single function in CommonJS style.
When using with TypeScript, it is better to use the import = require() statement.
import postcss = require('metalsmith-postcss2');
metalsmith
.use(postcss());Options
The default value for options are defined like this:
const path = require('path');
{
pattern: ['**/*.css'],
plugins: [],
options: {},
renamer: filename => {
const newFilename = path.basename(filename, path.extname(filename)) + '.css';
return path.join(path.dirname(filename), newFilename);
},
dependenciesKey: false,
}pattern
Only files that match this pattern will be processed. Specify a glob expression string or an array of strings as the pattern.
Pattern are verified using multimatch v4.0.0.
Default value (source):
['**/*.css']Type definition (source):
string | string[]plugins
Specifies an array of PostCSS plugins. In addition to PostCSS plugins, you can also specify the following values:
An array of strings listed the plugin package names
[ 'postcss-import', // equal to require('postcss-import') 'postcss-preset-env', // equal to require('postcss-preset-env') 'cssnano' // equal to require('cssnano') ]Object that has plugin package name as key and plugin options as value. Plugins with a value of
falseare excluded{ 'postcss-import': {}, // equal to require('postcss-import') ; if value object has no properties, it is not used for options 'postcss-preset-env': { stage: 0 }, // equal to require('postcss-preset-env')({ stage: 0 }) 'cssnano': 42, // equal to require('cssnano') ; if value is not an object, it is not used for options 'postcss-pseudoelements': false // if value is false, plugin will not be imported }An array of the values described above. Arrays can recurse indefinitely
[ 'postcss-import', { 'postcss-preset-env': { stage: 0 } }, require('postcss-pseudoelements')(), [ [ 'cssnano' ] ] ]
Default value (source):
[]Type definition (source line 26 / source line 41 - 46):
// import postcss from 'postcss';
//
// type NestedArray<T> = (T | NestedArray<T>)[]
// type PluginsRecord = Record<string, unknown>;
NestedArray<postcss.AcceptedPlugin | string | PluginsRecord> | PluginsRecordoptions
Specify options to pass to the PostCSS Processor#process() method. See the PostCSS documentation for details on options.
The from and to properties cannot be specified because the plugin automatically sets them internally.
If set, an exception will be thrown.
Default value (source):
{}Type definition (source):
// import postcss from 'postcss';
Omit<postcss.ProcessOptions, 'from' | 'to'>renamer
Specify a function to rename of processed CSS files.
If you specify a falsy value other than undefined, such as null or false, processed files will not be renamed.
// These values disable file renaming
false
0
-0
NaN
-NaN
''
""
``
nullIf undefined or a truthy value other than function is specified, use the default renamer.
// These values use the default renamer
undefined
true
42
-42
Infinity
-Infinity
'str'
"0"
`false`
{}
[]
/ab+c/i
new Date()
... // And other non-function objectsBy default, a function that replaces file extension with .css is setted.
Default value (source):
const path = require('path');
filename => {
const newFilename = path.basename(filename, path.extname(filename)) + '.css';
return path.join(path.dirname(filename), newFilename);
}Type definition (source line 28 / source line 47):
true | false | null | (filename: string) => stringdependenciesKey
To understand the description of this option, knowledge of the Metalsmith plugin is required.
Specify the property name. The property specified by this option contains an object with the name and metadata of the file used in the CSS conversion.
For example, if you convert the following files with the postcss-import plugin:
main.css
@import "foo.css";
body {
background: black;
}foo.css
.foo {
font-weight: bold;
}If value 'dependencies data' is specified in dependenciesKey option, the following "dependencies object" are inserted into the Metalsmith metadata:
// This object is the value that subsequent Metalsmith plugins read from the "files" argument
// see: https://github.com/segmentio/metalsmith#useplugin
{
'main.css': {
// ↓ Properties automatically added by Metalsmith
contents: Buffer.from('.foo { ... body { ...'), // Converted CSS contents
mode: ...,
stats: Stats { ... },
// ↑ Properties automatically added by Metalsmith
// ↓ dependencies object added by specifying "dependenciesKey" option
'dependencies data': {
'main.css': {
contents: Buffer.from('@import "foo.css"; ...'), // Contents of main.css before conversion
mode: ...,
stats: Stats { ... },
...
},
'foo.css': {
contents: Buffer.from('.foo { ...'), // Contents of foo.css before conversion
mode: ...,
stats: Stats { ... },
...
}
}
},
'foo.css': {
// ↓ Properties automatically added by Metalsmith
contents: Buffer.from('.foo { ...'), // Converted CSS contents
mode: ...,
stats: Stats { ... },
// ↑ Properties automatically added by Metalsmith
// ↓ dependencies object added by specifying "dependenciesKey" option
'dependencies data': {
'foo.css': {
contents: Buffer.from('.foo { ...'), // Contents of foo.css before conversion
mode: ...,
stats: Stats { ... },
...
}
}
},
...
}If an empty string or a non-string value is specified in the dependenciesKey option, the dependencies object is not insert.
// These values not insert dependencies object
false
true
null
undefined
''
""
``Default value (source):
falseType definition (source):
string | false | nullPostCSS Plugin array
An options can also be an array.
If an array is specified, its value is used as the plugins option.
const postcss = require('metalsmith-postcss2');
postcss([ 'postcss-import' ])
// equal to:
// postcss({
// plugins: [ 'postcss-import' ]
// })PostCSS Config Context
For more advanced usage it's recommend to to use a function in postcss.config.js, this gives you access to the CLI context to dynamically apply options and plugins per file
| Name | Type | Description | Default |
|---|---|---|---|
cwd | string | process.cwd() | process.cwd() |
env | string | process.env.NODE_ENV | 'development' |
options | postcss.ProcessOptions | PostCSS Options | from, to, parser, stringifier, syntax, map |
file | {dirname: string, basename: string, extname: string} | Source File Data | dirname, basename, extname |
pluginsList | (postcss.Plugin | postcss.pluginFunction | postcss.Processor)[] | PostCSS Plugins Array | [] |
metalsmith | Metalsmith | Metalsmith instance | Metalsmith(...) |
postcss.config.js
module.exports = ctx => ({
map: ctx.options.map,
parser: ctx.file.extname === '.sss' ? 'sugarss' : false,
plugins: {
'postcss-import': { root: ctx.file.dirname },
cssnano: ctx.env === 'production' ? {} : false
}
})Debug mode
This plugin supports debugging output. To enable, use the following command when running your build script:
DEBUG=metalsmith-postcss2,metalsmith-postcss2:* node my-website-build.jsFor more details, please check the description of debug v4.1.1.
Tests
To run the test suite, first install the dependencies, then run npm test:
npm install
npm testContributing
see CONTRIBUTING.md