/ webpack.config.js
webpack.config.js
1 // some packages, plugins, and presets referenced/required in this webpack 2 // config are deps of embark and will be transitive dapp deps unless specified 3 // in the dapp's own package.json 4 5 // embark modifies process.env.NODE_PATH so that when running dapp scripts in 6 // embark's child processes, embark's own node_modules directory will be 7 // searched by node's require(); however, webpack and babel do not directly 8 // support NODE_PATH, so modules such as babel plugins and presets must be 9 // resolved with require.resolve(); that is only necessary if a plugin/preset 10 // is in embark's node_modules vs. the dapp's node_modules 11 12 const cloneDeep = require('lodash.clonedeep'); 13 // const CompressionPlugin = require('compression-webpack-plugin'); 14 const glob = require('glob'); 15 const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); 16 const path = require('path'); 17 18 const dappPath = process.env.DAPP_PATH; 19 const embarkPath = process.env.EMBARK_PATH; 20 21 const embarkAliases = require(path.join(dappPath, '.embark/embark-aliases.json')); 22 const embarkAssets = require(path.join(dappPath, '.embark/embark-assets.json')); 23 const embarkNodeModules = path.join(embarkPath, 'node_modules'); 24 const embarkJson = require(path.join(dappPath, 'embark.json')); 25 26 const buildDir = path.join(dappPath, embarkJson.buildDir); 27 28 // it's important to `embark reset` if a pkg version is specified in 29 // embark.json and changed/removed later, otherwise pkg resolution may behave 30 // unexpectedly 31 let versions; 32 try { 33 versions = glob.sync(path.join(dappPath, '.embark/versions/*/*')); 34 } catch (e) { 35 versions = []; 36 } 37 38 const entry = Object.keys(embarkAssets) 39 .filter(key => key.match(/\.js$/)) 40 .reduce((obj, key) => { 41 // webpack entry paths should start with './' if they're relative to the 42 // webpack context; embark.json "app" keys correspond to lists of .js 43 // source paths relative to the top-level dapp dir and may be missing the 44 // leading './' 45 obj[key] = embarkAssets[key] 46 .map(file => { 47 let file_path = file.path; 48 if (!file.path.match(/^\.\//)) { 49 file_path = './' + file_path; 50 } 51 return file_path; 52 }); 53 return obj; 54 }, {}); 55 56 function resolve(pkgName) { 57 if (Array.isArray(pkgName)) { 58 const _pkgName = pkgName[0]; 59 pkgName[0] = require.resolve(_pkgName); 60 return pkgName; 61 } 62 return require.resolve(pkgName); 63 } 64 65 // base config 66 // ----------------------------------------------------------------------------- 67 68 const base = { 69 context: dappPath, 70 entry: entry, 71 module: { 72 rules: [ 73 { 74 test: /\.css$/, 75 use: [{loader: 'style-loader'}, {loader: 'css-loader'}] 76 }, 77 { 78 test: /\.scss$/, 79 use: [{loader: 'style-loader'}, {loader: 'css-loader'}] 80 }, 81 { 82 test: /\.(png|woff|woff2|eot|ttf|svg)$/, 83 loader: 'url-loader?limit=100000' 84 }, 85 { 86 test: /\.coffee$/, 87 loader: 'better-coffee-loader', 88 // Options for coffeescript compiler 89 options: {} 90 } 91 ] 92 }, 93 output: { 94 filename: (chunkData) => chunkData.chunk.name, 95 // globalObject workaround for node-compatible UMD builds with webpack 4 96 // see: https://github.com/webpack/webpack/issues/6522#issuecomment-371120689 97 globalObject: 'typeof self !== \'undefined\' ? self : this', 98 libraryTarget: 'umd', 99 path: buildDir 100 }, 101 plugins: [new HardSourceWebpackPlugin()], 102 // profiling and generating verbose stats increases build time; if stats 103 // are generated embark will write the output to: 104 // path.join(dappPath, '.embark/stats.[json,report]') 105 // to visualize the stats info in a browser run: 106 // npx webpack-bundle-analyzer .embark/stats.json <buildDir> 107 profile: true, stats: 'verbose', 108 resolve: { 109 alias: embarkAliases, 110 modules: [ 111 ...versions, 112 'node_modules', 113 embarkNodeModules 114 ] 115 }, 116 resolveLoader: { 117 modules: [ 118 'node_modules', 119 embarkNodeModules 120 ] 121 } 122 }; 123 124 // development config 125 // ----------------------------------------------------------------------------- 126 127 const development = cloneDeep(base); 128 // full source maps increase build time but are useful during dapp development 129 development.devtool = 'source-map'; 130 development.mode = 'development'; 131 // alternatively: 132 // development.mode = 'none'; 133 development.name = 'development'; 134 const devBabelLoader = development.module.rules[3]; 135 devBabelLoader.options.compact = false; 136 137 // production config 138 // ----------------------------------------------------------------------------- 139 140 const production = cloneDeep(base); 141 production.mode = 'production'; 142 production.name = 'production'; 143 // compression of webpack's JS output not enabled by default 144 // production.plugins.push(new CompressionPlugin()); 145 146 // export a list of named configs 147 // ----------------------------------------------------------------------------- 148 149 module.exports = [ 150 development, 151 production 152 ];