Git Product home page Git Product logo

rules_postcss's People

Contributors

davidmorgan avatar dependabot[bot] avatar dgp1130 avatar fenghaolw avatar jathak avatar nex3 avatar philwo avatar rzhw avatar tjgq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rules_postcss's Issues

Publish build rules via npm

Similar to the TypeScript rules for Bazel, these build rules could be made available via npm.

Installing these build rules via npm avoids a Bazel workspace depending on these build rules having a package.json for rules_nodejs also depending on postcss, then having that version being hoisted up and interfering with the version used by these build rules.

Formatting pre-commit hook

We can consider adding a pre-commit hook to either manually require, or automatically apply formatting.

For example, bazelbuild/rules_nodejs does the former, causing commits to fail if files aren't formatted, and telling the author to run yarn format.

autoprefixer pointing to internal rule label

I'm getting the error below when trying to use autoprefixer. I assume it's because the line here https://github.com/bazelbuild/rules_postcss/blob/master/internal/autoprefixer/build_defs.bzl#L41 doesn't include the workspace name.

 no such package 'internal/autoprefixer': BUILD file not found in any of the following directories. Add a BUILD file to a directory to mark it as a package.

Defining a local binary works:

postcss_binary(
    name = "autoprefixer",
    src = ":raw_styles",
    output_name = "styles.css",
    plugins = {
        "@build_bazel_rules_postcss//internal/autoprefixer": "",
    },
)

Update rules_nodejs to 5.0.0

Per #73 (comment), these rules are incompatible with rules_nodejs 4.0.0 due to the @bazel/worker dep being outdated.

One option is to update to the last 3.x release of @bazel/worker as suggested in #73 (comment) as that relaxes the rules_nodejs version constraint.

However, absent of a strong reason to avoid doing so, upgrading rules_nodejs, and consequentially @bazel/worker, to the latest version, 4.0.0 should be the approach taken.

CSS Import statements are failing.

Hi, I'm using this for something that we develop on the long run also helps me learn bazel.
My Current build file:

load("@build_bazel_rules_postcss//:defs.bzl", "postcss_binary", "postcss_plugin")
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web")

package(default_visibility = ["//:__subpackages__"])

filegroup(
    name = "css",
    srcs = glob(["*.css"]),
)

postcss_plugin(
    name = "tailwindcss",
    node_require = "tailwindcss",
)

postcss_plugin(
    name = "postcss-preset-env",
    node_require = "postcss-preset-env",
)

postcss_plugin(
    name = "postcss-import",
    node_require = "postcss-import",
)

postcss_binary(
    name = "style_processed",
    src = "index.css",
    output_name = "style.css",
    plugins = {
        ":postcss-preset-env": "",
        ":tailwindcss": "",
    },
    deps = [
        ":css",
        "@npm//postcss-preset-env",
        "@npm//tailwindcss",
    ],
)

pkg_web(
    name = "web_package",
    srcs = [
        "package.json",
        ":style_processed",
    ],
)

I have a folder contains bunch of css files with an index.css

 /* @import "tailwindcss/base"; */
@import "./base.css";
/* @import "./layout.css";*/
 @import "tailwindcss/components"; 
 @import "tailwindcss/utilities"; 
/* @import "./utilities.css";*/

Since I using this repo with local_repository I'm also debuging the issue.

Add an option to disable source map generation

Some users want to disable source map generation, either to speed up the build or to limit generated file clutter. Right now though postcss_binary will always generate a source map. It would be good to add an optional sourcemap arg that can disable this.

Investigate workers

In larger projects, postcss_binary and/or postcss_multi_binary may see repeated numbers of calls in a single build invocation.

Currently, the PostCSS build rules generate new source files and new corresponding nodejs_binary targets in order to run PostCSS with a configuration.

We should investigate whether using workers can reduce the impact of this.

Avoid double-specifying plugins

If #17 is resolved, we'll start writing this:

Currently plugins are double-specified with their defs:

postcss_plugin(
    name = "list_selectors",
    node_require = "build_bazel_rules_postcss/examples/additional_outputs/list-selectors.js",
    srcs = [
        "list-selectors.js",
    ],
)

