You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular13升级至15后,webpack_require.context不是函数报错如何解决?

问题:Angular13迁移至Angular15后require.context调用报错

我开发了一个文档应用,支持在组件示例旁查看TS、HTML、SCSS源码及运行效果。从Angular13迁移到Angular15后出现如下问题:

在AppModule的providers中配置了令牌:

{
    provide: DEMO_PATH_TOKEN_SCSS,
    useFactory: () => (require as any).context(`!sass-loader!./`, true, /.*\.(scss)$/),
}

这个工厂函数用于获取源码文件列表,后续由承载示例的容器组件过滤;TS和HTML文件也有类似配置。

该令牌注入到非根级提供的SourcesService中:

@Injectable()
export class SourcesService {
    constructor(
        @SkipSelf() @Optional() @Inject(DEMO_PATH_TOKEN_SCSS) private contextScss: any
    ) { }
}

打开提供SourcesService的组件页面时,触发错误:

ERROR Error: Uncaught (in promise): TypeError: webpack_require(...).context is not a function
TypeError: webpack_require(...).context is not a function


修复方案

1. 适配Webpack 5的require.context写法

Angular15升级至Webpack 5,require.context不支持运行时动态调用,需提前创建上下文并导出:

在项目根目录创建demo-contexts.ts文件:

// 提前创建SCSS文件上下文
export const scssDemoContext = require.context(`!sass-loader!./`, true, /.*\.(scss)$/);
// 同理创建TS和HTML的上下文
export const tsDemoContext = require.context(`!raw-loader!./`, true, /.*\.(ts)$/);
export const htmlDemoContext = require.context(`!raw-loader!./`, true, /.*\.(html)$/);

修改AppModule的providers配置,直接引用导出的上下文:

import { scssDemoContext, tsDemoContext, htmlDemoContext } from './demo-contexts';

@NgModule({
  providers: [
    {
      provide: DEMO_PATH_TOKEN_SCSS,
      useValue: scssDemoContext
    },
    // TS和HTML的令牌配置同理
    {
      provide: DEMO_PATH_TOKEN_TS,
      useValue: tsDemoContext
    },
    {
      provide: DEMO_PATH_TOKEN_HTML,
      useValue: htmlDemoContext
    }
  ]
})
export class AppModule { }

2. 确保loader配置正确

Angular15默认配置有变化,需确保raw-loader和sass-loader已安装并配置:

安装依赖:

npm install raw-loader sass-loader --save-dev

在angular.json的build配置中添加允许的CommonJS依赖:

"build": {
  "builder": "@angular-devkit/build-angular:browser",
  "options": {
    "allowedCommonJsDependencies": ["sass-loader"],
    "stylePreprocessorOptions": {
      "includePaths": ["./src"]
    }
  }
}

若需自定义Webpack规则,创建webpack.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['raw-loader', 'sass-loader'],
        exclude: /node_modules/
      },
      {
        test: /\.ts$/,
        use: ['raw-loader'],
        exclude: /node_modules/
      },
      {
        test: /\.html$/,
        use: ['raw-loader'],
        exclude: /node_modules/
      }
    ]
  }
};

3. 调整SourcesService注入逻辑

确保依赖注入规则符合Angular规范,避免令牌重复提供冲突:

@Injectable({
  providedIn: 'any' // 或根据实际场景设置为对应特性模块
})
export class SourcesService {
  constructor(
    @Optional() @Inject(DEMO_PATH_TOKEN_SCSS) private contextScss: any
  ) {
    // 添加空值判断,避免无上下文时报错
    if (!this.contextScss) {
      console.warn('SCSS demo context not provided');
    }
  }
}

内容的提问来源于stack exchange,提问作者Eugeny89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:22:24