Files
zulip/tools/webpack.config.ts
Anders Kaseorg 6bca996e2e webpack: Chill. Out. When watching for changes.
Polling for changes every 100 milliseconds was burning enough CPU to
set mid-2015 MacBooks on fire.  Use the default inotify watching,
except on filesystems where that’s known not to work (nfs, vboxsf), in
which case polling once per second is more than enough for even the
fastest typers.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-08-16 11:05:21 -07:00

214 lines
8.4 KiB
TypeScript

import { resolve } from 'path';
import * as BundleTracker from 'webpack-bundle-tracker';
import * as webpack from 'webpack';
// The devServer member of webpack.Configuration is managed by the
// webpack-dev-server package. We are only importing the type here.
import * as _webpackDevServer from 'webpack-dev-server';
import { getExposeLoaders, cacheLoader } from './webpack-helpers';
import * as MiniCssExtractPlugin from 'mini-css-extract-plugin';
const assets = require('./webpack.assets.json');
export default (env?: string): webpack.Configuration[] => {
const production: boolean = env === "production";
const publicPath = production ? '/static/webpack-bundles/' : '/webpack/';
const config: webpack.Configuration = {
name: "frontend",
mode: production ? "production" : "development",
context: resolve(__dirname, "../"),
entry: assets,
module: {
rules: [
// Generate webfont
{
test: /\.font\.js$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'webfonts-loader',
options: {
fileName: production ? 'files/[fontname].[chunkhash].[ext]' : 'files/[fontname].[ext]',
publicPath,
},
},
],
},
// Transpile .js and .ts files with Babel
{
test: /\.(js|ts)$/,
include: resolve(__dirname, '../static/js'),
loader: 'babel-loader',
},
// 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.
{
// We dont want to match admin.js
test: /(\.min|min\.|zxcvbn)\.js/,
use: [cacheLoader, 'script-loader'],
},
// regular css files
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: !production,
},
},
cacheLoader,
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
// sass / scss loader
{
test: /\.(sass|scss)$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: !production,
},
},
cacheLoader,
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.hbs$/,
loader: 'handlebars-loader',
options: {
// Tell webpack not to explicitly require these.
knownHelpers: ['if', 'unless', 'each', 'with',
// The ones below are defined in static/js/templates.js
'plural', 'eq', 'and', 'or', 'not',
't', 'tr'],
preventIndent: true,
},
},
// load fonts and files
{
test: /\.(woff(2)?|ttf|eot|svg|otf|png)$/,
use: [{
loader: 'file-loader',
options: {
name: production ? '[name].[hash].[ext]' : '[name].[ext]',
outputPath: 'files/',
},
}],
},
],
},
output: {
path: resolve(__dirname, '../static/webpack-bundles'),
publicPath,
filename: production ? '[name].[chunkhash].js' : '[name].js',
},
resolve: {
extensions: [".ts", ".js"],
},
// We prefer cheap-module-source-map over any eval-** options
// because the eval-options currently don't support being
// source mapped in error stack traces
// We prefer it over eval since eval has trouble setting
// breakpoints in chrome.
devtool: production ? 'source-map' : 'cheap-module-source-map',
};
// Expose Global variables for third party libraries to webpack modules
// Use the unminified versions of jquery and underscore so that
// Good error messages show up in production and development in the source maps
var exposeOptions = [
{ path: "blueimp-md5/js/md5.js" },
{ path: "clipboard/dist/clipboard.js", name: "ClipboardJS" },
{ path: "xdate/src/xdate.js", name: "XDate" },
{ path: "simplebar/dist/simplebar.js"},
{ path: "../static/third/marked/lib/marked.js" },
{ path: "../static/generated/emoji/emoji_codes.js" },
{ path: "../static/generated/pygments_data.js" },
{ path: "../static/js/debug.js" },
{ path: "../static/js/blueslip.js" },
{ path: "../static/js/common.js" },
{ path: "jquery/dist/jquery.js", name: ['$', 'jQuery'] },
{ path: "underscore/underscore.js", name: '_' },
{ path: "handlebars/dist/cjs/handlebars.runtime.js", name: 'Handlebars' },
{ path: "to-markdown/dist/to-markdown.js", name: 'toMarkdown' },
{ path: "sortablejs/Sortable.js"},
{ path: "winchan/winchan.js", name: 'WinChan'},
];
config.module.rules.unshift(...getExposeLoaders(exposeOptions));
if (production) {
config.plugins = [
new BundleTracker({filename: 'webpack-stats-production.json'}),
// Extract CSS from files
new MiniCssExtractPlugin({
filename: (data) => {
// This is a special case in order to produce
// a static CSS file to be consumed by
// static/html/5xx.html
if (data.chunk.name === 'error-styles') {
return 'error-styles.css';
}
return '[name].[contenthash].css';
},
chunkFilename: "[chunkhash].css",
}),
];
} else {
// Out JS debugging tools
config.entry['common'].push('./static/js/debug.js'); // eslint-disable-line dot-notation
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: "[chunkhash].css",
}),
];
config.devServer = {
clientLogLevel: "error",
stats: "errors-only",
};
}
const serverConfig: webpack.Configuration = {
mode: production ? "production" : "development",
target: "node",
context: resolve(__dirname, "../"),
entry: {
"katex-cli": "shebang-loader!katex/cli",
},
output: {
path: resolve(__dirname, "../static/webpack-bundles"),
filename: "[name].js",
},
};
return [config, serverConfig];
};