ASP.Net Core 2中Webpack编译SASS样式不生效问题求助
Let's break down why your SASS styles aren't showing up, even though Webpack is compiling them into main-client.js:
The Core Issue
Your current SCSS loader uses to-string-loader, which converts compiled CSS into a raw string—but it doesn't automatically inject that string into the browser's DOM. Unless you're manually taking that string and creating a <style> tag with it (which it doesn't look like you are), those styles will sit unused in your JS bundle.
Plus, your Webpack config is split between client (browser) and server (prerendering) bundles, so you need different loader setups for each environment.
Step-by-Step Fixes
1. Install Missing Dependencies (If Needed)
First, make sure you have style-loader (for injecting styles into the browser) and node-sass (required by sass-loader) installed:
npm install style-loader node-sass --save-dev
2. Update Your webpack.config.js
You need to split SCSS handling between client and server bundles. Here's the full, corrected config (filling in your incomplete code):
const path = require('path'); const webpack = require('webpack'); const merge = require('webpack-merge'); const AotPlugin = require('@ngtools/webpack').AotPlugin; const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin; const ExtractTextPlugin = require('extract-text-webpack-plugin'); // Add this module.exports = (env) => { const isDevBuild = !(env && env.prod); const extractSCSS = new ExtractTextPlugin('main.css'); // Extract compiled SCSS to a file // Shared base config const sharedConfig = { stats: { modules: false }, resolve: { extensions: ['.js', '.ts'] }, module: { rules: [ { test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' }, { test: /\.html$/, use: 'html-loader?minimize=false' }, { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' } ] }, plugins: [new CheckerPlugin()] }; // Client (Browser) Bundle Config const clientBundleConfig = merge(sharedConfig, { entry: { 'main-client': './ClientApp/boot.browser.ts' }, output: { path: path.join(__dirname, 'wwwroot', 'dist'), filename: '[name].js', publicPath: 'dist/' }, module: { rules: [ // For client: Use style-loader in dev to inject styles; extract to file in prod { test: /\.scss$/, use: isDevBuild ? ['style-loader', 'css-loader', 'sass-loader?sourceMap'] : extractSCSS.extract({ use: ['css-loader?minimize', 'sass-loader?sourceMap'] }) }, { test: /\.css$/, use: ['style-loader', 'css-loader'] } ] }, plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./wwwroot/dist/vendor-manifest.json') }), extractSCSS // Include the extraction plugin for prod ].concat(isDevBuild ? [ new webpack.SourceMapDevToolPlugin({ filename: '[file].map', moduleFilenameTemplate: path.relative('wwwroot/dist', '[resourcePath]') }) ] : [ new webpack.optimize.UglifyJsPlugin(), new AotPlugin({ tsConfigPath: './tsconfig.json', entryModule: path.join(__dirname, 'ClientApp/app/app.module.browser#AppModule'), exclude: ['./**/*.server.ts'] }) ]) }); // Server (Prerendering) Bundle Config const serverBundleConfig = merge(sharedConfig, { target: 'node', entry: { 'main-server': './ClientApp/boot.server.ts' }, output: { path: path.join(__dirname, 'ClientApp', 'dist'), filename: '[name].js', libraryTarget: 'commonjs2' }, module: { rules: [ // For server: Use to-string-loader so styles work with prerendering { test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader?sourceMap'] }, { test: /\.css$/, use: ['to-string-loader', 'css-loader'] } ] }, plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./ClientApp/dist/vendor-manifest.json'), sourceType: 'commonjs2', name: './vendor' }), new AotPlugin({ tsConfigPath: './tsconfig.json', entryModule: path.join(__dirname, 'ClientApp/app/app.module.server#AppModule'), exclude: ['./**/*.browser.ts'] }) ] }); return [clientBundleConfig, serverBundleConfig]; };
3. Ensure Styles Are Properly Imported
- Global Styles: If you have a global
styles.scssfile, import it in yourboot.browser.tsfile:import './styles.scss'; - Component Styles: For Angular components, reference SCSS files directly in the component's
styleUrls:@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] })
4. Reference Extracted CSS in Your Layout (Production Only)
In production mode, Webpack extracts SCSS to main.css. Add this reference to your _Layout.cshtml alongside vendor.css:
<link rel="stylesheet" href="~/dist/vendor.css" /> <link rel="stylesheet" href="~/dist/main.css" />
Additional Troubleshooting Tips
- Check Chrome DevTools' Elements tab to see if
<style>tags (dev mode) or themain.csslink (prod mode) are present. - Use the Computed tab in DevTools to verify if your styles are being overridden by higher-specificity CSS (like Bootstrap).
- Run Webpack with verbose logging (
webpack --env.prod --verbose) to check for any hidden compilation warnings related to SASS.
内容的提问来源于stack exchange,提问作者Dan_J

