mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	CSS: Move portico styles to webpack compilation.
static/styles/scss/portico.scss is now compiled by webpack and supports SCSS syntax. Changed the server-side templates to render the portico-styles bundle instead of directly requiring the portico stylesheet. This allows webpack to handle stylesheet compilation and minification. We use the mini-css-extract-plugin to extract out css from the includes in webpack and let webpacks production mode handle minification. Currently we're not able to use it for dev mode because it does not support HMR so we use style-loader instead. Once the plugin supports HMR we can go on to use it for both dev and prod. The downside of this is that when reloading pages in the development environment, there's an annoying flash of unstyled content :(. It is now possible to make a change in any of the styles included by static/styles/scss/portico.scss and see the code reload live in the browser. This is because style-loader which we currently use has the module.accept code built-in.
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							f20671a509
						
					
				
				
					commit
					93ac40105f
				
			
							
								
								
									
										8
									
								
								static/styles/scss/portico.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								static/styles/scss/portico.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					@import "../../third/zocial/zocial.css";
 | 
				
			||||||
 | 
					@import "../components.css";
 | 
				
			||||||
 | 
					@import "../portico.css";
 | 
				
			||||||
 | 
					@import "../portico-signin.css";
 | 
				
			||||||
 | 
					@import "../pygments.css";
 | 
				
			||||||
 | 
					@import "../../third/thirdparty-fonts.css";
 | 
				
			||||||
 | 
					@import "../../generated/icons/style.css";
 | 
				
			||||||
 | 
					@import "../fonts.css";
 | 
				
			||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block customhead %}
 | 
					{% block customhead %}
 | 
				
			||||||
{% stylesheet 'portico' %}
 | 
					{{ render_bundle('portico-styles') }}
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
#}
 | 
					#}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block porticocustomhead %}
 | 
					{% block porticocustomhead %}
 | 
				
			||||||
{% stylesheet 'portico' %}
 | 
					{{ render_bundle('portico-styles') }}
 | 
				
			||||||
{{ render_bundle('translations') }}
 | 
					{{ render_bundle('translations') }}
 | 
				
			||||||
{{ render_bundle('portico') }}
 | 
					{{ render_bundle('portico') }}
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
#}
 | 
					#}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block porticocustomhead %}
 | 
					{% block porticocustomhead %}
 | 
				
			||||||
{% stylesheet 'portico' %}
 | 
					{{ render_bundle('portico-styles') }}
 | 
				
			||||||
{{ render_bundle('translations') }}
 | 
					{{ render_bundle('translations') }}
 | 
				
			||||||
{{ render_bundle('portico') }}
 | 
					{{ render_bundle('portico') }}
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,9 +66,9 @@ echo; echo "Now testing that the newly installed server's homepage loads"; echo
 | 
				
			|||||||
wget https://localhost -O /tmp/index.html --no-check-certificate -S 2> /tmp/wget-output || true # || true so we see errors.log if this 500s
 | 
					wget https://localhost -O /tmp/index.html --no-check-certificate -S 2> /tmp/wget-output || true # || true so we see errors.log if this 500s
 | 
				
			||||||
grep -vi '\(Vary\|Content-Language\|expires\|issued by\|modified\|saved\|[.][.][.]\|Date\|[-][-]\)' /tmp/wget-output > /tmp/http-headers-processed
 | 
					grep -vi '\(Vary\|Content-Language\|expires\|issued by\|modified\|saved\|[.][.][.]\|Date\|[-][-]\)' /tmp/wget-output > /tmp/http-headers-processed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Simplify the diff by getting replacing 4-digit length numbers with <Length>.
 | 
					# Simplify the diff by getting replacing 4-5 digit length numbers with <Length>.
 | 
				
			||||||
sed -i 's|Length: [0-9][0-9][0-9][0-9]\( [(][0-9][.][0-9]K[)]\)\?|Length: <Length>|' /tmp/http-headers-processed
 | 
					sed -i 's|Length: [0-9]\+\( [(][0-9]\+[.][0-9]K[)]\)\?|Length: <Length>|' /tmp/http-headers-processed
 | 
				
			||||||
