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

//考虑用,parallel-webpack  并发打包加快打包速度
const path = require('path')
const webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');//本插件基于 webpack v4 的新特性(模块类型)构建,并且需要 webpack 4 才能正常工作。
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')

//运行打包命令的时候就可以看到每个loader 和插件执行耗时
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

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

//读取.evn 对应的文件,写入环境变量
var dotenv = require('dotenv').config({ path: resolve('.env.' + process.env.NODE_ENV) });
var cfg = { ...Object.fromEntries(Object.entries(process.env).filter(([k]) => /^VITE_/.test(k))) }
let evnConfig = {}
for (let key in cfg) {
    evnConfig[key] = '"' + cfg[key] + '"'
}

//路径转换
function resolve(dir) {
    // console.log(dir,'---------------------------',path.join(__dirname, '..', 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: true
    }
})

const useEslint = true;
//project 这个目录是暂时命名,当用hivui create 创建时候 会根据用户输入确定
const projectName = packageConfig.name == 'hi-vui-template' ? 'project' : packageConfig.name;

const smp = new SpeedMeasurePlugin();//smp.wrap smp.wrap(
module.exports = {
    //指定目录,默认的值就是项目的根目录
    // context: resolve(projectName),
    //编译入口 String||Array
    // entry: '',
    //没有指定入口文件时,按目录搜索 对应的package.json所在的入口
    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: 'static/js/[name].js',
        //指定打包后的资源目录 相对于dist 下 模块index.html
        publicPath: './'
    },
    //如何寻找模块所对应的文件
    resolve: {
        // 配置省略文件路径后缀名,引入文件的时候可以不用写文件的后缀名
        extensions: ['.css', '.less', '.js', '.jsx', '.vue', '.json'],
        //指定引用别名
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@': resolve(projectName),
            '@main': resolve(projectName + '/hivuiMain'),
        }
    },
    //排除不打包
    externals: {
        // 'axios':'axios',
        'vue': 'Vue',
        "element-ui": "ELEMENT",
        // 'vue-router': 'VueRouter',
        // 'vuex':'Vuex',      
    },
    //解析模块的规则
    module: {
        rules: [

            // ...(useEslint ? [createLintingRule()] : []),
            ...(utils.styleLoaders({
                sourceMap: false,
                extract: true,
                usePostCSS: true
            })),
            {
                test: /\.(vue)$/,
                loader: 'vue-loader',
                options: vueLoaderConfig
            },
            {
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                options: {
                    cacheDirectory: true
                }
                // exclude: [
                //     /node_modules\/(webpack|html-webpack-plugin)\//,
                // ],
            },
            // element amdin src/icons使用
            // {
            //     test: /\.svg$/,
            //     loader: 'svg-sprite-loader',
            //     include: [resolve('src/icons')],
            //     options: {
            //         symbolId: 'icon-[name]'
            //     }
            // },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/img/[name].[ext]'//.[hash:7]
                    // publicPath:"../img/",	//替换CSS引用的图片路径 可以替换成爱拍云上的路径
                    // outputPath:"static/img/"		//生成之后存放的路径
                }
            },
            {
                test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/media/[name].[ext]'//.[hash:7]
                    // publicPath:"../media/",	//替换CSS引用的图片路径 可以替换成爱拍云上的路径
                    // outputPath:"static/media/"		//生成之后存放的路径
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: "[name].[ext]",//[hash:8].
                    publicPath: "../fonts/",	//替换CSS引用的图片路径 可以替换成爱拍云上的路径
                    outputPath: "static/fonts/"		//生成之后存放的路径
                    // name: 'static/fonts/[name].[hash:7].[ext]'
                }
            }
        ]
    },
    devtool: "source-map",
    optimization: {
        minimizer: [
            new CssMinimizerPlugin(),
            new MiniCssExtractPlugin({
                filename: 'static/css/[name].[contenthash:10].css'//.[contenthash]
            }),
            new TerserPlugin()
        ],
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                // vue: {
                //     name: 'vue',
                //     test: /[\\/]node_modules[\\/]vue[\\/]/,
                //     priority: -10
                // },
                // vuex: {
                //     name: 'vuex',
                //     test: /[\\/]node_modules[\\/]vuex[\\/]/,
                //     priority: -10
                // },
                // 'vue-router': {
                //     name: 'vue-router',
                //     test: /[\\/]node_modules[\\/]vue-router[\\/]/,
                //     priority: -10
                // },
                // 'element-ui': {
                //     name: 'element-ui',
                //     test: /[\\/]node_modules[\\/]element-ui[\\/]/,
                //     priority: -10
                // },
                'module-vendors': {
                    name: 'module-vendors',
                    test: /[\\/]node_modules[\\/]/,
                    priority: -20
                }
            },
        }
    },
    plugins: [
        //注入全局变量的插件,通常使用该插件来判别代码运行的环境变量
        new webpack.DefinePlugin({
            'process.env': evnConfig
        }),
        new VueLoaderPlugin(),
        //预设一些基础库
        new webpack.DllReferencePlugin({
            context: resolve("assets_platform/vendor_dll"),
            //告诉webpack哪些库不参与打包,同时使用时名称也得变
            manifest:resolve('assets_platform/vendor_dll/vuelibs-manifest.json')
        }),
        new webpack.DllReferencePlugin({
            context: resolve("assets_platform/vendor_dll"),
            //告诉webpack哪些库不参与打包,同时使用时名称也得变
            manifest:resolve('assets_platform/vendor_dll/vendor-manifest.json')
        }),
        // new AddAssetHtmlPlugin({
        //     filepath: resolve('webpackDll/Vue.js'),
        //     outputPath:'./static/js/',
        //     publicPath:'./static/js/'
        // }),
    ],
};