Coder Social home page Coder Social logo

rollup-plugin-postcss's Introduction

rollup-plugin-postcss

NPM version NPM downloads Build Status codecov donate

Seamless integration between Rollup and PostCSS.

Install

yarn add postcss rollup-plugin-postcss --dev

Usage

v2.0 support rollup v1 or above, but it prints deprecated warning from rollup v2.

Breaking change: v3.0 only support rollup v2, and the extract path based on bundle root the location of the generated file outside the bundle directory not allowed in rollup v2.

// rollup.config.js
import postcss from 'rollup-plugin-postcss'

export default {
  plugins: [
    postcss({
      plugins: []
    })
  ]
}

Then you can use CSS files:

import './style.css'

Note that the generated CSS will be injected to <head> by default, and the CSS string is also available as default export unless extract: true:

// Inject to `<head>` and also available as `style`
import style from './style.css'

It will also automatically use local PostCSS config files.

Extract CSS

// for v2
postcss({
  extract: true,
  // Or with custom file name, it will generate file relative to bundle.js in v3
  extract: 'dist/my-custom-file-name.css'
})

// for v3
import path from 'path'
postcss({
  extract: true,
  // Or with custom file name
  extract: path.resolve('dist/my-custom-file-name.css')
})

CSS modules

postcss({
  modules: true,
  // Or with custom options for `postcss-modules`
  modules: {}
})

With Sass/Stylus/Less

Install corresponding dependency:

  • For Sass install node-sass: yarn add node-sass --dev
  • For Stylus Install stylus: yarn add stylus --dev
  • For Less Install less: yarn add less --dev

That's it, you can now import .styl .scss .sass .less files in your library.

imports

For Sass/Scss Only.

Similar to how webpack's sass-loader works, you can prepend the path with ~ to tell this plugin to resolve in node_modules:

@import "~bootstrap/dist/css/bootstrap";

Options

extensions

Type: string[]
Default: ['.css', '.sss', '.pcss']

This plugin will process files ending with these extensions and the extensions supported by custom loaders.

plugins

Type: Array

PostCSS Plugins.

inject

Type: boolean object function(cssVariableName, fileId): string

Default: true

Inject CSS into <head>, it's always false when extract: true.

You can also use it as options for style-inject.

It can also be a function , returning a string which is js code.

extract

Type: boolean string
Default: false

Extract CSS to the same location where JS file is generated but with .css extension.

You can also set it to an absolute path.

modules

Type: boolean object
Default: false

Enable CSS modules or set options for postcss-modules.

autoModules

Type: boolean
Default: true

Automatically enable CSS modules for .module.css .module.sss .module.scss .module.sass .module.styl .module.stylus .module.less files.

namedExports

Type: boolean function
Default: false

Use named exports alongside default export.

You can supply a function to control how exported named is generated:

namedExports(name) {
  // Maybe you simply want to convert dash to underscore
  return name.replace(/-/g, '_')
}

If you set it to true, the following will happen when importing specific classNames:

  • dashed class names will be transformed by replacing all the dashes to $ sign wrapped underlines, eg. -- => $__$
  • js protected names used as your style class names, will be transformed by wrapping the names between $ signs, eg. switch => $switch$

All transformed names will be logged in your terminal like:

Exported "new" as "$new$" in test/fixtures/named-exports/style.css

The original will not be removed, it's still available on default export:

import style, { class$_$name, class$__$name, $switch$ } from './style.css'
console.log(style['class-name'] === class$_$name) // true
console.log(style['class--name'] === class$__$name) // true
console.log(style['switch'] === $switch$) // true

minimize

Type: boolean object
Default: false

Minimize CSS, boolean or options for cssnano.

sourceMap

Type: boolean "inline"

Enable sourceMap.

parser

Type: string function

PostCSS parser, like sugarss.

stringifier

Type: string function

PostCSS Stringifier.

syntax

Type: string function

PostCSS Syntax.

exec

Type: boolean

Enable PostCSS Parser support in CSS-in-JS.

config

Type: boolean object
Default: true

Load PostCSS config file.

config.path

Type: string

The path to config file, so that we can skip searching.

config.ctx

Type: object

ctx argument for PostCSS config file.

Note: Every key you pass to config.ctx will be available under options inside the postcss config.

// rollup.config.js
postcss({
  config: {
    ctx: {
      foo: 'bar'
    }
  }
})

// postcss.config.js
module.exports = context => {
  console.log(context.options.foo) // 'bar'

  return {}
}

to

Type: string

Destination CSS filename hint that could be used by PostCSS plugins, for example, to properly resolve path, rebase and copy assets.

use

Type: name[] [name, options][] { sass: options, stylus: options, less: options }

Default: ['sass', 'stylus', 'less']

Use a loader, currently built-in loaders are:

  • sass (Support .scss and .sass)
  • stylus (Support .styl and .stylus)
  • less (Support .less)

They are executed from right to left.

If you pass the object, then its property sass, stylus and less will be pass in the corresponding loader.

loaders

Type: Loader[]

An array of custom loaders, check out our sass-loader as example.

interface Loader {
  name: string,
  test: RegExp,
  process: (this: Context, input: Payload) => Promise<Payload> | Payload
}

interface Context {
  /** Loader options */
  options: any
  /** Sourcemap */
  sourceMap: any
  /** Resource path */
  id: string
  /** Files to watch */
  dependencies: Set<string>
  /** Emit a waring */
  warn: PluginContext.warn
  /** https://rollupjs.org/guide/en#plugin-context */
  plugin: PluginContext
}

interface Payload {
  /** File content */
  code: string
  /** Sourcemap */
  map?: string | SourceMap
}

onImport

Type: id => void

A function to be invoked when an import for CSS file is detected.

License

