Next.js集成TypeScript与Stylus插件遇样式导入返回undefined问题
我来帮你一步步排查这个问题,这种情况通常是配置细节或者类型声明的小疏漏导致的,咱们逐个分析:
1. 检查类型声明文件的正确性
你提到在externals.d.ts里加了模块声明,但可能写法不够完整,TypeScript无法识别导出的样式对象类型。请确保你的声明是这样的:
// externals.d.ts declare module '*.styl' { const styles: Record<string, string>; export default styles; }
同时确认tsconfig.json的include字段确实包含了这个文件,比如:
{ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "externals.d.ts"] }
2. 验证next.config.js的插件配置顺序和正确性
next-compose-plugins的插件顺序很关键,样式处理插件需要正确配置,而且要确保你用的是适配Next.js版本的插件。比如如果你用的是Next.js 12+,官方已经内置了CSS支持,不需要@zeit/next-css,可以直接用@zeit/next-stylus配合配置。
正确的next.config.js示例(用next-compose-plugins):
const withPlugins = require('next-compose-plugins'); const withStylus = require('@zeit/next-stylus'); const withTypeScript = require('@zeit/next-typescript'); module.exports = withPlugins([ // 注意:样式插件要放在TypeScript插件前面 [withStylus, { // 重中之重:必须开启CSS Modules才能导出样式类名对象! cssModules: true, cssLoaderOptions: { importLoaders: 1, localIdentName: "[local]_[hash:base64:5]", }, }], [withTypeScript, { // 你的TypeScript配置选项 transpileModules: [] }] ], { // Next.js基础配置 });
⚠️ 这里最容易踩坑:如果没开cssModules: true,Stylus文件会被全局注入,根本没法通过默认导入获取类名对象,这大概率是你遇到问题的核心原因!
3. 确认导入方式正确
在button.tsx里,你必须用默认导入的方式接收样式对象:
import styles from './button.styl'; console.log(styles); // 现在应该能拿到类名对象了 const Button = () => { return <button className={styles.button}>Click Me</button>; }; export default Button;
如果你的导入是import './button.styl'(没有接收默认导出),那styles变量自然是undefined,这点一定要注意。
4. 检查插件版本兼容性
如果你的Next.js版本比较新(比如13+),@zeit/next-stylus和@zeit/next-typescript可能已经不再维护,建议改用Next.js内置的CSS支持配合stylus-loader:
修改next.config.js为:
const nextConfig = { webpack: (config) => { config.module.rules.push({ test: /\.styl$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: { localIdentName: "[local]_[hash:base64:5]", }, }, }, 'stylus-loader', ], }); return config; }, }; module.exports = nextConfig;
同时安装必要的依赖:
npm install stylus stylus-loader css-loader style-loader --save-dev
5. 清除缓存重启开发服务器
有时候缓存会导致配置不生效,执行以下命令清除缓存后重启:
rm -rf .next node_modules/.cache npm run dev
按照以上步骤排查,应该能解决styles为undefined的问题。
内容的提问来源于stack exchange,提问作者Boris Zagoruiko

