gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

639 lines
20KB

  1. /////////////////////////////////////////////////////////////
  2. //
  3. // pgAdmin 4 - PostgreSQL Tools
  4. //
  5. // Copyright (C) 2013 - 2020, The pgAdmin Development Team
  6. // This software is released under the PostgreSQL Licence
  7. //
  8. //////////////////////////////////////////////////////////////
  9. /* eslint-env node */
  10. // Import file, libraries and plugins
  11. const path = require('path');
  12. const webpack = require('webpack');
  13. const fs = require('fs');
  14. const sourceDir = __dirname + '/pgadmin/static';
  15. // webpack.shim.js contains path references for resolve > alias configuration
  16. // and other util function used in CommonsChunksPlugin.
  17. const webpackShimConfig = require('./webpack.shim');
  18. const PRODUCTION = process.env.NODE_ENV === 'production';
  19. const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  20. const TerserPlugin = require('terser-webpack-plugin');
  21. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  22. const extractStyle = new MiniCssExtractPlugin({
  23. filename: '[name].css',
  24. chunkFilename: '[name].css',
  25. allChunks: true,
  26. });
  27. const WebpackRequireFromPlugin = require('webpack-require-from');
  28. const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  29. const CopyPlugin = require('copy-webpack-plugin');
  30. const IconfontWebpackPlugin = require('iconfont-webpack-plugin');
  31. const envType = PRODUCTION ? 'production': 'development';
  32. const devToolVal = PRODUCTION ? false : 'eval';
  33. const analyzerMode = process.env.ANALYZE=='true' ? 'static' : 'disabled';
  34. const outputPath = __dirname + '/pgadmin/static/js/generated';
  35. const pgadminThemesJson = __dirname + '/pgadmin/misc/themes/pgadmin.themes.json';
  36. // Expose libraries in app context so they need not to
  37. // require('libname') when used in a module
  38. const providePlugin = new webpack.ProvidePlugin({
  39. $: 'jquery',
  40. jQuery: 'jquery',
  41. 'window.jQuery': 'jquery',
  42. _: 'underscore',
  43. Backbone: 'backbone',
  44. Backgrid: 'backgrid',
  45. pgAdmin: 'pgadmin',
  46. 'moment': 'moment',
  47. 'window.moment':'moment',
  48. });
  49. // Optimize CSS Assets by removing comments while bundling
  50. const optimizeAssetsPlugin = new OptimizeCssAssetsPlugin({
  51. assetNameRegExp: /\.css$/g,
  52. cssProcessor: require('cssnano'),
  53. cssProcessorOptions: {
  54. discardComments: {
  55. removeAll: true,
  56. },
  57. },
  58. canPrint: true,
  59. });
  60. // Helps in debugging each single file, it extracts the module files
  61. // from bundle so that they are accessible by search in Chrome's sources panel.
  62. // Reference: https://webpack.js.org/plugins/source-map-dev-tool-plugin/#components/sidebar/sidebar.jsx
  63. const sourceMapDevToolPlugin = new webpack.SourceMapDevToolPlugin({
  64. filename: '[name].js.map',
  65. exclude: /(vendor|codemirror|slickgrid|pgadmin\.js|pgadmin.theme|pgadmin.static|style\.js|popper)/,
  66. columns: false,
  67. });
  68. // Supress errors while compiling as the getChunkURL method will be available
  69. // on runtime. window.getChunkURL is defined in base.html
  70. const webpackRequireFrom = new WebpackRequireFromPlugin({
  71. methodName: 'getChunkURL',
  72. supressErrors: true,
  73. });
  74. // can be enabled using bundle:analyze
  75. const bundleAnalyzer = new BundleAnalyzerPlugin({
  76. analyzerMode: analyzerMode,
  77. reportFilename: 'analyze_report.html',
  78. });
  79. const copyFiles = new CopyPlugin([
  80. pgadminThemesJson,
  81. {
  82. from: './pgadmin/static/scss/resources/**/*.png',
  83. to: outputPath + '/img',
  84. flatten: true,
  85. },
  86. ]);
  87. function cssToBeSkiped(curr_path) {
  88. /** Skip all templates **/
  89. if(curr_path.indexOf('template') > -1) {
  90. return true;
  91. }
  92. for(let i=0; i< webpackShimConfig.css_bundle_skip.length; i++) {
  93. if(path.join(__dirname, webpackShimConfig.css_bundle_skip[i]) === curr_path){
  94. return true;
  95. }
  96. }
  97. return false;
  98. }
  99. /* Get all the style files recursively and store in array to
  100. * give input to webpack.
  101. */
  102. function pushModulesStyles(curr_path, pgadminStyles, extn) {
  103. /** Skip Directories */
  104. if(cssToBeSkiped(curr_path)) {
  105. return;
  106. }
  107. fs.readdirSync(curr_path).map(function(curr_file) {
  108. /** Skip Files */
  109. if(cssToBeSkiped(path.join(curr_path, curr_file))) {
  110. return;
  111. }
  112. let stats = fs.statSync(path.join(curr_path, curr_file));
  113. /* if directory, dig further */
  114. if(stats.isDirectory()) {
  115. pushModulesStyles(path.join(curr_path, curr_file), pgadminStyles, extn);
  116. }
  117. else if(stats.isFile() && (curr_file.endsWith(extn))) {
  118. pgadminStyles.push(path.join(curr_path, curr_file));
  119. }
  120. });
  121. }
  122. let pgadminScssStyles = [];
  123. let pgadminCssStyles = [];
  124. /* Include what is given in shim config */
  125. for(let i=0; i<webpackShimConfig.css_bundle_include.length; i++) {
  126. if(webpackShimConfig.css_bundle_include[i].endsWith('.scss')) {
  127. pgadminScssStyles.push(path.join(__dirname, webpackShimConfig.css_bundle_include[i]));
  128. } else if(webpackShimConfig.css_bundle_include[i].endsWith('.css')){
  129. pgadminCssStyles.push(path.join(__dirname, webpackShimConfig.css_bundle_include[i]));
  130. }
  131. }
  132. pushModulesStyles(path.join(__dirname,'./pgadmin'), pgadminScssStyles, '.scss');
  133. pushModulesStyles(path.join(__dirname,'./pgadmin'), pgadminCssStyles, '.css');
  134. /* Get all the themes */
  135. let all_themes_dir = path.join(__dirname,'./pgadmin/static/scss/resources');
  136. let pgadminThemes = {};
  137. /* Read all the theme dirs */
  138. /* Theme format
  139. "theme_name": {
  140. "disp_name": "theme_name",
  141. "cssfile": "pgadmin.theme.theme_name",
  142. "preview_img": "theme_name_preview.png"
  143. }
  144. */
  145. fs.readdirSync(all_themes_dir).map(function(curr_dir) {
  146. let stats = fs.statSync(path.join(all_themes_dir, curr_dir));
  147. if(stats.isDirectory()) {
  148. /* Theme directory found */
  149. let cssfile = 'pgadmin.theme.'+curr_dir;
  150. let disp_name = curr_dir;
  151. if(curr_dir == 'high_contrast') {
  152. disp_name = curr_dir + ' (Beta)';
  153. }
  154. pgadminThemes[curr_dir] = {
  155. /* For now lets keep it as beta release */
  156. disp_name: disp_name,
  157. cssfile: cssfile,
  158. preview_img: curr_dir + '_preview.png',
  159. };
  160. }
  161. });
  162. fs.writeFileSync(pgadminThemesJson, JSON.stringify(pgadminThemes, null, 4));
  163. var themeCssRules = function(theme_name) {
  164. return [{
  165. test: /\.(jpe?g|png|gif|svg)$/i,
  166. loaders: [{
  167. loader: 'url-loader',
  168. options: {
  169. emitFile: true,
  170. name: 'img/[name].[ext]',
  171. limit: 4096,
  172. },
  173. }, {
  174. loader: 'image-webpack-loader',
  175. query: {
  176. bypassOnDebug: true,
  177. mozjpeg: {
  178. progressive: true,
  179. },
  180. gifsicle: {
  181. interlaced: false,
  182. },
  183. optipng: {
  184. optimizationLevel: 7,
  185. },
  186. pngquant: {
  187. quality: '75-90',
  188. speed: 3,
  189. },
  190. },
  191. }],
  192. exclude: /vendor/,
  193. }, {
  194. test: /\.(eot|svg|ttf|woff|woff2)$/,
  195. loaders: [{
  196. loader: 'file-loader',
  197. options: {
  198. name: 'fonts/[name].[ext]',
  199. emitFile: true,
  200. },
  201. }],
  202. include: [
  203. /node_modules/,
  204. path.join(sourceDir, '/css/'),
  205. path.join(sourceDir, '/scss/'),
  206. path.join(sourceDir, '/fonts/'),
  207. ],
  208. exclude: /vendor/,
  209. }, {
  210. test: /\.scss$/,
  211. use: [
  212. {loader: MiniCssExtractPlugin.loader},
  213. {loader: 'css-loader'},
  214. {
  215. loader: 'postcss-loader',
  216. options: {
  217. plugins: (loader) => [
  218. require('autoprefixer')(),
  219. new IconfontWebpackPlugin(loader),
  220. ],
  221. },
  222. },
  223. {loader: 'sass-loader'},
  224. {
  225. loader: 'sass-resources-loader',
  226. options: {
  227. resources: function(_theme_name){
  228. let ret_res = [
  229. './pgadmin/static/scss/resources/' + _theme_name + '/_theme.variables.scss',
  230. './pgadmin/static/scss/resources/pgadmin.resources.scss',
  231. ];
  232. if(_theme_name!='standard') {
  233. ret_res.unshift('./pgadmin/static/scss/resources/' + _theme_name + '/_theme.variables.scss');
  234. }
  235. return ret_res;
  236. }(theme_name),
  237. },
  238. },
  239. ],
  240. }, {
  241. test: /\.css$/,
  242. use: [
  243. MiniCssExtractPlugin.loader,
  244. 'css-loader',
  245. {
  246. loader: 'postcss-loader',
  247. options: {
  248. plugins: (loader) => [
  249. require('autoprefixer')(),
  250. new IconfontWebpackPlugin(loader),
  251. ],
  252. },
  253. },
  254. ],
  255. }];
  256. };
  257. var getThemeWebpackConfig = function(theme_name) {
  258. return {
  259. mode: envType,
  260. devtool: devToolVal,
  261. stats: { children: false },
  262. // The base directory, an absolute path, for resolving entry points and loaders
  263. // from configuration.
  264. context: __dirname,
  265. // Specify entry points of application
  266. entry: {
  267. [pgadminThemes[theme_name].cssfile]: pgadminScssStyles,
  268. },
  269. // path: The output directory for generated bundles(defined in entry)
  270. // Ref: https://webpack.js.org/configuration/output/#output-library
  271. output: {
  272. libraryTarget: 'amd',
  273. path: outputPath,
  274. filename: '[name].js',
  275. libraryExport: 'default',
  276. },
  277. // Templates files which contains python code needs to load dynamically
  278. // Such files specified in externals are loaded at first and defined in
  279. // the start of generated bundle within define(['libname'],fn) etc.
  280. externals: webpackShimConfig.externals,
  281. module: {
  282. // References:
  283. // Module and Rules: https://webpack.js.org/configuration/module/
  284. // Loaders: https://webpack.js.org/loaders/
  285. //
  286. // imports-loader: it adds dependent modules(use:imports-loader?module1)
  287. // at the beginning of module it is dependency of like:
  288. // var jQuery = require('jquery'); var browser = require('pgadmin.browser')
  289. // It solves number of problems
  290. // Ref: http:/github.com/webpack-contrib/imports-loader/
  291. rules: themeCssRules(theme_name),
  292. },
  293. resolve: {
  294. alias: webpackShimConfig.resolveAlias,
  295. modules: ['node_modules', '.'],
  296. extensions: ['.js'],
  297. unsafeCache: true,
  298. },
  299. // Watch mode Configuration: After initial build, webpack will watch for
  300. // changes in files and compiles only files which are changed,
  301. // if watch is set to True
  302. // Reference: https://webpack.js.org/configuration/watch/#components/sidebar/sidebar.jsx
  303. watchOptions: {
  304. aggregateTimeout: 300,
  305. poll: 1000,
  306. ignored: /node_modules/,
  307. },
  308. // Define list of Plugins used in Production or development mode
  309. // Ref:https://webpack.js.org/concepts/plugins/#components/sidebar/sidebar.jsx
  310. plugins: PRODUCTION ? [
  311. extractStyle,
  312. optimizeAssetsPlugin,
  313. sourceMapDevToolPlugin,
  314. ]: [
  315. extractStyle,
  316. sourceMapDevToolPlugin,
  317. ],
  318. };
  319. };
  320. var pgadminThemesWebpack = [];
  321. Object.keys(pgadminThemes).map((theme_name)=>{
  322. pgadminThemesWebpack.push(getThemeWebpackConfig(theme_name));
  323. });
  324. module.exports = [{
  325. mode: envType,
  326. devtool: devToolVal,
  327. stats: { children: false },
  328. // The base directory, an absolute path, for resolving entry points and loaders
  329. // from configuration.
  330. context: __dirname,
  331. // Specify entry points of application
  332. entry: {
  333. 'app.bundle': sourceDir + '/bundle/app.js',
  334. codemirror: sourceDir + '/bundle/codemirror.js',
  335. slickgrid: sourceDir + '/bundle/slickgrid.js',
  336. sqleditor: './pgadmin/tools/sqleditor/static/js/sqleditor.js',
  337. debugger_direct: './pgadmin/tools/debugger/static/js/direct.js',
  338. schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js',
  339. file_utils: './pgadmin/misc/file_manager/static/js/utility.js',
  340. 'pgadmin.style': pgadminCssStyles,
  341. pgadmin: pgadminScssStyles,
  342. style: './pgadmin/static/css/style.css',
  343. },
  344. // path: The output directory for generated bundles(defined in entry)
  345. // Ref: https://webpack.js.org/configuration/output/#output-library
  346. output: {
  347. libraryTarget: 'amd',
  348. path: outputPath,
  349. filename: '[name].js',
  350. chunkFilename: '[name].chunk.js',
  351. libraryExport: 'default',
  352. },
  353. // Templates files which contains python code needs to load dynamically
  354. // Such files specified in externals are loaded at first and defined in
  355. // the start of generated bundle within define(['libname'],fn) etc.
  356. externals: webpackShimConfig.externals,
  357. module: {
  358. // References:
  359. // Module and Rules: https://webpack.js.org/configuration/module/
  360. // Loaders: https://webpack.js.org/loaders/
  361. //
  362. // imports-loader: it adds dependent modules(use:imports-loader?module1)
  363. // at the beginning of module it is dependency of like:
  364. // var jQuery = require('jquery'); var browser = require('pgadmin.browser')
  365. // It solves number of problems
  366. // Ref: http:/github.com/webpack-contrib/imports-loader/
  367. rules: [{
  368. test: /\.js$/,
  369. exclude: [/node_modules/, /vendor/],
  370. use: {
  371. loader: 'babel-loader',
  372. options: {
  373. presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}]],
  374. },
  375. },
  376. }, {
  377. test: /external_table.*\.js/,
  378. use: {
  379. loader: 'babel-loader',
  380. options: {
  381. presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}]],
  382. },
  383. },
  384. }, {
  385. // Transforms the code in a way that it works in the webpack environment.
  386. // It uses imports-loader internally to load dependency. Its
  387. // configuration is specified in webpack.shim.js
  388. // Ref: https://www.npmjs.com/package/shim-loader
  389. test: /\.js/,
  390. exclude: [/external_table/],
  391. loader: 'shim-loader',
  392. query: webpackShimConfig,
  393. include: path.join(__dirname, '/pgadmin/browser'),
  394. }, {
  395. test: require.resolve('./pgadmin/tools/datagrid/static/js/datagrid'),
  396. use: {
  397. loader: 'imports-loader?' +
  398. 'pgadmin.dashboard' +
  399. ',pgadmin.tools.user_management' +
  400. ',pgadmin.browser.object_statistics' +
  401. ',pgadmin.browser.dependencies' +
  402. ',pgadmin.browser.dependents' +
  403. ',pgadmin.browser.object_sql' +
  404. ',pgadmin.browser.bgprocess' +
  405. ',pgadmin.node.server_group' +
  406. ',pgadmin.node.server' +
  407. ',pgadmin.node.database' +
  408. ',pgadmin.node.role' +
  409. ',pgadmin.node.cast' +
  410. ',pgadmin.node.tablespace' +
  411. ',pgadmin.node.resource_group' +
  412. ',pgadmin.node.event_trigger' +
  413. ',pgadmin.node.extension' +
  414. ',pgadmin.node.language' +
  415. ',pgadmin.node.foreign_data_wrapper' +
  416. ',pgadmin.node.foreign_server' +
  417. ',pgadmin.node.user_mapping' +
  418. ',pgadmin.node.schema' +
  419. ',pgadmin.node.catalog' +
  420. ',pgadmin.node.catalog_object' +
  421. ',pgadmin.node.collation' +
  422. ',pgadmin.node.domain' +
  423. ',pgadmin.node.domain_constraints' +
  424. ',pgadmin.node.foreign_table' +
  425. ',pgadmin.node.fts_configuration' +
  426. ',pgadmin.node.fts_dictionary' +
  427. ',pgadmin.node.fts_parser' +
  428. ',pgadmin.node.fts_template' +
  429. ',pgadmin.node.function' +
  430. ',pgadmin.node.procedure' +
  431. ',pgadmin.node.edbfunc' +
  432. ',pgadmin.node.edbproc' +
  433. ',pgadmin.node.edbvar' +
  434. ',pgadmin.node.edbvar' +
  435. ',pgadmin.node.trigger_function' +
  436. ',pgadmin.node.package' +
  437. ',pgadmin.node.sequence' +
  438. ',pgadmin.node.synonym' +
  439. ',pgadmin.node.type' +
  440. ',pgadmin.node.rule' +
  441. ',pgadmin.node.index' +
  442. ',pgadmin.node.row_security_policy' +
  443. ',pgadmin.node.trigger' +
  444. ',pgadmin.node.catalog_object_column' +
  445. ',pgadmin.node.view' +
  446. ',pgadmin.node.mview' +
  447. ',pgadmin.node.table' +
  448. ',pgadmin.node.partition' +
  449. ',pgadmin.node.compound_trigger',
  450. },
  451. }, {
  452. test: require.resolve('./node_modules/acitree/js/jquery.aciTree.min'),
  453. use: {
  454. loader: 'imports-loader?this=>window',
  455. },
  456. }, {
  457. test: require.resolve('./node_modules/acitree/js/jquery.aciPlugin.min'),
  458. use: {
  459. loader: 'imports-loader?this=>window',
  460. },
  461. }, {
  462. test: require.resolve('./pgadmin/static/bundle/browser'),
  463. use: {
  464. loader: 'imports-loader?' +
  465. 'pgadmin.about' +
  466. ',pgadmin.preferences' +
  467. ',pgadmin.file_manager' +
  468. ',pgadmin.settings' +
  469. ',pgadmin.tools.backup' +
  470. ',pgadmin.tools.restore' +
  471. ',pgadmin.tools.grant_wizard' +
  472. ',pgadmin.tools.maintenance' +
  473. ',pgadmin.tools.import_export' +
  474. ',pgadmin.tools.debugger.controller' +
  475. ',pgadmin.tools.debugger.direct' +
  476. ',pgadmin.node.pga_job' +
  477. ',pgadmin.tools.schema_diff' +
  478. ',pgadmin.tools.search_objects',
  479. },
  480. }, {
  481. test: require.resolve('snapsvg'),
  482. use: {
  483. loader: 'imports-loader?this=>window,fix=>module.exports=0',
  484. },
  485. }].concat(themeCssRules('standard')),
  486. // Prevent module from parsing through webpack, helps in reducing build time
  487. noParse: [/moment.js/],
  488. },
  489. resolve: {
  490. alias: webpackShimConfig.resolveAlias,
  491. modules: ['node_modules', '.'],
  492. extensions: ['.js'],
  493. unsafeCache: true,
  494. },
  495. // Watch mode Configuration: After initial build, webpack will watch for
  496. // changes in files and compiles only files which are changed,
  497. // if watch is set to True
  498. // Reference: https://webpack.js.org/configuration/watch/#components/sidebar/sidebar.jsx
  499. watchOptions: {
  500. aggregateTimeout: 300,
  501. poll: 1000,
  502. ignored: /node_modules/,
  503. },
  504. optimization: {
  505. minimizer: [
  506. new TerserPlugin({
  507. parallel: true,
  508. cache: true,
  509. terserOptions: {
  510. compress: true,
  511. extractComments: true,
  512. output: {
  513. comments: false,
  514. },
  515. },
  516. }),
  517. ],
  518. splitChunks: {
  519. cacheGroups: {
  520. slickgrid: {
  521. name: 'slickgrid',
  522. filename: 'slickgrid.js',
  523. chunks: 'all',
  524. reuseExistingChunk: true,
  525. priority: 9,
  526. minChunks: 2,
  527. enforce: true,
  528. test(module) {
  529. return webpackShimConfig.matchModules(module, 'slickgrid');
  530. },
  531. },
  532. codemirror: {
  533. name: 'codemirror',
  534. filename: 'codemirror.js',
  535. chunks: 'all',
  536. reuseExistingChunk: true,
  537. priority: 8,
  538. minChunks: 2,
  539. enforce: true,
  540. test(module) {
  541. return webpackShimConfig.matchModules(module, 'codemirror');
  542. },
  543. },
  544. vendor_main: {
  545. name: 'vendor_main',
  546. filename: 'vendor.main.js',
  547. chunks: 'all',
  548. reuseExistingChunk: true,
  549. priority: 7,
  550. minChunks: 2,
  551. enforce: true,
  552. test(module) {
  553. return webpackShimConfig.matchModules(module, ['wcdocker', 'backbone', 'jquery', 'bootstrap', 'popper']);
  554. },
  555. },
  556. vendor_others: {
  557. name: 'vendor_others',
  558. filename: 'vendor.others.js',
  559. chunks: 'all',
  560. reuseExistingChunk: true,
  561. priority: 6,
  562. minChunks: 2,
  563. enforce: true,
  564. test(module) {
  565. return webpackShimConfig.isExternal(module);
  566. },
  567. },
  568. secondary: {
  569. name: 'pgadmin_commons',
  570. filename: 'pgadmin_commons.js',
  571. chunks: 'all',
  572. priority: 5,
  573. minChunks: 2,
  574. enforce: true,
  575. test(module) {
  576. return webpackShimConfig.isPgAdminLib(module);
  577. },
  578. },
  579. browser_nodes: {
  580. name: 'browser_nodes',
  581. filename: 'browser_nodes.js',
  582. chunks: 'all',
  583. priority: 4,
  584. minChunks: 2,
  585. enforce: true,
  586. test(module) {
  587. return webpackShimConfig.isBrowserNode(module);
  588. },
  589. },
  590. },
  591. },
  592. },
  593. // Define list of Plugins used in Production or development mode
  594. // Ref:https://webpack.js.org/concepts/plugins/#components/sidebar/sidebar.jsx
  595. plugins: PRODUCTION ? [
  596. extractStyle,
  597. providePlugin,
  598. optimizeAssetsPlugin,
  599. sourceMapDevToolPlugin,
  600. webpackRequireFrom,
  601. bundleAnalyzer,
  602. copyFiles,
  603. ]: [
  604. extractStyle,
  605. providePlugin,
  606. sourceMapDevToolPlugin,
  607. webpackRequireFrom,
  608. copyFiles,
  609. ],
  610. }].concat(pgadminThemesWebpack);
上海开阖软件有限公司 沪ICP备12045867号-1