Angular 应用内的 React 组件:导入 scss 文件
React component inside Angular app: import scss files
我正在尝试了解如何自定义 Angular CLI 构建过程,以便能够在导入 scss 文件时正确构建 React 组件。
我目前能够构建一个 Angular 项目,其中使用了一些 React 组件。那里有很多 material 解释了如何实现它(实际上很简单)。
不过,我仍然没有找到指出如何在 .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 文件的加载器?
我发现 指示我使用自定义构建器而不是标准构建器,这将允许我提供额外的 webpack 配置文件。我不明白的是如何在该文件中编写加载程序来解决我的问题。
默认的 Angular CLI webpack 配置已经有一个 .scss 文件的加载器,需要被 Angular 组件转换和引用,我不想覆盖它......所以我怎么能只为导入到 .tsx 文件中的 .scss 文件添加一个加载器?除了通常的正则表达式之外,有没有办法告诉 webpack 根据兄弟姐妹匹配文件?
我想这毕竟是一个精致的 webpack 问题。
注意:使用 Angular CLI v7 和 webpack 4。
真正的问题是:我需要区分 Angular .scss 文件和 React .scss 文件。
我想出的解决方案是围绕在 Webpack 的 .scss 文件规则配置中使用 oneOf
,这允许更精细地区分通过相同测试(/\.scss|\.sass$/
)的文件粒度方式。
所以我按照我在问题中发布的link的建议使用了@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;
很有魅力。
我正在尝试了解如何自定义 Angular CLI 构建过程,以便能够在导入 scss 文件时正确构建 React 组件。 我目前能够构建一个 Angular 项目,其中使用了一些 React 组件。那里有很多 material 解释了如何实现它(实际上很简单)。 不过,我仍然没有找到指出如何在 .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 文件的加载器?
我发现
我想这毕竟是一个精致的 webpack 问题。
注意:使用 Angular CLI v7 和 webpack 4。
真正的问题是:我需要区分 Angular .scss 文件和 React .scss 文件。
我想出的解决方案是围绕在 Webpack 的 .scss 文件规则配置中使用 oneOf
,这允许更精细地区分通过相同测试(/\.scss|\.sass$/
)的文件粒度方式。
所以我按照我在问题中发布的link的建议使用了@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;
很有魅力。