nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.22k stars 2.31k forks source link

Module based and non-module based CSS preprocessors should be configured with the same options #5669

Closed hbj closed 3 years ago

hbj commented 3 years ago

Description

When working with React, module-based (e.g. .module.less) and non-module based (e.g. .less) CSS preprocessors use different options. If I take the example of LESS, we have the following differences:

The objective is to have both configurations use the same preprocessor options.

Motivation

This change would solve the following issues (non exhaustive list, these are things I faced):

Concrete example

I use ant design in my React project and I want to be able to adapt its theme and use its LESS variables in my code, so I have the following setup (all files are under apps/my-app/src):

variables.less

@import 'antd/lib/style/themes/default.less';

@primary-color: green;

styles.less

@import './variables.less';

@import 'antd/lib/style/index.less';
@import 'antd/lib/style/components.less';

app/app.module.less

@import '../variables.less';

.app {
  color: @text-color; // ant design variable
}

This setup doesn't work for different reasons:

  1. app/app.module.less imports variables.less which imports ant design files from node_modules but uses the non-tilde format, so it will fail (if I add the tilde then the styles.less file will fail to compile because it needs the non-tilde format) => so variables.less can't be imported by both types of files
  2. the file antd/lib/style/themes/default.less imported by variables.less uses JS so it will fail to compile if we make the import in app/app.module.less work as module files don't support JS

I'm currently working around the issues with a custom webpack file:

const reactWebpack = require('@nrwl/react/plugins/webpack');
const { resolve } = require('path');

module.exports = (config) => {
  config = reactWebpack(config);

  const lessModulesLoader = config.module.rules[1].oneOf[2].use[2];

  lessModulesLoader.options = {
    javascriptEnabled: true,
    paths: [resolve(__dirname, 'node_modules')],
  };

  return config;
};

But it would be very helpful if we could just configure the preprocessors through stylePreprocessorOptions and have both module and non-module preprocessors behave the same.

Suggested Implementation

One possible implementation would be to have the web plugin (which is the base of the react plugin) use the stylePreprocessorOptions configuration option and prepare all preprocessor configurations accordingly, then the react plugin could get these configs and use them directly without modification.

Alternate Implementations

Another option would be to centralise all preprocessors configuration (module and non-module) in the web plugin and make them use the same options.

jaysoo commented 3 years ago

This will be fixed in the next Nx release (12.6).

hbj commented 3 years ago

@jaysoo this has been only partially fixed. Here are the outstanding issues:

It would really make sense to make both use the exact same options because it happens often that we import non-module files from module files, so they must work the same way otherwise importing would be impossible.

github-actions[bot] commented 1 year ago

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.