const isProduction = process.env.NODE_ENV === 'production'; const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const CompressionPlugin = require('compression-webpack-plugin') const path = require('path'); module.exports = { publicPath: './', // assetsDir: 'public', filenameHashing: true, productionSourceMap: false, parallel: require('os').cpus().length > 1, lintOnSave: false, pluginOptions: { route: { // 默认:page。存放Vue路由页面的文件夹名称 TemplateFolderName: 'page', // 默认:./src/application。从src/开始到TemplateFolderName文件夹父一级文件夹相对路径 RootFolderName: './src/application', // 默认 src/core/config/route.config.ts。生成的配置文件保存路径,相对插件的位置来。 SaveConfigPath: '../../../src/core/config/route.config.ts' } }, devServer: { hot: true, hotOnly: true, host: '0.0.0.0', port: 9000, compress: true, open: true, openPage: '#/User/Login', overlay: { warnings: false, errors: true, }, }, configureWebpack: (config) => { // 设置程序核心入口 config.entry.app = ['babel-polyfill', './src/core/run/start.run.ts']; if (process.env.NODE_ENV === 'production') { /** * Gzip压缩 */ config.mode = 'production' return { plugins: [new CompressionPlugin({ test: /\.js$|\.html$|\.css/, //匹配文件名 threshold: 10240, //对超过10k的数据进行压缩 deleteOriginalAssets: false //是否删除原文件 })] } /** * 去除这些公共包,让webpack不打包到项目源码的js中,减小项目js体积 * 然后使用 pages 节点下的 cdn 数组里面的资源外链来引入。 */ config.externals = { vue: 'Vue', 'vue-router': 'VueRouter', axios: 'axios', Vant: 'Vant', }; /** * 部署阶段 代码压缩 */ config.plugins.push( // 生产环境自动删除console new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, drop_debugger: true, drop_console: true, }, }, sourceMap: false, parallel: true, }), ); // 开启 BundleAnalyzerPlugin return { plugins: [ new BundleAnalyzerPlugin(), ], }; } }, chainWebpack: (config) => { if (process.env.NODE_ENV === 'production') { // 去除混淆加密 config.optimization.minimize(false) } /** * 移除不必要的 prefetch 和 preload请求 */ config.plugins.delete('prefetch'); config.plugins.delete('preload'); /** * html 模板引擎 pug 配置 */ config.module.rule('pug') .test(/\.pug$/) .use('pug-html-loader') .loader('pug-html-loader') .end(); /** * 导入全局css * @type {*[]} */ const types = ['vue-modules', 'vue', 'normal-modules', 'normal']; types.forEach(type => addStyleResource(config.module.rule('stylus').oneOf(type))); /** * 配置路径别名,项目中引用资源的时候路径可以更简短 * 但是ts文件在用的时候,编译器会报错,需要添加 @ts-ignore * 忽略开发工具的错误。 */ config.resolve.alias .set('@', resolve('src')) .set('@core', resolve('src/core')) .set('@router', resolve('src/core/router')) .set('@store', resolve('src/core/store')) .set('@types', resolve('src/core/types')) .set('@config', resolve('src/core/config')) .set('@utils', resolve('src/core/utils')) .set('@run', resolve('src/core/run')) .set('@ann', resolve('src/core/annotation')) .set('@model', resolve('src/core/model')) .set('@dao', resolve('src/core/dao')) .set('@service', resolve('src/core/service')) .set('@impl', resolve('src/core/service/impl')) .set('@application', resolve('src/application')) .set('@img', resolve('src/application/assets/img')) .set('@less', resolve('src/application/assets/less')) .set('@lessCom', resolve('src/application/assets/less/components')) .set('@pageLess', resolve('src/application/assets/less/page')) .set('@components', resolve('src/application/components')) .set('@page', resolve('src/application/page')) .set('@logic', resolve('src/application/logic')) .set('@layout', resolve('src/application/layout')) } }; function resolve(dir) { return path.join(__dirname, dir); } function addStyleResource(rule) { rule.use('style-resource') .loader('style-resources-loader') .options({ patterns: [ path.resolve(__dirname, './src/application/assets/less/imports.less') ], }); }