sed -i 's|Length: [0-9][0-9][0-9][0-9]\( [(][0-9][.][0-9]K[)]\)\?|Length: <Length>|' ~/success-http-headers.txt
 | 
					sed -i 's|Length: [0-9]\+\( [(][0-9]\+[.][0-9]K[)]\)\?|Length: <Length>|' ~/success-http-headers.txt
 | 
				
			||||||
if ! diff -ur /tmp/http-headers-processed ~/success-http-headers.txt; then
 | 
					if ! diff -ur /tmp/http-headers-processed ~/success-http-headers.txt; then
 | 
				
			||||||
    set +x
 | 
					    set +x
 | 
				
			||||||
    echo
 | 
					    echo
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,5 +31,6 @@
 | 
				
			|||||||
              "./node_modules/plotly.js/dist/plotly-basic.min.js"
 | 
					              "./node_modules/plotly.js/dist/plotly-basic.min.js"
 | 
				
			||||||
             ],
 | 
					             ],
 | 
				
			||||||
    "translations": "./static/js/translations.js",
 | 
					    "translations": "./static/js/translations.js",
 | 
				
			||||||
    "zxcvbn": "./node_modules/zxcvbn/dist/zxcvbn.js"
 | 
					    "zxcvbn": "./node_modules/zxcvbn/dist/zxcvbn.js",
 | 
				
			||||||
 | 
					    "portico-styles": "./static/styles/scss/portico.scss"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,27 @@
 | 
				
			|||||||
import { resolve } from 'path';
 | 
					import { resolve } from 'path';
 | 
				
			||||||
import * as BundleTracker from 'webpack-bundle-tracker';
 | 
					import * as BundleTracker from 'webpack-bundle-tracker';
 | 
				
			||||||
