JPeer264 / node-rcs-core

Rename css selectors across all files
MIT License
37 stars 7 forks source link

Plugin for postcss and webpack #12

Closed klimashkin closed 5 years ago

klimashkin commented 7 years ago

Hi, Thanks for great project!

I'm just thinking, since modern css pipeline in most cases is built around webpack/postcss, would be great to have corresponding plugins for rcs.

For instance, I'm using css-modules, that means in development I use postcss-, css- and styles- loaders for webpack rules stack. And for production build I additionally use extract-text-webpack-plugin to extract it into separate css bundle and then apply postcss css-mqpacker and csswring plugins on that result bundle. I wish there also was rcs plugin for postcss to include it into that last stage of production assembly process, so having source maps would be possible. In case of css-modules, rcs should have two plugins - for postcss to gather and replace class names in css bundle, and webpack plugin to replace mapped names in result js chunks.

JPeer264 commented 7 years ago

Yes thats a pretty big topic, also for me. There will be a webpeck plugin indeed in the future.

I guess postcss won't really work quite well, because I think that a plugin of one thing (js renaming) shouldn't depend on another (css renaming), so is it with postcss and webpack (because I never saw it in production). But the workflow with extract-text-webpack-plugin seems quite nice.

A short question (as you seem more experienced in webpack than me). If the webpack plugin exists, how would you possibly implement the plugin into the config? Because the css rewrites should happen before rewriting all the js/html stuff.

EDIT Also, where do you apply the postcss plugins?

klimashkin commented 7 years ago

where do you apply the postcss plugins?

Both, on webpack loader stage, what means individually for each css module which is imported by js module. And then on webpack plugin stage after extract-text-webpack-plugin when final css chunk is assembled.

Short example could be

modules: {
  rules: [
    {
      test: /\.css/,
      exclude: [/node_modules/],
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
          {
            loader: 'css-loader',
            options: {
              modules: true,
              importLoaders: 1,
              camelCase: 'dashesOnly',
              localIdentName: '[sha512:hash:base64]',
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: {
                'postcss-import': {},
                'postcss-nested': {},
                'postcss-css-variables': {},
                'postcss-color-function': {},
                'postcss-calc': {precision: 6},
                'autoprefixer': {cascade: false, flexbox: 'no-2009', grid: false},
             },
            },
          },
        ],
      }),
    }
  ],
},
plugins: [
    // Extract all individual css-modules into one separate css bundle
    new ExtractTextPlugin({
      filename: getPath => `../styles/${getPath(`[name].css`)}`,
      ignoreOrder: true,
      allChunks: true,
    }),

    // Apply css optimizations on that separate css bundle result
    new PostcssAssetsPlugin({
      test: /\.css$/,
      log: true,
      plugins: {
        'css-mqpacker': {},
        'csswring': {preservehacks: true, removeallcomments: true},
      },
    }),
],

PostcssAssetsPlugin runs on result big css file, and compress its in a whole instead of each separate css modules (it's more effective). On that plugin stage css and js files are already built, so you can modify them, for instance, using postcss plugin to gather and replace all class names and using separate webpack plugin replace them in built js.

It could be like

plugins: [
    // Extract all individual css-modules into one separate css bundle
    new ExtractTextPlugin({
      filename: getPath => `../styles/${getPath(`[name].css`)}`,
      ignoreOrder: true,
      allChunks: true,
    }),

    // Apply css optimizations on that separate css bundle result
    new PostcssAssetsPlugin({
      test: /\.css$/,
      log: true,
      plugins: {
        'rcs': {__some_options__},
        'css-mqpacker': {},
        'csswring': {preservehacks: true, removeallcomments: true},
      },
    }),

    new RCSPlugin({test: /\.js$/}, {__some_options__}})
],
JPeer264 commented 7 years ago

Wow that seems easier than I though it could be. Thanks for this hint. I will try to start soon to make those two plugins.

JPeer264 commented 7 years ago

@klimashkin the postcss plugin is ready: postcss-rcs. I'm heading now to the webpack plugin.

klimashkin commented 7 years ago

Tried postcss-rcs, it works! Looking forward to webpack plugin

klimashkin commented 7 years ago

Btw, babili-webpack-plugin is a good example how to save sourcemaps while transforming code https://github.com/webpack-contrib/babili-webpack-plugin/blob/master/src/index.js

JPeer264 commented 5 years ago

@klimashkin I had some time and created the webpack plugin

https://github.com/JPeer264/rcs-webpack-plugin