Webpack 4用于搜索和包含组件级SASS样式的规则

时间:2018-08-08 10:02:24

标签: angular webpack sass

我有一个基于模板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。

1 个答案:

答案 0 :(得分:0)

webpack确认每个依赖项的方式是从入口点开始分析您的依赖关系树。 Webpack只会在已知依赖项的情况下捆绑/触摸它们,即:

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

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

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

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

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