Bertug
Bertug

Reputation: 1090

How to use custom style loader in Vite

We have a react project and using webpack for bundling but also we want to try vite too. Webpack bundle css files from style-loader.js too. In style-loader.js we have some rules which are related to components and components are added to node modules. My rule's aim is mainly importing css files from node_modules components. When we run our project with vite, Our custom scss files does not override css which came from components. Is there any solution for override or Is there any way to use a custom style loader in vite ?

Our custom style loader webpack-dev is;

module: {
 rules: [
   {
     test: /\.js?$/,
     exclude: /(node_modules|bower_components)/,
     loader: './config/webpack/style-loader'
   },
]}

Our style-loader.js file is;

const babylon = require('babylon');
const traverse = require('babel-traverse').default;
const fs = require('fs');

module.exports = function (source) {
    var astResult = babylon.parse(source, {
        sourceType: "module",
        ranges: true,
        plugins: [
            "jsx",
            "objectRestSpread",
            "flow",
            "typescript",
            "decorators",
            "doExpressions",
            "classProperties",
            "classPrivateProperties",
            "classPrivateMethods",
            "exportExtensions",
            "asyncGenerators",
            "functionBind",
            "functionSent",
            "dynamicImport",
            "numericSeparator",
            "optionalChaining",
            "importMeta",
            "bigInt",
            "optionalCatchBinding"
        ]
    });
    let addedIndexCounter = 0;
    let isViewDirty = false; 

    traverse(astResult, { 
        enter: function (path) {
            let node = path.node;
            if (node.type == 'ImportDeclaration' && 
                node.source && 
                node.source.type == 'StringLiteral' &&
                node.source.value &&
                node.source.value.indexOf('@packagename') >= 0 && 
                node.source.value.indexOf('core') < 0 && 
                node.source.value.indexOf('.css') < 0) {    
                if(fs.existsSync('./node_modules/' + node.source.value + '/styles.css')) {
                    let starting = node.end;
                    starting += addedIndexCounter;
                    let targettacCss = "; import '" + node.source.value + "/styles.css';"
                    addedIndexCounter += targettacCss.length;
                    source = source.substring(0, starting) + targettacCss + source.substring(starting);
                    isViewDirty = true;
                }
            }
        }
    });
    /*if(isViewDirty){
        let fileName = "view_" + (new Date()).toISOString().slice(0, 10)+"_" + Math.random().toString(35).substr(2,10);
        fs.writeFileSync('./logs/views/' + fileName, source);
    }*/
    return source;
};

Upvotes: 2

Views: 5103

Answers (1)

JoeH
JoeH

Reputation: 547

You can use plugins to achieve your feature, the following is my general idea.

// vite.config.js

import { defineConfig } from "vite";
import customerPlugin from "./plugin/customer-plugin";

export default defineConfig(() => {
  return {
    // ..
    plugins: [customerPlugin()] // Put your plugin here
  };
});
// ./plugin/customer-plugin.js

const customerPlugin = () => {
  return {
    name: "customer-transform",
    transform(code, id) {
      // id = "/some/path/xxx.js"
      if (!id.endsWith(".js")) return; // Only transform js file.

      let resultCode = "";
      // Paste your transform logic here.
      return resultCode;
    }
  };
};
export default customerPlugin;

reference: https://vitejs.dev/guide/api-plugin.html

Upvotes: 0

Related Questions