mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
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.
179 lines
6.6 KiB
TypeScript
179 lines
6.6 KiB
TypeScript
import { resolve } from 'path';
|
|
import * as BundleTracker from 'webpack-bundle-tracker';
|
|
import * as webpack from 'webpack';
|
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
|
|
|
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 => {
|
|
const production: boolean = env === "production";
|
|
let config: webpack.Configuration = {
|
|
mode: production ? "production" : "development",
|
|
context: resolve(__dirname, "../"),
|
|
entry: assets,
|
|
module: {
|
|
rules: [
|
|
// Run the typescript compilier on .ts files before webpack
|
|
{
|
|
test: /\.tsx?$/,
|
|
loader: 'ts-loader',
|
|
options: {
|
|
configFile: require.resolve('../static/ts/tsconfig.json')
|
|
}
|
|
},
|
|
// Uses script-loader on minified files so we don't change global variables in them.
|
|
// Also has the effect of making processing these files fast
|
|
// Currently the source maps don't work with these so use unminified files
|
|
// if debugging is required.
|
|
{
|
|
test: /(min|zxcvbn)\.js/,
|
|
use: [ 'script-loader' ],
|
|
},
|
|
// Expose Global variables to webpack
|
|
// Use the unminified versions of jquery and underscore so that
|
|
// Good error messages show up in production and development in the source maps
|
|
{
|
|
test: require.resolve('../static/node_modules/jquery/dist/jquery.js'),
|
|
use: [
|
|
{loader: 'expose-loader', options: '$'},
|
|
{loader: 'expose-loader', options: 'jQuery'},
|
|
],
|
|
},
|
|
{
|
|
test: require.resolve('../node_modules/underscore/underscore.js'),
|
|
use: [
|
|
{loader: 'expose-loader', options: '_'},
|
|
],
|
|
},
|
|
{
|
|
test: require.resolve('../static/js/debug.js'),
|
|
use: [
|
|
{loader: 'expose-loader', options: 'debug'},
|
|
],
|
|
},
|
|
{
|
|
test: require.resolve('../static/js/blueslip.js'),
|
|
use: [
|
|
{loader: 'expose-loader', options: 'blueslip'},
|
|
],
|
|
},
|
|
{
|
|
test: require.resolve('../static/js/common.js'),
|
|
use: [
|
|
{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: {
|
|
path: resolve(__dirname, '../static/webpack-bundles'),
|
|
filename: production ? '[name]-[hash].js' : '[name].js',
|
|
},
|
|
resolve: {
|
|
extensions: [".tsx", ".ts", ".js", ".json", ".scss", ".css"],
|
|
},
|
|
// We prefer cheap-module-eval-source-map over eval because
|
|
// currently eval has trouble setting breakpoints per line
|
|
// in Google Chrome. There's almost no difference
|
|
// between the compilation time for the two and could be
|
|
// re-evaluated as the size of files grows
|
|
devtool: production ? 'source-map' : 'cheap-module-eval-source-map',
|
|
};
|
|
if (production) {
|
|
config.plugins = [
|
|
new BundleTracker({filename: 'webpack-stats-production.json'}),
|
|
// Extract CSS from files
|
|
new MiniCssExtractPlugin({
|
|
filename: "[name].[contenthash].css",
|
|
chunkFilename: "[id].css"
|
|
})
|
|
];
|
|
} else {
|
|
// Out JS debugging tools
|
|
config.entry['common'].push('./static/js/debug.js');
|
|
|
|
config.output.publicPath = '/webpack/';
|
|
config.plugins = [
|
|
new BundleTracker({filename: 'var/webpack-stats-dev.json'}),
|
|
// Better logging from console for hot reload
|
|
new webpack.NamedModulesPlugin(),
|
|
// script-loader should load sourceURL in dev
|
|
new webpack.LoaderOptionsPlugin({debug: true}),
|
|
// Extract CSS from files
|
|
new MiniCssExtractPlugin({
|
|
filename: "[name].css",
|
|
chunkFilename: "[id].css"
|
|
})
|
|
];
|
|
|
|
config.devServer = {
|
|
clientLogLevel: "error",
|
|
stats: "errors-only",
|
|
watchOptions: {
|
|
poll: 100
|
|
}
|
|
};
|
|
}
|
|
return config;
|
|
};
|