embark-area-51/lib/pipeline/webpack.config.js

190 lines
5.9 KiB
JavaScript
Raw Normal View History

2018-08-20 19:19:26 +00:00
// some packages, plugins, and presets referenced/required in this webpack
2018-08-16 20:49:19 +00:00
// config are deps of embark and will be transitive dapp deps unless specified
2018-08-20 19:19:26 +00:00
// in the dapp's own package.json
2018-08-16 20:49:19 +00:00
2018-08-20 19:19:26 +00:00
// embark modifies process.env.NODE_PATH so that when running dapp scripts in
// embark's child processes, embark's own node_modules directory will be
// searched by node's require(); however, webpack and babel do not directly
// support NODE_PATH, so modules such as babel plugins and presets must be
// resolved with require.resolve(); that is only necessary if a plugin/preset
// is in embark's node_modules vs. the dapp's node_modules
2018-08-17 17:32:58 +00:00
2018-08-16 20:49:19 +00:00
const cloneDeep = require('lodash.clonedeep');
// const CompressionPlugin = require('compression-webpack-plugin');
2018-08-16 20:49:19 +00:00
const glob = require('glob');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const path = require('path');
const dappPath = process.env.DAPP_PATH;
const embarkPath = process.env.EMBARK_PATH;
2018-08-16 20:49:19 +00:00
const embarkAliases = require(path.join(dappPath, '.embark/embark-aliases.json'));
const embarkAssets = require(path.join(dappPath, '.embark/embark-assets.json'));
2018-08-17 22:55:59 +00:00
const embarkNodeModules = path.join(embarkPath, 'node_modules');
2018-08-17 21:45:35 +00:00
const embarkJson = require(path.join(dappPath, 'embark.json'));
2018-08-16 20:49:19 +00:00
2018-08-17 22:55:59 +00:00
const buildDir = path.join(dappPath, embarkJson.buildDir);
2018-08-16 20:49:19 +00:00
// it's important to `embark reset` if a pkg version is specified in
// embark.json and changed/removed later, otherwise pkg resolution may behave
2018-08-20 19:19:26 +00:00
// unexpectedly
2018-08-16 20:49:19 +00:00
let versions;
try {
versions = glob.sync(path.join(dappPath, '.embark/versions/*/*'));
} catch (e) {
versions = [];
}
2018-08-17 21:45:47 +00:00
const entry = Object.keys(embarkAssets)
2018-09-05 21:49:26 +00:00
.filter(key => key.match(/\.js$/))
2018-08-20 15:28:43 +00:00
.reduce((obj, key) => {
2018-08-20 18:52:48 +00:00
// webpack entry paths should start with './' if they're relative to the
// webpack context; embark.json "app" keys correspond to lists of .js
// source paths relative to the top-level dapp dir and may be missing the
// leading './'
2018-08-20 15:28:43 +00:00
obj[key] = embarkAssets[key]
.map(file => {
let file_path = file.path;
if (!file.path.match(/^\.\//)) {
file_path = './' + file_path;
}
return file_path;
});
return obj;
}, {});
2018-08-16 20:49:19 +00:00
2018-08-19 00:55:34 +00:00
function resolve(pkgName) {
if (Array.isArray(pkgName)) {
const _pkgName = pkgName[0];
pkgName[0] = require.resolve(_pkgName);
return pkgName;
}
2018-08-20 18:57:04 +00:00
return require.resolve(pkgName);
2018-08-19 00:55:34 +00:00
}
2018-08-16 20:49:19 +00:00
// base config
// -----------------------------------------------------------------------------
// order and options of plugins and presets adapted from babel-preset-react-app:
// see: https://github.com/facebook/create-react-app/blob/72d4ab02922c54b80126da2e132f60fdbdc2f6b3/packages/babel-preset-react-app/create.js
2018-10-01 23:36:46 +00:00
// + Plugins run before Presets.
// + Plugin ordering is first to last.
// + Preset ordering is reversed (last to first).
// see: https://babeljs.io/docs/en/plugins#plugin-ordering
2018-08-16 20:49:19 +00:00
const base = {
context: dappPath,
entry: entry,
module: {
rules: [
{
2018-10-02 00:16:32 +00:00
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
2018-08-16 20:49:19 +00:00
},
{
test: /\.scss$/,
use: [{loader: 'style-loader'}, {loader: 'css-loader'}]
},
{
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
loader: 'url-loader?limit=100000'
},
{
2018-08-16 21:49:32 +00:00
test: /\.jsx?$/,
2018-08-16 20:49:19 +00:00
loader: 'babel-loader',
exclude: /(node_modules|bower_components|\.embark[\\/]versions)/,
options: {
plugins: [
[
2018-08-19 00:55:34 +00:00
'babel-plugin-module-resolver', {
2018-08-16 20:49:19 +00:00
'alias': embarkAliases
}
],
[
2018-08-19 00:55:34 +00:00
'@babel/plugin-transform-runtime', {
2018-08-16 20:49:19 +00:00
corejs: 2,
useESModules: true
}
]
2018-08-19 00:55:34 +00:00
].map(resolve),
2018-08-16 20:49:19 +00:00
presets: [
[
2018-08-19 00:55:34 +00:00
'@babel/preset-env', {
2018-08-16 20:49:19 +00:00
modules: false,
targets: {
browsers: ['last 1 version', 'not dead', '> 0.2%']
}
}
],
2018-08-19 00:55:34 +00:00
'@babel/preset-react'
].map(resolve)
2018-08-16 20:49:19 +00:00
}
}
]
},
output: {
filename: (chunkData) => chunkData.chunk.name,
// globalObject workaround for node-compatible UMD builds with webpack 4
// see: https://github.com/webpack/webpack/issues/6522#issuecomment-371120689
globalObject: 'typeof self !== \'undefined\' ? self : this',
libraryTarget: 'umd',
2018-08-17 22:55:59 +00:00
path: buildDir
2018-08-16 20:49:19 +00:00
},
2018-08-17 22:14:28 +00:00
plugins: [new HardSourceWebpackPlugin()],
2018-08-16 20:49:19 +00:00
// profiling and generating verbose stats increases build time; if stats
// are generated embark will write the output to:
// path.join(dappPath, '.embark/stats.[json,report]')
// to visualize the stats info in a browser run:
// npx webpack-bundle-analyzer .embark/stats.json <buildDir>
2018-08-16 20:49:19 +00:00
profile: true, stats: 'verbose',
resolve: {
alias: embarkAliases,
modules: [
...versions,
'node_modules',
2018-08-17 22:55:59 +00:00
embarkNodeModules
2018-08-16 20:49:19 +00:00
]
},
resolveLoader: {
modules: [
'node_modules',
2018-08-17 22:55:59 +00:00
embarkNodeModules
2018-08-17 22:14:28 +00:00
]
2018-08-16 20:49:19 +00:00
}
};
// development config
// -----------------------------------------------------------------------------
const development = cloneDeep(base);
// full source maps increase build time but are useful during dapp development
development.devtool = 'source-map';
2018-08-16 20:49:19 +00:00
development.mode = 'development';
2018-08-17 21:46:36 +00:00
// alternatively:
// development.mode = 'none';
2018-08-16 20:49:19 +00:00
development.name = 'development';
const devBabelLoader = development.module.rules[3];
devBabelLoader.options.compact = false;
// production config
// -----------------------------------------------------------------------------
const production = cloneDeep(base);
production.mode = 'production';
production.name = 'production';
// compression of webpack's JS output not enabled by default
// production.plugins.push(new CompressionPlugin());
2018-08-16 20:49:19 +00:00
// export a list of named configs
// -----------------------------------------------------------------------------
module.exports = [
development,
production
];