MIT Β© EGOIST

rollup-plugin-postcss's People

Contributors

alexboffey avatar benjaminparnell avatar benmccann avatar coxmi avatar dependabot[bot] avatar dforesman avatar dikaio avatar dnjstrom avatar egoist avatar flying-sheep avatar gerardrodes avatar himself65 avatar jessethomson avatar jkjustjoshing avatar jounqin avatar jsanchez034 avatar katywings avatar kendrickw avatar kytta avatar ludofischer avatar lukeed avatar m4rw3r avatar mosanger avatar nstepien avatar pascalduez avatar sasuke40 avatar shirotech avatar sormy avatar wardpeet avatar warlo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rollup-plugin-postcss's Issues

Improve logging of transformed names

Since I upgraded this plugin to 1.x, building my app now logs hundreds of lines like these:

Exported "nav-left" as "navLeft" in lib/css/nav-bar.css
Exported "nav-search-wrapper" as "navSearchWrapper" in lib/css/nav-bar.css
Exported "nav-user" as "navUser" in lib/css/nav-bar.css
Exported "spinner-container" as "spinnerContainer" in lib/css/common.css
Exported "error-container" as "errorContainer" in lib/css/common.css
Exported "header-upload-container" as "headerUploadContainer" in lib/css/header.css
Exported "background-image" as "backgroundImage" in lib/css/header.css

... which is super useless.

The reason this happens is because I camelcase the exports using the namedExports option, to avoid the weird $__$ stuff that this plugin does by default. Here is my config:

postcss({
    modules : true,
    namedExports(name) {
        return camelcase(name);
    }
})

As discussed in #64 (comment), camelcasing should probably just be the default behavior. Presumably, at that point we would expect the plugin to only log if it encountered an export that would be a reserved word in JS.

In the meantime, while I'm waiting for a 2.x version to be released, I was thinking this plugin should skip these logs when namedExports is a function, as the user is fully controlling the name transformation, so shouldn't need to be told about it. I think it's okay to keep logging when it's true, as the default algorithm is unintuitive for now.

Alternatively, there could be an option to disable these logs, but that just increases the API surface unnecessarily IMO. And when 2.x comes, it would be even less necessary.

extract: true broken

when used via rollup.config.js, rollup now provides options.file instead of options.dest.

node_modules resolve not working with @import for SCSS

I'm running into this error msg when I'm trying to @import a .scss file from my node_modules folder via this method:

@import "react-input-range/src/scss/index.scss";

Results in this error:

[!] (postcss plugin) Error: File to import not found or unreadable: react-input-range/src/scss/index.scss.

However, if I include the entire relative path to the .scss, that'll work:

@import "../../../../../../node_modules/react-input-range/src/scss/index.scss";

and this works as well

@import "react-input-range/lib/css/index.css";

I need to import the .scss to override the SASS variables, so can't make use of of the .css file. I can't seem to figure out the cause and need some assistance with my issue, thanks!


So to reiterate:

Component.scss

// Works
@import "react-input-range/lib/css/index.css"; 
@import "../../../../../../node_modules/react-input-range/src/scss/index.scss";

// Does not work
@import "react-input-range/src/scss/index.scss";

rollup.config.js

import easyImport from "postcss-easy-import";
import postcssFlexbugsFixes from 'postcss-flexbugs-fixes';
import autoprefixer from "autoprefixer";

