build/ | build/ | ||||
src/main/webapp/js/ | src/main/webapp/js/ | ||||
src/main/webapp/css/ | src/main/webapp/css/ | ||||
src/main/webapp/index.html | |||||
src/main/webapp/WEB-INF/lib/*.jar | src/main/webapp/WEB-INF/lib/*.jar | ||||
# tests | # tests |
// config after eject: we're in ./config/ | // config after eject: we're in ./config/ | ||||
module.exports = { | module.exports = { | ||||
appBuild: resolveApp('src/main/webapp/js/bundles'), | |||||
appBuild: resolveApp('src/main/webapp'), | |||||
appPublic: resolveApp('public'), | |||||
appHtml: resolveApp('public/index.html'), | |||||
appPackageJson: resolveApp('package.json'), | appPackageJson: resolveApp('package.json'), | ||||
appSrc: resolveApp('src/main/js'), | appSrc: resolveApp('src/main/js'), | ||||
jsBuild: resolveApp('src/main/webapp/js'), | |||||
cssBuild: resolveApp('src/main/webapp/css'), | cssBuild: resolveApp('src/main/webapp/css'), | ||||
htmlBuild: resolveApp('src/main/webapp/index.html'), | |||||
appNodeModules: resolveApp('node_modules'), | appNodeModules: resolveApp('node_modules'), | ||||
ownNodeModules: resolveApp('node_modules'), | ownNodeModules: resolveApp('node_modules'), | ||||
nodePaths: nodePaths | nodePaths: nodePaths |
/* eslint no-var: 0 */ | |||||
var path = require('path'); | var path = require('path'); | ||||
var autoprefixer = require('autoprefixer'); | var autoprefixer = require('autoprefixer'); | ||||
var webpack = require('webpack'); | var webpack = require('webpack'); | ||||
var ExtractTextPlugin = require('extract-text-webpack-plugin'); | var ExtractTextPlugin = require('extract-text-webpack-plugin'); | ||||
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); | |||||
var url = require('url'); | |||||
var paths = require('../paths'); | var paths = require('../paths'); | ||||
var autoprefixerOptions = require('../autoprefixer'); | var autoprefixerOptions = require('../autoprefixer'); | ||||
'sonar': './src/main/js/libs/sonar.js', | 'sonar': './src/main/js/libs/sonar.js', | ||||
'app': './src/main/js/app/index.js', | |||||
// not unique url | |||||
'source-viewer': './src/main/js/apps/source-viewer/app.js' | |||||
'app': './src/main/js/app/index.js' | |||||
}, | }, | ||||
output: { | output: { | ||||
path: paths.appBuild, | path: paths.appBuild, | ||||
filename: '[name].js' | |||||
filename: 'js/[name].[chunkhash:8].js', | |||||
chunkFilename: 'js/[name].[chunkhash:8].chunk.js', | |||||
}, | }, | ||||
plugins: [ | |||||
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'), | |||||
new ExtractTextPlugin('../../css/sonar.css', { allChunks: true }) | |||||
], | |||||
resolve: { | resolve: { | ||||
// This allows you to set a fallback for where Webpack should look for modules. | // 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 read `NODE_PATH` environment variable in `paths.js` and pass paths here. |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
var webpack = require('webpack'); | 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 CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); | ||||
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); | var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); | ||||
var paths = require('../paths'); | var paths = require('../paths'); | ||||
var config = require('./webpack.config.base'); | var config = require('./webpack.config.base'); | ||||
var getClientEnvironment = require('../env'); | var getClientEnvironment = require('../env'); | ||||
// Webpack uses `publicPath` to determine where the app is being served from. | |||||
var publicPath = '/js/bundles/'; | |||||
// Get environment variables to inject into our app. | |||||
var publicPath = ''; | |||||
var webContext = ''; | |||||
var env = getClientEnvironment(); | var env = getClientEnvironment(); | ||||
// This makes the bundle appear split into separate modules in the devtools. | // This makes the bundle appear split into separate modules in the devtools. | ||||
// This is the URL that app is served from. | // This is the URL that app is served from. | ||||
config.output.publicPath = publicPath; | config.output.publicPath = publicPath; | ||||
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.: | |||||
// <link rel="shortcut icon" href="%WEB_CONTEXT%/favicon.ico"> | |||||
// In development, this will be an empty string. | |||||
new InterpolateHtmlPlugin({ | |||||
WEB_CONTEXT: webContext | |||||
}), | |||||
// Generates an `index.html` file with the <script> injected. | |||||
new HtmlWebpackPlugin({ | |||||
inject: false, | |||||
template: paths.appHtml, | |||||
}), | |||||
config.plugins = [].concat(config.plugins, [ | |||||
// Makes some environment variables available to the JS code, for example: | // Makes some environment variables available to the JS code, for example: | ||||
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`. | // if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`. | ||||
new webpack.DefinePlugin(env), | new webpack.DefinePlugin(env), | ||||
// This is necessary to emit hot updates (currently CSS only): | // This is necessary to emit hot updates (currently CSS only): | ||||
new webpack.HotModuleReplacementPlugin(), | new webpack.HotModuleReplacementPlugin(), | ||||
// Watcher doesn't work well if you mistype casing in a path so we use | // Watcher doesn't work well if you mistype casing in a path so we use | ||||
// a plugin that prints an error when you attempt to do this. | // a plugin that prints an error when you attempt to do this. | ||||
// See https://github.com/facebookincubator/create-react-app/issues/240 | // See https://github.com/facebookincubator/create-react-app/issues/240 | ||||
new CaseSensitivePathsPlugin(), | new CaseSensitivePathsPlugin(), | ||||
// If you require a missing module and then `npm install` it, you still have | // If you require a missing module and then `npm install` it, you still have | ||||
// to restart the development server for Webpack to discover it. This plugin | // to restart the development server for Webpack to discover it. This plugin | ||||
// makes the discovery automatic so you don't have to restart. | // makes the discovery automatic so you don't have to restart. | ||||
// See https://github.com/facebookincubator/create-react-app/issues/186 | // See https://github.com/facebookincubator/create-react-app/issues/186 | ||||
new WatchMissingNodeModulesPlugin(paths.appNodeModules) | new WatchMissingNodeModulesPlugin(paths.appNodeModules) | ||||
]); | |||||
]; | |||||
module.exports = config; | module.exports = config; |
* along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
var webpack = require('webpack'); | |||||
var ExtractTextPlugin = require('extract-text-webpack-plugin'); | |||||
var HtmlWebpackPlugin = require('html-webpack-plugin'); | |||||
var config = require('./webpack.config.base'); | var config = require('./webpack.config.base'); | ||||
var getClientEnvironment = require('../env'); | |||||
var paths = require('../paths'); | |||||
// Get environment variables to inject into our app. | |||||
var env = getClientEnvironment(); | |||||
// disable eslint loader | // disable eslint loader | ||||
config.module.preLoaders = []; | config.module.preLoaders = []; | ||||
// Don't attempt to continue if there are any errors. | |||||
config.bail = true; | |||||
config.plugins = [ | |||||
new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.[chunkhash:8].js'), | |||||
new ExtractTextPlugin('css/sonar.[chunkhash:8].css', { allChunks: true }), | |||||
new HtmlWebpackPlugin({ | |||||
inject: false, | |||||
template: paths.appHtml | |||||
}) | |||||
]; | |||||
module.exports = config; | module.exports = config; |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
var webpack = require('webpack'); | var webpack = require('webpack'); | ||||
var ExtractTextPlugin = require('extract-text-webpack-plugin'); | |||||
var HtmlWebpackPlugin = require('html-webpack-plugin'); | |||||
var config = require('./webpack.config.base'); | var config = require('./webpack.config.base'); | ||||
var getClientEnvironment = require('../env'); | var getClientEnvironment = require('../env'); | ||||
var paths = require('../paths'); | |||||
// Get environment variables to inject into our app. | // Get environment variables to inject into our app. | ||||
var env = getClientEnvironment(); | var env = getClientEnvironment(); | ||||
// Don't attempt to continue if there are any errors. | // Don't attempt to continue if there are any errors. | ||||
config.bail = true; | config.bail = true; | ||||
config.plugins = [].concat(config.plugins, [ | |||||
config.plugins = [ | |||||
new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.[chunkhash:8].js'), | |||||
new ExtractTextPlugin('css/sonar.[chunkhash:8].css', { allChunks: true }), | |||||
new HtmlWebpackPlugin({ | |||||
inject: false, | |||||
template: paths.appHtml, | |||||
minify: { | |||||
removeComments: true, | |||||
collapseWhitespace: true, | |||||
removeRedundantAttributes: true, | |||||
useShortDoctype: true, | |||||
removeEmptyAttributes: true, | |||||
removeStyleLinkTypeAttributes: true, | |||||
keepClosingSlash: true, | |||||
minifyJS: true, | |||||
minifyCSS: true, | |||||
minifyURLs: true | |||||
} | |||||
}), | |||||
// Makes some environment variables available to the JS code, for example: | // Makes some environment variables available to the JS code, for example: | ||||
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`. | // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`. | ||||
// It is absolutely essential that NODE_ENV was set to production here. | // It is absolutely essential that NODE_ENV was set to production here. | ||||
// Otherwise React will be compiled in the very slow development mode. | // Otherwise React will be compiled in the very slow development mode. | ||||
new webpack.DefinePlugin(env), | new webpack.DefinePlugin(env), | ||||
// This helps ensure the builds are consistent if source hasn't changed: | // This helps ensure the builds are consistent if source hasn't changed: | ||||
new webpack.optimize.OccurrenceOrderPlugin(), | new webpack.optimize.OccurrenceOrderPlugin(), | ||||
// Try to dedupe duplicated modules, if any: | // Try to dedupe duplicated modules, if any: | ||||
new webpack.optimize.DedupePlugin(), | new webpack.optimize.DedupePlugin(), | ||||
// Minify the code. | // Minify the code. | ||||
new webpack.optimize.UglifyJsPlugin({ | new webpack.optimize.UglifyJsPlugin({ | ||||
compress: { | compress: { | ||||
comments: false, | comments: false, | ||||
screw_ie8: true | screw_ie8: true | ||||
} | } | ||||
}), | |||||
]); | |||||
}) | |||||
]; | |||||
module.exports = config; | module.exports = config; |
"handlebars": "2.0.0", | "handlebars": "2.0.0", | ||||
"handlebars-loader": "1.1.4", | "handlebars-loader": "1.1.4", | ||||
"history": "2.0.0", | "history": "2.0.0", | ||||
"html-webpack-plugin": "2.24.1", | |||||
"imports-loader": "0.6.5", | "imports-loader": "0.6.5", | ||||
"jest": "15.1.1", | "jest": "15.1.1", | ||||
"jquery": "2.2.0", | "jquery": "2.2.0", |
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<link href="%WEB_CONTEXT%/favicon.ico" rel="shortcut icon" type="image/x-icon"> | |||||
<% for (var css in htmlWebpackPlugin.files.css) { %> | |||||
<link href="%WEB_CONTEXT%/<%= htmlWebpackPlugin.files.css[css] %>" rel="stylesheet"> | |||||
<% } %> | |||||
<title>SonarQube</title> | |||||
</head> | |||||
<body> | |||||
<div id="content"></div> | |||||
<script>window.baseUrl = '%WEB_CONTEXT%';</script> | |||||
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %> | |||||
<script src="%WEB_CONTEXT%/<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script> | |||||
<% } %> | |||||
</body> | |||||
</html> |
process.env.NODE_ENV = 'production'; | process.env.NODE_ENV = 'production'; | ||||
var chalk = require('chalk'); | var chalk = require('chalk'); | ||||
var fs = require('fs'); | |||||
var fs = require('fs-extra'); | |||||
var path = require('path'); | var path = require('path'); | ||||
var rimrafSync = require('rimraf').sync; | var rimrafSync = require('rimraf').sync; | ||||
var webpack = require('webpack'); | var webpack = require('webpack'); | ||||
require('../config/webpack/webpack.config.fast') : | require('../config/webpack/webpack.config.fast') : | ||||
require('../config/webpack/webpack.config.prod'); | require('../config/webpack/webpack.config.prod'); | ||||
function clean () { | |||||
// Remove all content but keep the directory so that | // Remove all content but keep the directory so that | ||||
// if you're in it, you don't end up in Trash | // if you're in it, you don't end up in Trash | ||||
console.log(chalk.cyan.bold('Cleaning output directories...')); | |||||
console.log(chalk.cyan.bold('Cleaning output directories and files...')); | |||||
console.log(paths.appBuild + '/*'); | |||||
rimrafSync(paths.appBuild + '/*'); | |||||
console.log(paths.jsBuild + '/*'); | |||||
rimrafSync(paths.jsBuild + '/*'); | |||||
console.log(paths.cssBuild + '/*'); | |||||
rimrafSync(paths.cssBuild + '/*'); | |||||
console.log(paths.cssBuild + '/*'); | |||||
rimrafSync(paths.cssBuild + '/*'); | |||||
console.log(); | |||||
console.log(paths.htmlBuild); | |||||
rimrafSync(paths.htmlBuild); | |||||
if (isFastBuild) { | |||||
console.log(chalk.magenta.bold('Running fast build...')); | |||||
} else { | |||||
console.log(chalk.cyan.bold('Creating optimized production build...')); | |||||
console.log(); | |||||
} | } | ||||
console.log(); | |||||
webpack(config, (err, stats) => { | |||||
if (err) { | |||||
console.log(chalk.red.bold('Failed to create a production build!')); | |||||
console.log(chalk.red(err.message || err)); | |||||
process.exit(1); | |||||
function build () { | |||||
if (isFastBuild) { | |||||
console.log(chalk.magenta.bold('Running fast build...')); | |||||
} else { | |||||
console.log(chalk.cyan.bold('Creating optimized production build...')); | |||||
} | } | ||||
console.log(); | |||||
if (stats.compilation.errors && stats.compilation.errors.length) { | |||||
console.log(chalk.red.bold('Failed to create a production build!')); | |||||
stats.compilation.errors.forEach(err => console.log(chalk.red(err.message || err))); | |||||
process.exit(1); | |||||
} | |||||
webpack(config, (err, stats) => { | |||||
if (err) { | |||||
console.log(chalk.red.bold('Failed to create a production build!')); | |||||
console.log(chalk.red(err.message || err)); | |||||
process.exit(1); | |||||
} | |||||
if (stats.compilation.errors && stats.compilation.errors.length) { | |||||
console.log(chalk.red.bold('Failed to create a production build!')); | |||||
stats.compilation.errors.forEach(err => console.log(chalk.red(err.message || err))); | |||||
process.exit(1); | |||||
} | |||||
var jsonStats = stats.toJson(); | |||||
console.log('Assets:'); | |||||
var assets = jsonStats.assets.slice(); | |||||
assets.sort((a, b) => b.size - a.size); | |||||
assets.forEach(asset => { | |||||
var sizeLabel = formatSize(asset.size); | |||||
var leftPadding = ' '.repeat(Math.max(0, 8 - sizeLabel.length)); | |||||
sizeLabel = leftPadding + sizeLabel; | |||||
console.log('', chalk.yellow(sizeLabel), asset.name); | |||||
}); | |||||
console.log(); | |||||
var jsonStats = stats.toJson(); | |||||
var seconds = jsonStats.time / 1000; | |||||
console.log('Duration: ' + seconds.toFixed(2) + 's'); | |||||
console.log(); | |||||
console.log('Assets:'); | |||||
var assets = jsonStats.assets.slice(); | |||||
assets.sort((a, b) => b.size - a.size); | |||||
assets.forEach(asset => { | |||||
var sizeLabel = formatSize(asset.size); | |||||
var leftPadding = ' '.repeat(8 - sizeLabel.length); | |||||
sizeLabel = leftPadding + sizeLabel; | |||||
console.log('', chalk.yellow(sizeLabel), asset.name); | |||||
console.log(chalk.green.bold('Compiled successfully!')); | |||||
}); | }); | ||||
console.log(); | |||||
} | |||||
function copyPublicFolder () { | |||||
fs.copySync(paths.appPublic, paths.appBuild, { | |||||
dereference: true, | |||||
filter: file => file !== paths.appHtml | |||||
}); | |||||
} | |||||
var seconds = jsonStats.time / 1000; | |||||
console.log('Duration: ' + seconds.toFixed(2) + 's'); | |||||
console.log(); | |||||
console.log(chalk.green.bold('Compiled successfully!')); | |||||
}); | |||||
clean(); | |||||
build(); | |||||
copyPublicFolder(); |
var PROXY_URL = 'http://localhost:9000'; | var PROXY_URL = 'http://localhost:9000'; | ||||
// You can safely remove this after ejecting. | |||||
// We only use this block for testing of Create React App itself: | |||||
var isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1); | |||||
if (isSmokeTest) { | |||||
handleCompile = function (err, stats) { | |||||
if (err || stats.hasErrors() || stats.hasWarnings()) { | |||||
process.exit(1); | |||||
} else { | |||||
process.exit(0); | |||||
} | |||||
}; | |||||
} | |||||
function setupCompiler (host, port, protocol) { | function setupCompiler (host, port, protocol) { | ||||
// "Compiler" is a low-level interface to Webpack. | // "Compiler" is a low-level interface to Webpack. | ||||
// It lets us listen to some events and provide our own custom messages. | // It lets us listen to some events and provide our own custom messages. | ||||
// - /*.hot-update.json (WebpackDevServer uses this too for hot reloading) | // - /*.hot-update.json (WebpackDevServer uses this too for hot reloading) | ||||
// - /sockjs-node/* (WebpackDevServer uses this for hot reloading) | // - /sockjs-node/* (WebpackDevServer uses this for hot reloading) | ||||
// Tip: use https://jex.im/regulex/ to visualize the regex | // Tip: use https://jex.im/regulex/ to visualize the regex | ||||
var mayProxy = /^(?!\/(.*\.hot-update\.json$|sockjs-node\/)).*$/; | |||||
var mayProxy = /^(?!\/(index\.html$|.*\.hot-update\.json$|sockjs-node\/)).*$/; | |||||
devServer.use(mayProxy, | devServer.use(mayProxy, | ||||
// Pass the scope regex both to Express and to the middleware for proxying | // Pass the scope regex both to Express and to the middleware for proxying | ||||
// of both HTTP and WebSockets to work without false positives. | // of both HTTP and WebSockets to work without false positives. | ||||
function runDevServer (host, port, protocol) { | function runDevServer (host, port, protocol) { | ||||
var devServer = new WebpackDevServer(compiler, { | var devServer = new WebpackDevServer(compiler, { | ||||
// Enable gzip compression of generated files. | |||||
compress: true, | |||||
// Silence WebpackDevServer's own logs since they're generally not useful. | // Silence WebpackDevServer's own logs since they're generally not useful. | ||||
// It will still show compile warnings and errors with this setting. | // It will still show compile warnings and errors with this setting. | ||||
clientLogLevel: 'none', | clientLogLevel: 'none', |