awesome-compose/react-express-mysql/frontend/webpack/config-builder.js

232 lines
7.6 KiB
JavaScript
Raw Normal View History

'use strict';
const path = require('path'),
webpack = require('webpack'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
MiniCssExtractPlugin = require("mini-css-extract-plugin");
const PROJECT_ROOT = path.resolve(__dirname, "..");
module.exports = (env) => {
const isDev = env === 'development';
const isTest = env === 'test';
const isProd = !isDev && !isTest;
const getAppEntry = () => {
const appEntry = path.resolve(PROJECT_ROOT, "src/app/entry.jsx");
if(isDev) {
return [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:9000',
'webpack/hot/only-dev-server',
appEntry
]
} else {
return [appEntry]
}
};
const getPlugins = () => {
// common plugins
let plugins = [
// Global variables
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env),
'__DEV__': isDev,
'__PROD__': isProd,
'__TEST__': isTest,
}),
// ignore moment locale files
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// extract styles to css file
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].css",
disable: isDev,
}),
// makes index.html
new HtmlWebpackPlugin({
template: path.resolve(PROJECT_ROOT, 'src/index.ejs'),
})
];
// development plugins
if(isDev) {
plugins.push(
// Hot Reload (HMR)
new webpack.HotModuleReplacementPlugin(),
// Named Modules
new webpack.NamedModulesPlugin()
);
}
// production plugins
if(isProd) {
plugins.push(
new webpack.optimize.ModuleConcatenationPlugin()
);
}
return plugins;
};
return {
target: 'web',
mode: isProd ? "production" : "development",
context: PROJECT_ROOT,
entry: {
app: getAppEntry()
},
output: {
path: path.resolve(PROJECT_ROOT, isProd ? 'dist' : 'build'),
filename: isProd ? '[name].[chunkhash:8].js' : '[name].js',
publicPath: '/',
sourceMapFilename: '[file].map',
chunkFilename: isProd ? '[name].[chunkhash:8].js' : '[name].js',
pathinfo: isDev
},
devtool: isProd ? "hidden-sourcemap" : 'eval',
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
modules: ["node_modules", "src"],
alias: {}
},
module: {
rules: [
// JS / JSX files
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
]
},
// SASS files
{
test: /\.scss$/,
exclude: /(node_modules|bower_components)/,
use: [
isDev ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 2,
url: true,
import: false,
sourceMap: isDev
}
},
{
loader: "postcss-loader",
options: {
sourceMap: isDev,
plugins: isDev ? [] : [
require("autoprefixer"),
require("cssnano")({
safe: true,
zindex: false,
discardComments: {
removeAll: true
}
})
]
}
},
{
loader: "sass-loader",
options: {
sourceMap: isDev,
includePaths: [".", path.join(process.cwd(), "src/app/core/styles")]
}
}
]
},
// Plain CSS files
{
test: /\.css$/,
use: [
isDev ? "style-loader" : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
url: true,
import: false,
sourceMap: isDev
}
},
{
loader: "postcss-loader",
options: {
sourceMap: isDev,
plugins: isDev ? [] : [
require("autoprefixer"),
require("cssnano")({
safe: true,
zindex: false,
discardComments: {
removeAll: true
}
})
]
}
}
]
},
// images loader
{
test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,
use: [
{
loader: 'file-loader',
options: {
name: "[name].[ext]",
outputPath: isProd ? "../images/" : "images/"
}
}
]
},
// font loader
{
test: /\.(woff|woff2|ttf|eot)(\?.*)?$/,
use: [
{
loader: 'file-loader',
options: {
name: "[name].[ext]",
publicPath: isProd ? "" : "/webpack/",
useRelativePath: isProd,
outputPath: isProd ? "../fonts/" : "fonts/"
}
}
]
}
]
},
plugins: getPlugins(),
node: {
__filename: true,
__dirname: true,
fs: 'empty',
vm: 'empty',
net: 'empty',
tls: 'empty',
}
};
};