import * as webpack from 'webpack';
 | 
					import * as webpack from 'webpack';
 | 
				
			||||||
 | 
					const MiniCssExtractPlugin = require("mini-css-extract-plugin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const assets = require('./webpack.assets.json');
 | 
					const assets = require('./webpack.assets.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Currently we're using style-loader for local dev
 | 
				
			||||||
 | 
					// because MiniCssExtractPlugin doesn't support
 | 
				
			||||||
 | 
					// HMR as yet. When this changes we can switch
 | 
				
			||||||
 | 
					// over to MiniCssExtractPlugin which will Also
 | 
				
			||||||
 | 
					// solve the flash of unstsyled elements on page load.
 | 
				
			||||||
 | 
					// https://github.com/webpack-contrib/mini-css-extract-plugin/issues/34
 | 
				
			||||||
 | 
					function getCSSLoader(isProd: boolean) {
 | 
				
			||||||
 | 
					    if(isProd) {
 | 
				
			||||||
 | 
					        return MiniCssExtractPlugin.loader
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        loader: 'style-loader',
 | 
				
			||||||
 | 
					        options: {
 | 
				
			||||||
 | 
					            sourceMap: true
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
export default (env?: string) : webpack.Configuration => {
 | 
					export default (env?: string) : webpack.Configuration => {
 | 
				
			||||||
    const production: boolean = env === "production";
 | 
					    const production: boolean = env === "production";
 | 
				
			||||||
    let config: webpack.Configuration = {
 | 
					    let config: webpack.Configuration = {
 | 
				
			||||||
@@ -62,6 +80,49 @@ export default (env?: string) : webpack.Configuration => {
 | 
				
			|||||||
                        {loader: 'expose-loader', options: 'common'},
 | 
					                        {loader: 'expose-loader', options: 'common'},
 | 
				
			||||||
                    ],
 | 
					                    ],
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 | 
					                // regular css files
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    test: /\.css$/,
 | 
				
			||||||
 | 
					                    use: [
 | 
				
			||||||
 | 
					                        getCSSLoader(production),
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            loader: 'css-loader',
 | 
				
			||||||
 | 
					                            options: {
 | 
				
			||||||
 | 
					                                sourceMap: true
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                // sass / scss loader
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    test: /\.(sass|scss)$/,
 | 
				
			||||||
 | 
					                    use: [
 | 
				
			||||||
 | 
					                        getCSSLoader(production),
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            loader: 'css-loader',
 | 
				
			||||||
 | 
					                            options: {
 | 
				
			||||||
 | 
					                                sourceMap: true
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            loader: 'sass-loader',
 | 
				
			||||||
 | 
					                            options: {
 | 
				
			||||||
 | 
					                                sourceMap: true
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                // load fonts and files
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
 | 
				
			||||||
 | 
					                    use: [{
 | 
				
			||||||
 | 
					                        loader: 'file-loader',
 | 
				
			||||||
 | 
					                        options: {
 | 
				
			||||||
 | 
					                            name: '[name].[ext]',
 | 
				
			||||||
 | 
					                            outputPath: 'fonts/'
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }]
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        output: {
 | 
					        output: {
 | 
				
			||||||
@@ -69,7 +130,7 @@ export default (env?: string) : webpack.Configuration => {
 | 
				
			|||||||
            filename: production ? '[name]-[hash].js' : '[name].js',
 | 
					            filename: production ? '[name]-[hash].js' : '[name].js',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        resolve: {
 | 
					        resolve: {
 | 
				
			||||||
            extensions: [".tsx", ".ts", ".js", ".json"],
 | 
					            extensions: [".tsx", ".ts", ".js", ".json", ".scss", ".css"],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        // We prefer cheap-module-eval-source-map over eval because
 | 
					        // We prefer cheap-module-eval-source-map over eval because
 | 
				
			||||||
        // currently eval has trouble setting breakpoints per line
 | 
					        // currently eval has trouble setting breakpoints per line
 | 
				
			||||||
@@ -81,6 +142,11 @@ export default (env?: string) : webpack.Configuration => {
 | 
				
			|||||||
    if (production) {
 | 
					    if (production) {
 | 
				
			||||||
        config.plugins = [
 | 
					        config.plugins = [
 | 
				
			||||||
            new BundleTracker({filename: 'webpack-stats-production.json'}),
 | 
					            new BundleTracker({filename: 'webpack-stats-production.json'}),
 | 
				
			||||||
 | 
					            // Extract CSS from files
 | 
				
			||||||
 | 
					            new MiniCssExtractPlugin({
 | 
				
			||||||
 | 
					                filename: "[name].[contenthash].css",
 | 
				
			||||||
 | 
					                chunkFilename: "[id].css"
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // Out JS debugging tools
 | 
					        // Out JS debugging tools
 | 
				
			||||||
@@ -93,6 +159,11 @@ export default (env?: string) : webpack.Configuration => {
 | 
				
			|||||||
            new webpack.NamedModulesPlugin(),
 | 
					            new webpack.NamedModulesPlugin(),
 | 
				
			||||||
            // script-loader should load sourceURL in dev
 | 
					            // script-loader should load sourceURL in dev
 | 
				
			||||||
            new webpack.LoaderOptionsPlugin({debug: true}),
 | 
					            new webpack.LoaderOptionsPlugin({debug: true}),
 | 
				
			||||||
 | 
					            // Extract CSS from files
 | 
				
			||||||
 | 
					            new MiniCssExtractPlugin({
 | 
				
			||||||
 | 
					                filename: "[name].css",
 | 
				
			||||||
 | 
					                chunkFilename: "[id].css"
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        config.devServer = {
 | 
					        config.devServer = {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -871,6 +871,12 @@ PIPELINE = {
 | 
				
			|||||||
            'source_filenames': ('styles/stats.css',),
 | 
					            'source_filenames': ('styles/stats.css',),
 | 
				
			||||||
            'output_filename': 'min/stats.css'
 | 
					            'output_filename': 'min/stats.css'
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        # Although this is being handled by webpack already it seems
 | 
				
			||||||
 | 
					        # portico.css would still need to be generated for 5xx.html
 | 
				
			||||||
 | 
					        # (the error page for when Django is down) which can't be
 | 
				
			||||||
 | 
					        # rendered as a template.  This block could be removed after
 | 
				
			||||||
 | 
					        # we add another way for that template. to find `portico.css`.
 | 
				
			||||||
 | 
					        # (Or maybe use premailer to generate it?)
 | 
				
			||||||
        'portico': {
 | 
					        'portico': {
 | 
				
			||||||
            'source_filenames': (
 | 
					            'source_filenames': (
 | 
				
			||||||
                'third/zocial/zocial.css',
 | 
					                'third/zocial/zocial.css',
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user