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;