Angular Webpack 设置:使用 webpack 从 css 迁移到 sass

Posted

技术标签:

【中文标题】Angular Webpack 设置:使用 webpack 从 css 迁移到 sass【英文标题】:Angular Webpack setup: Migrate from css to sass using webpack 【发布时间】:2019-01-04 11:49:23 【问题描述】:

我担心这个问题可能过于宽泛,但我希望在我的 webpack 设置方面得到一些帮助。

我有一个大型的 Angular 堆栈设置。该解决方案目前在功能上使用 Webpack 构建。

到目前为止,我使用的都是纯 css 文件,Angular 在组件声明中引用了这些文件,例如:

@Component(
  selector: 'something',
  templateUrl: 'template',
  styleUrls: ['some_component_style.css', 'other.css']
)

但是我计划将来将我所有的 css 文件迁移到 sass 文件,但是我有点不确定如何在 Webpack 中进行设置。

这是我当前的 webpack 配置:

webpack.config.common.js:

var webpack = require('webpack');

module.exports = 
    entry: 
        'app': './assets/app/main.ts'
    ,

    resolve: 
        extensions: ['.js', '.ts']
    ,

    module: 
        rules: [
            
                test: /\.html$/,
                use: [ loader: 'html-loader' ]
            ,
            
                test: /\.css$/, // for legacy purposes
                use: [ loader: 'raw-loader' ]
            ,
            
                test: /\.scss$/,
                use: [
                    loader: "style-loader" // creates style nodes from JS strings
                , 
                    loader: "css-loader" // translates CSS into CommonJS
                , 
                    loader: "sass-loader" // compiles Sass to CSS
                ]
            ,
            
                test: /\.(png|jpe?g|gif|svg|woff|woff2|tff|eot|ico)$/,
                use: [ loader: 'file-loader?name=assets/[name].[hash].[ext]' ]
            
        ],
    exprContextCritical: false
    
;

webpack.config.dev.js:

var path = require('path');

var webpackMerge = require('webpack-merge');
var commonConfig = require('./webpack.config.common.js');

module.exports = webpackMerge(commonConfig, 
    devtool: 'cheap-module-eval-source-map',

    output: 
        path: path.resolve(__dirname + '/public/js/app'),
        publicPath: "/js/app/",
        filename: 'bundle.js',
        chunkFilename: '[id].chunk.js'
    ,
    module: 
        rules: [
            
                test: /\.ts$/,
                use: [
                    loader: 'awesome-typescript-loader', options: 
                        transpileOnly: true
                    ,
                    loader: 'angular2-template-loader',
                    loader: 'angular-router-loader'
                ]
            
        ]

    
);

webpack.config.prod.js:

const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;

var path = require('path');

var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var commonConfig = require('./webpack.config.common.js');

module.exports = webpackMerge.smart(commonConfig, 
    entry: 
        'app': './assets/app/main.aot.ts'
    ,

    output: 
        path: path.join(__dirname + '/public/js/app'),
        filename: 'bundle.js',
        publicPath: '/js/app/',
        chunkFilename: '[id].[hash].chunk.js'
    ,

    module: 
        rules: [
            
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                loader: '@ngtools/webpack'
            ,
            
                test: /\.ts$/,
                use: [
                    'awesome-typescript-loader',
                    'angular2-template-loader',
                    'angular-router-loader?aot=true'
                ]
            
        ]
    ,

    plugins: [
        new webpack.optimize.UglifyJsPlugin(
            sourceMap: false
        ),
        new AngularCompilerPlugin(
            tsConfigPath: './tsconfig.json',
            entryModule: './assets/app/app.module#AppModule',
            sourceMap: true
        )
    ]
);

还有来自 package.json 的构建脚本:

"scripts": 
    "start": "node ./bin/www",
    "build": "del-cli public/js/app && webpack --config webpack.config.dev.js --progress --profile --watch",
    "build:prod": "del-cli public/js/app && ngc -p tsconfig.aot.json && ngc -p tsconfig.aot.json && webpack --config webpack.config.prod.js --progress --profile --bail && del-cli 'public/js/app/**/*.js' 'public/js/app/**/*.js.map' '!public/js/app/bundle.js' '!public/js/app/*.chunk.js' 'assets/app/**/*.*.ngfactory.ts' 'assets/app/**/*.shim.ts' 'assets/app/**/*.ngsummary.json' 'assets/app/**/*.ngstyle.ts'",
  ,

我知道使用 sass 设置解决方案可能会从完全不同的结构中受益匪浅。例如,我使用了不使用“styleUrls”角度标签的解决方案,因为没有为此设置 sass。但只为整个站点生成了一个大的 css 文件。我想这是这个问题的“记住”,但主要问题是:

如何从使用 css 文件迁移到使用 webpack 的 sass 文件? (我使用的是 webpack 3.x)

【问题讨论】:

我不熟悉 angular,但我可以说你的 scss/css 的 webpack 配置没问题,你只需要 extract-text-webpack-plugin 将你的 css 从你的包中提取到真正的 css 文件。我从您的问题中遗漏了其他内容,但我认为它与 angular 的关系比 webpack 更重要 理想情况下,我实际上想摆脱使用角度样式声明。它很有用,但我更喜欢将 sass 设置与 Angular 组件分开。 Angular 样式声明用于将 css 隔离到特定组件 - 我认为这对于 css 文件很聪明。 sass 可以为项目带来的使用,可以从 sass 代码与 Angular 代码完全分离中受益匪浅。我很欣赏这个提示,并将尽快使用该插件进行测试。 【参考方案1】:

你的 webpack 配置没问题。

您始终可以混合使用全局 scss 和组件 scss,正如您所说的 Angular 样式声明隔离每个组件的 css(或 scss),这是您想要的功能。

但如果你还想拥有全局样式,你可以这样做:

在 /src/styles/ 文件夹中创建一个 styles.scss

从你的app.module.ts(你项目的根模块),像这样导入scss文件(显然选择正确的路径):

import '../styles/styles.scss';

现在您可以使用 styles.scss 导入其他将全局应用于您的项目的 scss(或 css)文件。

作为一个例子,这是我在我的项目中的 styles.scss:

@import '_bootstrap_settings.scss';
@import "~bootstrap/scss/bootstrap";
@import '~c3/c3';

// Angular Material Theme
@import "~@angular/material/prebuilt-themes/indigo-pink";

@import 'variables';

【讨论】:

以上是关于Angular Webpack 设置:使用 webpack 从 css 迁移到 sass的主要内容,如果未能解决你的问题,请参考以下文章

如何强制 CSS url 尊重 webpack 的 publicPath 设置?

Angular 8:Webpack - 三个.js 加载两次

Webpack - 在 Angular 2 中调用外部 JS

Angular2 webpack:如何导入引导 css

在 Angular2 和 Webpack 中使用 CDN 文件

使用 Angular 13 for Electron 应用程序时如何升级 webpack 5?