Embedding JavaScript Code with `@import

Stylus is a powerful CSS preprocessor known for its unique syntax and function system. When dealing with complex styling logic, modularity is one of the key strategies for improving maintainability. However, unlike Sass or Less, Stylus natively does not support embedding JavaScript code blocks directly to execute dynamic calculations (e.g., @import directives in Stylus are primarily used for importing external files rather than JS). If your goal is to "embed JavaScript logic into the style processing flow," it typically means you need to leverage its built-in function system combined with a Node.js environment, or implement via custom compiler plugins. This article will explore how to effectively integrate JavaScript code into Stylus projects, addressing cross-language collaboration and dynamic calculation requirements.
First and foremost, it must be clear that in standard CSS and Stylus syntax, @import is a directive used to import external style sheets, not a container for embedding JS directly. If you attempt to use @import 'file.js' directly in a Stylus file to execute logic, the preprocessor will fail to recognize it and throw an error.

The correct usage of Stylus involves encapsulating JavaScript code into functions or modules and then invoking these functions when needed. For example, you can create a separate .js file to store calculation logic (such as adjusting colors based on user preferences) and introduce the code from this JS module into your Stylus files via require() statements or other mechanisms. This separation architecture adheres to the principle of separation of concerns, decoupling styles from behavior.

// styles.styl
@import './utils' // Import utility file containing JS logic (requires specific configuration)
body {
    background-color: getDynamicColor(userPreference)
}

The above example demonstrates how to call an externally defined JavaScript function within Stylus, provided your build tool is correctly configured to support mixed-language compilation.

Three Main Approaches for Implementing Dynamic Calculations

Since native @import does not support JS, actual projects often adopt one of the following three strategies to achieve an "embedding" effect:

  1. Using Node.js API + Stylus Plugin
    By writing custom plugins (such as stylus-plugin-jsx), you can inject JavaScript code into template strings during the compilation phase. This approach is suitable for handling complex conditional rendering logic.

  2. Leveraging Stylus Built-in Functions to Simulate JS Behavior
    Stylus provides a rich set of mathematical and boolean operation functions that can replace simple JS calculations:

    // colors.styl
    function lighten(color, amount) {
        return color + '0' + (parseInt(amount, 16)) / 256 * hexToDec('ffffff')
    }
    
    body {
       background: lighten(#3498db, 20%)
    }
    
  3. Utilizing the Webpack/Babel Build Chain
    Extract JS logic into independent modules and convert them into Stylus-recognizable expressions during the bundling phase. This is the most recommended solution for enterprise-level projects.

Practical Case: Dynamic Theme Switching System

Below is a complete example demonstrating how to combine Stylus with JavaScript to implement a responsive theme switching feature:

// theme.js
module.exports = function (userTheme) {
    return userTheme === 'dark' ? '#1a1a2e' : '#f4f7f6';
};

The corresponding Stylus file calls the result of the above module via a plugin and dynamically generates CSS based on the user's theme:

// main.styl
require('theme')(userPreference) as themeColor

body {
    background-color: themeColor
}

button:hover {
    transform: scale(1.05)
    transition: all 0.3s ease-in-out
}

This approach not only maintains code clarity but also allows for complex logical judgments to be executed at compile time.

Best Practices and Considerations

  • Avoid Misusing @import: Do not attempt to use it to replace JavaScript control flow, as this leads to syntax errors and performance degradation.
  • Prioritize Functional Programming Style: Stylus's function system is already powerful enough; external JS is often unnecessary in most cases.
  • Build Tool Configuration is Critical: Ensure tools like Webpack or Gulp correctly identify and process mixed-language files.
  • Test All Branch Logic: Dynamic calculations may produce unforeseen side effects; thoroughly verify output results across different input scenarios.

By reasonably designing the architecture and selecting an appropriate integration strategy, developers can fully leverage the flexibility of JavaScript to build modern web applications while maintaining Stylus's concise syntax. Remember, "embedding" is not about writing code blocks directly, but rather achieving logical fusion through the toolchain.