postcss_binary(
    name = "style_processed",
    src = "style.css",
    plugins = {
        ":list_selectors": "[{markdownDir: 'examples/additional_outputs'}]",
    },
    additional_outputs = ["selectors.md"],
    deps = [
        ":list_selectors",
    ],
)

We could do one better by not needing to specify :list_selectors in the deps attribute:

postcss_plugin(
    name = "list_selectors",
    node_require = "build_bazel_rules_postcss/examples/additional_outputs/list-selectors.js",
    srcs = [
        "list-selectors.js",
    ],
)

postcss_binary(
    name = "style_processed",
    src = "style.css",
    plugins = {
        ":list_selectors": "[{markdownDir: 'examples/additional_outputs'}]",
    },
    additional_outputs = ["selectors.md"],
)

This would likewise apply for things we get from npm:

postcss_plugin(
    name = "autoprefixer",
    node_require = "autoprefixer",
)

postcss_plugin(
    name = "unquote",
    node_require = "build_bazel_rules_postcss/examples/custom_plugin/unquote.js",
    srcs = [
        "unquote.js",
    ],
)

sass_binary(
    name = "style",
    src = "style.scss",
    output_style = "expanded",
)

postcss_binary(
    name = "style_processed",
    src = ":style",
    plugins = {
        ":autoprefixer": "[{ browsers: '%s' }]" % AUTO_PREFIXER_BROWSERS,
        ":unquote": "",
    },
    deps = [
        ":unquote",
        "@npm//autoprefixer",
    ],
)

Would become something like this:

postcss_plugin(
    name = "autoprefixer",
    node_require = "autoprefixer",
    deps = [
        "@npm//autoprefixer",
    ],
)

postcss_plugin(
    name = "unquote",
    node_require = "build_bazel_rules_postcss/examples/custom_plugin/unquote.js",
    srcs = [
        "unquote.js",
    ],
)

sass_binary(
    name = "style",
    src = "style.scss",
    output_style = "expanded",
)

postcss_binary(
    name = "style_processed",
    src = ":style",
    plugins = {
        ":autoprefixer": "[{ browsers: '%s' }]" % AUTO_PREFIXER_BROWSERS,
        ":unquote": "",
    },
)

Move responsibility for defining Node.js require into postcss_plugin

Currently, postcss_binary is where plugin deps and the Node.js require string for each plugin is meant to be written. Take the following example:

postcss_plugin(
    name = "list_selectors",
    srcs = [
        "list-selectors.js",
    ],
)

postcss_binary(
    name = "style_processed",
    src = "style.css",
    plugins = {
        "build_bazel_rules_postcss/examples/additional_outputs/list-selectors.js": "[{markdownDir: 'examples/additional_outputs'}]",
    },
    additional_outputs = ["selectors.md"],
    deps = [
        ":list_selectors",
    ],
)

If we wanted to reuse the :list_selectors plugin in another postcss_binary target, then we need to write out not only the ":list_selectors" dep, but also "build_bazel_rules_postcss/examples/additional_outputs/list-selectors.js" all over again.

This string is also pretty verbose.

Can we make it so we write out something like this instead?

postcss_plugin(
    name = "list_selectors",
    node_require = "build_bazel_rules_postcss/examples/additional_outputs/list-selectors.js",
    srcs = [
        "list-selectors.js",
    ],
)

postcss_binary(
    name = "style_processed",
    src = "style.css",
    plugins = {
        ":list_selectors": "[{markdownDir: 'examples/additional_outputs'}]",
    },
    additional_outputs = ["selectors.md"],
    deps = [
        ":list_selectors",
    ],
)

It'd be great if we could leave out deps too, but if we can't let's leave that out of scope for this issue.

Plugin output support

Some PostCSS plugins such as postcss-sprites have their own outputs (and/or inputs), in addition to what PostCSS itself would generate after such plugins are run.

The current build rules don't support this use case.

`postcss_multi_binary()` additional outputs