postcss({
    sourceMap: true,
    minimize: true,
    modules: true,
    namedExports: true,
    plugins: [
        easyImport,
        postcssFlexbugsFixes,
        autoprefixer({
            browsers: [
                '>1%',
                'last 4 versions',
                'Firefox ESR',
                'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
        }),
    ],
    extract: path.resolve("./dist/style.css"),
}),

Help upgrading to 1.x

Hi and thanks for this great Rollup plugin. It's been working well for me.

I am looking to upgrade from version 0.5.6 to 1.2.7 but am having difficulty figuring out what changes I need to make.

My use case is a React app with CSS modules. The existing setup is below:

const cssExportMap = {};

postcss({
    plugins : [
        cssModules({
            getJSON(id, exportTokens) {
                cssExportMap[id] = camelcaseKeys(exportTokens);
            },
            // Rc-slider needs some global CSS classes defined
            globalModulePaths : [/node_modules\/rc-slider\/assets\/index.css/]
        })
    ],
    getExportNamed : true,
    getExport(id) {
        return cssExportMap[id];
    }
})

The main goal of this special config is to enabled named imports with the more idiomatic convention of camelcase names, avoiding the -- to $__$ conversion that this plugin does by default.

/* sheet.css */
.foo-bar { background : blue }
import { fooBar } from './sheet.css';

... much better than ...

import { foo$__$bar } from './sheet.css';

This worked perfectly prior to 1.0.0. Now I see output like below.

lib/js/components/nav-bar/nav-bar.jsx
navSearchWrapper is not exported by lib/css/nav-bar.css
21:             React.createElement(
22:                 'div',
23:                 { className: style.navSearchWrapper },
                                       ^
24:                 React.createElement('input', { name: 'search', id: 'nav-search', placeholder: 'Search' }),
25:                 React.createElement(Icon, { svgInfo: searchIcon, width: '25', height: '25' })

Based on what I see in the README now, I tried using the modules option, as below.

postcss({
    modules : {
        getJSON(id, exportTokens) {
            cssExportMap[id] = camelcaseKeys(exportTokens);
        },
        // Rc-slider needs some global CSS classes defined
        globalModulePaths : [/node_modules\/rc-slider\/assets\/index.css/]
    },
    getExportNamed : true,
    getExport(id) {
        return cssExportMap[id];
    }
})

But there was no effect, the output remains the same. Based on some logging I tried, it seems that getExport() is no longer being called.

I'm happy to migrate to any other pattern that achieves the same end goal of importing classes as camelcased names. Any advice on how to upgrade would be much appreciated.

unnamed requires breaks bundled code

Sorry for undetailed issue, I'm still digging and learning about rollup and this es6 thing..

When using unnamed requires (i.e. pivotal-ui's typography) the plugin does not add expected(?) variable.

Example of some generated code, where __$styleInject does not add the variable name but the caller expects var typography to be available.

__$styleInject("@font-face{font-...", undefined);

var typography$1 = Object.freeze({
    default: typography
});

Adding a var typography = require('./typography.css'); fixes the issue.

Due to my lack of knowledge of rollup i'm not sure if require should automatically prepend the basename as a variable, it might cause some weird naming collisions...

Doing something like

const varname = path.basename(id, path.extname(id))
const code = `var ${varname} = ${injectFnName}(${JSON.stringify(result.css)},${JSON.stringify(getExport(result.opts.from))});\nexport default ${varname};`;

resolves the issue, but again i'm not sure if this is a problem with the library in question, this library or rollup....

Let me know what you think is the best option to resolve this!

scss not compiled

Hi, I'm having an issue with scss files which I read "just work" - am I missing something?

Error:

> rollup -c -w

[!] Error: Unexpected token
src/transformicons.scss (1:10)
1: $tcon-size: 4rem !default;
             ^
2:
3: $tcon-menu-radius: 0;

rollup.config.js:

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import postcss from 'rollup-plugin-postcss';
import autoprefixer from 'autoprefixer';
import handlebars from 'rollup-plugin-handlebars';
// import uglify from 'rollup-plugin-uglify';
import pkg from './package.json';

export default [
  {
    input: 'src/main.js',
    output: {
      name: 'AngularTransformicons',
      file: pkg.browser,
      format: 'umd',
    },
    plugins: [
      resolve(),
      commonjs(),
      postcss({
        exclude: 'none',
        plugins: [autoprefixer],
      }),
      handlebars({
        exclude: '.',
      }),
      babel(),
      // uglify(),
    ],
  },
  {
    input: 'src/main.js',
    external: ['angular'],
    output: [
      { file: pkg.main, format: 'cjs' },
      { file: pkg.module, format: 'es' },
    ],
  },
];

package.json:

{
  "name": "angular-transformicons",
  "version": "0.0.2",
  "description": "Angular directive to quickly include Transformicons in your templates",
  "repository": {
    "type": "git",
    "url": "https://github.com/homerjam/angular-transformicons"
  },
  "main": "dist/angular-transformicons.cjs.js",
  "module": "dist/angular-transformicons.esm.js",
  "browser": "dist/angular-transformicons.umd.js",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  },
  "author": "homerjam <[email protected]>",
  "license": "MIT",
  "dependencies": {
    "angular": "^1.6.9"
  },
  "devDependencies": {
    "autoprefixer": "^7.2.5",
    "babel-core": "^6.26.0",
    "babel-preset-env": "^1.6.1",
    "eslint": "^4.17.0",
    "eslint-config-airbnb-base": "^12.1.0",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-react": "^7.6.1",
    "node-sass": "^4.7.2",
    "rollup": "^0.55.3",
    "rollup-plugin-babel": "^3.0.3",
    "rollup-plugin-commonjs": "^8.3.0",
    "rollup-plugin-handlebars": "^1.0.0",
    "rollup-plugin-node-resolve": "^3.0.2",
    "rollup-plugin-postcss": "^1.2.8",
    "rollup-plugin-uglify": "^3.0.0",
    "transformicons": "github:transformicons/transformicons"
  }
}

main.js:

import angular from 'angular';
import addrmPlusCheck from 'transformicons/site/templates/includes/tcons/addrm-plus-check.hbs';
import './transformicons.scss';
...

Any help appreciated!

Thanks

Plugins run twice on css modules

Hi,

I'm still investigating the issue but wanted some feedback:

postcss({
  modules: true,
  extract: true,
  plugins: [
    require('postcss-custom-properties')({ preserve: true })
  ],
})

Result:

.Button_primary__1gH9y {
  color: green;
  color: green;
  color: var(--color-primary);
}

I did some logging and the postcss-custom-properties is run twice on the same css module, hence the duplicate fallback.

1st

.primary {
  color: var(--color-primary);
}

2nd

.Button_primary__1gH9y {
  color: green;
  color: var(--color-primary);
}

Use css modules and cssnext

Not sure what I'm doing wrong but using css modules and cssnext doesn't seem to work, here is my setup:

image

Any thoughts?

How to get CSS output?

// vendor.js
import 'material-design-lite/dist/material.indigo-pink.min.css';
import 'material-design-lite/material';

Cordova build problem...

sourcemap refence wrong with manual destination

When specifying a manual destination for the css output file, the reference to the sourcemap is wrong.

my rollup.js config:

export default {
  entry: 'src/main.js',
  dest: 'dist/main.js',
  format: 'iife',
  sourceMap: true,
  plugins: [
    ...
    postcss({
      sourceMap: true,
      extract : 'dist/bundle.css'
    }),
    ...
  ],
}

The file bundle.css.map is created, but bundle.css references to main.css.map:

/*# sourceMappingURL=main.css.map */

This is because of the following line of code (https://github.com/egoist/rollup-plugin-postcss/blob/master/src/index.js#L44):

          css += `\n/*# sourceMappingURL=${fileName}.css.map */`
          promises.push(fs.writeFile(`${cssOutputDest}.map`, map))

${fileName} is always taken from the automatic destination, while the ${cssOutputDest} is taken from manualDest when it is available.

Suggested fix:

          fileName = path.basename(cssOutputDest)
          css += `\n/*# sourceMappingURL=${fileName}.map */`
          promises.push(fs.writeFile(`${cssOutputDest}.map`, map))

Optional StyleInject β€” just the compiled CSS as an output

I'm trying to use this plugin to compile the styles of a Web Component.

These are the relevant bits of code in the JS entry point:

import styles from './styles.css';
// ...
template.innerHTML = `<style>${styles}</style> ${html}`;

As you can see, I just need the imported styles to be the compiled CSS string, but so far I haven't managed to get rid of the call to the __$styleInject function.

Is there a way to obtain, as an output, just the processed CSS string?

How to compile the css inject html

my rollup.confige.js is below

const path = require('path')
const json = require('rollup-plugin-json')

const commonjs = require('rollup-plugin-commonjs')
const resolve = require('rollup-plugin-node-resolve')
// babel
const babel = require('rollup-plugin-babel')
// env
const replace = require('rollup-plugin-replace')

const uglify = require('rollup-plugin-uglify')

// css
const sass = require('node-sass')
const postcss = require('rollup-plugin-postcss')
const cssnano = require('cssnano')
const autoprefixer = require('autoprefixer')

const sassPreprocessor = (content, id) => new Promise((resolve) => {
    const result = sass.renderSync({ file: id })
    resolve({ code: result.css.toString() })
})

export default {
    name: 'fox',
    input: path.resolve(__dirname, '../src/index.js'),
    output: {
        file: path.resolve(__dirname, '../dist/bundle.js'),
        format: 'umd'
    },
    plugins: [
        json(),

        postcss({
            extract: true,
            sourceMap: true,
            extensions: ['.scss'],
            preprocessor: sassPreprocessor, // Pre-process all imports with Sass
            plugins: [
                autoprefixer(), 
                // cssnano()
            ]
        }),
        resolve({
            jsnext: true,
            main: true,
            browser: true,
            extensions: ['.js', '.json']
        }),
        commonjs({

        }),
        babel({
            exclude: 'node_modules/**'
        }),
        replace({
            exclude: 'node_modules/**',
            ENV: JSON.stringify(process.env.NODE_ENV || 'development')
        }),
        (process.env.NODE_ENV === 'production' && uglify())
    ],
    sourcemap: true
}

If anyone knows, please tell me, please
thanks very much

An @import loop has been found

Hi there,

I just noticed a regression in v1.3.0 /w Rollup v0.56.3 on Node v8.9.4. Given a main.scss that imports other .scss files: when I run a rollup build I am getting the following message:

// main.scss
@import "./base";
[!] (postcss plugin) Error: An @import loop has been found:
    /src/styles/main.scss imports /src/styles/main.scss

Downgrading to v1.2.9 works perfectly.

"Use with CSS modules" and "Custom pre-processor" examples don't work together

Thank you for the hard work putting this plugin together. I've come across an issue trying to use the CSS Modules and CSS preprocessor example code together. I have a hack solution that is technically working for me, but I'd like to work out a better solution if possible.

Here is my rollup.config.js before I implemented my hack solution.

import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import postcss from 'rollup-plugin-postcss';
import postcssModules from 'postcss-modules';
import autoprefixer from 'autoprefixer';
import sass from 'node-sass';

const preprocessor = (content, id) => new Promise((resolve, reject) => {
    const result = sass.renderSync({ file: id });
    resolve({ code: result.css.toString() });
});

const cssExportMap = {};

export default {
    entry: 'src/components.js',
    format: 'cjs',
    external: ['react'],
    plugins: [
        // enables us to resolve packages located in node_modules
        resolve(),
        // converts CommonJS modules into a format Rollup understands
        commonjs({ sourceMap: false }),
        // compile CSS Modules
        postcss({
            preprocessor,
            plugins: [
                autoprefixer({ browsers: 'last 2 versions' }),
                postcssModules({
                    getJSON(id, exportTokens) {
                        cssExportMap[id] = exportTokens;
                    }
                })
            ],
            getExport(id) {
                return cssExportMap[id];
            },
            extensions: ['.scss'],
            extract: true
        }),
        // transform ES6 code
        babel({
            exclude: 'node_modules/**',
            presets: [
                'react',
                ['es2015', { modules: false }]
            ],
            plugins: ['external-helpers']
        })
    ],
    dest: 'dist/bundle.js'
};

I'm building a React UI kit library and I want to use CSS Modules to scope my styles to the components, but I also want to use SCSS in these component style sheets for mixins, variables, etc.

This appeared to be working at first. The SCSS files would be processed into normal CSS and then the classes would get correctly hashed. The issues occurred once I started using the composes feature of CSS Modules. I have a SCSS file that looks like this:

@import '../styles/mixins';

.container {
    composes: container from '../styles/composables/binary-input.scss';
}

.faux-input {
    composes: faux-input from '../styles/composables/binary-input.scss';
    @include default-border-radius();

    &:after {
        @include default-border-radius();
    }
}

.real-input {
    composes: real-input from '../styles/composables/binary-input.scss';
}

.label {
    composes: label from '../styles/composables/binary-input.scss';
}

Then I have another SCSS file that looks very similar (composing the same classes from the same binary-input.scss file).

In the Webpack build I have these SCSS files that are included via a composes from statement get preprocessed like any other SCSS file. Then the CSS that ultimately is outputted will include just one hashed container class from the binary-input.scss file that is included in the className that is generated for the child style sheets that use the binary-inputs.scss styles via composes. In my Rollup builds, however, the files included via the composes statement do not get preprocessed. So they end up producing a CssSyntaxError error.

The hack solution I've put together expands on the preprocessor function in my rollup.config.js. What I do is actually inspect the processed CSS and look for composes from statements. Then I take the filename it composes from, run it through the sass processor, output the CSS in a temp dir, and then finally replace the composes statement to point to that temp file. This mostly works. All the components do look correctly styled, but the extracted CSS file has the hashed binary-inputs.scss classes in it twice. I then use CSS Purge to eliminate the duplicated class.

Here is the hack version of the preprocessor function:

const processedMap = {};

const preprocessor = (content, filePath) => new Promise((resolve, reject) => {
    const regex = /composes(.)*('(.)*\.scss')/g;
    let finalCss = sass.renderSync({ file: filePath }).css.toString();
    let m;
    while ((m = regex.exec(finalCss)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        // m[2] will be something like
        // "'../styles/composables/binary-input.scss'" if it exist
        if (m[2]) {
            // remove the ' at the beginning and end of the match leaving just
            // the file path
            const composableRelativePath = m[2].replace(/'/g, '');
            let composableFileName = composableRelativePath.split('/').pop();
            let tempPath = processedMap[composableFileName];
            if (!tempPath) {
                let fullPathToMainScssFileDir = filePath;
                fullPathToMainScssFileDir = fullPathToMainScssFileDir.split('/');
                fullPathToMainScssFileDir.pop();
                fullPathToMainScssFileDir = fullPathToMainScssFileDir.join('/');
                const fullPathToComposable = fullPathToMainScssFileDir + '/' + composableRelativePath;
                const composableCSS = sass.renderSync({ file: fullPathToComposable }).css.toString();
                tempPath = fullPathToComposable.split('/');
                let tempFile = tempPath.pop();
                tempPath = __dirname + '/temp/' + tempFile.replace('.scss', '.css');
                fs.writeFileSync(tempPath, composableCSS);
                processedMap[composableFileName] = tempPath;
            } else {
                console.log('skipping since we\'ve already processed it...', composableFileName)
            }
            finalCss = finalCss.replace(
                new RegExp(
                    composableRelativePath.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),
                    'g'
                ),
                tempPath
            );
        }
    }
    resolve({ code: finalCss });
});

Hopefully the issue is clear from my description. I'd like to find a better solution. Please let me know if you have any ideas or if anything is unclear. Thanks

Add syntaxes/parsers

There is a limitation for not allowing the parser or syntax options?
Or there is a way I'm not seeing... I've tried:

postcss({
  plugins: [],
  options: {
    parser: sugarss
  }
})

and:

postcss({
  plugins: [],
  parser: sugarss
})

And either works.

What's the correct way to specify output file path

After the 1.0.0 update, I'm unclear about how the extract options works. Before 1.0.0, extract could take a string as a file path. Now, it only takes a boolean, and the output is always in the same directory as the javascript.

What's the correct way to specify a different file name/path, or different output directory?

Breaks Sourcemaps?

Hi - am I correct in assuming this plugin breaks sourceMaps? It's doing a string transformation on the CSS file. When I add this to my rollup plugin stack I get the following error:

Cannot read property 'split' of undefined
TypeError: Cannot read property 'split' of undefined
    at decode (~proj/node_modules/rollup/www/ROLLUP/rollup/node_modules/sourcemap-codec/dist/sourcemap-codec.es6.js:100:22)
    at ~proj/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:32:11
    at Array.map (native)
    at ~proj/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:30:32
    at Array.map (native)
    at collapseSourcemaps (~proj/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:29:25)
    at Bundle.render (~proj/node_modules/rollup/www/ROLLUP/rollup/src/Bundle.js:256:42)
    at Object.write (~proj/node_modules/rollup/www/ROLLUP/rollup/src/rollup.js:64:32)
    at ~proj/node_modules/rollup/bin/runRollup.js:116:18
    at tryCatch (~proj/node_modules/rollup/www/ROLLUP/rollup/node_modules/es6-promise/lib/es6-promise/-internal.js:182:12)

This is the offending rollup.config.js:

import babel from 'rollup-plugin-babel';
import npm from 'rollup-plugin-npm';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';

export default {
    entry: 'src/index.js',
    dest: 'bundle.js',
    sourceMap: true,
    format: 'umd',
    plugins: [
        babel({ exclude: 'node_modules/**' }),
        npm({ jsnext: true, main: true }),
        commonjs(),
        postcss()
    ]
};

... note that reordering the plugins doesn't seem to help.

0.5.5 is not published

I see, that 0.5.5 was released 6 days ago, but it's not yet been published. I've tried adding it to my repo through "github:egoist/rollup-plugin-postcss#0.5.5", but it is missing some files, so I assume, that publishing requires some additional building.

Can you please publish it?

Empty classes get stripped out

I have a CSS like the following:

.Foo {
}
.Foo__bar {
  color: red;
}

When I import this with postcss-modules I only get:

{ Foo__bar: 'Foo__bar_xxxx' }

The empty Foo is lost.

Autoprefixer as a plugin stopped working with the new version of rollup-plugin-postcss

Hello,

I don't know if it's the recent update, or me changing something accidentally that has caused this error, but autoprefxer now does nothing when it used to work!

If i set minimize: true if minifies OK. Has something broken in the new version, or changed with the API?

I took the last lines of CSS in the source file from https://autoprefixer.github.io/ , it should add prefixes at any default setting.

Here are some details of my settings, thanks for your help!:

** EDIT I just saw that there were breaking API changes using the node-update utility, but the new 1.0+ docs on the front page don't really explain how to use any other plugins and gives no examples like the old front page used to. I still have no idea how to make autoprefixer work, maybe I am stupid? :)

EDIT 2 - Just saw your Twitter, THANKS for this amazing application and your continued support! I really love it, I spent the day looking into switching to webpack, and it was dependency hell. I hate how bloated JS development has become, every extra package in the tool-chain is another point of failure, I am not about to install 5,000 NPM packages by 100 different people just to print my name on the screen in JS :) I am spending more time with tooling than programming, I am hoping this will all end with my 'final' Rollup set-up.

**package.json**

"devDependencies": {
    "autoprefixer": "^7.2.4",
    "rollup": "^0.53.4",
    "rollup-plugin-postcss": "^1.0.2"
  }
**rollup.config.js**

import postcss from 'rollup-plugin-postcss';
import autoprefixer from 'autoprefixer';

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'iife',
    banner: '/* http://www.elsewebdevelopment.com/ */',
  },
  plugins: [
    postcss({
      plugins: [
        autoprefixer(),
      ],
      sourceMap: true,
      extract: true,
      extensions: ['.css'],
      // minimize: true,
    }),
  ],
  sourcemap: true,
};
**The source file**

* {
    box-sizing: border-box;
}

#canvas {
    outline: black 2px solid;
}

