const path = require('path') const defaultSettings = require('./src/settings.js') const CompressionPlugin = require('compression-webpack-plugin') const { RetryChunkLoadPlugin } = require('webpack-retry-chunk-load-plugin') const Timestamp = new Date().getTime() function resolve(dir) { return path.join(__dirname, dir) } const name = defaultSettings.title || 'vue Element Admin' // page title // If your port is set to 80, // use administrator privileges to execute the command line. // For example, Mac: sudo npm run // You can change the port by the following method: // port = 9527 npm run dev OR npm run dev --port = 9527 const port = process.env.port || process.env.npm_config_port || 9527 // dev port // All configuration item explanations can be find in https://cli.vuejs.org/config/ module.exports = { /** * You will need to set publicPath if you plan to deploy your site under a sub path, * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/, * then publicPath should be set to "/bar/". * In most cases please use '/' !!! * Detail: https://cli.vuejs.org/config/#publicpath */ publicPath: process.env.VUE_APP_PACKAGE_PATH || '/', outputDir: 'dist', assetsDir: 'static', lintOnSave: process.env.VUE_APP_MODE === 'development', productionSourceMap: false, devServer: { port: port, hot: true, open: false, proxy: { 'api56/open': { target: 'http://gatewayservicev2.fujica.com.cn/open', changeOrigin: true, pathRewrite: { '^/api56/open': '' } }, // change xxx-api/login => mock/login // detail: https://cli.vuejs.org/config/#devserver-proxy 'api56': { target: process.env.VUE_APP_BASE_API, changeOrigin: true, pathRewrite: { '^/api56': '' } }, 'api11': { target: process.env.VUE_APP_BASE_API, // target: 'http://119.23.214.109:32011', changeOrigin: true, pathRewrite: { '^/api11': '' } } }, // history模式下的url会请求到服务器端,但是服务器端并没有这一个资源文件,就会返回404,所以需要配置这一项 // historyApiFallback: { // index: '/index.html' // 与output的publicPath // }, disableHostCheck: true // after: require('./mock/mock-server.js') }, configureWebpack: { // provide the app's title in webpack's name field, so that // it can be accessed in index.html to inject the correct title. name: name, resolve: { alias: { '@': resolve('src') } }, // 打包时忽略以下文件 externals: { 'vue': 'Vue', 'element-ui': 'Element' }, output: { // 输出重构 打包编译后的 文件名称 【模块名称.时间戳】 'filename': `[name].${Timestamp}.js`, 'chunkFilename': `[name].${Timestamp}.js` }, performance: { hints: 'warning', // 入口起点的最大体积 maxEntrypointSize: 50000000, // 生成文件的最大体积 maxAssetSize: 50000000, // 只给出 js 文件的性能提示 assetFilter: function(assetFilename) { return assetFilename.endsWith('.js') } }, plugins: [ new RetryChunkLoadPlugin({ cacheBust: `function() { return Date.now(); }`, retryDelay: 3000, maxRetries: 2, // chunks: ['chunks.**.**.js'], lastResortScript: 'window.location.reload(true);' }) ] }, chainWebpack(config) { // if (process.env.VUE_APP_MODE === 'production') { // // 清除css,js版本号 // config.output.filename('static/js/[name].v1.11.js').end() // config.output.chunkFilename('static/js/[name].v1.11.js').end() // // 为生产环境修改配置... // config.plugin('extract-css').tap(args => [{ // filename: `static/css/[name].v1.11.css`, // chunkFilename: `static/css/[name].v1.11.css` // }]) // } else { // config.output.filename(`static/js/[name].${Timestamp}.js`).end() // config.output.chunkFilename(`static/js/[name].${Timestamp}.js`).end() // } config.plugins.delete('prefetch') // TODO: need test // 可视化显示包的大小 // config // .plugin('webpack-bundle-analyzer') // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) // 开启gzip压缩,加快访问速度 // 开发环境下不使用压缩 config .when(process.env.VUE_APP_MODE !== 'development', config => { config.plugin('compression') .use(CompressionPlugin, [{ algorithm: 'gzip', test: /\.js$|\.html$|\.css/, threshold: 10240, deleteOriginalAssets: false }]) .end() }) // config.plugin('compression') // .use(CompressionPlugin, [{ // algorithm: 'gzip', // test: /\.js$|\.html$|\.css/, // threshold: 10240, // deleteOriginalAssets: false // }]) // .end() // set svg-sprite-loader config.module .rule('svg') .exclude.add(resolve('src/icons')) .end() config.module .rule('icons') .test(/\.svg$/) .include.add(resolve('src/icons')) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() // set preserveWhitespace config.module .rule('vue') .exclude.add(resolve('src/views/V1')) .end() .use('vue-loader') .loader('vue-loader') .tap(options => { options.compilerOptions.preserveWhitespace = true return options }) .end() // config // // 开发环境下打包生产map文件,其他环境不生成 // .when(process.env.VUE_APP_MODE === 'development', // config => config.devtool('cheap-source-map') // ) config .when(process.env.VUE_APP_MODE !== 'development', config => { config .plugin('ScriptExtHtmlWebpackPlugin') .after('html') .use('script-ext-html-webpack-plugin', [{ // `runtime` must same as runtimeChunk name. default is `runtime` // inline: /runtime\..*\.js$/ }]) .end() config .optimization.splitChunks({ chunks: 'all', cacheGroups: { libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 10, chunks: 'initial' // only package third parties that are initially dependent }, elementUI: { name: 'chunk-elementUI', // split elementUI into a single package priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm }, commons: { name: 'chunk-commons', test: resolve('src/components'), // can customize your rules minChunks: 3, // minimum common number priority: 5, reuseExistingChunk: true } } }) config.optimization.runtimeChunk('single') } ) } }