///////////////////////////////////////////////////////////// // // pgAdmin 4 - PostgreSQL Tools // // Copyright (C) 2013 - 2019, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // ////////////////////////////////////////////////////////////// /* eslint-env node */ // Import file, libraries and plugins const path = require('path'); const webpack = require('webpack'); const fs = require('fs'); const sourceDir = __dirname + '/pgadmin/static'; // webpack.shim.js contains path references for resolve > alias configuration // and other util function used in CommonsChunksPlugin. const webpackShimConfig = require('./webpack.shim'); const PRODUCTION = process.env.NODE_ENV === 'production'; const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const extractStyle = new MiniCssExtractPlugin({ filename: '[name].css', allChunks: true, }); const envType = PRODUCTION ? 'production': 'development'; const devToolVal = PRODUCTION ? false : 'eval'; const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); // Expose libraries in app context so they need not to // require('libname') when used in a module const providePlugin = new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', _: 'underscore', S: 'underscore.string', Backbone: 'backbone', Backgrid: 'backgrid', pgAdmin: 'pgadmin', 'moment': 'moment', 'window.moment':'moment', }); // Optimize CSS Assets by removing comments while bundling const optimizeAssetsPlugin = new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css$/g, cssProcessor: require('cssnano'), cssProcessorOptions: { discardComments: {removeAll: true } }, canPrint: true, }); // Manages the cache and stores it into 'sources/generated/.cache//' path // where env = dev || prod const hardSourceWebpackPlugin = new HardSourceWebpackPlugin({ cacheDirectory: './.cache/hard-source/' + envType +'/[confighash]', recordsPath: './.cache/hard-source/' + envType +'/[confighash]/records.json', configHash: require('node-object-hash')({sort: false}).hash, environmentHash: { root: process.cwd(), directories: ['node_modules'], files: ['package.json'], }, }); // Helps in debugging each single file, it extracts the module files // from bundle so that they are accessible by search in Chrome's sources panel. // Reference: https://webpack.js.org/plugins/source-map-dev-tool-plugin/#components/sidebar/sidebar.jsx const sourceMapDevToolPlugin = new webpack.SourceMapDevToolPlugin({ filename: '[name].js.map', exclude: ['vendor.js', 'codemirror.js', 'popper.js'], columns: false, }); function cssToBeSkiped(curr_path) { /** Skip all templates **/ if(curr_path.indexOf('template') > -1) { return true; } for(let i=0; i< webpackShimConfig.css_bundle_skip.length; i++) { if(path.join(__dirname, webpackShimConfig.css_bundle_skip[i]) === curr_path){ return true; } } return false; } /* Get all the style files recursively and store in array to * give input to webpack. */ function pushModulesCss(curr_path, pgadminStyles) { /** Skip Directories */ if(cssToBeSkiped(curr_path)) { return; } fs.readdirSync(curr_path).map(function(curr_file) { /** Skip Files */ if(cssToBeSkiped(path.join(curr_path, curr_file))) { return; } let stats = fs.statSync(path.join(curr_path, curr_file)); /* if directory, dig further */ if(stats.isDirectory()) { pushModulesCss(path.join(curr_path, curr_file), pgadminStyles); } else if(stats.isFile() && (curr_file.endsWith('.scss') || curr_file.endsWith('.css'))) { pgadminStyles.push(path.join(curr_path, curr_file)); } }); } let pgadminStyles = []; /* Include what is given in shim config */ for(let i=0; iwindow', }, }, { test: require.resolve('./node_modules/acitree/js/jquery.aciPlugin.min'), use: { loader: 'imports-loader?this=>window', }, }, { test: require.resolve('./pgadmin/static/bundle/browser'), use: { loader: 'imports-loader?' + 'pgadmin.about' + ',pgadmin.preferences' + ',pgadmin.file_manager' + ',pgadmin.settings' + ',pgadmin.tools.backup' + ',pgadmin.tools.restore' + ',pgadmin.tools.grant_wizard' + ',pgadmin.tools.maintenance' + ',pgadmin.tools.import_export' + ',pgadmin.tools.debugger.controller' + ',pgadmin.tools.debugger.direct' + ',pgadmin.node.pga_job', }, }, { test: require.resolve('snapsvg'), use: { loader: 'imports-loader?this=>window,fix=>module.exports=0', }, }, { test: /\.(jpe?g|png|gif|svg)$/i, loaders: [{ loader: 'url-loader', options: { emitFile: true, name: 'img/[name].[ext]', limit: 4096, }, }, { loader: 'image-webpack-loader', query: { bypassOnDebug: true, mozjpeg: { progressive: true, }, gifsicle: { interlaced: false, }, optipng: { optimizationLevel: 7, }, pngquant: { quality: '75-90', speed: 3, }, }, }], exclude: /vendor/, }, { test: /\.(eot|svg|ttf|woff|woff2)$/, loaders: [{ loader: 'file-loader', options: { name: 'fonts/[name].[ext]', emitFile: true, }, }], include: [ /node_modules/, path.join(sourceDir, '/css/'), path.join(sourceDir, '/scss/'), path.join(sourceDir, '/fonts/'), ], exclude: /vendor/, }, { test: /\.scss$/, use: [ {loader: MiniCssExtractPlugin.loader}, {loader: 'css-loader'}, {loader: 'sass-loader'}, { loader: 'sass-resources-loader', options: { resources: [ './pgadmin/static/scss/resources/pgadmin.resources.scss', ], }, }, ], }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', ], }], // Prevent module from parsing through webpack, helps in reducing build time noParse: [/moment.js/], }, resolve: { alias: webpackShimConfig.resolveAlias, modules: ['node_modules', '.'], extensions: ['.js'], unsafeCache: true, }, // Watch mode Configuration: After initial build, webpack will watch for // changes in files and compiles only files which are changed, // if watch is set to True // Reference: https://webpack.js.org/configuration/watch/#components/sidebar/sidebar.jsx watchOptions: { aggregateTimeout: 300, poll: 1000, ignored: /node_modules/, }, // Webpack 4: uglifyPlugin moved from plugins to optimization optimization: { minimizer: [ new UglifyJsPlugin({ parallel: true, cache: true, uglifyOptions: { compress: false, }, }), ], splitChunks: { cacheGroups: { vendors: { name: 'vendors', filename: 'vendor.js', chunks: 'all', reuseExistingChunk: true, priority: 1, minChunks: 2, enforce: true, test(module) { return webpackShimConfig.isExternal(module); }, }, secondary: { name: 'pgadmin_commons', filename: 'pgadmin_commons.js', chunks: 'all', priority: 2, minChunks: 2, enforce: true, test(module) { return webpackShimConfig.isPgAdminLib(module); }, }, }, }, }, // Define list of Plugins used in Production or development mode // Ref:https://webpack.js.org/concepts/plugins/#components/sidebar/sidebar.jsx plugins: PRODUCTION ? [ extractStyle, providePlugin, optimizeAssetsPlugin, sourceMapDevToolPlugin, ]: [ extractStyle, providePlugin, hardSourceWebpackPlugin, sourceMapDevToolPlugin, ], };