.example {
    display: flex;
    transition: all .5s;
    user-select: none;
    background: linear-gradient(to bottom, white, black);
}
**the destination file**

* {
    box-sizing: border-box;
}

#canvas {
    outline: black 2px solid;
}

.example {
    display: flex;
    transition: all .5s;
    user-select: none;
    background: linear-gradient(to bottom, white, black);
}

/*# sourceMappingURL=bundle.css.map */

Multiple imports creates duplicates.

This issue is specifically tied to the postcss-modules plugin but I am not sure if the issue is located here. Let me know if otherwise.

Given the following js file:

import './style1.css'
import './style2.css'

With the following css files:

style1.css

.style1 {
  composes: style2 from "./style2.css";
  color: gold;
}

style2.css

.style2 {
  background: green;
}

style2.css gets duplicated since it is composed and imported (seems to be treated separately).

Can you think of a way around this?

File not found when import .less file in a .less file required by .tsx file

Problem:
I have a .tsx file which imports a .less style file. In this .less file, I @import 'another/file/like/variable.less', but I only get File not found error when I compile with rollup.

rollup.config.js

import resolve from 'rollup-plugin-node-resolve';
import postcss from 'rollup-plugin-postcss';
import typescript from 'rollup-plugin-typescript2';
import filesize from 'rollup-plugin-filesize';
import progress from 'rollup-plugin-progress';
import cleaner from 'rollup-plugin-cleaner';
import commonjs from 'rollup-plugin-commonjs';
import path from 'path';
// import fs from 'fs';

