08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / build / webpack.build.conf.js
caibinghong on 9 Jun 2021 add

const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

const utils = require('./utils')
const packageConfig = require('../package.json')
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

//路径转换
function resolve(dir) {
    return path.join(__dirname, '..', dir)
}

//语法验证
const createLintingRule = () => ({
    test: /\.(js|vue|dtvevt)$/,
    loader: 'eslint-loader',
    enforce: 'pre',
    include: [resolve('src'), resolve('test')],
    options: {
        formatter: require('eslint-friendly-formatter'),
        emitWarning: !config.dev.showEslintErrorsInOverlay
    }
})

const useEslint = true;
const projectName = packageConfig.name||'project';

module.exports = {
    //指定目录,默认的值就是项目的根目录
    context: resolve(projectName),
    //编译入口 String||Array
    // entry: '',
    //动态多入门文件时
    entry() {
        // 初始化入口配置
        const entry = {}
        // 所有模块的列表
        const moduleToBuild = require('./module-conf').getModuleToBuild() || []
        // 根据传入的待打包目录名称,构建多入口配置
        for (let module of moduleToBuild) {
          // entry[module] = `${module}/index.js`
          let name = module.replace(/\//gi, '_');
          entry[name] = `${module}/index.js`
        }
        return entry
      },
    //输出路径 
    output: {
        path: resolve('dist'),
        filename: '[name].js',
        //指定打包后的资源目录 相对于dist 下
        publicPath: './'
    },    
    // output: {
    //     filename:'static/js/[name].[chunkhash].js',
    //     chunkFilename: 'static/js/[id].[chunkhash].js'
    // },
    //如何寻找模块所对应的文件
    resolve: {
        // 配置省略文件路径后缀名,引入文件的时候可以不用写文件的后缀名
        extensions: ['.js', '.vue', '.json'],
        //指定引用别名
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            // '@': resolve('src'),
        }
    },
    //排除不打包
    externals: {
        // jquery: "jQuery",
    },
    //解析模块的规则
    module: {
        rules: [
            ...(useEslint ? [createLintingRule()] : []),
            ...(utils.styleLoaders({
                sourceMap: config.build.productionSourceMap,
                extract: true,
                usePostCSS: true
            })),
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: vueLoaderConfig
            },
            {
                test: /\.js$/,
                loader: 'babel-loader?cacheDirectory',
                //需要被loader 处理的文件或文件夹
                include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')],
                //不需要被loader 处理的文件或文件夹
                exclude: []
            },
            {
                test: /\.svg$/,
                loader: 'svg-sprite-loader',
                include: [resolve('src/icons')],
                options: {
                    symbolId: 'icon-[name]'
                }
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                // exclude: [resolve('src/icons')],
                options: {
                    limit: 10000,
                    name: 'static/img/[name].[hash:7].[ext]'
                }
            },
            {
                test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/media/[name].[hash:7].[ext]'
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/fonts/[name].[hash:7].[ext]'
                }
            }
        ]
    },
    devtool: '#source-map',
    plugins: [
        //注入全局变量的插件,通常使用该插件来判别代码运行的环境变量
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"',
                ENV_CONFIG: '"prod"',
                BASE_API: '"https://api-prod"'
            }
        }),
        //webpack 4之前的版本是通过webpack.optimize.CommonsChunkPlugin来压缩js,
        //webpack 4版本之后被移除了,使用config.optimization.splitChunks来代替
        //用来缩小(压缩优化)js文件
        new UglifyJsPlugin({
            uglifyOptions: {
                compress: {
                    warnings: false
                }
            },
            sourceMap: false,
            parallel: true
        }),
        // 将css提取到自己的文件中
        new ExtractTextPlugin({
            filename: 'static/css/[name].[contenthash].css',
            // Setting the following option to `false` will not extract CSS from codesplit chunks.
            // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
            // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
            allChunks: false,
        }),
        // 压缩提取的CSS。我们使用这个插件是为了来自不同组件的重复CSS可以被删除。
        new OptimizeCSSPlugin({
            //开发环境
            // cssProcessorOptions:{
            //     safe: true, map: { inline: false } 
            // },
            //打包生产
            cssProcessorOptions: { safe: true }
        }),
        // keep module.id stable when vender modules does not change
        new webpack.HashedModuleIdsPlugin(),
        // enable scope hoisting
        new webpack.optimize.ModuleConcatenationPlugin(),
        // split vendor js into its own file
        // 分别提取公共库
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks(module) {
                // any required modules inside node_modules are extracted to vendor
                return (
                    module.resource &&
                    /\.js$/.test(module.resource) &&
                    module.resource.indexOf(
                        path.join(__dirname, '../node_modules')
                    ) === 0
                )
            }
        }),
        // extract webpack runtime and module manifest to its own file in order to
        // prevent vendor hash from being updated whenever app bundle is updated
        new webpack.optimize.CommonsChunkPlugin({
            name: 'manifest',
            minChunks: Infinity
        }),
        //提取引用最小3次的公共包
        // This instance extracts shared chunks from code splitted chunks and bundles them
        // in a separate chunk, similar to the vendor chunk
        // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
        new webpack.optimize.CommonsChunkPlugin({
            name: 'app',
            async: 'vendor-async',
            children: true,
            minChunks: 3
        }),
        // split echarts into its own file
        new webpack.optimize.CommonsChunkPlugin({
            async: 'echarts',
            minChunks(module) {
                var context = module.context;
                return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
            }
        }),
        // split xlsx into its own file
        new webpack.optimize.CommonsChunkPlugin({
            async: 'xlsx',
            minChunks(module) {
                var context = module.context;
                return context && (context.indexOf('xlsx') >= 0);
            }
        }),
        // split codemirror into its own file
        new webpack.optimize.CommonsChunkPlugin({
            async: 'codemirror',
            minChunks(module) {
                var context = module.context;
                return context && (context.indexOf('codemirror') >= 0);
            }
        }),
        // copy custom static assets
        new CopyWebpackPlugin([
            {
                from: resolve('static'),
                to: 'static',
                ignore: ['.*']
            }
        ]),
        // 打包后,对包进行大小分析
        // new BundleAnalyzerPlugin()
    ],
}