Example Codes for Importing CSS/SCSS Modules in TypeScript
- TypeScript: A superset of JavaScript that adds static typing for improved code reliability and maintainability.
- Imports: A mechanism in TypeScript (and JavaScript) to bring code from other files into the current file.
- Sass/SCSS: A preprocessor syntax extension for CSS that allows for variables, nesting, mixins, and other features for more organized and maintainable stylesheets.
The Issue:
When you're using TypeScript and want to import CSS or SCSS modules, you might encounter this error because TypeScript, by default, doesn't understand how to handle these non-JavaScript files. It expects to find actual JavaScript modules to import.
Resolving the Error:
There are two main approaches to fix this:
-
Type Declaration Files:
- Create a file (e.g.,
styles.d.ts
) in your project's source directory. - Add a type declaration that tells TypeScript how to interpret CSS modules:
declare module "*.module.css" { const content: { [className: string]: string }; export default content; }
- This tells TypeScript that CSS modules with the
.module.css
extension export an object with class names as keys and their corresponding CSS values as strings.
- Create a file (e.g.,
-
Webpack Loader Configuration (if using Webpack):
- If your project uses Webpack for bundling, you can configure a loader to handle CSS/SCSS modules:
module.exports = { module: { rules: [ { test: /\.module\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true } } ] }, { test: /\.module\.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' // Add Sass loader if using Sass ] } ] } };
- This configuration instructs Webpack to use the
style-loader
andcss-loader
(and optionallysass-loader
for Sass) to process and inject the CSS/SCSS styles into your application. Themodules: true
option in thecss-loader
enables module-based CSS/SCSS processing.
Choosing the Approach:
- If you're not using a bundler like Webpack, type declaration files are the way to go.
- If you're using Webpack, consider using both the loader configuration and type declaration files for better type safety and potential code completion/navigation features in your IDE.
Additional Tips:
- Ensure the path to your CSS/SCSS modules in your import statements is correct relative to the file where you're importing them.
- Consider using a linter or code formatter to enforce consistent styling and naming conventions, which can help prevent errors and improve code readability.
Example Codes for Importing CSS/SCSS Modules in TypeScript
Using Type Declaration Files
styles.d.ts:
declare module "*.module.css" {
const content: { [className: string]: string };
export default content;
}
Component.tsx:
import styles from './styles.module.css'; // Import the CSS module
const MyComponent = () => {
return (
<div className={styles.myClass}>This is content with a class from CSS module.</div>
);
};
Using Webpack Loader Configuration
webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.module\.css$/, // Matches CSS files ending with .module.css
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true, // Enable CSS Modules
},
},
],
},
{
test: /\.module\.scss$/, // Matches SCSS files ending with .module.scss
use: [
'style-loader',
'css-loader',
'sass-loader', // Add Sass loader for SCSS processing
],
},
],
},
};
import styles from './styles.module.scss'; // Import the SCSS module
const MyComponent = () => {
return (
<div className={styles.myClass}>This is content with a class from SCSS module.</div>
);
};
Key Points:
- In both examples, the CSS/SCSS files use the
.module.css
or.module.scss
extension to differentiate them from regular CSS/SCSS files. - The import statement in the component uses the same path as the CSS/SCSS file but with the extension changed to
.module.css
or.module.scss
. - The imported object (
styles
) has properties that correspond to the class names defined in the CSS/SCSS module. - The Webpack configuration is only necessary if you're using Webpack for bundling.
This method is generally not recommended for modern TypeScript projects due to the lack of type safety and potential for runtime errors. However, it could be a quick workaround if you need a simple way to import a CSS/SCSS file:
import styles from './styles.css'; // Using require
const MyComponent = () => {
const myClass = styles; // Access the entire CSS object (not type-safe)
return (
<div className={myClass}>This is content with a class from CSS module.</div>
);
};
In this case, styles
will be an object containing all the CSS properties from the imported file, but TypeScript won't have any information about the specific class names, leading to potential errors if you mistype them.
CSS-in-JS Libraries (For Advanced Styling Needs):
If you have complex styling requirements or want to integrate styles more tightly with your components, you can explore CSS-in-JS libraries like Styled Components, Emotion, or JSS. These libraries allow you to define styles directly within your JavaScript or TypeScript code using template literals or functions. While they offer more flexibility and type safety, they can add complexity to your project setup and might have a slight performance overhead compared to traditional CSS modules.
Here's an example using Styled Components:
import styled from 'styled-components';
const MyStyledComponent = styled.div`
color: red;
font-size: 16px;
`;
import MyStyledComponent from './styles.tsx'; // Import the styled component
const MyComponent = () => {
return (
<div>
<MyStyledComponent>This is styled content using Styled Components.</MyStyledComponent>
</div>
);
};
Choosing the Right Method:
- For most TypeScript projects: Use type declaration files or Webpack loader configuration for type safety and compatibility with common build tools.
- For quick workarounds (not recommended for production): Consider
require
if you just need to import a CSS file without type safety. - For complex styling needs or tight integration with components: Explore CSS-in-JS libraries for advanced features and type safety.
typescript import sass