const config = {
  input: './src/index.ts',
  output: {
    file: './lib/index.js',
    format: 'es',
    banner: '/* eslint-disable */',
  },
  plugins: [
    // rollup-plugin-cleaner
    cleaner({
      targets: ['./lib'],
    }),
    // rollup-plugin-postcss
    postcss({
      inject: false,
      extract: true,
      minimize: false,
      modules: true,
      to: 'lib/index.css',
      plugins: [
        require('autoprefixer')(),
      ],
    }),
    // rollup-plugin-node-resolve
    resolve(),
    // rollup-plugin-typescript2
    typescript(),
    // rollup-plugin-filesize
    filesize(),
    // rollup-plugin-progress
    progress(),
    // rollup-plugin-commonjs
    commonjs(),
  ],
  external: [
    'react',
    'react-dom',
  ],
};

export default config;

tsconfig.json

{
  "include": [
    "src",
  ],
  "exclude": [
    "node_modules"
  ],
  "compilerOptions": {
    "target": "es5",                          
    "module": "es2015",                    
    "lib": ["es2015", "es2015.core", "dom"],                            
    "jsx": "react",
    "declaration": true,                 
    "removeComments": true,      
    "strict": true,                           
    "moduleResolution": "node",           
    "typeRoots": ["./typings", "./node_module/@types"],                       
    "types": ["modules", "node"],                           
    "allowSyntheticDefaultImports": true
  }
}

