UNPKG

cordova-elm-template-jumpstart

Version:

Cordova template to jumpstart development using Elm and Webpack

280 lines (274 loc) 8.38 kB
const ExtractTextPlugin = require("extract-text-webpack-plugin"); const webpack = require("webpack"); const os = require("os"); const path = require("path"); const _ = require("lodash"); const keysToConstCase = (map) => _.mapKeys(map, (val,key) => _.toUpper(_.snakeCase(key))); const fs = require("fs"); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const ClosureCompilerPlugin = require('webpack-closure-compiler'); const OptimizeJsPlugin = require("optimize-js-plugin"); const FaviconsWebpackPlugin = require('favicons-webpack-plugin'); const packageJson = keysToConstCase(require("./package.json")); const optional = require("optional"); const googleServices = keysToConstCase(optional("./google-services.json") || {}); const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); const WebpackShellPlugin = require('webpack-shell-plugin'); googleServices.FB_PROJECT_ID = _.get(googleServices, "project_info.project_id"); googleServices.FB_MESSAGING_SENDER_ID = _.get(googleServices, "project_info.project_number"); const ENV = process.env['NODE_ENV'] || 'development'; const IS_DEV = ENV == 'development'; const notDev = (it) => IS_DEV ? null : it; const onlyDev = (it) => IS_DEV ? it : null; const node_modules = /\/(?:node_modules|elm_stuff)\//; const localConfig = fs.existsSync("./local.config.json") ? require("./local.config.json") : {}; const babel = { loader: 'babel-loader', options: { presets: _.compact(['env', 'bluebird', notDev('minify') ]), plugins: _.compact([ "transform-strict-mode", "transform-undefined-to-void", "transform-node-env-inline", notDev('transform-remove-console'), notDev('transform-remove-debugger'), ]), cacheDirectory: IS_DEV, } } const urlLoader = { loader: 'url-loader', options: { limit: IS_DEV ? 1024 * 1024 : 32 * 1024 - 1, // 32k is the maximum safe size for data uris on old browsers hash: 'sha256', digest: 'hex', name: '[path][name].' + (IS_DEV ? "dev" : '[sha256:hash:base62]') + '.[ext]', useRelativePath: false, }, } const imageMinLoader = { loader: 'image-webpack-loader', options: { mozjpeg: { quality: 65, interlaced: true, }, pngquant:{ quality: "65-90", speed: 1 }, svgo:{ }, gifsicle: { optimizationLevel: 7, interlaced: true, }, optipng: { optimizationLevel: 7, }, }, } const scssLoaders = [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 3, sourceMap: true, minimize: !IS_DEV, } }, { loader: 'postcss-loader', options: { sourceMap: true, } }, 'resolve-url-loader', { loader: 'sass-loader', options: { sourceMap: true, sourceMapContents: true, sourceMapEmbed: true, precision: 2, sourceComments: IS_DEV, outputStyle: IS_DEV ? 'nested' : 'compressed', includePaths: [ path.resolve(__dirname, 'node_modules'), path.resolve(__dirname, 'src', 'scss'), ], }, }, ] module.exports = { devtool: 'source-map', context: path.resolve(__dirname), watchOptions: { ignored: [ /node_modules\//, /\.git\//, /www\//, /platforms\//, /plugins\//, /hooks\//, /scripts\// ] }, entry: { bootstrap : [ path.resolve(__dirname, "src", "vendor", "jquery.js"), path.resolve(__dirname, "src", "vendor", "popper.js"), "bootstrap", ], compatibility: [ 'babel-polyfill', path.resolve(__dirname, "src", "vendor", "svg4everybody.js"), path.resolve(__dirname, "src", "vendor", "touchEmulator.js"), ], app: [ path.resolve(__dirname, "src", "index.js"), ], style: [ path.resolve(__dirname, "src", "scss", "index.scss"), ], }, output: { path: path.resolve(__dirname, 'www'), chunkFilename: 'chunk.[id].' + (IS_DEV ? "dev" : '[chunkhash]') + '.js', filename: '[name].' + (IS_DEV ? "dev" : '[chunkhash]') + '.js', crossOriginLoading: 'anonymous', hashFunction: 'sha256', pathinfo: IS_DEV, strictModuleExceptionHandling: true }, module: { rules: [ { test: /\.json5?$/i, use: [ 'json5-loader' ], }, { test: /\.(gif|png|jpe?g|svg)$/i, use: _.compact([ urlLoader, notDev(imageMinLoader), ]), }, { test: /\.elm$/i, use: [ babel, { loader: 'elm-webpack-loader', options: { cwd: path.resolve(__dirname, "src", "elm"), warn: IS_DEV, debug: IS_DEV, verbose: true, pathToMake: path.resolve(__dirname, "script", "unbuffer-elm-make"), } }, ], }, { test: /\.jsx?$/i, exclude: node_modules, use: [ babel, ] }, { test: /\.(eot|ttf|woff2?)(\?.*)?$/i, loader: [ urlLoader, ], }, { test: /\.s?css$/i, use: scssLoaders, }, ], }, plugins: _.compact([ new FaviconsWebpackPlugin({ logo: path.resolve(__dirname, 'icon.png'), prefix: 'favicon/' + (IS_DEV ? "dev" : '[hash]') + '/', emitStats: false, persistentCache: false, inject: true, background: '#fff', title: 'Elm-Based Cordova App', icons: { android: !IS_DEV, appleIcon: !IS_DEV, appleStartup: !IS_DEV, coast: !IS_DEV, favicons: true, firefox: !IS_DEV, windows: !IS_DEV, yandex: !IS_DEV } }), new webpack.DefinePlugin(_.mapValues(_.merge({ // Add in any "constants" that you want. Note that NODE_ENV is already handled by Babel // Also, you have all of package.json (but the keys are constant-cased). // Finally, it loads 'local.config.json' and merges those things in. MIN_SPLASH_MS: 5000, // Minimum amount of time for a splash screen to be up IS_DEV: IS_DEV, // Note for a development environment // Google Analytics constants GOOGLE_TRACKING_ID: null, // Defining this to truthy enables Google tracking in production GA_CUSTOM_DIM_CORDOVA_VERSION: 1, // Defining this to >0 sets the Cordova version as a custom dimension GA_CUSTOM_DIM_DEVICE_MODEL: 2, // Defining this to >0 sets the hardware device model as a custom dimension GA_CUSTOM_DIM_CONNECTIVITY: 3, // Defining this to >0 sets the Internet connectivity as a custom dimension GA_CUSTOM_DIM_PLATFORM: 4, // Defining this to >0 sets the OS platform (iOS/Android/web) as a custom dimension GA_CUSTOM_DIM_DEVICE_UUID: 5, // Defining this to >0 sets the device UUID as a custom dimension GA_CUSTOM_DIM_DEVICE_VERSION: 6, // Defining this to >0 sets the OS/device version as a custom dimension GA_CUSTOM_DIM_DEVICE_MANUFACTURER: 7, // Defining this to >0 sets the manufacturer as a custom dimension }, googleServices, packageJson, localConfig), it => JSON.stringify(it))), new UglifyJSPlugin({ parallel: true, sourceMap: true, uglifyOptions: { compress: !IS_DEV, output: { comments: IS_DEV, beautify: IS_DEV, }, ecma: 8, } }), notDev(new OptimizeJsPlugin({ sourceMap: true, })), new HtmlWebpackPlugin({ inject: 'head', minify: notDev({}), filename: "index.html", template: path.resolve("src", "index.html"), chunkSortMode: "dependency" }), new CopyWebpackPlugin([ { from: './splash.png', to: './splash.png' }, ], { debug: 'info' }), new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: 2, children: true, minSize: 0, }), new WebpackShellPlugin({ // See https://github.com/kevlened/copy-webpack-plugin/issues/15 onBuildStart: [ 'echo "Cleaning up previous build leftovers"', 'rm -r -v -f ./www/*', ], onBuildEnd: [ 'echo "Copying the files to the browser"', 'cp -r -v -f ./www ./platforms/browser/', 'echo "Build complete"', ], dev: false // Weird name for executing only once }), ]), };