JHipster-如何使用angular 7直接编译SCSS文件

时间:2019-02-14 06:15:34

标签: jhipster angular7

通常,将SCSS样式添加到具有角形组件的组件中确实很容易(只需创建scss文件并将其导入component.ts中),但是此样式不会渲染到普通的CSS文件中,而是嵌入样式(从我的理解是,我对angular非常陌生。

这产生了一个问题,我正在尝试将theme with some dinamic skins与“ 自定义面板”一起使用,但是该组件需要独立地到达我编译的css的路径。

要实现此目的,我可以在供应商基本应用中看到他们将其添加到了angular.js

{
  ...
  "projects": {
    "angular-starter": {
      ...,
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angular-starter",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss",

              { "input": "src/vendor/styles/appwork.scss", "bundleName": "vendor/styles/appwork", "lazy": true },
              { "input": "src/vendor/styles/appwork-material.scss", "bundleName": "vendor/styles/appwork-material", "lazy": true },
              { "input": "src/vendor/styles/bootstrap.scss", "bundleName": "vendor/styles/bootstrap", "lazy": true },
              { "input": "src/vendor/styles/bootstrap-material.scss", "bundleName": "vendor/styles/bootstrap-material", "lazy": true },
              // More styles like this
            ],
            ...

然后可以直接将其作为css文件引用,如索引所示:

<html lang="en" class="default-style">
  <head>
    ...
    <!-- Here it references the compiled scss as css directly -->
    <link rel="stylesheet" href="vendor/styles/bootstrap.css" class="theme-settings-bootstrap-css">
    <link rel="stylesheet" href="vendor/styles/appwork.css" class="theme-settings-appwork-css">
    <link rel="stylesheet" href="vendor/styles/theme-corporate.css" class="theme-settings-theme-css">
    <link rel="stylesheet" href="vendor/styles/colors.css" class="theme-settings-colors-css">
    <link rel="stylesheet" href="vendor/styles/uikit.css">

    ...
    <script>
      // Here uses the path of the compiled css as parameter,
      // this way the skin selector changes the css used in the page
      window.themeSettings = new ThemeSettings({
        cssPath: 'vendor/styles/',
        themesPath: 'vendor/styles/'
      });
    </script>

  </head>
  ...
</html>

但是

检查从jhipster生成的angular.js,我可以看到Architect部分为空:

{
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
        "consuldent": {
            "root": "",
            "sourceRoot": "src/main/webapp",
            "projectType": "application",
            "architect": {}
        }
    },

我不知道这是否是因为在示例代码中它使用ng serve来运行演示页面,并使用node.js服务器(jhipster直接使用spring),我尝试将样式部分添加到jhipster的angular.js文件,但是我找不到可以加载css的任何路由,所以我想它只是忽略了我添加的代码

2 个答案:

答案 0 :(得分:2)

以角度显示,视图封装有每个唯一属性。

在主要组件中添加encapsulation: ViewEncapsulation.None,因此css将被所有组件共享

import { Component, ViewEncapsulation } from '@angular/core';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
  name = 'Angular app';
}

Jhipster使用webpack打包角度模块。您想捆绑 css 将您的CSS复制到 /src/main/webapp/vendor/styles/appwork.css ” 在webpack.common.js

中添加一个条目
new CopyWebpackPlugin([
    { from: './node_modules/swagger-ui/dist/css', to: 'swagger-ui/dist/css' },
    { from: './node_modules/swagger-ui/dist/lib', to: 'swagger-ui/dist/lib' },
    { from: './node_modules/swagger-ui/dist/swagger-ui.min.js', to: 'swagger-ui/dist/swagger-ui.min.js' },
    { from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' },
    { from: './src/main/webapp/content/', to: 'content' },        
    { from: './src/main/webapp/vendor/styles/appwork.css', to: 'content/vendor/styles/appwork.css' },    
    { from: './src/main/webapp/favicon.ico', to: 'favicon.ico' },
    { from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp' },
    // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
    { from: './src/main/webapp/robots.txt', to: 'robots.txt' }
]),

要编译自定义sass

webpack.prod.js 中添加条目,例如 myfile myfile2 。然后更改sass编译器以包含我们的myfile.scss,myfile2.scss,最后注释MiniCssExtractPlugin

    entry: {
    polyfills: './src/main/webapp/app/polyfills',
    global: './src/main/webapp/content/scss/global.scss',
    myfile: './src/main/webapp/content/scss/myfile.scss',
    myfile2: './src/main/webapp/content/scss/myfile2.scss',
    main: './src/main/webapp/app/app.main'
  },
 .
 .
 .
 .
  exclude: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/
 .
 .
 .
 .
 test: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/ 
 .
 .
 .
 .
 exclude: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/
 .
 .
 .
 .
 test: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/,
 .
 .
 .
 .
     new MiniCssExtractPlugin({
        // Options similar to the same options in webpackOptions.output
        // both options are optional
       // filename: '[name].[contenthash].css',
        // chunkFilename: '[id].css'
    }),

您的webpack.prod.js文件如下

    const webpack = require('webpack');
    const webpackMerge = require('webpack-merge');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
    const Visualizer = require('webpack-visualizer-plugin');
    const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
    const TerserPlugin = require('terser-webpack-plugin');
    const WorkboxPlugin = require('workbox-webpack-plugin');
    const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
    const path = require('path');

    const utils = require('./utils.js');
    const commonConfig = require('./webpack.common.js');

    const ENV = 'production';
    const sass = require('sass');

    module.exports = webpackMerge(commonConfig({ env: ENV }), {
        // Enable source maps. Please note that this will slow down the build.
        // You have to enable it in UglifyJSPlugin config below and in tsconfig-aot.json as well
        // devtool: 'source-map',
        entry: {
            polyfills: './src/main/webapp/app/polyfills',
            global: './src/main/webapp/content/scss/global.scss',
            myfile: './src/main/webapp/content/scss/myfile.scss',
            myfile2: './src/main/webapp/content/scss/myfile2.scss',
            main: './src/main/webapp/app/app.main'
        },
        output: {
            path: utils.root('build/www'),
            filename: 'app/[name].[hash].bundle.js',
            chunkFilename: 'app/[id].[hash].chunk.js'
        },
        module: {
            rules: [{
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                loader: '@ngtools/webpack'
            },
            {
                test: /\.scss$/,
                use: ['to-string-loader', 'css-loader', {
                    loader: 'sass-loader',
                    options: { implementation: sass }
                }],
                exclude: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/
            },
            {
                test: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    {
                        loader: 'sass-loader',
                        options: { implementation: sass }
                    }
                ]
            },
            {
                test: /\.css$/,
                use: ['to-string-loader', 'css-loader'],
                exclude: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/
            },
            {
                test: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            }]
        },
        optimization: {
            runtimeChunk: false,
            splitChunks: {
                cacheGroups: {
                    commons: {
                        test: /[\\/]node_modules[\\/]/,
                        name: 'vendors',
                        chunks: 'all'
                    }
                }
            },
            minimizer: [
                new TerserPlugin({
                    parallel: true,
                    cache: true,
                    terserOptions: {
                        ie8: false,
                        // sourceMap: true, // Enable source maps. Please note that this will slow down the build
                        compress: {
                            dead_code: true,
                            warnings: false,
                            properties: true,
                            drop_debugger: true,
                            conditionals: true,
                            booleans: true,
                            loops: true,
                            unused: true,
                            toplevel: true,
                            if_return: true,
                            inline: true,
                            join_vars: true
                        },
                        output: {
                            comments: false,
                            beautify: false,
                            indent_level: 2
                        }
                    }
                }),
                new OptimizeCSSAssetsPlugin({})
            ]
        },
        plugins: [
             new MiniCssExtractPlugin({
                 // Options similar to the same options in webpackOptions.output
                 // both options are optional
                // filename: '[name].[contenthash].css',
                 // chunkFilename: '[id].css'
             }),
            new MomentLocalesPlugin({
                localesToKeep: [
                        'en',
                        'es'
                        // jhipster-needle-i18n-language-moment-webpack - JHipster will add/remove languages in this array
                    ]
            }),
            new Visualizer({
                // Webpack statistics in target folder
                filename: '../stats.html'
            }),
            new AngularCompilerPlugin({
                mainPath: utils.root('src/main/webapp/app/app.main.ts'),
                tsConfigPath: utils.root('tsconfig-aot.json'),
                sourceMap: true
            }),
            new webpack.LoaderOptionsPlugin({
                minimize: true,
                debug: false
            }),
            new WorkboxPlugin.GenerateSW({
              clientsClaim: true,
              skipWaiting: true,
            })
        ],
        mode: 'production'
    });

类似地对 webpack.dev.js

执行相同的步骤
const webpack = require('webpack');
const writeFilePlugin = require('write-file-webpack-plugin');
const webpackMerge = require('webpack-merge');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const SimpleProgressWebpackPlugin = require('simple-progress-webpack-plugin');
const WebpackNotifierPlugin = require('webpack-notifier');
const path = require('path');
const sass = require('sass');

const utils = require('./utils.js');
const commonConfig = require('./webpack.common.js');

const ENV = 'development';

module.exports = (options) => webpackMerge(commonConfig({ env: ENV }), {
    devtool: 'eval-source-map',
    devServer: {
        contentBase: './build/www',
        proxy: [{
            context: [
                /* jhipster-needle-add-entity-to-webpack - JHipster will add entity api paths here */
                '/api',
                '/management',
                '/swagger-resources',
                '/v2/api-docs',
                '/h2-console',
                '/auth'
            ],
            target: `http${options.tls ? 's' : ''}://127.0.0.1:8080`,
            secure: false,
            changeOrigin: options.tls,
            headers: { host: 'localhost:9000' }
        }],
        stats: options.stats,
        watchOptions: {
            ignored: /node_modules/
        }
    },
    entry: {
        polyfills: './src/main/webapp/app/polyfills',
        global: './src/main/webapp/content/scss/global.scss',
        myfile: './src/main/webapp/content/scss/myfile.scss',
        myfile2: './src/main/webapp/content/scss/myfile2.scss',
        main: './src/main/webapp/app/app.main'
    },
    output: {
        path: utils.root('build/www'),
        filename: 'app/[name].bundle.js',
        chunkFilename: 'app/[id].chunk.js'
    },
    module: {
        rules: [{
            test: /\.ts$/,
            enforce: 'pre',
            loader: 'tslint-loader',
            exclude: [/(node_modules)/, new RegExp('reflect-metadata\\' + path.sep + 'Reflect\\.ts')]
        },
        {
            test: /\.ts$/,
            use: [
                'angular2-template-loader',
                {
                    loader: 'cache-loader',
                    options: {
                      cacheDirectory: path.resolve('build/cache-loader')
                    }
                },
                {
                    loader: 'thread-loader',
                    options: {
                        // there should be 1 cpu for the fork-ts-checker-webpack-plugin
                        workers: require('os').cpus().length - 1
                    }
                },
                {
                    loader: 'ts-loader',
                    options: {
                        transpileOnly: true,
                        happyPackMode: true
                    }
                },
                'angular-router-loader'
            ],
            exclude: /(node_modules)/
        },
        {
            test: /\.scss$/,
            use: ['to-string-loader', 'css-loader', {
                loader: 'sass-loader',
                options: { implementation: sass }
            }],
            exclude: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/
        },
        {
            test: /(vendor\.scss|global\.scss|myfile\.scss|myfile2\.scss)/,
            use: ['style-loader', 'css-loader', 'postcss-loader', {
                loader: 'sass-loader',
                options: { implementation: sass }
            }]
        },
        {
            test: /\.css$/,
            use: ['to-string-loader', 'css-loader'],
            exclude: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/
        },
        {
            test: /(vendor\.css|global\.css|myfile\.css|myfile2\.css)/,
            use: ['style-loader', 'css-loader']
        }]
    },
    stats: process.env.JHI_DISABLE_WEBPACK_LOGS ? 'none' : options.stats,
    plugins: [
        process.env.JHI_DISABLE_WEBPACK_LOGS
            ? null
            : new SimpleProgressWebpackPlugin({
                format: options.stats === 'minimal' ? 'compact' : 'expanded'
              }),
        new FriendlyErrorsWebpackPlugin(),
        new ForkTsCheckerWebpackPlugin(),
        new BrowserSyncPlugin({
            host: 'localhost',
            port: 9000,
            proxy: {
                target: 'http://localhost:9060'
            },
            socket: {
                clients: {
                    heartbeatTimeout: 60000
                }
            }
        }, {
            reload: false
        }),
        new webpack.ContextReplacementPlugin(
            /angular(\\|\/)core(\\|\/)/,
            path.resolve(__dirname, './src/main/webapp')
        ),
        new writeFilePlugin(),
        new webpack.WatchIgnorePlugin([
            utils.root('src/test'),
        ]),
        new WebpackNotifierPlugin({
            title: 'JHipster',
            contentImage: path.join(__dirname, 'logo-jhipster.png')
        })
    ].filter(Boolean),
    mode: 'development'
});

然后,如果您希望将CSS包含在index.html中,请更改 webpack.common.js

new HtmlWebpackPlugin({
    template: './src/main/webapp/index.html',
    chunks: ['vendors', 'polyfills', 'main', 'global','myfile','myfile2'],
    chunksSortMode: 'manual',
    inject: 'body'
})

答案 1 :(得分:0)

将自定义样式添加到src / main / webapp / content / scss / global.scss