diff --git a/web/package.json b/web/package.json
index 80e4e5a..6b79154 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,10 +1,24 @@
{
+ "dependencies": {
+ "webpack": "^2.6.1"
+ },
"devDependencies": {
"jasmine-core": "^2.5.2",
"karma": "^1.5.0",
"karma-jasmine": "^1.1.0",
"karma-phantomjs-launcher": "^1.0.2",
"karma-requirejs": "^1.1.0",
- "requirejs": "^2.3.3"
+ "requirejs": "^2.3.3",
+ "grunt": "^1.0.1",
+ "css-loader": "^0.28.3",
+ "style-loader": "^0.18.1",
+ "extract-text-webpack-plugin": "^2.1.0",
+ "file-loader": "^0.11.1",
+ "image-webpack-loader": "^3.3.1",
+ "optimize-css-assets-webpack-plugin": "^1.3.2",
+ "clean-webpack-plugin": "^0.1.16"
+ },
+ "scripts": {
+ "build": "webpack --hide-modules"
}
}
diff --git a/web/pgadmin/templates/base.html b/web/pgadmin/templates/base.html
index 375b39d..3789b1a 100755
--- a/web/pgadmin/templates/base.html
+++ b/web/pgadmin/templates/base.html
@@ -18,6 +18,7 @@
+ {% if config.DEBUG %}
@@ -54,13 +55,20 @@
+ {% else %}
+
+ {% endif %}
{% for stylesheet in current_app.stylesheets %}
{% endfor %}
+ {% if config.DEBUG %}
+ {% else %}
+
+ {% endif %}
{% block css_link %}{% endblock %}
diff --git a/web/webpack.config.js b/web/webpack.config.js
new file mode 100644
index 0000000..01b1365
--- /dev/null
+++ b/web/webpack.config.js
@@ -0,0 +1,111 @@
+const path = require('path'),
+ grunt = require('grunt'),
+ cleanWebpackPlugin = require('clean-webpack-plugin'),
+ ExtractTextPlugin = require('extract-text-webpack-plugin'),
+ OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
+
+const baseDir = './pgadmin/static/',
+ vendorDir = baseDir + 'vendor/';
+
+let cssResources = [],
+ excludes = [
+ 'merge.css', 'dropzone.css', 'slick.headerbuttons.css',
+ 'slick.headermenu.css', 'semantic.css', 'default.css',
+ 'dialog.css', 'fullscreen.css', 'foldgutter.css',
+ 'show-hint.css', 'lint.css', 'merge.css', 'matchesonscrollbar.css',
+ 'tern.css', 'slick.columnpicker.css', 'slick.pager.css',
+ 'bootstrap-datetimepicker.min.css', 'bootstrap-theme.css'
+ ];
+
+// Path(s) that should be cleaned
+let pathsToClean = ['dist'];
+
+// Clean options to use
+let cleanOptions = {
+ root: path.resolve(__dirname, './pgadmin/static/'),
+ verbose: true,
+ dry: false
+};
+
+// extract vendor css files in cssResources
+grunt.file.expand({ cwd: vendorDir }, "**/*.css").forEach(function(page) {
+ file_name = path.basename(page).replace('.min', '').replace('.rtl', '');
+ if (excludes.indexOf(file_name) === -1) {
+ excludes.push(file_name);
+ cssResources.push((vendorDir + page));
+ }
+});
+
+// Add css files explicitly
+cssResources.push(vendorDir + 'bootstrap/css/bootstrap.min.css');
+cssResources.push(vendorDir + 'bootstrap/css/bootstrap-theme.min.css');
+cssResources.push('./pgadmin/browser/static/vendor/aciTree/css/aciTree.css');
+
+// Main webpack configurations starts here
+const config = {
+ // Create two files main.css and overrides.css
+ entry: {
+ main: cssResources,
+ overrides: [
+ baseDir + 'css/bootstrap.overrides.css',
+ baseDir + 'css/pgadmin.css',
+ ]
+ },
+ output: {
+ path: path.resolve(__dirname, './pgadmin/static/dist/'), // path to dist directory
+ filename: '[name].css' // output js file name is identical to css file name
+ },
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: 'css-loader'
+ }),
+ exclude: /node_modules/
+ },
+ {
+ test: /\.(jpe?g|png|gif|svg)$/i,
+ loaders: [
+ 'file-loader?hash=sha512&digest=hex&name=img/[name].[ext]', {
+ loader: 'image-webpack-loader',
+ query: {
+ bypassOnDebug: true,
+ mozjpeg: {
+ progressive: true,
+ },
+ gifsicle: {
+ interlaced: false,
+ },
+ optipng: {
+ optimizationLevel: 7,
+ },
+ pngquant: {
+ quality: '75-90',
+ speed: 3
+ },
+ }
+ }
+ ],
+ exclude: /node_modules/
+ },
+ {
+ test: /\.(eot|svg|ttf|woff|woff2)$/,
+ loader: 'file-loader?name=fonts/[name].[ext]',
+ exclude: /node_modules/
+ }
+ ]
+ },
+ plugins: [
+ new cleanWebpackPlugin(pathsToClean, cleanOptions), // clean dist directory
+ new ExtractTextPlugin('[name].css'),
+ new OptimizeCssAssetsPlugin({
+ assetNameRegExp: /\.css$/g,
+ cssProcessor: require('cssnano'),
+ cssProcessorOptions: { discardComments: {removeAll: true } },
+ canPrint: true
+ })
+ ]
+};
+module.exports = config;