@jsxc/jsxc
Version:
Real-time XMPP chat application with video calls, file transfer and encrypted communication
267 lines (242 loc) • 7.49 kB
JavaScript
/* jshint node:true */
const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const packageJson = require('./package.json');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const GitRevisionPlugin = new(require('git-revision-webpack-plugin'))();
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const TerserPlugin = require('terser-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
let supportedLangs = fs.readdirSync('./locales/').filter(filename => {
if (!/\.json$/.test(filename)) {
return false;
}
let file = require(`./locales/${filename}`);
for (let key in file.translation) {
if (typeof file.translation[key] === 'string') {
return true;
}
}
return false;
}).map(filename => filename.replace(/\.json$/, ''));
const MOMENTJS_LOCALES = supportedLangs.map(lang => lang.replace(/-.+/, ''));
const JS_BUNDLE_NAME = 'jsxc.bundle.js';
const dependencies = Object.keys(packageJson.dependencies).map(function (name) {
let package = require('./node_modules/' + name + '/package.json');
return `${package.name}@${package.version} (${package.license})`;
});
let version = packageJson.version.replace(/-.+$/, '') + '-git.' + GitRevisionPlugin.version();
let buildDate = (new Date()).toDateString();
let definePluginConfig = {
__BUILD_DATE__: JSON.stringify(buildDate),
__BUNDLE_NAME__: JSON.stringify(JS_BUNDLE_NAME),
__DEPENDENCIES__: JSON.stringify(dependencies.join(', ')),
__LANGS__: JSON.stringify(supportedLangs),
};
const fileLoader = {
loader: 'file-loader',
options: {
name: '[path][name]-[sha1:hash:hex:8].[ext]',
outputPath: 'assets/'
}
};
const OUTPUT_PATH = path.resolve(__dirname, './dist/');
let config = {
entry: ['./scss/main.scss', './src/index.ts'],
output: {
filename: JS_BUNDLE_NAME,
chunkFilename: "[name].chunk.js",
path: OUTPUT_PATH,
publicPath: 'dist/',
libraryTarget: 'var',
library: 'JSXC',
clean: true,
},
optimization: {
splitChunks: {
minSize: 10,
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
},
},
performance: {
maxEntrypointSize: 1024 * 1000 * 1000 * 3,
maxAssetSize: 1024 * 1000 * 1000 * 3,
},
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
include: [path.resolve(__dirname, 'src'), path.resolve(__dirname, 'test')],
options: {
// transpileOnly: true,
},
},
{
test: /\.hbs$/,
loader: 'handlebars-loader',
include: path.resolve(__dirname, 'template'),
options: {
helperDirs: [
path.resolve(__dirname, 'template', 'helpers')
],
partialDirs: [
path.resolve(__dirname, 'template', 'partials')
]
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader?importLoaders=1',
],
},
{
test: /\.(sass|scss)$/,
include: path.resolve(__dirname, 'scss'),
use: [
MiniCssExtractPlugin.loader, {
loader: 'css-loader',
options: {
url: false
}
},
'sass-loader'
]
},
{
test: /.*\.(png|jpg|gif|mp3|wav|svg)$/,
use: [fileLoader]
},
{
test: /.*\.(js)$/,
resourceQuery: /path/,
use: [fileLoader]
}
]
},
resolve: {
extensions: [".ts", ".js", ".hbs", ".json"],
alias: {
'@connection': path.resolve(__dirname, 'src/connection/'),
'@ui': path.resolve(__dirname, 'src/ui/'),
'@util': path.resolve(__dirname, 'src/util/'),
'@vendor': path.resolve(__dirname, 'src/vendor/'),
'@src': path.resolve(__dirname, 'src/'),
},
fallback: {
fs: false,
stream: false,
path: false,
crypto: false,
process: false,
}
},
externals: {
'child_process': 'child_process',
'webworker-threads': 'webworker-threads'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
process: 'process/browser',
}),
new MiniCssExtractPlugin({
filename: 'styles/jsxc.bundle.css',
}),
new CopyWebpackPlugin({
patterns: [{
from: 'images/',
to: 'images/'
}, {
from: 'fonts/',
to: 'fonts/'
}, {
from: 'node_modules/emojione/assets/svg/',
to: 'images/emojione/'
}, {
from: 'LICENSE',
to: 'LICENSE',
toType: 'file',
}],
}),
new webpack.LoaderOptionsPlugin({
options: {
handlebarsLoader: {}
}
}),
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, new RegExp(MOMENTJS_LOCALES.join('|'))),
new ForkTsCheckerWebpackPlugin(),
],
devServer: {
// https://github.com/webpack/webpack-dev-server/issues/2484
injectClient: false,
port: 8091,
inline: true,
publicPath: '/dist/',
open: true,
openPage: 'example/index.html',
proxy: {
"/http-bind": "http://localhost:5280",
"/libsignal": "http://localhost",
"/xmpp-websocket": "ws://localhost:5280"
},
watchOptions: {
aggregateTimeout: 1300,
ignored: [
path.resolve(__dirname, 'dist'),
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, '.git'),
path.resolve(__dirname, 'test'),
'**/*.swp',
]
}
},
};
module.exports = (env, argv) => {
if (typeof argv.mode === 'string') {
config.mode = argv.mode;
}
if (config.mode === 'development') {
config.devtool = 'eval-source-map';
} else {
config.optimization.minimizer = [
new TerserPlugin({
terserOptions: {
keep_fnames: /Session$/,
},
}),
];
}
if (argv.release || process.env.BUILD === 'release') {
version = packageJson.version;
}
if (argv.bundleAnalyzer) {
config.plugins.push(new BundleAnalyzerPlugin());
}
definePluginConfig['__VERSION__'] = JSON.stringify(version);
// prep for Webpack 5
// definePluginConfig['process'] = JSON.stringify({});
// definePluginConfig['process.env.NODE_DEBUG'] = JSON.stringify(process.env.NODE_DEBUG || false);
config.plugins.push(new webpack.DefinePlugin(definePluginConfig));
config.plugins.push(new webpack.BannerPlugin({
banner: `JavaScript XMPP Client - the open chat
Version: ${version}
Build date: ${buildDate}
${packageJson.homepage}
JSXC is released under the MIT license, but this file also contains
dependencies which are released under a different license.`
}));
return config;
};