From f7e9c0f2ac6d5a80d2719ea0cecfa4ced05216d4 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 14 Jun 2017 11:10:48 +0200 Subject: [PATCH] simplify config of sonar-web --- server/sonar-web/.eslintignore | 3 - server/sonar-web/config/env.js | 42 ----- server/sonar-web/config/jest/FileStub.js | 2 +- .../config/jest/SetupTestEnvironment.js | 4 +- server/sonar-web/config/paths.js | 17 +- server/sonar-web/config/polyfills.js | 1 - server/sonar-web/config/webpack.config.js | 162 +++++++++++++++++ .../config/webpack/webpack.config.base.js | 104 ----------- .../config/webpack/webpack.config.dev.js | 95 ---------- .../config/webpack/webpack.config.fast.js | 47 ----- .../config/webpack/webpack.config.prod.js | 89 --------- server/sonar-web/package.json | 12 +- server/sonar-web/scripts/analyze.js | 5 +- server/sonar-web/scripts/build.js | 44 +++-- server/sonar-web/scripts/start.js | 172 ++++++++++-------- server/sonar-web/scripts/test.js | 8 +- server/sonar-web/scripts/utils/formatSize.js | 10 +- server/sonar-web/yarn.lock | 104 +---------- 18 files changed, 305 insertions(+), 616 deletions(-) delete mode 100644 server/sonar-web/config/env.js create mode 100644 server/sonar-web/config/webpack.config.js delete mode 100644 server/sonar-web/config/webpack/webpack.config.base.js delete mode 100644 server/sonar-web/config/webpack/webpack.config.dev.js delete mode 100644 server/sonar-web/config/webpack/webpack.config.fast.js delete mode 100644 server/sonar-web/config/webpack/webpack.config.prod.js diff --git a/server/sonar-web/.eslintignore b/server/sonar-web/.eslintignore index fbff2a98255..49b0bda4a35 100644 --- a/server/sonar-web/.eslintignore +++ b/server/sonar-web/.eslintignore @@ -1,5 +1,2 @@ src/main/js/libs src/main/js/app/components/GlobalFooterBranding.js -tests -scripts -config diff --git a/server/sonar-web/config/env.js b/server/sonar-web/config/env.js deleted file mode 100644 index 77aa261dab7..00000000000 --- a/server/sonar-web/config/env.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be -// injected into the application via DefinePlugin in Webpack configuration. - -var REACT_APP = /^REACT_APP_/i; - -function getClientEnvironment () { - return Object - .keys(process.env) - .filter(key => REACT_APP.test(key)) - .reduce((env, key) => { - env['process.env.' + key] = JSON.stringify(process.env[key]); - return env; - }, { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - 'process.env.NODE_ENV': JSON.stringify( - process.env.NODE_ENV || 'development' - ) - }); -} - -module.exports = getClientEnvironment; - diff --git a/server/sonar-web/config/jest/FileStub.js b/server/sonar-web/config/jest/FileStub.js index 70a6c197806..bff56dc8933 100644 --- a/server/sonar-web/config/jest/FileStub.js +++ b/server/sonar-web/config/jest/FileStub.js @@ -17,4 +17,4 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -module.exports = "test-file-stub"; +module.exports = 'test-file-stub'; diff --git a/server/sonar-web/config/jest/SetupTestEnvironment.js b/server/sonar-web/config/jest/SetupTestEnvironment.js index 536db746157..64c8d0c15aa 100644 --- a/server/sonar-web/config/jest/SetupTestEnvironment.js +++ b/server/sonar-web/config/jest/SetupTestEnvironment.js @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ window.baseUrl = ''; -window.t = window.tp = function () { - var args = Array.prototype.slice.call(arguments, 0); +window.t = window.tp = function() { + const args = Array.prototype.slice.call(arguments, 0); return args.join('.'); }; diff --git a/server/sonar-web/config/paths.js b/server/sonar-web/config/paths.js index 3773a6a6439..5b380588750 100644 --- a/server/sonar-web/config/paths.js +++ b/server/sonar-web/config/paths.js @@ -17,12 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -var path = require('path'); -var fs = require('fs'); +const path = require('path'); +const fs = require('fs'); // Make sure any symlinks in the project folder are resolved: // https://github.com/facebookincubator/create-react-app/issues/637 -var appDirectory = fs.realpathSync(process.cwd()); +const appDirectory = fs.realpathSync(process.cwd()); function resolveApp(relativePath) { return path.resolve(appDirectory, relativePath); } @@ -38,10 +38,10 @@ function resolveApp(relativePath) { // It will then be used by Webpack configs. // Jest doesn’t need this because it already handles `NODE_PATH` out of the box. -var nodePaths = (process.env.NODE_PATH || '') - .split(process.platform === 'win32' ? ';' : ':') - .filter(Boolean) - .map(resolveApp); +const nodePaths = (process.env.NODE_PATH || '') + .split(process.platform === 'win32' ? ';' : ':') + .filter(Boolean) + .map(resolveApp); // config after eject: we're in ./config/ module.exports = { @@ -55,6 +55,5 @@ module.exports = { htmlBuild: resolveApp('src/main/webapp/index.html'), appNodeModules: resolveApp('node_modules'), ownNodeModules: resolveApp('node_modules'), - nodePaths: nodePaths + nodePaths }; - diff --git a/server/sonar-web/config/polyfills.js b/server/sonar-web/config/polyfills.js index 3b51c254e7a..fdb2b100715 100644 --- a/server/sonar-web/config/polyfills.js +++ b/server/sonar-web/config/polyfills.js @@ -19,4 +19,3 @@ */ import 'babel-polyfill'; import 'whatwg-fetch'; - diff --git a/server/sonar-web/config/webpack.config.js b/server/sonar-web/config/webpack.config.js new file mode 100644 index 00000000000..33fe812c428 --- /dev/null +++ b/server/sonar-web/config/webpack.config.js @@ -0,0 +1,162 @@ +const path = require('path'); +const autoprefixer = require('autoprefixer'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); +const webpack = require('webpack'); +const paths = require('./paths'); +const autoprefixerOptions = require('./autoprefixer'); + +module.exports = ({ production = true, fast = false }) => ({ + bail: production, + + devtool: production ? fast ? false : 'source-map' : 'cheap-module-eval-source-map', + + entry: { + vendor: [ + !production && require.resolve('react-dev-utils/webpackHotDevClient'), + require.resolve('./polyfills'), + 'jquery', + 'underscore', + 'lodash', + 'd3-array', + 'd3-hierarchy', + 'd3-scale', + 'd3-selection', + 'd3-shape', + 'react', + 'react-dom', + 'backbone', + 'backbone.marionette', + 'moment', + 'handlebars/runtime', + './src/main/js/libs/third-party/jquery-ui.js', + './src/main/js/libs/third-party/select2.js', + './src/main/js/libs/third-party/bootstrap/tooltip.js', + './src/main/js/libs/third-party/bootstrap/dropdown.js' + ].filter(Boolean), + + app: [ + './src/main/js/app/utils/setPublicPath.js', + './src/main/js/app/index.js', + './src/main/js/components/SourceViewer/SourceViewer.js' + ] + }, + output: { + path: paths.appBuild, + pathinfo: !production, + filename: production ? 'js/[name].[chunkhash:8].js' : 'js/[name].js', + chunkFilename: production ? 'js/[name].[chunkhash:8].chunk.js' : 'js/[name].chunk.js' + }, + resolve: { + // This allows you to set a fallback for where Webpack should look for modules. + // We read `NODE_PATH` environment variable in `paths.js` and pass paths here. + // We use `fallback` instead of `root` because we want `node_modules` to "win" + // if there any conflicts. This matches Node resolution mechanism. + // https://github.com/facebookincubator/create-react-app/issues/253 + fallback: paths.nodePaths + }, + module: { + // First, run the linter. + // It's important to do this before Babel processes the JS. + // Run for development or full build + preLoaders: !production || !fast + ? [ + { + test: /\.js$/, + loader: 'eslint', + include: paths.appSrc + } + ] + : [], + loaders: [ + { + test: /\.js$/, + loader: 'babel', + exclude: /(node_modules|libs)/ + }, + { + test: /(blueimp-md5|numeral)/, + loader: 'imports?define=>false' + }, + { + test: /\.hbs$/, + loader: 'handlebars', + query: { + helperDirs: path.join(__dirname, '../src/main/js/helpers/handlebars') + } + }, + { + test: /\.css$/, + loader: 'style!css!postcss' + }, + { + test: /\.less$/, + loader: ExtractTextPlugin.extract('style', 'css?-url!postcss!less') + }, + { test: require.resolve('jquery'), loader: 'expose?$!expose?jQuery' }, + { test: require.resolve('underscore'), loader: 'expose?_' }, + { test: require.resolve('backbone'), loader: 'expose?Backbone' }, + { test: require.resolve('backbone.marionette'), loader: 'expose?Marionette' }, + { test: require.resolve('react'), loader: 'expose?React' }, + { test: require.resolve('react-dom'), loader: 'expose?ReactDOM' } + ] + }, + plugins: [ + new webpack.optimize.CommonsChunkPlugin( + 'vendor', + production ? 'js/vendor.[chunkhash:8].js' : 'js/vendor.js' + ), + + new ExtractTextPlugin(production ? 'css/sonar.[chunkhash:8].css' : 'css/sonar.css', { + allChunks: true + }), + + !production && new InterpolateHtmlPlugin({ WEB_CONTEXT: '' }), + + new HtmlWebpackPlugin({ + inject: false, + template: paths.appHtml, + minify: production && + !fast && { + removeComments: true, + collapseWhitespace: true, + removeRedundantAttributes: true, + useShortDoctype: true, + removeEmptyAttributes: true, + removeStyleLinkTypeAttributes: true, + keepClosingSlash: true, + minifyJS: true, + minifyCSS: true, + minifyURLs: true + } + }), + + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(production ? 'production' : 'development') + }), + + production && new webpack.optimize.OccurrenceOrderPlugin(), + production && new webpack.optimize.DedupePlugin(), + + production && + !fast && + new webpack.optimize.UglifyJsPlugin({ + compress: { screw_ie8: true, warnings: false }, + mangle: { screw_ie8: true }, + output: { comments: false, screw_ie8: true } + }), + + !production && new webpack.HotModuleReplacementPlugin() + ].filter(Boolean), + postcss() { + return [autoprefixer(autoprefixerOptions)]; + }, + // Some libraries import Node modules but don't use them in the browser. + // Tell Webpack to provide empty mocks for them so importing them works. + node: { + fs: 'empty', + net: 'empty', + tls: 'empty' + } +}); diff --git a/server/sonar-web/config/webpack/webpack.config.base.js b/server/sonar-web/config/webpack/webpack.config.base.js deleted file mode 100644 index e8b615bccf8..00000000000 --- a/server/sonar-web/config/webpack/webpack.config.base.js +++ /dev/null @@ -1,104 +0,0 @@ -var path = require('path'); -var autoprefixer = require('autoprefixer'); -var webpack = require('webpack'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); -var paths = require('../paths'); -var autoprefixerOptions = require('../autoprefixer'); - -module.exports = { - entry: { - vendor: [ - require.resolve('../polyfills'), - 'jquery', - 'underscore', - 'lodash', - 'd3-array', - 'd3-hierarchy', - 'd3-scale', - 'd3-selection', - 'd3-shape', - 'react', - 'react-dom', - 'backbone', - 'backbone.marionette', - 'moment', - 'handlebars/runtime', - './src/main/js/libs/third-party/jquery-ui.js', - './src/main/js/libs/third-party/select2.js', - './src/main/js/libs/third-party/bootstrap/tooltip.js', - './src/main/js/libs/third-party/bootstrap/dropdown.js' - ], - - app: [ - './src/main/js/app/utils/setPublicPath.js', - './src/main/js/app/index.js', - './src/main/js/components/SourceViewer/SourceViewer.js' - ] - }, - output: { - path: paths.appBuild, - filename: 'js/[name].[chunkhash:8].js', - chunkFilename: 'js/[name].[chunkhash:8].chunk.js' - }, - resolve: { - // This allows you to set a fallback for where Webpack should look for modules. - // We read `NODE_PATH` environment variable in `paths.js` and pass paths here. - // We use `fallback` instead of `root` because we want `node_modules` to "win" - // if there any conflicts. This matches Node resolution mechanism. - // https://github.com/facebookincubator/create-react-app/issues/253 - fallback: paths.nodePaths - }, - module: { - // First, run the linter. - // It's important to do this before Babel processes the JS. - preLoaders: [ - { - test: /\.js$/, - loader: 'eslint', - include: paths.appSrc - } - ], - loaders: [ - { - test: /\.js$/, - loader: 'babel', - exclude: /(node_modules|libs)/ - }, - { - test: /(blueimp-md5|numeral)/, - loader: 'imports?define=>false' - }, - { - test: /\.hbs$/, - loader: 'handlebars', - query: { - helperDirs: path.join(__dirname, '../../src/main/js/helpers/handlebars') - } - }, - { - test: /\.css$/, - loader: 'style!css!postcss' - }, - { - test: /\.less$/, - loader: ExtractTextPlugin.extract('style', 'css?-url!postcss!less') - }, - { test: require.resolve('jquery'), loader: 'expose?$!expose?jQuery' }, - { test: require.resolve('underscore'), loader: 'expose?_' }, - { test: require.resolve('backbone'), loader: 'expose?Backbone' }, - { test: require.resolve('backbone.marionette'), loader: 'expose?Marionette' }, - { test: require.resolve('react'), loader: 'expose?React' }, - { test: require.resolve('react-dom'), loader: 'expose?ReactDOM' } - ] - }, - postcss() { - return [autoprefixer(autoprefixerOptions)]; - }, - // Some libraries import Node modules but don't use them in the browser. - // Tell Webpack to provide empty mocks for them so importing them works. - node: { - fs: 'empty', - net: 'empty', - tls: 'empty' - } -}; diff --git a/server/sonar-web/config/webpack/webpack.config.dev.js b/server/sonar-web/config/webpack/webpack.config.dev.js deleted file mode 100644 index 6f4f4da2fac..00000000000 --- a/server/sonar-web/config/webpack/webpack.config.dev.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -var webpack = require('webpack'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); -var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); -var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); -var paths = require('../paths'); -var config = require('./webpack.config.base'); -var getClientEnvironment = require('../env'); - -var webContext = ''; -var env = getClientEnvironment(); - -// This makes the bundle appear split into separate modules in the devtools. -// We don't use source maps here because they can be confusing: -// https://github.com/facebookincubator/create-react-app/issues/343#issuecomment-237241875 -// You may want 'cheap-module-source-map' instead if you prefer source maps. -config.devtool = 'eval'; - -// Include an alternative client for WebpackDevServer. A client's job is to -// connect to WebpackDevServer by a socket and get notified about changes. -// When you save a file, the client will either apply hot updates (in case -// of CSS changes), or refresh the page (in case of JS changes). When you -// make a syntax error, this client will display a syntax error overlay. -// Note: instead of the default WebpackDevServer client, we use a custom one -// to bring better experience for Create React App users. You can replace -// the line below with these two lines if you prefer the stock client: -// require.resolve('webpack-dev-server/client') + '?/', -// require.resolve('webpack/hot/dev-server'), -config.entry.vendor.unshift(require.resolve('react-dev-utils/webpackHotDevClient')); - -// Add /* filename */ comments to generated require()s in the output. -config.output.pathinfo = true; - -// This is the URL that app is served from. -config.output.filename = 'js/[name].js'; -config.output.chunkFilename = 'js/[name].chunk.js'; - -config.plugins = [ - new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.js'), - - new ExtractTextPlugin('css/sonar.css', { allChunks: true }), - - // Makes the web context available as %WEB_CONTEXT% in index.html, e.g.: - // - // In development, this will be an empty string. - new InterpolateHtmlPlugin({ - WEB_CONTEXT: webContext - }), - - // Generates an `index.html` file with the