file in ./typings

declare module "*.css" {
    const content: {
        [key: string]: string
    };
    export default content;
}

declare module "*.less" {
    const content: {
        [key: string]: string
    };
    export default content;
}

But when I run rollup -c, I get error:
😨

./src/index.ts β†’ ./lib/index.js...
(4): node_modules/tslib/tslib.es6.js[!] (postcss plugin) Error: '../../../styles/variables.less' wasn't found. Tried - ../../../styles/variables.less,../../../styles/variables.less
src/components/Common/Portal/style.less

In my index.ts, I import a ts file like:

import styles from './style.less';

console.log(styles);

In the './style.less' file:

@import "../../../styles/variables.less";

.test-less {
  background: @background;
}

Any help is appreciated! 😁
(And sorry for my bad English! πŸ˜…)

how to use with rollup-plugin-vue and export a single css file?

I updated from v. 0.5.6 to 1.0.1 (in this project: https://github.com/francoisromain/camomile-ui/blob/master/build/rollup.config.dist.js)

In this project there are two sources of css:

  • a main css file is imported in app.js with import './css/styles.css'
  • many components css in the vue files.

With the previous version of rollup-plugin-postcss, I had all the css extracted in a single dist/styles.css file (from vue templates and from the styles.css).

With version 1, /dist/styles.css only contains css from the vue templates. The css imported in the main js file is extracted in its own css file named after the exported js file (/dist/my-project.common.css), which is not what I want.

my rollup config with v0.5.6:

vue({
        compileTemplate: true,
        css: '../dist/styles.css'
      }),
      postcss({
        plugins: postcssPlugins,
        extract: '../dist/styles.css'
      }),

and now with v.1.0.1

      vue({
        compileTemplate: true,
        css: '../dist/styles.css'
      }),
      postcss({
        extract: '../dist/styles.css'
      }),

What is the config to export all the css in a single file?
Thank you

extract: true or extract: 'path/to/file' creates dublicated empty .CSS file

Hi all,

whenever I define a path or set extract: true two .CSS files are created.

  • One file always sits in the root path and has the actual content in it.
  • The second file is in the bundle.js target path (when extract:true) or in the defined path (extract: 'path') but empty.

a) Why two .CSS files are bundled?
b) Why is the actual .CSS file I want to have empty?

