将自定义样式添加到src / main / webapp / content / scss / global.scss
通常,将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的任何路由,因此即时通讯猜测它只是忽略了我添加的代码
在角度图中,视图封装有每个唯一属性。
在主要组件中添加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,最后注释MiniCssExtractPluginentry: { 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' })
将自定义样式添加到src / main / webapp / content / scss / global.scss
将自定义样式添加到src / main / webapp / content / scss / global.scss