@area17/a17-boilerplate
Version:
The official AREA 17 boilerplate
183 lines (171 loc) • 5.99 kB
JavaScript
const merge = require('webpack-merge');
const path = require('path');
const utils = require('./utils');
const data = utils.getManifest();
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const entries = {};
// Scripts
// Dynamic entry points defined in the manifest with fallback on the default head.js and app.js
if (data.scripts) {
for (var key in data.scripts) {
const entryName = path.parse(key).name;
entries[entryName] = path.resolve(data.paths.source, data.scripts[key]);
}
}
// Styles
// Dynamic entry points defined in the manifest with fallback on the default app.scss and html4css.scss
if (data.styles) {
for (var key in data.styles) {
const entryName = path.parse(key).name;
entries[entryName] = path.resolve(data.paths.source, data.styles[key]);
}
}
module.exports = (env, argv) => {
const devMode = Boolean(argv.mode !== 'production');
const extendedConf = devMode ? 'dev' : 'prod';
const verboseMode = Boolean(argv.verbosemode !== 'false');
const sourcePath = path.resolve(data.paths.source);
let defaultWebpackConfig = {
entry: entries,
output: {
filename: '[name].js',
path: path.resolve(data.paths.dist)
},
resolve: {
alias: {
'@': sourcePath
}
},
stats: verboseMode ? 'verbose' : {
children: false, // Shut up child plugin logs. Example: MiniCssExtractPlugin,
entrypoints: true,
// Set the maximum number of modules to be shown
maxModules: 15
},
devtool: devMode ? 'source-map' : false,
module: {
rules: [
{ test: /\.js$/,
exclude: /node_modules\/(?!(|-sourcemaps|)\/).*/,
loader: require.resolve('babel-loader'),
options: {
presets: [require.resolve('@babel/preset-env')],
cacheDirectory: true
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 2,
url: false,
sourceMap: devMode
}
},
{
loader: require.resolve('sass-loader'),
options: {
url: false,
sourceMap: devMode,
implementation: require('sass') // dart-sass
}
}
]
},
{ test: /\.svg$/,
loader: require.resolve('svg-url-loader'),
options: {
}
}
]
},
optimization: {
minimizer: [
new TerserPlugin(),
new OptimizeCSSAssetsPlugin()
]
},
plugins: [
new CleanWebpackPlugin(data.paths.dist, {
root: path.resolve(),
verbose: verboseMode,
beforeEmit: true
}),
new CopyWebpackPlugin([
{
from: path.resolve(data.paths.source + 'fonts/'),
filename: '[name].[ext]',
to: path.resolve(data.paths.dist + 'fonts/')
},
{
from: path.resolve(data.paths.source + 'images/'),
ignore: [ 'icons.svg' ],
filename: '[name].[ext]',
to: path.resolve(data.paths.dist + 'images/')
},
{
from: path.resolve(data.paths.source + 'images/icons.svg'),
filename: '[name].[ext]',
to: path.resolve(data.paths.dist + 'icons/')
}
]),
new FixStyleOnlyEntriesPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
path: path.resolve(data.paths.dist)
})
]
};
if(devMode) {
// Default BrowserSyncOptions
// You can override these options by extending the Webpack options by creating a webpack.bs.js in your project
const projectBrowserSyncConfig = path.resolve('./webpack.bs.js');
let defaultBrowserSyncConfig = {
ui: { port: 3001 },
port: 3000,
snippetOptions: {
whitelist: data.config.whitelist,
blacklist: data.config.blacklist
}
};
// Default BrowserSync config altered by the manifest.json
//
// Proxy : it will use the environment DEV_URL variable or the manifest.config.devUrl if set
if(data.config.devUrl) defaultBrowserSyncConfig.proxy = data.config.devUrl;
if(process.env.DEV_URL) defaultBrowserSyncConfig.proxy = process.env.DEV_URL;
// Port or the Browser Sync UI and port of the application
if(data.config.browsersyncUiPort) defaultBrowserSyncConfig.ui.port = data.config.browsersyncUiPort;
if(data.config.browsersyncPort) defaultBrowserSyncConfig.port = data.config.browsersyncPort;
defaultWebpackConfig.plugins.push(
new BrowserSyncPlugin(utils.desire(projectBrowserSyncConfig, defaultBrowserSyncConfig),{ reload: true })
);
}
// Defining your own logic in the project is possible
//
// Extend Webpack with a custom config that is living in the project :
// webpack.dev.js : development mode only
// webpack.prod.js : production mode only
// webpack.all.js : development or production
const projectWebpackConfigMode = path.resolve('./webpack.' + extendedConf + '.js');
const projectWebpackConfigFallback = path.resolve('./webpack.all.js');
const fullWebpackConfig = merge.smartStrategy({
entry: 'replace',
output: 'replace',
'module.loaders': 'replace',
'optimization': 'replace'
})(
defaultWebpackConfig,
utils.desire(projectWebpackConfigMode, {}),
utils.desire(projectWebpackConfigFallback, {})
);
return fullWebpackConfig;
}