Here the project: https://github.com/zugende/Rollup_Vue_Postcss_Test
Here my rollup config:

import vue from 'rollup-plugin-vue';
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import buble from 'rollup-plugin-buble';
import postcss from 'rollup-plugin-postcss';
//import cssnano from 'cssnano';
//import postcssnedsted from 'postcss-nested';
import includepaths from 'rollup-plugin-includepaths';

const includepathoptions = {
    include: {
        'vue': 'node_modules/vue/dist/vue.common.js' 
    },
    external: ['vue']
}

const config = {
    input: 'src/index.js',
    plugins: [
        postcss({
            sourcemap: false,
            extract: 'stylesheets/bundle.css'
        }),
        vue(),
        buble(),
        resolve({
            jsnext: true,
            main: true,
            browser: true,
          }),
        commonjs(),
        includepaths({includepathoptions})
    ],
    output: {
        file: 'javascripts/bundle.js',
        format: 'iife',
        sourcemap: true
    }
}

export default config;

image

Not sure if I found a bug or still a newby when it comes to rollup and postcss. ;)
Any help is much appreciated!
Best
zugende

sourceMap sourceRoot information is missing

Ideal result

{
  "version": 3,
  "sources": [
    "src/routes/admin/admin.css"
  ],
  "names": [],
  "mappings": "AAAA;EACE,YAAY;EACZ,aAAa;CACd;;AAED;EACE,eAAe;CAChB",
  "file": "bundle.css",
  "sourcesContent": [
    ".main {\n  width: 100%;\n  height: 100%;\n}\n\n.sider {\n  overflow: auto;\n}\n"
  ]
}

actual results

{
  "version": 3,
  "sources": [
    "admin.css"
  ],
  "names": [],
  "mappings": "AAAA;EACE,YAAY;EACZ,aAAa;CACd;;AAED;EACE,eAAe;CAChB",
  "file": "bundle.css",
  "sourcesContent": [
    ".main {\n  width: 100%;\n  height: 100%;\n}\n\n.sider {\n  overflow: auto;\n}\n"
  ]
}

Incorrect postcssOpts.to passed to postcss plugins

While investigating an issue with path transforms, it seems I might have hit a bug in this plugin. I created a example to reproduce the issue with minimal settings here: https://github.com/osdevisnot/rollup-plugin-postcss-demo

In a nutshell, it seems we are passing incorrect to option to postcss plugins which causes issues with path transformation for postcss-copy-assets

Let me know if I should add more information to this bug report, but the README here summarizes issue correctly:

getExport will cause error with '--' in css

When my css is written like this

.button--primary {
  composes: base;
  composes: primary;
}
.button--secondary {
  composes: base;
  composes: secondary;
}
.button--dashed {
  composes: base;
  composes: dashed;
}

The transformed code will cause error

export const button-Primary="_3hh9tei XY-M_dO _19BpMwo";
export const button-Secondary="vXJ9qrz XY-M_dO _3S37_fc";
export const button-Dashed="BNj9gmv XY-M_dO _35mc8WS";

Add ~ alias for scss imports from node_modules

Currently when you import a file via sass/scss you have to run

<style lang="scss" scoped> @import 'node_modules/path/to/*.scss'; </style>

In other bundlers (e.g. Poi with webpack) you have the alias ~ for node_modules. Would be nice to have this alias to this repo too for consistency when building with different environments (Poi/Webpack + Bili/Rollup).

npm install vs yarn install

$ npm i
[15:03:01] Starting 'copy'...
[15:03:01] Starting 'index'...
[15:03:01] Starting 'app'...
[15:03:01] Starting 'vendor'...
[15:03:01] Starting 'polyfills'...
[15:03:02] Finished 'index' after 534 ms
[15:03:04] Finished 'copy' after 3.11 s
[15:03:28] Finished 'vendor' after 26 s
[15:03:28] Finished 'polyfills' after 26 s
[15:03:29] Finished 'app' after 28 s
[15:03:29] Starting 'build'...
[15:03:29] Finished 'build' after 54 ΞΌs

via yarn

$ yarn
[05:48:50] Starting 'copy'...
[05:48:50] Starting 'index'...
[05:48:50] Starting 'app'...
[05:48:50] Starting 'vendor'...
[05:48:50] Starting 'polyfills'...
[05:48:50] Finished 'index' after 301 ms
[05:48:50] Finished 'copy' after 465 ms
[05:49:07] Finished 'vendor' after 17 s
[05:49:10] Finished 'polyfills' after 21 s
src/components/file-upload/file-upload.css
undefined [undefined]
[05:49:12] Finished 'app' after 22 s
[05:49:12] Starting 'build'...
[05:49:12] Finished 'build' after 58 ΞΌs

A message appears

src/components/file-upload/file-upload.css
undefined [undefined]

Update style-inject

I have removed returnValue in style-inject v0.2.0, it should be handled here instead. eg:

code: `${codeExportSparse}export default ${injectFnName}(${JSON.stringify(
result.css
)},${JSON.stringify(codeExportDefault)});`,

we should not export the return value of styleInject() but the actual codeExportDefault directly.

Add SugarCSS loader or how to append it?

Heya @egoist! πŸŽ‰

This rollup plugin seems amazing! So much things.. :D I can't believe.
So, i like that it support SASS/SCSS, LESS, Stylus, but i'm wondering how to add SugarCSS to be used on .sss and/or .css?

[Question] Process and extract CSS but leave an `import` statement

