【问题标题】:React component inside Angular app: import scss filesAngular 应用程序中的 React 组件:导入 scss 文件
【发布时间】:2022-01-14 11:06:30
【问题描述】:

我正在尝试了解如何自定义 Angular CLI 构建过程,以便在导入 scss 文件时能够正确构建 React 组件。 我目前能够构建一个使用一些 React 组件的 Angular 项目。有很多材料可以解释如何实现它(实际上很简单)。 我仍然没有找到一篇文章指出如何在 .tsx 文件中正确解析 scss 文件导入。

例如,如果我有这个简单的 React 组件:

import * as styles from "./styles.scss";
const ReactComponentWithBrokenStyles = () => (
    <div className={styles.root}>This div won't have a class</div>
);
export default ReactComponentWithBrokenStyles;

如何编辑 Angular CLI 构建过程以正确添加可转换 .scss 文件的加载器?

我发现 some resources 指向我使用自定义构建器而不是标准构建器,这将允许我提供额外的 webpack 配置文件。我不明白的是如何在该文件中编写加载程序来解决我的问题。 默认的 Angular CLI webpack 配置已经有一个 .scss 文件的加载器,它需要被 Angular 组件转换和引用,我不想覆盖它......所以我怎样才能为 .scss 文件添加一个加载器在 .tsx 文件中导入?除了通常的正则表达式之外,有没有办法告诉 webpack 根据兄弟姐妹匹配文件?

我想这毕竟是一个精致的 webpack 问题。

注意:使用 Angular CLI v7 和 webpack 4。

【问题讨论】:

    标签: reactjs angular webpack loader


    【解决方案1】:

    真正的问题是:我需要区分 Angular .scss 文件和 React .scss 文件。

    我想出的解决方案主要围绕在 Webpack 的 .scss 文件规则配置中使用 oneOf,它允许以更细粒度的方式区分通过相同测试 (/\.scss|\.sass$/) 的文件。

    所以我按照我在问题中发布的链接的建议使用了@angular-builders/custom-webpack,并且我已经为标准 Angular CLI Webpack 配置创建了这个定制器:

    const reactScssFilesLoaders = [
        "style-loader",
        {
            loader: "css-loader",
            options: {
                discardDuplicates: true,
                importLoaders: 1,
                modules: true,
                localIdentName: "[name]__[local]___[hash:base64:5]",
            },
        },
        "postcss-loader",
        "sass-loader"
    ];
    
    /**
     * Modifies the default Webpack config so that our React components are able to
     * import styles from scss files as JS objects
     * @param {*} defaultAngularConfig The default Webpack config that comes with the NG Cli
     * @param {*} buildOptions The build options (not needed here)
     * @returns The adjusted Webpack config
     */
    function customizeWebpackConfig(defaultAngularConfig, buildOptions) {
        const builtInNgScssFilesRule = defaultAngularConfig.module.rules.find(r => r.test.source.includes("scss"));
        if (!builtInNgScssFilesRule) {
            throw new Error("WTF?");
        }
    
        const angularScssFilesLoaders = builtInNgScssFilesRule.use;
        // We only want one top level rule for .scss files, so we need to further test
        // We want to leave normal Angular style files to the default loaders, and
        // we just want to turn styles into JS code when imported by tsx components
        builtInNgScssFilesRule.oneOf = [{
            issuer: /\.(tsx)$/,
            use: reactScssFilesLoaders
        }, {
            test: /\.(component)\.(scss)$/,
            use: angularScssFilesLoaders
        }]
        delete builtInNgScssFilesRule.exclude;
        delete builtInNgScssFilesRule.use;
        return defaultAngularConfig;
    }
    
    module.exports = customizeWebpackConfig;
    

    像魅力一样工作。

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2018-11-17
      相关资源
      最近更新 更多