I noticed that postcss_multi_binary() does not seem to have an additional_outputs parameter like postcss_binary() does. This means the multi binary rule can't be used with a plugin that outputs additional files (such as postcss-modules, which is the motivating example).

Is this a deliberate omission due to some technical or philosophical reason, or is it just an oversight? I could probably put together a PR if we agree this is worth adding.

Support execution-time entry points in `postcss_multi_binary()`

In postcss_multi_binary(), srcs is defined as a label_list() which requires individual files to be listed. This means that in order to process a CSS file, it needs to be known at analysis-time, which is not always feasible. Sometimes the full list of CSS entry points in a build is not known until execution-time. dgp1130/rules_prerender#27 is one such example (I can elaborate more on the use case if that is helpful, but TL;DR: I can't know all the CSS entry points of a build until execution-time). Without knowing all the CSS entry points up front, postcss_multi_binary() is unusable for such use cases.

Ideally, it would be awesome if postcss_multi_binary() srcs would accept a directory of CSS files and process all of them, outputting another directory of processed files at the same relative paths. With this scheme, a tool could output any number of CSS files and reliably process all of them with postcss_multi_binary(). The Bazel side of this would be relatively straightforward, but I'm not familiar with the PostCSS binary or how hard it would be to make it process files in this manner.

I could probably make a PR with a more specific proposal, but this is a pretty specific use case, so I wanted to bring it up for discussion first. Are there any thoughts / concerns about support such a use case or any other constraints I might not be considering?

Release to be compatible with NodeJS 14+?

[email protected] uses NodeJS 14.17.5 by default. This is not compatible with @bazel/[email protected] as it will not generate source maps. Attempting to use postcss_binary(sourcemap = True) fails with:

(node:38) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE] [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of SourceMapGenerator
    at Object.writeFileSync (fs.js:1517:5)
    at /home/dparker/.cache/bazel/_bazel_dparker/3b4ba8c4eec5951318c36cb07368e75b/sandbox/linux-sandbox/1223/execroot/rules_prerender/bazel-out/host/bin/examples/styles/page_styles.postcss_runner.runner_src.js:213:16
(Use `node --trace-warnings ...` to show where the warning was created)
(node:38) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:38) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
ERROR: /home/dparker/Source/rules_prerender/examples/styles/BUILD.bazel:5:16: output 'examples/styles/page_styles_bundled.css.map' was not created
ERROR: /home/dparker/Source/rules_prerender/examples/styles/BUILD.bazel:5:16: Running PostCSS runner on <generated file examples/styles/page_page_styles.css> failed: not all outputs were created or valid

This appears to have been fixed a couple months ago in #69, which solved the problem in google3, but this doesn't appear to have been released to NPM. Considering that rules_nodejs@4 uses Node 14 by default, @bazel/postcss is not usable out of the box and requires an older Node version to run.

Workarounds include:

  • Remove sourcemap = True, which is a functionality regression.
  • Revert to an older version of NodeJS, v13 is already out of maintenance, but v12 is still in LTS, so I think 12.22.5 is the current latest supported version that works with @bazel/[email protected].
  • Use rules_postcss via a repository rule linked against 95fefe3 or later. This is highly discouraged and a lot of effort to work around a simple bug.
  • Locally patch @bazel/rules_postcss to include 95fefe3. Also a lot of effort for a simple bug.

Any chance we can get a release with this fix?

Integration tests

These should test that installing the rules and applying them works as expected.

Support postcss.config.js

postcss.config.js is a configuration format used by many PostCSS runners, such as postcss-loader for webpack and rollup-plugin-postcss, and is commonly referred to by PostCSS plugin docs such as Tailwind's.

This is currently low priority, however I've created this issue to gather interest for configuring via postcss.config.js instead of or in addition to the current postcss_binary#plugins approach.

An open design question is how this can work with Bazel's model, which requires all inputs and outputs to be specified ahead of time.

For example, would we need to replicate availability of the special bazel.binDir, bazel.additionalOutputs and bazel.data variables?

Requiring use of these bazel.* variables breaks portability assumptions, if the reason for supporting postcss.config.js is because it's a standardised approach that could be used with other PostCSS runners.

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.