Suppose I have the following source files:

// src/Add.js 
import React from 'react';
import styles from './Add.css';
export const Add = () => <span className={styles.Add}>+</span>

And a corresponding css file (that needs to be post-processed with postcss with cssnext):

// src/Add.css
.Add {
  color: red;

  &:hover {
    color: blue;
  }
}

My current rollup config looks like:

{
//...
  plugins: [
    postcss({
      sourceMap: true,
      extract: true,
      plugins: [
        cssImport(),
        cssNext(),
        postcssModules({
          getJSON(id, exportTokens) {
            cssExportMap[id] = exportTokens;
          }
        })
      ],
      getExport(id) {
        return cssExportMap[id];
      },
      getExportNamed: false,
      extensions: [".css"]
    }),
    babel({
      babelrc: false,
      presets: [require.resolve("babel-preset-react-app")]
    })
  ]
}

Which, when ran, creates two dist files, this js file:

// dist/Add.js
import React from 'react';

var styles = { "Add": "_Add_1kcg1_1" };

var Add = function Add() {
  return React.createElement(
    'span',
    { className: styles.Add },
    '+'
  );
};

export { Add };

and this css file:

// dist/Add.css
._Add_1kcg1_1 {
  color: red
}
._Add_1kcg1_1:hover {
  color: blue;
}

This is almost exactly what I want, but in an effort to make this Add component easier for apps to consume (like create-react-apps without ejecting), I'd like for the dist/Add.js to reference the processed dist/Add.css file, eg:

// desired dist/Add.js
import React from 'react';
import './Add.css'; // <-- this is what I want added

var styles = { "Add": "_Add_1kcg1_1" };

var Add = function Add() {
  return React.createElement(
    'span',
    { className: styles.Add },
    '+'
  );
};

export { Add };

Otherwise, apps consuming this Add component would need to import both the js and css file, which I'm trying to avoid.

So 3 questions:

  1. Am I making sense? 😬
  2. Is this possible?
  3. If so, how?

Consider adding postcss-modules integration

Now CSS-files returns nothing on export. But it would be good to export class names map like Webpack does with css-modules enabled.

There is a postcss-modules plugin that gives CSS-modules feature support for postcss. It emits JSON with class names mapping and it can be used as actual export. So, the generated output will look like:

__$styleInject('.a {color:red;}.b {color:blue;}');

export default {
    'a': '_a_16zx1_1',
    'b': '_b_16zx1_2'
};

What do you think about it? If you interested in this feature, I can contribute and send a pull-request.

invalid z-index after postcss with `minimize` option

preprocessor sourcemap

I have configured the plugin like this:

import sass from 'node-sass'
import autoprefixer from 'autoprefixer'
import postcss from 'rollup-plugin-postcss'

export default {
  entry: 'src/app.js',
  dest: 'dist/bundle.js',
  format: 'iife',
  sourceMap: true,
  plugins: [
    postcss({
      preprocessor: (content, id) => new Promise((resolve, reject) => {
        const result = sass.renderSync({ 
          file: id, 
          sourceMap: true, 
          outFile: './dummy.css' // must be set or sourcemap wont be generated
        })
        let code = result.css.toString()
        let map = result.map.toString() // => CONTAINS AN EXTENDED SOURCEMAP
        resolve({ code, map })
      }),
      plugins: [
        autoprefixer
      ],
      sourceMap: true, // => RESULTS IN SOURCEMAP ONLY REFERENCING ENTRYPOINT
      extract: true,
      extensions: ['.sass','.css']
    })
  ]
}

While node-sass is correctly generating a source map that references all the individual imports, the resulting postcss sourcemap only contains a reference to the entrypoint. Is this the normal behaviour?

error on styleinject

Hi all,

I am new to rollup and postcss

I am getting this error even after rollup-plugin-node-resolve


(!) Unresolved dependencies
https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
olluplearn-rollup
ode_modulesstyle-injectdiststyle-inject.es.js (imported by src\styles\main.css)
(!) Missing global variable name
Use output.globals to specify browser global variable names corresponding to external modules
C:\Users\Charlie\AppData\Roaming\npm\node_modules\rollup\dist\rollup.js (guessing 'styleInject')
created build/js/main.min.js in 936ms

This is my rollup.conig.js

import babel from "rollup-plugin-babel";
import eslint from "rollup-plugin-eslint";
import commonjs from "rollup-plugin-commonjs";
import resolve from "rollup-plugin-node-resolve";
import replace from "rollup-plugin-replace";
import uglify from "rollup-plugin-uglify";
import postcss from "rollup-plugin-postcss";
import simplevars from "postcss-simple-vars";
import nested from "postcss-nested";
import cssnext from "postcss-cssnext";
import cssnano from "cssnano";

export default {
  input: "src/scripts/main.js",
  output: {
    file: "build/js/main.min.js",
    format: "iife",
    sourcemap: process.env.NODE_ENV !== "production" ? false : "inline-map"
  },
  plugins: [
    eslint({ exclude: "src/styles/**" }),
    resolve({ jsnext: true, main: true, browser: true }),
    commonjs(),
    postcss({
      plugins: [
        simplevars(),
        nested(),
        cssnext({ warnForDuplicates: false }),
        cssnano()
      ],
      extensions: [".css"]
    }),
    replace({
      exclude: "node_modules/**",
      ENV: JSON.stringify(process.env.NODE_ENV || "development")
    }),
    babel({ exclude: "node_modules/**" }),
    process.env.NODE_ENV === "production" && uglify()
  ]
};

I am learning using this tutorial (may be outdated)

How to get one style tag?

Currently if o use component way to define styles, i have one <style> per component, which is not very good. Is any way now to combine them all? If no, would you be ok if i create PR?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.