348 lines
12 KiB
JavaScript
348 lines
12 KiB
JavaScript
const path = require('path');
|
||
const fs = require('fs');
|
||
const glob = require('glob');
|
||
// const webpack = require('webpack');
|
||
const devServerPort = process.env.VUE_APP_DEV_SERVER_PORT || 8090;
|
||
const PAGE_PATH = path.resolve(__dirname, './src/pages');
|
||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||
const StaticEnvConfigPlugin = require('@wecity/static-env-config').default;
|
||
const TIconReplaceWebpackPlugin = require('@gtff/tdesign-gt-vue/icon/plugin');
|
||
const AutoRouterPlugin = require('@gtff/tdesign-gt-vue/plugins/auto-router');
|
||
const CSSSplitWebpackPlugin = require('css-split-webpack-plugin').default;
|
||
const TerserPlugin = require('terser-webpack-plugin');
|
||
const mock = require('./mock');
|
||
const packageName = require('./package.json').name;
|
||
|
||
const LOCAL_DEV = process.env.VUE_APP_MODEL === 'local';
|
||
|
||
// 本地开发配置代理
|
||
// const PROXY = LOCAL_DEV ? require('./proxy') : {};
|
||
|
||
// 根据启动的模式使用不同的template
|
||
const template = LOCAL_DEV ? 'public/local.html' : 'public/index.html';
|
||
const isExtract = process.env.NODE_ENV === 'production' || process.env.VUE_APP_CSS_EXTRACT === 'true';
|
||
|
||
/**
|
||
* 获取页面入口集合 for devServer
|
||
*/
|
||
function getPagesEntities(pagePath) {
|
||
const entities = {};
|
||
glob.sync(pagePath).forEach((entity) => {
|
||
const moduleName = entity.split('/').slice(-1);
|
||
entities[moduleName] = entity;
|
||
});
|
||
// eg:
|
||
// {
|
||
// apply_admin: './src/pages/admin_manage/index',
|
||
// test: './src/pages/test/index'
|
||
// }
|
||
return entities;
|
||
}
|
||
|
||
const pages = getPagesEntities(`${PAGE_PATH}/*`);
|
||
|
||
const multiPage = {};
|
||
|
||
Object.keys(pages).forEach((page) => {
|
||
if (!Object.prototype.hasOwnProperty.call(pages, page)) {
|
||
return;
|
||
}
|
||
const configFile = `${PAGE_PATH}/${page}/config.js`;
|
||
const config = fs.existsSync(configFile) ? require(configFile) : {};
|
||
multiPage[page] = {
|
||
// page 的入口
|
||
entry: `src/pages/${page}/main.js`,
|
||
// 模板来源
|
||
template,
|
||
// 在 dist/index.html 的输出
|
||
filename: page === 'index' ? `${page}.html` : `${page}/index.html`,
|
||
// 当使用 title 选项时,
|
||
// template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title>
|
||
title: process.env.VUE_APP_NAME || '智能申报',
|
||
// 在这个页面中包含的块,默认情况下会包含
|
||
// 提取出来的通用 chunk 和 vendor chunk。
|
||
chunks: ['chunk-vendors', 'chunk-common', page],
|
||
...config,
|
||
};
|
||
});
|
||
|
||
/**
|
||
* 将对应环境的env的环境变量处理成常量,等待注入到static-env-config插件配置中去
|
||
* 只注入VUE_APP_开头的环境变量
|
||
*/
|
||
const STATIC_ENV_CONFIG = {};
|
||
Object.keys(process.env).forEach((key) => {
|
||
if (/^VUE_APP_/.test(key)) {
|
||
Object.assign(STATIC_ENV_CONFIG, {
|
||
[key]: process.env[key],
|
||
});
|
||
}
|
||
});
|
||
|
||
delete STATIC_ENV_CONFIG.VUE_APP_API_BASE_URL;
|
||
delete STATIC_ENV_CONFIG.VUE_APP_CDN_PATH;
|
||
delete STATIC_ENV_CONFIG.VUE_APP_ROUTER_BASE;
|
||
|
||
/**
|
||
* 修复生产模式build出来的css background image url(~@)路径不符合预期的问题
|
||
* @type {string[]}
|
||
*/
|
||
const styles = ['css', 'postcss', 'scss', 'sass', 'less', 'stylus'];
|
||
const modules = ['vue-modules', 'vue', 'normal-modules', 'normal'];
|
||
|
||
const configureWebpackPlugin = [];
|
||
|
||
/**
|
||
* 本地开发启用hard-source-webpack-plugin
|
||
*/
|
||
if (LOCAL_DEV) {
|
||
console.log('====>> 启动本地开发缓存');
|
||
configureWebpackPlugin.push(
|
||
new HardSourceWebpackPlugin({
|
||
// 缓存目录,支持相对目录或绝对目录
|
||
// 如果有设置VUE_APP_HARD_SOURCE_FOLDER目录则使用设置值
|
||
// 一般在coding流水线编译使用,把缓存设置到`/data/npm/`中,不会丢失
|
||
cacheDirectory: `${(process.env.VUE_APP_HARD_SOURCE_FOLDER && path.join(process.env.VUE_APP_HARD_SOURCE_FOLDER, '/')) ||
|
||
path.join(process.cwd(), 'node_modules', '/')
|
||
}.cache/hard-source/[confighash]`,
|
||
// 基于package.json中的name来生成不同的hash串用于cacheDirectory的目录
|
||
// @param webpackConfig
|
||
configHash(webpackConfig) {
|
||
return require('node-object-hash')({ sort: false }).hash({ packageName, ...webpackConfig });
|
||
},
|
||
// 根据目录中的lock文件来决定是否重设缓存,如果设置false则需要手动删除
|
||
environmentHash: {
|
||
root: process.cwd(),
|
||
directories: [],
|
||
files: ['package-lock.json', 'yarn.lock'],
|
||
},
|
||
info: {
|
||
// 'none' or 'test'.
|
||
mode: 'none',
|
||
// 'debug', 'log', 'info', 'warn', or 'error'.
|
||
level: 'debug',
|
||
},
|
||
// 自动清除过期、过大缓存
|
||
cachePrune: {
|
||
// 缓存时间:默认7天
|
||
maxAge: 7 * 24 * 60 * 60 * 1000,
|
||
// 超过该处设置的阈值(默认500MB),则自动删除缓存
|
||
sizeThreshold: 500 * 1024 * 1024,
|
||
},
|
||
}),
|
||
new HardSourceWebpackPlugin.ExcludeModulePlugin([
|
||
{
|
||
// HardSource works with mini-css-extract-plugin but due to how
|
||
// mini-css emits assets, assets are not emitted on repeated builds with
|
||
// mini-css and hard-source together. Ignoring the mini-css loader
|
||
// modules, but not the other css loader modules, excludes the modules
|
||
// that mini-css needs rebuilt to output assets every time.
|
||
test: /mini-css-extract-plugin[\\/]dist[\\/]loader/,
|
||
},
|
||
]),
|
||
);
|
||
}
|
||
|
||
if (isExtract) {
|
||
configureWebpackPlugin.push(
|
||
new CSSSplitWebpackPlugin({
|
||
size: 4000,
|
||
preserve: true,
|
||
filename: 'assets_res/css/[name]-[part].[ext]',
|
||
}),
|
||
);
|
||
}
|
||
|
||
if (process.env.VUE_APP_AUTO_ROUTER === 'true') {
|
||
console.log('====>> 启动自动路由,若不需要请在.env.development文件把[VUE_APP_AUTO_ROUTER]变量删除或者设置为false');
|
||
configureWebpackPlugin.push(new AutoRouterPlugin({ pages: './src/pages/*/views' }));
|
||
}
|
||
const transpileDependencies = ['tdesign-icons-vue', '@gt4/common-front'];
|
||
if (LOCAL_DEV && process.env.VUE_APP_IE === 'true') {
|
||
transpileDependencies.push('sockjs-client');
|
||
}
|
||
module.exports = {
|
||
lintOnSave: LOCAL_DEV,
|
||
transpileDependencies,
|
||
publicPath: process.env.NODE_ENV === 'production' ? '/' : process.env.VUE_APP_CDN_PATH,
|
||
assetsDir: 'assets_res',
|
||
// 生产模式生成sourcemap
|
||
productionSourceMap: false,
|
||
css: {
|
||
sourceMap: false,
|
||
// 在真实ie9下调试dev需要开始样式分离才能正常加载样式
|
||
extract: isExtract,
|
||
},
|
||
chainWebpack: (config) => {
|
||
// alias注册
|
||
// eg:
|
||
// config.resolve.alias.set('@src', path.resolve(process.cwd(), 'src'));
|
||
|
||
/**
|
||
* 修复生产模式build出来的css background-image: url(~@)路径不符合预期的问题
|
||
* eg: alias to pages/index => ~@/pages/index
|
||
*/
|
||
if (process.env.NODE_ENV === 'production') {
|
||
styles.forEach((s) => {
|
||
modules.forEach((m) =>
|
||
config.module
|
||
.rule(s)
|
||
.oneOf(m)
|
||
.use('extract-css-loader')
|
||
.tap((options) => {
|
||
// Set whatever you want as publicPath
|
||
// options.publicPath = process.env.VUE_APP_CDN_PATH;
|
||
// Object.assign(options, {
|
||
// publicPath: './',
|
||
// });
|
||
return options;
|
||
}),
|
||
);
|
||
});
|
||
}
|
||
|
||
config.plugin('static-env-config').use(
|
||
new StaticEnvConfigPlugin({
|
||
// url: './env.config.js',
|
||
url: '/view/tzzx/env.config.js',
|
||
headResourceTags: [
|
||
{
|
||
tagName: 'link',
|
||
attributes: {
|
||
href: '/favicon.ico',
|
||
rel: 'icon',
|
||
},
|
||
},
|
||
],
|
||
config: {
|
||
// 这三个必须配置,默认从.env文件中来
|
||
ROUTER_PREFIX: process.env.VUE_APP_ROUTER_BASE,
|
||
API_PREFIX: process.env.VUE_APP_API_BASE_URL,
|
||
RESOURCE_PREFIX: process.env.VUE_APP_CDN_PATH,
|
||
// 把config里面的配置注入到最终的env.config.js中
|
||
...STATIC_ENV_CONFIG,
|
||
},
|
||
}),
|
||
);
|
||
|
||
// 移除prefetch插件
|
||
config.plugins.delete('prefetch-index');
|
||
},
|
||
|
||
configureWebpack: {
|
||
// 以下规则用于微前端
|
||
// 让主应用能正确识别微应用暴露出来的一些信息
|
||
output: {
|
||
library: `${packageName}-[name]`,
|
||
libraryTarget: 'umd',
|
||
jsonpFunction: `webpackJsonp_${packageName}`,
|
||
},
|
||
optimization: {
|
||
minimizer: [
|
||
new TerserPlugin({
|
||
terserOptions: {
|
||
compress: {
|
||
warnings: false,
|
||
drop_console: true,
|
||
drop_debugger: true,
|
||
},
|
||
},
|
||
}),
|
||
],
|
||
},
|
||
plugins: [
|
||
...configureWebpackPlugin,
|
||
// t-icon替换插件
|
||
new TIconReplaceWebpackPlugin({
|
||
staticPath: 'static_res',
|
||
}),
|
||
],
|
||
},
|
||
|
||
/**
|
||
* 本地开发服务配置
|
||
*/
|
||
devServer: {
|
||
port: devServerPort,
|
||
host: '0.0.0.0',
|
||
contentBase: './dist',
|
||
publicPath: process.env.VUE_APP_ROUTER_BASE,
|
||
https: process.env.VUE_APP_PROTOCOL_HTTPS === 'true',
|
||
compress: false,
|
||
disableHostCheck: true,
|
||
overlay: {
|
||
warnings: false,
|
||
errors: true,
|
||
},
|
||
headers: {
|
||
'X-Custom-Foo': 'bar',
|
||
'Access-Control-Allow-Origin': '*',
|
||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
||
'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
|
||
},
|
||
// proxy: {
|
||
// // '/api': {
|
||
// // // target: 'http://dzswj.mhnsrd.jcsj.tax.cn/sbzx/api/cxssb', // 云测试环境
|
||
// // target: 'http://86.20.165.47:8082/dfts/api/sbf/',
|
||
// // changeOrigin: true,
|
||
// // // 用于将/api从请求路径中移除
|
||
// // pathRewrite: {
|
||
// // '^/api': '',
|
||
// // },
|
||
// // },
|
||
// [process.env.VUE_APP_API_BASE_URL]: {
|
||
// // target: 'http://dzswj.mhnsrd.jcsj.tax.cn/sbzx/api/cxssb', // 云测试环境
|
||
// target: 'http://127.0.0.1:48080/', // 苗梓誉职工&单位缴费证明开具
|
||
// changeOrigin: true,
|
||
// // 用于将/api从请求路径中移除
|
||
// pathRewrite: {
|
||
// // '^/znsb/api': '',
|
||
// },
|
||
// },
|
||
// '/gs-api': {
|
||
// target: 'https://zr.jcsk100.com//', // 目标服务器地址 跳转到个税页面,跨域用的
|
||
// changeOrigin: true,
|
||
// pathRewrite: {
|
||
// '^/gs-api': ''
|
||
// }
|
||
// }
|
||
// },
|
||
before(app) {
|
||
if (process.env.VUE_APP_MOCK === 'true') {
|
||
// 是否开启MOCK,默认开启,检查项目根目录下是否存在.env.development文件 内容为VUE_APP_MOCK=true
|
||
// 设置mock数据路由, 创建get或者post目录,该目录下的文件则为url请求地址
|
||
// app对象、请求方法、url前缀
|
||
// mock.setMock(app, 'get', process.env.VUE_APP_API_BASE_URL);
|
||
// app对象、请求方法、url前缀 eg: user_bulk__delete.json => /api/user/bulk_delete
|
||
// mock.setMock(app, 'post', process.env.VUE_APP_API_BASE_URL);
|
||
// mock.mockSubDirs(app, ['post'], '/abc') // 增加子目录,mock/xxx/post 目录下的文件为url请求地址 eg: user_bulk__delete.json => /xxx/abc/user/bulk_delete
|
||
// 设置mock数据路由, 对应目录下,创建get或者post目录,再请求目录下创建业务目录demo(没有层级层级的限制),该目录下的文件则为url请求地址 eg: fail.json => /demo/fail
|
||
// app对象、请求方法、url前缀
|
||
mock.setMockByBasePath(app, 'get', process.env.VUE_APP_API_BASE_URL);
|
||
mock.setMockByBasePath(app, 'post', process.env.VUE_APP_API_BASE_URL);
|
||
}
|
||
},
|
||
// ...PROXY,
|
||
},
|
||
/**
|
||
* 插件配置
|
||
*/
|
||
pluginOptions: {
|
||
// 添加了插件(@samhammer/vue-cli-plugin-stylelint), 所以需要配置
|
||
lintStyleOnBuild: true,
|
||
stylelint: {
|
||
fix: true, // boolean (default: true)
|
||
files: ['src/**/*.{vue,htm,html,css,sss,less,scss}'], // string | [string]
|
||
},
|
||
// 注入less全局变量
|
||
'style-resources-loader': {
|
||
preProcessor: 'less',
|
||
patterns: [path.resolve(__dirname, './src/styles/variables/*.less')],
|
||
},
|
||
},
|
||
/**
|
||
* 多页应用配置
|
||
*/
|
||
pages: multiPage,
|
||
};
|