Initial commit
This commit is contained in:
347
webpack.config.js
Normal file
347
webpack.config.js
Normal file
@@ -0,0 +1,347 @@
|
||||
// Sshwifty - A Web SSH client
|
||||
//
|
||||
// Copyright (C) 2019 Rui NI <nirui@gmx.com>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const webpack = require("webpack"),
|
||||
{ exec, spawn } = require("child_process"),
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
HtmlWebpackPlugin = require("html-webpack-plugin"),
|
||||
MiniCssExtractPlugin = require("mini-css-extract-plugin"),
|
||||
OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"),
|
||||
VueLoaderPlugin = require("vue-loader/lib/plugin"),
|
||||
FaviconsWebpackPlugin = require("favicons-webpack-plugin"),
|
||||
ManifestPlugin = require("webpack-manifest-plugin"),
|
||||
CopyPlugin = require("copy-webpack-plugin"),
|
||||
TerserPlugin = require("terser-webpack-plugin"),
|
||||
{ CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||
|
||||
let appSpawnProc = null,
|
||||
appBuildProc = null;
|
||||
|
||||
const killAppSpawnProc = then => {
|
||||
if (appSpawnProc === null) {
|
||||
then();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
process.stdout.write("Shutdown application ...\n");
|
||||
|
||||
process.kill(-appSpawnProc.proc.pid, "SIGINT");
|
||||
|
||||
let forceKill = setTimeout(() => {
|
||||
process.kill(-appSpawnProc.proc.pid);
|
||||
}, 3000);
|
||||
|
||||
appSpawnProc.waiter.then(() => {
|
||||
clearTimeout(forceKill);
|
||||
|
||||
appSpawnProc = null;
|
||||
|
||||
then();
|
||||
});
|
||||
};
|
||||
|
||||
const startAppSpawnProc = onExit => {
|
||||
killAppSpawnProc(() => {
|
||||
let mEnv = {};
|
||||
|
||||
for (let i in process.env) {
|
||||
mEnv[i] = process.env[i];
|
||||
}
|
||||
|
||||
mEnv["SSHWIFTY_CONFIG"] = path.join(
|
||||
__dirname,
|
||||
"sshwifty.conf.example.json"
|
||||
);
|
||||
|
||||
mEnv["SSHWIFTY_DEBUG"] = "_";
|
||||
|
||||
process.stdout.write("Starting application ...\n");
|
||||
|
||||
let proc = spawn("go", ["run", "sshwifty.go"], {
|
||||
env: mEnv,
|
||||
detached: true
|
||||
}),
|
||||
waiter = new Promise(resolve => {
|
||||
let closed = false;
|
||||
|
||||
proc.stdout.on("data", msg => {
|
||||
process.stdout.write(msg.toString());
|
||||
});
|
||||
|
||||
proc.stderr.on("data", msg => {
|
||||
process.stderr.write(msg.toString());
|
||||
});
|
||||
|
||||
proc.on("exit", n => {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
closed = true;
|
||||
|
||||
onExit();
|
||||
resolve(n);
|
||||
});
|
||||
});
|
||||
|
||||
appSpawnProc = {
|
||||
proc,
|
||||
waiter
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const killAllProc = () => {
|
||||
if (appBuildProc !== null) {
|
||||
appBuildProc.stdin.end();
|
||||
appBuildProc.stdout.destroy();
|
||||
appBuildProc.stderr.destroy();
|
||||
appBuildProc.kill();
|
||||
|
||||
appBuildProc = null;
|
||||
}
|
||||
|
||||
killAppSpawnProc(() => {
|
||||
process.exit(0);
|
||||
});
|
||||
};
|
||||
|
||||
process.on("SIGTERM", killAllProc);
|
||||
process.on("SIGINT", killAllProc);
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: path.join(__dirname, "ui", "app.js")
|
||||
},
|
||||
devtool:
|
||||
process.env.NODE_ENV === "development" ? "inline-source-map" : "source-map",
|
||||
output: {
|
||||
publicPath: "/assets/",
|
||||
path: path.join(__dirname, ".tmp", "dist"),
|
||||
filename: "[hash]d.js"
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
vue$: "vue/dist/vue.esm.js"
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
minimizer:
|
||||
process.env.NODE_ENV === "development"
|
||||
? []
|
||||
: [
|
||||
new TerserPlugin({
|
||||
test: /\.js$/,
|
||||
terserOptions: {
|
||||
ecma: undefined,
|
||||
warnings: false,
|
||||
parse: {},
|
||||
compress: {},
|
||||
mangle: true,
|
||||
module: false,
|
||||
output: {
|
||||
beautify: false,
|
||||
comments: false
|
||||
},
|
||||
toplevel: false,
|
||||
nameCache: null,
|
||||
ie8: false,
|
||||
keep_classnames: false,
|
||||
keep_fnames: false,
|
||||
safari10: false
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ["vue-style-loader", MiniCssExtractPlugin.loader, "css-loader"]
|
||||
},
|
||||
{
|
||||
test: /\.html/,
|
||||
use: ["html-loader"]
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: "vue-loader"
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: "file-loader"
|
||||
},
|
||||
{
|
||||
test: /\.(gif|png|jpe?g|svg)$/i,
|
||||
use: [
|
||||
"file-loader",
|
||||
{
|
||||
loader: "image-webpack-loader",
|
||||
options: {
|
||||
bypassOnDebug: true,
|
||||
disable: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules)/,
|
||||
use: "babel-loader"
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.ProgressPlugin(),
|
||||
new webpack.SourceMapDevToolPlugin(),
|
||||
new webpack.DefinePlugin(
|
||||
process.env.NODE_ENV === "production"
|
||||
? {
|
||||
"process.env": {
|
||||
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
|
||||
}
|
||||
}
|
||||
: {}
|
||||
),
|
||||
new webpack.LoaderOptionsPlugin({
|
||||
options: {
|
||||
handlebarsLoader: {}
|
||||
}
|
||||
}),
|
||||
new CleanWebpackPlugin(),
|
||||
new CopyPlugin([
|
||||
{
|
||||
from: path.join(__dirname, "ui", "robots.txt"),
|
||||
to: path.join(__dirname, ".tmp", "dist")
|
||||
},
|
||||
{
|
||||
from: path.join(__dirname, "README.md"),
|
||||
to: path.join(__dirname, ".tmp", "dist")
|
||||
},
|
||||
{
|
||||
from: path.join(__dirname, "DEPENDENCES.md"),
|
||||
to: path.join(__dirname, ".tmp", "dist")
|
||||
},
|
||||
{
|
||||
from: path.join(__dirname, "LICENSE.md"),
|
||||
to: path.join(__dirname, ".tmp", "dist")
|
||||
}
|
||||
]),
|
||||
new VueLoaderPlugin(),
|
||||
{
|
||||
apply: compiler => {
|
||||
compiler.hooks.afterEmit.tap("AfterEmitPlugin", () => {
|
||||
if (appBuildProc !== null) {
|
||||
process.stdout.write(
|
||||
"Killing the previous source code generater ...\n"
|
||||
);
|
||||
|
||||
appBuildProc.stdin.end();
|
||||
appBuildProc.stdout.destroy();
|
||||
appBuildProc.stderr.destroy();
|
||||
appBuildProc.kill();
|
||||
|
||||
appBuildProc = null;
|
||||
}
|
||||
|
||||
killAppSpawnProc(() => {
|
||||
process.stdout.write("Generating source code ...\n");
|
||||
|
||||
appBuildProc = exec(
|
||||
"NODE_ENV=" + process.env.NODE_ENV + " go generate ./...",
|
||||
(err, stdout, stderr) => {
|
||||
process.stdout.write("Source code is generated ...\n");
|
||||
|
||||
appBuildProc = null;
|
||||
|
||||
if (stdout) process.stdout.write(stdout);
|
||||
if (stderr) process.stderr.write(stderr);
|
||||
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return;
|
||||
}
|
||||
|
||||
startAppSpawnProc(() => {
|
||||
appSpawnProc = null;
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
new FaviconsWebpackPlugin({
|
||||
logo: path.join(__dirname, "ui", "sshwifty.png"),
|
||||
prefix: "[hash]-",
|
||||
emitStats: false,
|
||||
persistentCache: false,
|
||||
title: "Sswifty"
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
inject: false,
|
||||
template: require("html-webpack-template"),
|
||||
bodyHtmlSnippet: fs.readFileSync(
|
||||
path.join(__dirname, "ui", "body.html"),
|
||||
"utf8"
|
||||
),
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content: "Connect to a SSH Server from your web browser"
|
||||
},
|
||||
{
|
||||
name: "theme-color",
|
||||
content: "#333333"
|
||||
}
|
||||
],
|
||||
mobile: true,
|
||||
lang: "en-US",
|
||||
inlineManifestWebpackName: "webpackManifest",
|
||||
title: "Sshwifty Web SSH Client",
|
||||
minify: {
|
||||
html5: true,
|
||||
collapseWhitespace:
|
||||
process.env.NODE_ENV === "development" ? false : true,
|
||||
caseSensitive: true,
|
||||
removeComments: true,
|
||||
removeEmptyElements: false
|
||||
}
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: "[hash]d.css",
|
||||
chunkFilename: "[chunkhash]d.css"
|
||||
}),
|
||||
new OptimizeCssAssetsPlugin({
|
||||
assetNameRegExp: /\.dist\.css$/g,
|
||||
cssProcessor: require("cssnano"),
|
||||
cssProcessorPluginOptions: {
|
||||
preset: ["default", { discardComments: { removeAll: true } }]
|
||||
},
|
||||
canPrint: true
|
||||
}),
|
||||
new webpack.BannerPlugin({
|
||||
banner:
|
||||
"This file is a part of Sshwifty Project. Automatically " +
|
||||
"generated at " +
|
||||
new Date().toTimeString() +
|
||||
", DO NOT MODIFIY"
|
||||
}),
|
||||
new ManifestPlugin()
|
||||
]
|
||||
};
|
||||
Reference in New Issue
Block a user