123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /* eslint-disable filenames/match-regex */
- const path = require('path')
- const webpack = require('webpack')
- const AliasPlugin = require('enhanced-resolve/lib/AliasPlugin')
- const CircularDependencyPlugin = require('circular-dependency-plugin')
- const { argv } = require('yargs')
- const openInEditor = require('launch-editor-middleware')
- const designVariables = require('./src/common/design/variables.js')
- function isInSrc(context) {
- // 判断当前上下文是否属于src目录
- const srcPath = path.resolve(__dirname, 'src')
- return context === srcPath || context.startsWith(srcPath + path.sep)
- }
- const replaceRelative = new webpack.NormalModuleReplacementPlugin(/^\..*/, function(resource) {
- // 将相对路径改写为完整路径,便于在custom和src目录搜索
- const requstFullPath = path.resolve(resource.context, resource.request)
- // 不是src目录发起的 或 不是引用src目录的文件,退出
- // 比如请求node_module下的文件时,不处理
- if (!isInSrc(resource.context) || !isInSrc(requstFullPath)) return
- let p = path.resolve(resource.context, resource.request).replace(__dirname, '')
- p = p.replace(/\\/g, '/').replace('/src/', '')
- // console.warn('\nReplace path:', resource.request, p)
- resource.request = p
- })
- const replaceAtSign = new webpack.NormalModuleReplacementPlugin(/^@.*/, function(resource) {
- // 将@开始的路径改写为完整路径,便于在custom和src目录搜索
- if (!isInSrc(resource.context)) return
- const p = resource.request.replace('@/', '')
- // console.warn('\n@Replace path:', resource.request, p)
- resource.request = p
- })
- let appConfigCustom
- try {
- appConfigCustom = require('./src_custom/app-config.js')
- } catch (e) {
- appConfigCustom = {}
- }
- const appConfig = appConfigCustom
- // 各种API地址,转发到后台服务器
- const proxy = {}
- const proxySetting = {
- target: appConfig.apiEndpoint || 'https://192.168.2.177:8898/xcoa',
- secure: false,
- changeOrigin: true,
- // 转发时去掉虚拟的路径
- pathRewrite: { '^/-app-': '' },
- logLevel: 'debug',
- }
- const paths = ['api', 'docviewer-webapp', ...(appConfig.apiPaths || [])]
- paths.forEach((path) => {
- proxy['/-app-/' + path] = proxySetting
- })
- process.env.VUE_APP_TITLE = appConfig.appTitle || 'GRC.Platform'
- module.exports = {
- publicPath: '',
- transpileDependencies: [
- 'ant-design-vue',
- 'vue-echarts',
- 'resize-detector',
- 'signature_pad',
- 'sm-crypto',
- ],
- devServer: {
- // 本地的开发服务器也加一个app路径,模拟真实环境
- // 注意访问的时候要加上这个虚拟路径,如:http://localhost:8080/-app-/
- publicPath: '/-app-/',
- port: appConfig.devServerPort || 8080,
- proxy,
- // 处理mock数据
- before(app) {
- app.use('/__open-in-editor', openInEditor('code'))
- require('./src/_mock').getBeforeHook(app)
- },
- // 允许通过域名访问
- disableHostCheck: true,
- // 静态资源存放的目录,如indidoc安装文件
- contentBase: [path.join(__dirname, 'src_custom', 'www')],
- contentBasePublicPath: '/-app-',
- },
- configureWebpack: (config) => {
- // sass处理器会把\xxxx转义的字符,转义回中文。用css-unicode-loader再次转成\xxxx
- const sassLoader = require.resolve('sass-loader')
- config.module.rules
- .filter((rule) => {
- if (!rule.test) return false
- return rule.test.toString().indexOf('scss') !== -1
- })
- .forEach((rule) => {
- rule.oneOf.forEach((oneOfRule) => {
- const sassLoaderIndex = oneOfRule.use.findIndex((item) => item.loader === sassLoader)
- oneOfRule.use.splice(sassLoaderIndex, 0, {
- loader: require.resolve('css-unicode-loader'),
- })
- })
- })
- const plugins = [
- replaceRelative,
- replaceAtSign,
- new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/),
- ]
- if (argv.analyseCircularDependency) {
- plugins.push(
- new CircularDependencyPlugin({
- exclude: /node_modules/,
- include: /src/,
- failOnError: true,
- allowAsyncCycles: false,
- cwd: process.cwd(),
- })
- )
- }
- return {
- plugins,
- resolve: {
- plugins: [
- new AliasPlugin(
- 'described-resolve',
- [
- {
- name: '@extension-points',
- alias: [
- path.resolve('src_custom', '_extension-points'),
- path.resolve('src', '_extension-points'),
- ],
- },
- ],
- 'resolve'
- ),
- ],
- },
- }
- },
- /**
- * @param {import('webpack-chain')} config
- */
- chainWebpack: (config) => {
- config.resolve.alias
- .set('@custom', path.resolve('src_custom'))
- .set('@product', path.resolve('src_product'))
- .set('@external', path.resolve('lib-external'))
- // 把项目定制目录放在平台目录前面,可以覆盖
- config.resolve.modules.add(path.resolve(__dirname, 'src_custom/_override'))
- config.resolve.modules.add(path.resolve(__dirname, 'src'))
- config.plugin('html').tap((args) => {
- args[0].title = process.env.VUE_APP_TITLE
- args[0].primaryColor = designVariables['primary-color']
- return args
- })
- // 避免moment被打包多次的问题
- config.resolve.alias.set('moment$', path.resolve(__dirname, 'node_modules/moment/moment.js'))
- if ((process.env.NODE_ENV === 'production' && !argv.enableSourceMap) || argv.disableSourceMap) {
- config.devtool('(none)')
- }
- config.plugins.delete('prefetch')
- config.plugins.delete('preload')
- },
- css: {
- requireModuleExtension: true,
- loaderOptions: {
- css: {
- // js中可以使用camelCase获取classname
- localsConvention: 'camelCase',
- modules: {
- // css moudule 生成的class规则:原class+组件名+模块名
- localIdentName: '[local]_[name]_[1]',
- localIdentRegExp: /src.([a-z-]*)/i,
- },
- },
- less: {
- modifyVars: designVariables,
- javascriptEnabled: true,
- },
- },
- },
- }
|