'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

function resolve(dir) {
    return path.join(__dirname, '..', dir)
}

const env = require('../config/' + process.env.env_config + '.env')

// For NamedChunksPlugin
const seen = new Set()
const nameLength = 4

const webpackConfig = merge(baseWebpackConfig, {
    mode: 'production',
    module: {
        rules: utils.styleLoaders({
            sourceMap: config.build.productionSourceMap,
            extract: true,
            usePostCSS: true
        })
    },
    devtool: config.build.productionSourceMap ? config.build.devtool : false,
    output: {
        // path: config.build.assetsRoot,
        // filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
        // chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
        path: config.build.assetsRoot,
        publicPath: config.build.assetsPublicPath,
        
        filename: "zcomps.min.js", // 生成的文件名
        library: "zcomps", // 指定的就是你使用require时的模块名
        libraryTarget: "umd", // 会生成不同umd的代码,可以只是commonjs标准的，也可以是指amd标准的，也可以只是通过script标签引入的
        umdNamedDefine: true
    },
    plugins: [
        //moment优化
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        // http://vuejs.github.io/vue-loader/en/workflow/production.html
        new webpack.DefinePlugin({
            'process.env': env
        }),
        // extract css into its own file
        // new MiniCssExtractPlugin({
        //     filename: utils.assetsPath('css/[name].[contenthash:8].css'),
        //     chunkFilename: utils.assetsPath('css/[name].[contenthash:8].css')
        // }),
        new MiniCssExtractPlugin({
          // 固定的css文件名称
          filename: utils.assetsPath('css/zcomps.min.css'),
          allChunks: true,
        }),
        // generate dist index.html with correct asset hash for caching.
        // you can customize output by editing /index.html
        // see https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            // filename: config.build.index,
            // template: 'index.html',
            inject: true,
            // favicon: resolve('favicon.ico'),
            // title: 'vue-element-admin',
            // templateParameters: {
            //     BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory,
            // },
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
                    // more options:
                    // https://github.com/kangax/html-minifier#options-quick-reference
            }
            // default sort mode uses toposort which cannot handle cyclic deps
            // in certain cases, and in webpack 4, chunk order in HTML doesn't
            // matter anyway
        }),
        new ScriptExtHtmlWebpackPlugin({
            //`runtime` must same as runtimeChunk name. default is `runtime`
            inline: /runtime\..*\.js$/
        }),
        // keep chunk.id stable when chunk has no name
        new webpack.NamedChunksPlugin(chunk => {
            if (chunk.name) {
                return chunk.name
            }
            const modules = Array.from(chunk.modulesIterable)
            if (modules.length > 1) {
                const hash = require('hash-sum')
                const joinedHash = hash(modules.map(m => m.id).join('_'))
                let len = nameLength
                while (seen.has(joinedHash.substr(0, len))) len++
                    seen.add(joinedHash.substr(0, len))
                return `chunk-${joinedHash.substr(0, len)}`
            } else {
                return modules[0].id
            }
        }),
        // keep module.id stable when vender modules does not change
        new webpack.HashedModuleIdsPlugin(),
        // copy custom static assets
        new CopyWebpackPlugin([{
            from: path.resolve(__dirname, '../static'),
            to: config.build.assetsSubDirectory,
            ignore: ['.*']
        }]),
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false
            }
          },
          sourceMap: config.build.productionSourceMap,
          parallel: true
        }),
    ],
    // optimization: {
    //     splitChunks: {
    //         chunks: 'async',
    //         cacheGroups: {
    //             libs: {
    //                 name: 'chunk-libs',
    //                 test: /[\\/]node_modules[\\/]/,
    //                 priority: -10,
    //                 chunks: 'initial' // 只打包初始时依赖的第三方
    //             },
    //             // elementUI: {
    //             //     name: 'chunk-elementUI', // 单独将 elementUI 拆包
    //             //     priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
    //             //     test: /[\\/]node_modules[\\/]element-ui[\\/]/
    //             // },
    //             commons: {
    //                 name: 'chunk-commons',
    //                 test: resolve('src/components'), // 可自定义拓展你的规则
    //                 minChunks: 2, // 最小公用次数
    //                 priority: 5,
    //                 reuseExistingChunk: true
    //             }
    //         }
    //     },
    //     runtimeChunk: 'single',
    //     minimizer: [
    //         new UglifyJsPlugin({
    //             uglifyOptions: {
    //                 mangle: {
    //                     safari10: true
    //                 }
    //             },
    //             sourceMap: config.build.productionSourceMap,
    //             cache: true,
    //             parallel: true
    //         }),
    //         // Compress extracted CSS. We are using this plugin so that possible
    //         // duplicated CSS from different components can be deduped.
    //         new OptimizeCSSAssetsPlugin()
    //     ]
    // }
})

if (config.build.productionGzip) {
    const CompressionWebpackPlugin = require('compression-webpack-plugin')

    webpackConfig.plugins.push(
        new CompressionWebpackPlugin({
            // asset: '[path].gz[query]',
            algorithm: 'gzip',
            test: new RegExp(
                '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
            ),
            // deleteOriginalAssets:true,
            threshold: 0,
            minRatio: 0.8
        })
    )
}

if (config.build.generateAnalyzerReport || config.build.bundleAnalyzerReport) {
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
        .BundleAnalyzerPlugin

    if (config.build.bundleAnalyzerReport) {
        webpackConfig.plugins.push(
            new BundleAnalyzerPlugin({
                analyzerPort: 8080,
                generateStatsFile: false
            })
        )
    }

    if (config.build.generateAnalyzerReport) {
        webpackConfig.plugins.push(
            new BundleAnalyzerPlugin({
                analyzerMode: 'static',
                reportFilename: 'bundle-report.html',
                openAnalyzer: false
            })
        )
    }
}

module.exports = webpackConfig
