const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');//------------
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
// const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const webpack = require('webpack');
const threadLoader = require('thread-loader');
const packageConfig = require('../package.json');
const utils = require('./utils')
const vueLoaderConfig = require('./vue-loader.conf')
let evnConfig = require('./getEnvVar')
// HappyPack
// 原理:每次 webapck 解析一个模块时,HappyPack 会将它及它的依赖分配到worker线程中。
// 提示:由于HappyPack 对file-loader、url-loader 支持的不友好,所以不建议对该loader使用。
// 引入 Happpack 可以在 package.json 找到你下载的
const HappyPack = require('happypack');
// 安装 OS 模块 这个主要是拿到当前电脑的CPU核数
const os = require('os');
/*
这个是设置共享线程池中的数量
size 控制设置数量 类型 只能是 整数类型
*/
const cpus = os.cpus().length;
const happyThreadPool = HappyPack.ThreadPool({ size: cpus>1?cpus-1:1 });// os.cpus().length 不能开最大
// const happyThreadPool = HappyPack.ThreadPool({ size: 1 });//os.cpus().length 不能开最大
let threadCfg = {
loader: "thread-loader",
// 有同样配置的 loader 会共享一个 worker 池(worker pool)
options: {
// 产生的 worker 的数量,默认是 cpu 的核心数
// workers: Math.floor(cpus / 2) || 1,
// 一个 worker 进程中并行执行工作的数量
// 默认为 20
workerParallelJobs: 50,
// 额外的 node.js 参数
// workerNodeArgs: ['--max-old-space-size', '1024'],
// 闲置时定时删除 worker 进程
// 默认为 500ms
// 可以设置为无穷大, 这样在监视模式(--watch)下可以保持 worker 持续存在
poolTimeout: 2000,
// 池(pool)分配给 worker 的工作数量
// 默认为 200
// 降低这个数值会降低总体的效率,但是会提升工作分布更均一
poolParallelJobs: 50,
// 池(pool)的名称
// 可以修改名称来创建其余选项都一样的池(pool)
// name: "my-pool"
}
};
let projectName = packageConfig.name == 'hi-vui-template' ? 'project' : packageConfig.name;
module.exports = {
// entry: {
// 'login': ['babel-polyfill', './project/hivuiLogin/index.js'],
// 'main': ['babel-polyfill','./project/hivuiMain/index.js']
// },
// output: {
// filename: '[name].[contenthash].js',
// chunkFilename: '[name].[contenthash].js',
// path: path.resolve(__dirname, 'dist')
// },
//去除 node 系统模块不引用
node: {
fs: 'empty',
net:'empty',
tls:'empty',
},
stats: {
assets: true,
warnings: true,
errors: true,
errorDetails: true,
performance: true,
modules: false,
colors: true
},
resolve: {
extensions: ['.js', '.jsx', '.vue', '.json', '.dtvevt', '.dvue','.es6'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'vuex$': 'vuex/dist/vuex.esm.js',
'@': path.resolve(__dirname, `${projectName}`),
'@main': path.resolve(__dirname, `../${projectName}/hivuiMain`),
// '@': path.resolve(__dirname, 'src'),
'@birt':path.resolve(__dirname, `../${projectName}/hivuiBirt`),
'@sam':path.resolve(__dirname, `../${projectName}/hivuiSam`),
'pinyin': 'js-pinyin',
//这里单独对 vue-video-player中组件引用video.js 编译不过的问题做映射
'videojs': 'video.js'
}
},
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
"element-ui": "ELEMENT",
},
module: {
rules: [
...(utils.styleLoaders({
sourceMap: false,
extract: process.env.NODE_ENV === 'production',
usePostCSS: true
})),
{
test: /\.(js|jsx|dtvevt?|babel|es6)$/,
loader: 'happypack/loader?id=happy_js_jsx',
// use:[threadCfg,'babel-loader']
// loader: 'babel-loader',
// exclude: [path.resolve(__dirname, 'node_modules')]//放开,里头有些也是 可选链操作符
},
{
test: /\.(vue|dvue)$/,
loader: 'vue-loader',
// use:[{
// loader: "vue-loader",
// options: vueLoaderConfig
// }],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:7].[ext]',
// 注释下面,统一用,output.publicPath 配置,这样打包放在服务器上是绝对路径
// publicPath: "../img/", //替换CSS引用的图片路径 可以替换成爱拍云上的路径
outputPath: "static/img/" //生成之后存放的路径
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:7].[ext]',
// 注释下面,统一用,output.publicPath 配置,这样打包放在服务器上是绝对路径
// publicPath: "../img/", //替换CSS引用的图片路径 可以替换成爱拍云上的路径
outputPath: "static/media/" //生成之后存放的路径
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:7].[ext]',
// 注释下面,统一用,output.publicPath 配置,这样打包放在服务器上是绝对路径
// publicPath: "../fonts/", //替换CSS引用的图片路径 可以替换成爱拍云上的路径
outputPath: "static/fonts/" //生成之后存放的路径
}
}
]
},
optimization: {
minimizer: [
// new UglifyJsPlugin({
// cache: true,
// parallel: true,
// sourceMap: true
// }),
new TerserPlugin({
parallel: false, //使用多进程并发运行
}),
new OptimizeCSSAssetsPlugin({
cssProcessor: require('cssnano'),
cssProcessorPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
},
canPrint: false
})
],
runtimeChunk: {
"name": "manifest"
},
splitChunks: {
// chunks: 'all', // 将代码拆分到所有的 chunk 中,包括同步和异步导入的模块
// minSize: 30000, // 模块的最小大小,只有大于这个值的模块才会被拆分
// maxSize: 0, // 模块的最大大小,设置为 0 表示没有限制
// //minChunks: 1, // 至少被引用次数超过这个值的模块才会被拆分
// maxAsyncRequests: 5, // 按需加载的模块,最大的并行请求数
// maxInitialRequests: 3, // 入口点处的最大并行请求数
// automaticNameDelimiter: '~', // 文件名的连接符
// name: true, // 允许使用命名规则
cacheGroups: {
default: false,
vendors: false,
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
minSize: 200 * 1024, // 设置最大的文件大小为500KB
maxSize: 800 * 1024 // 设置最大的文件大小为500KB
}
},
},
/*splitChunks: {
cacheGroups: {
default: false,
vendors: false,
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}*/
},
plugins: [
new VueLoaderPlugin(),
new HappyPack({
id: 'happy_js_jsx',
verbose:false,//不输出日志
verboseWhenProfiling:true,//输出webpack日志
//共享进程池
threadPool: happyThreadPool,
loaders: ['babel-loader']
}),
new webpack.HashedModuleIdsPlugin(),
new ProgressBarPlugin(),
// new CleanWebpackPlugin(['dist']),
//注入全局变量的插件,通常使用该插件来判别代码运行的环境变量
new webpack.DefinePlugin({
'process.env': evnConfig
}),
new webpack.DllReferencePlugin({
context: path.resolve(__dirname),
manifest: require('../assets_platform/vendor_dll/vendor-manifest.json')
}),
//这个主要是将生成的vendor.dll.js文件加上hash值插入到页面中。[也可以手动写到html这里不做处理]
// new AddAssetHtmlPlugin([{
// filepath: path.resolve(__dirname, 'js_dll/comm_vendors.dll.js'),
// outputPath: 'js_dll/',
// publicPath: 'js_dll/',
// includeSourcemap: false,
// hash: true,
// }]),
// new CopyWebpackPlugin([
// {
// from: path.resolve(__dirname, 'assets_platform'),
// to: path.resolve(__dirname, 'dist/assets_platform')
// },
// // {
// // from: path.resolve(__dirname, 'js_dll'),
// // to: path.resolve(__dirname, 'dist')
// // }
// ])
]
};