const path = require("path");
const webpack = require("webpack");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const BundleAnalyzerPlugin =
require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
function resolve(relatedPath) {
return path.join(__dirname, relatedPath);
}
const baseConfig = {
context: resolve("../src"),
entry: {
index: resolve("../src/index.jsx"),
},
output: {
path: resolve("../dist"),
filename: "[name].js",
chunkFilename: "chunks/[name].[hash:8].js",
},
resolve: {
extensions: [".js", ".jsx", ".css", ".sass"],
alias: {
"@src": path.join(__dirname, "../src"),
immutable: path.resolve(process.cwd(), "node_modules", "immutable"),
},
},
resolveLoader: {
moduleExtensions: ["-loader"],
},
plugins: [
new HtmlWebpackPlugin({
template: resolve("../src/index.html"),
chunk: ["index"],
hash: true,
scriptLoading: "defer",
}),
new CopyWebpackPlugin([
{
context: resolve("../src/resource/"),
from: "**/*",
to: resolve("../dist/resource/"),
},
]),
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash:8].css",
chunkFilename: "css/[name].[contenthash:8].css",
}),
],
module: {
rules: [
{
test: /\.js[x]?$/,
exclude: /node_modules/,
include: [resolve("../app")],
use: [
{
loader: "babel-loader",
options: {
presets: ["react", "es2015", "stage-0"],
},
},
],
},
{
test: /\.(less|css|sass)$/,
use: [
"style-loader",
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "less-loader",
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
exclude: /node_modules/,
loader: "url-loader",
options: {
limit: 8192,
name: "../images/[name].[ext]",
outputPath: "images/",
},
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
loader: "file-loader",
},
{
test: /\.(woff|woff2)$/,
loader: "url-loader?prefix=font/&limit=5000",
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
loader: "url-loader?limit=10000&mimetype=application/octet-stream",
},
],
},
};
const devConfig = {
devtool: "source-map",
devServer: {
host: "0.0.0.0",
port: 3000,
open: true,
disableHostCheck: true,
proxy: require("./dev.config.js"),
},
};
const prodConfig = {
plugins: [
new CleanWebpackPlugin(resolve("../dist"), {
root: resolve("../"),
verbose: true,
}),
new BundleAnalyzerPlugin({
analyzerMode: "static",
openAnalyzer: false,
analyzerPort: 4000,
}),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn/),
],
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
parse: {},
compress: {},
keep_fnames: false,
safari10: false,
},
}),
new OptimizeCssAssetsWebpackPlugin({ canPrint: false, sourceMap: false }),
],
splitChunks: {
chunks: "all",
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: "~",
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
},
thirdDll: {
name: "dll",
test: /[\\/]node_modules[\\/](moment|loadsh|immutable)/,
priority: 10,
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},
},
};
module.exports = (env) => {
const environment = env.environment;
console.info(`当前测试环境: ${environment}`);
if (environment === "DEV") {
return merge(baseConfig, devConfig);
}
if (environment === "PRD") {
return merge(baseConfig, prodConfig);
}
};