2.0.0 • Published 5 years ago

metalsmith-postcss2 v2.0.0

Weekly downloads
12
License
MIT
Repository
github
Last release
5 years ago

metalsmith-postcss2

Go to the latest release page on npm License: MIT Supported Node.js version: ^8.3.0 || 10.x || >=12.x Supported Metalsmith version: ^2.2.0 Supported PostCSS version: ^7.0.8 Type Definitions: TypeScript Minified Bundle Size Details Install Size Details Dependencies Status Build Status Maintainability Status

Metalsmith plugin for PostCSS.

Features

Install

# This package does not include postcss. You need to install postcss.
npm install postcss

npm install metalsmith-postcss2

CLI 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.css

However, 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.css

PostCSS 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 false are 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> | PluginsRecord

options

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
''
""
``
null

If 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 objects

By 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) => string

dependenciesKey

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):

false

Type definition (source):

string | false | null

PostCSS 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

NameTypeDescriptionDefault
cwdstringprocess.cwd()process.cwd()
envstringprocess.env.NODE_ENV'development'
optionspostcss.ProcessOptionsPostCSS Optionsfrom, to, parser, stringifier, syntax, map
file{dirname: string, basename: string, extname: string}Source File Datadirname, basename, extname
pluginsList(postcss.Plugin | postcss.pluginFunction | postcss.Processor)[]PostCSS Plugins Array[]
metalsmithMetalsmithMetalsmith instanceMetalsmith(...)

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.js

For 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 test

Contributing

see CONTRIBUTING.md

Related