| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| const autoprefixer = require('autoprefixer'); |
| const HtmlWebpackPlugin = require('html-webpack-plugin'); |
| const ExtractTextPlugin = require("extract-text-webpack-plugin"); |
| const path = require('path'); |
| const fs = require('fs'); |
| const PropertiesReader = require('properties-reader'); |
| const LessToJs = require('less-vars-to-js'); |
| const pkg = require('./../../package.json'); |
| const webpack = require('webpack'); |
| const pj = path.join; |
| |
| const ENV = process.env.NODE_ENV || 'development'; |
| const ROOT_DIR = pj(path.resolve(__dirname), './../..'); |
| const SRC_DIR = pj(ROOT_DIR, 'app'); |
| const DEST_DIR = pj(ROOT_DIR, 'dist'); |
| const NODE_MODULES_DIR = pj(ROOT_DIR, 'node_modules'); |
| const UTILS_NODE_MODULES_DIR = pj(ROOT_DIR, '../utils/node_modules'); |
| const BRAND_FALLBACK_DIR = pj(ROOT_DIR, '../branding'); |
| const BRAND_DIR = (process.env.BROOKLYN_UI_BRAND_DIR && process.env.BROOKLYN_UI_BRAND_DIR!='default') |
| // default accepted because mvn needs to pass a value and empty isn't allowed |
| ? path.isAbsolute(process.env.BROOKLYN_UI_BRAND_DIR) |
| ? process.env.BROOKLYN_UI_BRAND_DIR |
| : pj(ROOT_DIR, process.env.BROOKLYN_UI_BRAND_DIR) |
| : pj(BRAND_FALLBACK_DIR, 'brooklyn'); |
| |
| const brandProps = PropertiesReader(path.resolve(BRAND_FALLBACK_DIR, 'brand.properties')); |
| brandProps.append(path.resolve(BRAND_DIR, 'brand.properties')); |
| const BRAND_IDENTIFIER = brandProps.get('brand-identifier'); |
| if (!BRAND_IDENTIFIER) { |
| throw("The brand.properties file in "+BRAND_DIR+" must specify a brand-identifier."); |
| } |
| var brandLess = {}; |
| const getBrandedText = ((brandProps) => (key) => { |
| var branded = key.split('.').reduce(function(o, x) { |
| return o ? o[x] : undefined; |
| }, brandProps); |
| |
| // TODO we should remove the "brooklyn" sections in package.json as a way of branding; |
| // always use the props above |
| return branded ? branded : key.split('.').reduce(function(o, x) { |
| return o ? o[x] : undefined; |
| }, pkg.brooklyn); |
| }); |
| |
| const getStyleLoader = function() { |
| var loader = []; |
| loader.push('css' + (ENV === 'development' ? '?sourceMap' : '')); |
| loader.push('postcss'); |
| |
| const brandLessVars = LessToJs(fs.readFileSync(path.resolve(BRAND_DIR, 'brand.less'), 'utf8')); |
| const brandLessVarsFromFallback = LessToJs(fs.readFileSync(path.resolve(BRAND_FALLBACK_DIR, 'brand.less'), 'utf8')); |
| var brandLessVarsFromProps = brandProps.getByRoot('less'); |
| Object.assign(brandLess, brandLessVarsFromFallback, brandLessVarsFromProps, brandLessVars); |
| brandLess['brand-identifier'] = BRAND_IDENTIFIER; |
| |
| var lessConfig = { modifyVars: brandLess }; |
| |
| if (ENV === 'development') { |
| lessConfig.sourceMap = true; |
| } |
| loader.push('less?' + JSON.stringify(lessConfig)); |
| |
| return loader.join('!'); |
| }; |
| |
| console.log('Build with:', 'ENV', ENV, '-', 'brand-identifier', BRAND_IDENTIFIER); |
| |
| const config = { |
| context: SRC_DIR, |
| entry: { |
| index: [ |
| 'babel-polyfill', |
| 'index.less', |
| 'index.js' |
| ] |
| }, |
| output: { |
| filename: '[name].[hash].js', |
| path: DEST_DIR |
| }, |
| module: { |
| loaders: [{ |
| test: /\.js$/i, |
| exclude: /node_modules/, |
| loader: 'babel', |
| query: { |
| presets: [ |
| 'babel-preset-env', |
| 'babel-preset-stage-0', |
| ].map(require.resolve) |
| } |
| }, { |
| test: /\.less$/, |
| exclude: /index.less/, |
| loader: getStyleLoader() |
| }, { |
| test: /index.less$/, |
| loader: ExtractTextPlugin.extract(getStyleLoader()) |
| }, { |
| test: /\.(jpe?g|png|gif)$/i, |
| loaders: [ |
| 'url-loader?limit=50000&name=assets/[name].[hash].[ext]', |
| 'image-webpack' |
| ] |
| }, { |
| test: /\.(woff|svg|ttf|eot)([\?]?.*)$/, |
| loader: 'file-loader?name=assets/[name].[hash].[ext]' |
| }, { |
| test: /\.json$/, |
| loader: 'raw-loader' |
| }, { |
| test: /\.html$/, |
| loader: 'html?interpolate&-minimize&attrs[]=img:src&attrs[]=img:data-src&attrs[]=object:data' |
| }] |
| }, |
| resolve: { |
| alias: { |
| 'brooklyn-shared': path.resolve(ROOT_DIR, '../shared'), |
| // user-supplied brand dir for overwrites (defaults to brooklyn brand) |
| 'brand': BRAND_DIR, |
| // fallback branding info |
| 'brand-fallback': BRAND_FALLBACK_DIR, |
| // brand-supplied JS definitions |
| 'brand-js': fs.existsSync(pj(BRAND_DIR, 'brand.js')) ? pj(BRAND_DIR, 'brand.js') : pj(BRAND_FALLBACK_DIR, 'brand.js'), |
| }, |
| root: SRC_DIR, |
| extensions: ['', '.js'], |
| modulesDirectories: [ |
| NODE_MODULES_DIR, |
| UTILS_NODE_MODULES_DIR |
| ] |
| }, |
| resolveLoader: { |
| root: [NODE_MODULES_DIR], |
| modulesDirectories: [ |
| NODE_MODULES_DIR, |
| UTILS_NODE_MODULES_DIR |
| ] |
| }, |
| postcss: [ |
| autoprefixer({ |
| browsers: ['last 2 versions'] |
| }) |
| ], |
| ejsHtml: { |
| // a "brooklyn" section in package.json can contain extra info like `product.name` and `appname` |
| app: pkg.brooklyn, |
| brand: brandProps.path(), |
| getBrandedText: getBrandedText(brandProps.path()) |
| }, |
| plugins: [ |
| new ExtractTextPlugin('[name].[chunkhash].css'), |
| new webpack.optimize.OccurenceOrderPlugin(), |
| new webpack.DefinePlugin({ |
| __BROOKLYN_VERSION__: JSON.stringify(process.env.BROOKLYN_VERSION || '1.1.0-SNAPSHOT'), |
| __BUILD_NAME__: JSON.stringify(process.env.BUILD_NAME), |
| __BUILD_VERSION__: JSON.stringify(process.env.BUILD_VERSION), |
| __BUILD_BRANCH__: JSON.stringify(process.env.BUILD_BRANCH), |
| __BUILD_COMMIT_ID__: JSON.stringify(process.env.BUILD_COMMIT_ID), |
| // from bootstrap, possibly overridden, included here for access from JS |
| __BRAND_SUCCESS__: JSON.stringify(brandLess['@brand-success'] || '#5cb85c'), |
| __BRAND_DANGER__: JSON.stringify(brandLess['@brand-danger'] || '#d9534f'), |
| 'process.env.NODE_ENV': JSON.stringify(ENV), |
| // used by brBrandInfo.getBrandedText |
| __BRAND_PROPS__: JSON.stringify(brandProps.path()), |
| }), |
| new webpack.ProvidePlugin({ |
| 'Promise': 'imports?this=>global!exports?global.Promise!es6-promise' |
| }), |
| new HtmlWebpackPlugin({ |
| template: 'ejs-html!' + pj(SRC_DIR, 'index.html'), |
| chunksSortMode: 'dependency' |
| }), |
| new webpack.optimize.CommonsChunkPlugin({ |
| name: 'vendor', |
| minChunks: function (module) { |
| // This prevents stylesheet resources with the .css or .scss extension |
| // from being moved from their original chunk to the vendor chunk |
| if (module.resource && (/^.*\.(css|scss|less)$/).test(module.resource)) { |
| return false; |
| } |
| return module.context && module.context.indexOf('node_modules') !== -1; |
| } |
| }), |
| new webpack.optimize.CommonsChunkPlugin({ |
| name: 'manifest', |
| minChunks: Infinity |
| }) |
| ] |
| }; |
| |
| if (fs.existsSync(pj(BRAND_DIR, 'build-config-tweak.js'))) { |
| eval(""+fs.readFileSync(pj(BRAND_DIR, 'build-config-tweak.js'))); |
| } |
| |
| if (ENV === 'development') { |
| config.watch = true; |
| config.debug = true; |
| config.devtool = 'source-map'; |
| config.entry.index.push('webpack-hot-middleware/client'); |
| config.plugins.push(new webpack.HotModuleReplacementPlugin()) |
| } else { |
| config.plugins.push( |
| new webpack.optimize.DedupePlugin(), |
| new webpack.optimize.UglifyJsPlugin({ |
| mangle: false, |
| compress: { |
| dead_code: true, |
| unused: true, |
| warnings: false |
| } |
| }), |
| new webpack.BannerPlugin(getBrandedText(brandProps.path())("banner")) |
| ) |
| } |
| |
| module.exports = config; |