【问题标题】:Webpack 4 Rules to search and include component level SASS stylesWebpack 4 搜索和包含组件级 SASS 样式的规则
【发布时间】:2018-08-09 00:11:11
【问题描述】:

我有一个基于模板 here 的 Angular 6 SPA。

现在我有几个自定义组件,其中包含仅与组件本身相关的 SCSS 文件。这些位于 SPA 的 /ClientApp 文件夹中。

webpack.prod.js中SASS输入的当前规则是

const path = require('path');
const rxPaths = require('rxjs/_esm5/path-mapping');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpackTools = require('@ngtools/webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
    .BundleAnalyzerPlugin;
const helpers = require('./webpack.helpers');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

const ROOT = path.resolve(__dirname, '..');

console.log('@@@@@@@@@ USING PRODUCTION @@@@@@@@@@@@@@@');

module.exports = {
    mode: 'production',
    entry: {
        polyfills: './ClientApp/polyfills.ts',
        vendor: './ClientApp/vendor.ts',
        app: './ClientApp/main-aot.ts'
    },

    output: {
        path: ROOT + '/wwwroot/',
        filename: 'dist/[name].[hash].bundle.js',
        chunkFilename: 'dist/[id].[hash].chunk.js',
        publicPath: '/'
    },

    resolve: {
        extensions: ['.ts', '.js', '.json'],
        alias: rxPaths()
    },

    devServer: {
        historyApiFallback: true,
        stats: 'minimal',
        outputPath: path.join(ROOT, 'wwwroot/')
    },

    module: {
        rules: [
            {
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                use: '@ngtools/webpack',
                parser: {
                    system: true
                }
            },
            {
                test: /\.(png|jpg|gif|woff|woff2|ttf|svg|eot)$/,
                use: 'file-loader?name=assets/[name]-[hash:6].[ext]',
                parser: {
                    system: true
                }
            },
            {
                test: /favicon.ico$/,
                use: 'file-loader?name=/[name].[ext]',
                parser: {
                    system: true
                }
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
                parser: {
                    system: true
                }
            },
            {
                test: /\.scss$/,
                include: path.join(ROOT, 'ClientApp/styles'),
                use: ['style-loader', 'css-loader', 'sass-loader'],
                parser: {
                    system: true
                }
            },
            {
                test: /\.scss$/,
                exclude: path.join(ROOT, 'ClientApp/styles'),
                use: ['raw-loader', 'sass-loader'],
                parser: {
                    system: true
                }
            },
            {
                test: /\.html$/,
                use: 'raw-loader',
                parser: {
                    system: true
                }
            }
        ],
        exprContextCritical: false
    },
    plugins: [
        // new BundleAnalyzerPlugin({
        //  analyzerMode: 'static',
        //  generateStatsFile: true
        // }),
        new webpackTools.AngularCompilerPlugin({
            tsConfigPath: './tsconfig-aot.json'
            // entryModule: './ClientApp/app/app.module#AppModule'
        }),

        // new webpack.optimize.ModuleConcatenationPlugin(),

        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery'
        }),

        new CleanWebpackPlugin(['./wwwroot/dist', './wwwroot/assets'], {
            root: ROOT
        }),
        new webpack.NoEmitOnErrorsPlugin(),

        // new UglifyJSPlugin({
        //   parallel: 2
        // }),

        // new webpack.optimize.CommonsChunkPlugin({
        //   name: ['vendor', 'polyfills']
        // }),
        new HtmlWebpackPlugin({
            filename: 'index.html',
            inject: 'body',
            template: './ClientApp/index.html',
            chunksSortMode: 'none' //fix for cyclic dependency
        }),

        new CopyWebpackPlugin([
            { from: './ClientApp/images/*.*', to: 'assets/', flatten: true }
        ])
    ]
};

这显然只是加载位于styles 中的SASS 文件。是否可以在 app 文件夹上添加某种递归搜索以获取其他 SASS 文件?或者我需要专门导入styles.scss。

【问题讨论】:

  • 您需要指定导入。否则 webpack 将不知道该资产。 Webpack 开始从入口点分析到树的叶子。
  • hmm 好的,所以对于每个具有特定 .SASS 文件的组件,我需要手动将其导入到样式文件夹中的 styles.SCSS 中?
  • 是的。或者您可以在其等效组件上导入每个 sass 文件。 A有一个.sass。以此类推。
  • 好的,如果它们被导入到 component.ts 中,那么文件加载器应该正确地拉出样式吗? (我正在这样做,它似乎并没有通过图像链接并从中创建资产)。
  • 不,这不是文件加载器的工作。发布您的 webpack 配置,以便我们也可以进行分析。

标签: angular webpack sass


【解决方案1】:

webpack 确认每一个依赖的方式是从入口点开始分析你的依赖树。如果它们是已知的依赖关系,Webpack 只会捆绑/触摸它们,即:

import {a} from 'b'; import 'styles.scss'; ...

要处理资产,您必须为每种类型的依赖项提供适当的加载器。 file-loader 通常用于图像。你声明的方式是正确的。

对于 css,你需要(顺序很重要):style-loadercss-loader

对于 scss,您需要(顺序很重要):style-loadercss-loadersass-loader

在您的配置中,您有 2 个 scss 文件规则,这可能是它使用 raw-loader(纯文本)的问题。

【讨论】:

    猜你喜欢
    • 2018-02-22
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 2016-10-31
    • 2017-10-16
    • 2021-11-24
    相关资源
    最近更新 更多