Scene description

I often run into CSS conflicts when working on several projects myself. The main performance is:

  1. The CSS library was introduced globally at the beginning of the project. When writing your own style, you need to consider that the style of the class with the same name as the third-party CSS library will be polluted, so you need to override the polluted attributes. Sometimes the weight of the class -Specificity is not high, so it cannot be covered! Important overwrite, very tired heart.

  2. The project has been under development for some time, due to new requirements for the introduction of third-party CSS libraries. However, the CSS library introduced has classes with the same name as the style of the project itself. So it also leads to style pollution.

In fact, there are online solutions to the above content, for example, when developing, stick to the BEM class name specification.

However, for those projects that do not use THE BEM specification, or do not have a set of specific naming specifications, it is easy to cause conflicts, so I wrote a Loader by myself using the keyboard.

The namespace

Namespace-prefixed class names do solve the problem of style conflicts caused by duplicate class names.

Some third-party CSS libraries also use namespaces, such as MUI, as shown below:

<ul class="mui-table-view"> 
  <li class="mui-table-view-cell mui-collapse">
    <a class="mui-navigate-right" href="#">Panel 1</a>
    <div class="mui-collapse-content">
      <p>Panel 1 subcontent</p>
    </div>
  </li>
</ul>
Copy the code

But many third-party libraries do not have namespaces. As shown in bootstrap:

<div class="container">
  <h1>Hello, world!</h1>
  <div class="row" >
    <div class="col-md-6 col-md-offset-3">
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </div>
  </div>
</div>
Copy the code

Therefore, every time you introduce a CSS style like Bootstrap, you should consider the class name of your own project.

css-namespacing-loader

So, in order to solve the above problem perfectly, I wrote CSS-Namespacing – Loader.

The following content is from the readme_cn.md of CSS-Namespacing – Loader

This loader has two main functions:

  • It is used to avoid global style contamination due to the introduction of third-party CSS libraries.

  • During development, when the CSS code is compiled, it automatically adds the namespace to the specified class name according to the configuration.

Quick start

To start, you need to download CSS-Namespacing -loader via NPM:

$ npm install css-namespacing --save-dev
Copy the code

Then add the Loader to the WebPack configuration. Such as:

entry.js

import 'bootstrap/dist/css/bootstrap.min.css'
Copy the code

webpack.config.js

module.exports = {
  module: {
    rules:[
      {
        test: /\.css$/i,
        use: [
          "style-loader"."css-loader",
          {
            loader:"css-namespacing-loader".options: {namespace:[
                { value: 'bsp-'.path: [/bootstrap/]}}]}}Copy the code

After running WebPack in your preferred way, you will use bsp-container instead of container when using the styles in bootstrap, for example:

<div class="bsp-container">
  <div class="bsp-row">
    <div class="bsp-col-sm">
      One of three columns
    </div>
    <div class="bsp-col-sm">
      One of three columns
    </div>
    <div class="bsp-col-sm">
      One of three columns
    </div>
  </div>
</div>
Copy the code

In options, you can set which class names do not need to be added to the namespace, or only which class names need to be added to the namespace, and the value of the namespace.

In addition, you can use the @Namespacing annotation to flexibly set the above configuration in your CSS code. If you want to learn more, check it out here.

If you would like to see the results of the processing, please read CSS-Name Racing.

The Options to configure

Name Type Default Necessary Description
namespace {Array} undefined true An array containing multiple configurations

namespace

Type: Array Default: undefined

The element in the Namespace array is an object that contains the following properties.

Name Type Default Necessary Description
path {Array<String/RegExp>} undefined false An array containing the matching paths of the CSS file to which the namespace is to be added
value {String} undefined false The value of the namespace to prefix
not {Array<RegExp>} undefined false An array containing class names that will not be added to the namespace
only {Array<RegExp>} undefined false An array containing only the names of classes to which namespaces will be added
### path

Type: {Array<String|RegExp>} Default: undefined

1. Use regular expressions in arrays

Such as:

options:{
  namespace:[
    { value: 'bsp-'.path: [/bootstrap/]]}}Copy the code

It finds the matching file by way of path.test(filepath) via regexp.prototype. test

2. Use strings in arrays

Such as:

options:{
  namespace:[
    { value: 'bsp-'.path: [path.resolve(___dirname,'./node_modules/bootstrap/dist/css/bootstrap.min.css']])}}Copy the code

He will pass the String. The prototype. Includes as filepath. Includes (path) file match is found

Note: Because of the difference in file separators between Windows and Linux, it is best to use path.resolve to get the file path.

3. Path is not defined

Such as:

options:{
  namespace:[
    { 
      value: 'my-',}}]Copy the code

With this setting, class names in all scanned CSS files are added to the namespace. .

value

Type: {String} Default: undefined

If the value is undefined, for example:

options:{
  namespace:[
    { 
      path: [/bootstrap/]]}}Copy the code

In this configuration, scanned files are not processed.

not

Type:{Array<RegExp>} Default:undefined

For example:

options:{
  namespace:[
    { 
      path: [/bootstrap/].not: [/^box$/]]}}Copy the code

In this configuration, all class names named box in the scanned CSS file will not be added to the namespace.

only

For example:

options:{
  namespace:[
    { 
      path: [/bootstrap/].not: [/^box$/]]}}Copy the code

In this configuration, only the class name box is added to the scanned CSS file.

Afterword.

I later added @Namespacing annotation to the Loader to write CSS and modify the namespace flexibly. However, for many people, this loader is only used to add namespaces to third-party CSS to prevent contamination. So I won’t cover that in this article. If you’re interested, check it out here