UNPKG

plugin-light

Version:

Webpack 相关插件、Loader、基础配置及 CLI 命令

912 lines (879 loc) 39 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var fs = require('fs'); var path = require('path'); var tComm = require('t-comm'); var FileManagerPlugin = require('filemanager-webpack-plugin'); var webpackBundleAnalyzer = require('webpack-bundle-analyzer'); var PrerenderSpaPlugin = require('prerender-spa-plugin'); var HooksScriptPlugin = require('webpack-hooks-shellscripts'); var WorkboxPlugin = require('workbox-webpack-plugin'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var fs__namespace = /*#__PURE__*/_interopNamespace(fs); var path__namespace = /*#__PURE__*/_interopNamespace(path); var FileManagerPlugin__default = /*#__PURE__*/_interopDefaultLegacy(FileManagerPlugin); var PrerenderSpaPlugin__default = /*#__PURE__*/_interopDefaultLegacy(PrerenderSpaPlugin); var HooksScriptPlugin__default = /*#__PURE__*/_interopDefaultLegacy(HooksScriptPlugin); var WorkboxPlugin__default = /*#__PURE__*/_interopDefaultLegacy(WorkboxPlugin); function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /* eslint-disable no-prototype-builtins */ /** * Execute html action * * @param {Object} command - Command data for given action * @return {Function|null} - Function that returns a promise or null * @ignore */ function htmlAction(command, options) { var verbose = options.verbose; if (!command.source || !command.destination) { if (verbose) { console.log(' - HtmlModifyPlugin: Warning - parameter has to be formatted as follows: { source: <string>, destination: <string> }'); } return null; } return function () { return new Promise(function (resolve, reject) { fs__namespace.lstat(command.destination, function (dErr, dStats) { if (dErr || !dStats.isFile()) { return reject(dErr); } var htmlString = ''; var htmlLine = []; if (command.ssr || dErr) { // ssr取源文件为模板。模板文件不存在也取源文件为模板。 htmlString = fs__namespace.readFileSync(command.source, 'utf-8'); } else { htmlString = fs__namespace.readFileSync(command.destination, 'utf-8'); } htmlLine = htmlString.split('\n'); // 修改html:匹配<body>字符串,替换为 <body>... var injectHtml = '<style>[v-cloak] {display: none;}</style>' + '\n'; if (!command.ssr) { if (htmlString.indexOf('<div id=\'app\'') == -1 && htmlString.indexOf('<div id="app"') == -1) { injectHtml += '<div id=\'app\'></div>' + '\n'; } injectHtml += "\n<script>\n window.__serverFailed = 0;\n window.__breakerTime = 0;\n</script>"; // 静态版本这两个也用于熔断保护,由熔断机制动态替换其值 } else { injectHtml += '<!--vue-ssr-outlet-->' + '\n'; injectHtml += "\n<script>\n window.__serverCount = {{__serverCount||0}};\n window.__serverFailed = {{__serverFailed||0}};\n window.__breakerTime = {{__breakerTime||0}};\n</script>"; } for (var i in command.urls) { injectHtml += "<script src='".concat(command.urls[i], "'></script>") + '\n'; } injectHtml += "<script>window.igameVersion = { version: ".concat(new Date().getTime(), ", author: '").concat(tComm.getGitAuthor(), "' };</script>"); var injectPrefetch = ''; var prefetchInjected = false; if (Array.isArray(command.prefetchList)) { command.prefetchList.map(function (item) { injectPrefetch += "<link rel=\"dns-prefetch\" href=\"".concat(item, "\">") + '\n'; injectPrefetch += "<link rel=\"preconnect\" href=\"".concat(item, "\" crossorigin>") + '\n'; }); } for (var _i in htmlLine) { if (htmlLine[_i].indexOf('<link') > -1 && injectPrefetch && !prefetchInjected) { prefetchInjected = true; // eslint-disable-next-line no-loop-func htmlLine[_i] = htmlLine[_i].replace(/<link.*>/, function (a) { return "".concat(a, "\n").concat(injectPrefetch); }); } if (htmlLine[_i].indexOf('<body>') > -1) { htmlLine[_i] = htmlLine[_i].replace('<body>', "<body>\n".concat(injectHtml)); } if (command.ssr && htmlLine[_i].indexOf('<title>') > -1) { // 多页面标题可变 htmlLine[_i] = htmlLine[_i].replace(/<title>.*?<\/title>/, '<title>{{title}}</title>'); } } fs__namespace.writeFileSync(command.destination, htmlLine.join('\n'), 'utf-8'); resolve(1); }); }); }; } var classCallCheck = function classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var toConsumableArray = function toConsumableArray(arr) { if (Array.isArray(arr)) { var arr2 = Array(arr.length); for (var i = 0; i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } return Array.from(arr); }; var HtmlModifyPlugin = function () { function HtmlModifyPlugin(options) { // @ts-ignore classCallCheck(this, HtmlModifyPlugin); // @ts-ignore this.options = this.setOptions(options); } createClass(HtmlModifyPlugin, [{ key: 'setOptions', value: function setOptions(userOptions) { var defaultOptions = { verbose: false, moveWithMkdirp: false, onStart: {}, onEnd: {} }; for (var key in defaultOptions) { if (userOptions.hasOwnProperty(key)) { defaultOptions[key] = userOptions[key]; } } return defaultOptions; } }, { key: 'checkOptions', // 只有两个调用:this.checkOptions('onStart')和this.checkOptions('onEnd') value: function checkOptions(stage, compiler) { var that = this; if (this.options.verbose && Object.keys(this.options[stage]).length) { console.log("HtmlModifyPlugin: processing ".concat(stage, " event")); } var operationList = []; if (this.options[stage] && Array.isArray(this.options[stage])) { // onEnd: [{copy:[]}, {delete:[]}],数组形式,按序执行 this.options[stage] // @ts-ignore .map(function (opts) { return operationList.push.apply(operationList, toConsumableArray(that.parseOptions(opts, true))); }); } else { // onEnd: {copy:[], delete:[]},对象形式,不保证顺序 // @ts-ignore operationList.push.apply(operationList, toConsumableArray(this.parseOptions(this.options[stage]))); } if (operationList.length) { operationList.reduce(function (previous, fn) { return previous.then(function (retVal) { return fn(retVal, compiler); })["catch"](function (err) { return console.warn(err); }); }, Promise.resolve()); } } }, { key: 'replaceHash', value: function replaceHash(filename) { return filename.replace('[hash]', this.fileHash); } }, { key: 'processAction', value: function processAction(action, params, commandOrder) { var result = action(params, this.options); if (result !== null) { commandOrder.push(result); } } }, { key: 'parseOptions', // options : {copy:[...], delete:[...]} value: function parseOptions(options) { var that = this; var commandOrder = []; Object.keys(options).forEach(function (actionType) { var actionOptions = options[actionType]; var actionParams = null; actionOptions.forEach(function (actionItem) { switch (actionType) { case 'html': actionParams = { source: that.replaceHash(actionItem.source), destination: actionItem.destination, urls: actionItem.urls, prefetchList: actionItem.prefetchList || [], ssr: actionItem.ssr || '' // '','client','server' }; that.processAction(htmlAction, actionParams, commandOrder); break; } }); }); return commandOrder; } }, { key: 'apply', value: function apply(compiler) { var that = this; var comp = function comp(compilation) { try { that.checkOptions('onStart', compiler); } catch (error) { compilation.errors.push(error); } }; var afterEmit = function afterEmit(compilation, cb) { // 已经计算好的hash that.fileHash = compilation.hash; try { that.checkOptions('onEnd', compiler); } catch (error) { compilation.errors.push(error); } cb(); }; if (compiler.hooks) { compiler.hooks.compilation.tap('compilation', comp); compiler.hooks.afterEmit.tapAsync('afterEmit', afterEmit); } else { compiler.plugin('compilation', comp); compiler.plugin('after-emit', afterEmit); } } }]); return HtmlModifyPlugin; }(); function getRootDir() { return process.cwd(); } var publishUtil = "./webpack-publish.js"; var vueDirective = "./loader/vue-directive.js"; var vueDirectiveProd = "./loader/vue-directive.prod.js"; var vLazy = "./loader/v-lazy.js"; var vLazyProd = "./loader/v-lazy.prod.js"; var transformDynamicComp = "./loader/transform-dynamic-comp.js"; var transformDynamicCompProd = "./loader/transform-dynamic-comp.prod.js"; var swipeComponent = "./loader/swipe-component.js"; var swipeComponentProd = "./loader/swipe-component.prod.js"; var replaceVueKey = "./loader/replace-vue-key.js"; var replaceVueKeyProd = "./loader/replace-vue-key.prod.js"; var replaceTemplateTag = "./loader/replace-template-tag.js"; var replaceTemplateTagProd = "./loader/replace-template-tag.prod.js"; var replaceLibrary = "./loader/replace-library.js"; var replaceLibraryProd = "./loader/replace-library.prod.js"; var replaceContent = "./loader/replace-content.js"; var replaceContentProd = "./loader/replace-content.prod.js"; var insertPageMeta = "./loader/insert-page-meta.js"; var insertPageMetaProd = "./loader/insert-page-meta.prod.js"; var insertGlobalComp = "./loader/insert-global-comp.js"; var insertGlobalCompProd = "./loader/insert-global-comp.prod.js"; var injectDynamicStyleWeb = "./loader/inject-dynamic-style-web.js"; var injectDynamicStyleWebProd = "./loader/inject-dynamic-style-web.prod.js"; var injectDynamicStyleMp = "./loader/inject-dynamic-style-mp.js"; var injectDynamicStyleMpProd = "./loader/inject-dynamic-style-mp.prod.js"; var ifdefLoader = "./loader/ifdef-loader.js"; var ifdefLoaderProd = "./loader/ifdef-loader.prod.js"; var ifdef = "./loader/ifdef.js"; var ifdefProd = "./loader/ifdef.prod.js"; var cssUrlBlankSpace = "./loader/css-url-blank-space.js"; var cssUrlBlankSpaceProd = "./loader/css-url-blank-space.prod.js"; var crossPlatform = "./loader/cross-platform.js"; var crossPlatformProd = "./loader/cross-platform.prod.js"; var crossModuleStyle = "./loader/cross-module-style.js"; var crossModuleStyleProd = "./loader/cross-module-style.prod.js"; var crossGameStyle = "./loader/cross-game-style.js"; var crossGameStyleProd = "./loader/cross-game-style.prod.js"; var autoPlaceholder = "./loader/auto-placeholder.js"; var autoPlaceholderProd = "./loader/auto-placeholder.prod.js"; var LoaderMap = { publishUtil: publishUtil, vueDirective: vueDirective, vueDirectiveProd: vueDirectiveProd, vLazy: vLazy, vLazyProd: vLazyProd, transformDynamicComp: transformDynamicComp, transformDynamicCompProd: transformDynamicCompProd, swipeComponent: swipeComponent, swipeComponentProd: swipeComponentProd, replaceVueKey: replaceVueKey, replaceVueKeyProd: replaceVueKeyProd, replaceTemplateTag: replaceTemplateTag, replaceTemplateTagProd: replaceTemplateTagProd, replaceLibrary: replaceLibrary, replaceLibraryProd: replaceLibraryProd, replaceContent: replaceContent, replaceContentProd: replaceContentProd, insertPageMeta: insertPageMeta, insertPageMetaProd: insertPageMetaProd, insertGlobalComp: insertGlobalComp, insertGlobalCompProd: insertGlobalCompProd, injectDynamicStyleWeb: injectDynamicStyleWeb, injectDynamicStyleWebProd: injectDynamicStyleWebProd, injectDynamicStyleMp: injectDynamicStyleMp, injectDynamicStyleMpProd: injectDynamicStyleMpProd, ifdefLoader: ifdefLoader, ifdefLoaderProd: ifdefLoaderProd, ifdef: ifdef, ifdefProd: ifdefProd, cssUrlBlankSpace: cssUrlBlankSpace, cssUrlBlankSpaceProd: cssUrlBlankSpaceProd, crossPlatform: crossPlatform, crossPlatformProd: crossPlatformProd, crossModuleStyle: crossModuleStyle, crossModuleStyleProd: crossModuleStyleProd, crossGameStyle: crossGameStyle, crossGameStyleProd: crossGameStyleProd, autoPlaceholder: autoPlaceholder, autoPlaceholderProd: autoPlaceholderProd }; function getLoaderMap() { return Object.keys(LoaderMap).reduce(function (acc, key) { acc[key] = path__namespace.resolve(__dirname, LoaderMap[key]); return acc; }, {}); } var LOADER_MAP = getLoaderMap(); var VUE2_VUE3_COMMON_CDN_URLS = ['https://image-1251917893.file.myqcloud.com/igame/npm/axios@0.18.0/dist/axios.min.js', 'https://image-1251917893.file.myqcloud.com/igame/npm/vue-lazyload@1.3.3/vue-lazyload.js', 'https://image-1251917893.file.myqcloud.com/igame/common/js/emonitor_custom_46f41566.js']; var DEFAULT_CDN_URLS = ['https://image-1251917893.file.myqcloud.com/igame/npm/vue%402.6.10/dist/vue.runtime.min.js', 'https://image-1251917893.file.myqcloud.com/igame/npm/vue-router@3.5.2/dist/vue-router.min.js', 'https://image-1251917893.file.myqcloud.com/igame/npm/vuex@3.0.1/dist/vuex.min.js'].concat(VUE2_VUE3_COMMON_CDN_URLS); var VUE3_CDN_URLS = ['https://unpkg.com/vue@3.2.31/dist/vue.runtime.global.prod.js', 'https://unpkg.com/vue-router@4.0.14/dist/vue-router.global.js', 'https://unpkg.com/vuex@4.0.2/dist/vuex.global.js'].concat(VUE2_VUE3_COMMON_CDN_URLS); var DEFAULT_PROJECT_MAP = { 'project/pvp-match-apply': 'project/match-apply', 'project/pvp-match-apply-mobile': 'project/match-apply-mobile', 'project/gp-match-apply': 'project/match-apply', 'project/gp-match-apply-mobile': 'project/match-apply-mobile', 'project/lol-match-apply': 'project/match-apply', 'project/lol-match-apply-mobile': 'project/match-apply-mobile', 'project/qp-match-apply': 'project/match-apply', 'project/qp-match-apply-mobile': 'project/match-apply-mobile' }; var DEFAULT_HANDLE_IF_DEF_FILES = /(press-ui|component|press-plus|@tencent\/pmd-).*(\.vue|\.ts|\.js|\.css|\.scss)$/; var DEFAULT_TRANSPILE_DEPENDENCIES = ['pmd-merchant-ui', 'press-ui', 'press-plus', 'pmd-aegis', 'pmd-app-info', 'pmd-config', 'pmd-location', 'pmd-login', 'pmd-network', 'pmd-report', 'pmd-tools', 'pmd-types', 'pmd-widget', 'pmd-vue', 'pmd-jsapi', 'pmd-component', 'pmd-business', 'pmd-api', '@zebra-ui/swiper' // /[@\\]tencent[/\\]press-ui/, // /[@\\]tencent[/\\]press-plus/, // /[@\\]tencent[/\\]pmd-aegis/, // /[@\\]tencent[/\\]pmd-app-info/, // /[@\\]tencent[/\\]pmd-config/, // /[@\\]tencent[/\\]pmd-location/, // /[@\\]tencent[/\\]pmd-login/, // /[@\\]tencent[/\\]pmd-network/, // /[@\\]tencent[/\\]pmd-report/, // /[@\\]tencent[/\\]pmd-tools/, // /[@\\]tencent[/\\]pmd-widget/, // /[@\\]tencent[/\\]pmd-vue/, // /[@\\]tencent[/\\]pmd-jsapi/, // /[@\\]zebra-ui[/\\]swiper/, ]; function checkBundleAnalyze() { return process.argv.includes('--bundleAnalyzer') || !!process.env.npm_config_report; } function checkDebugMode() { return !!process.env.DEBUG_MODE; } function getProjectName() { var result = ''; try { var json = tComm.readFileSync('package.json', true) || {}; result = json.name || ''; } catch (err) {} return result; } function getSubProjectName() { var _process$env$VUE_APP_; var name = ((_process$env$VUE_APP_ = process.env.VUE_APP_DIR) === null || _process$env$VUE_APP_ === void 0 || (_process$env$VUE_APP_ = _process$env$VUE_APP_.split('/')) === null || _process$env$VUE_APP_ === void 0 ? void 0 : _process$env$VUE_APP_[1]) || ''; return name; } function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function initWorkboxPlugin() { var useWorkBoxPlugin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return new WorkboxPlugin__default["default"].GenerateSW(_objectSpread$3({ swDest: "./service-worker-".concat(getProjectName(), "-").concat(getSubProjectName(), ".js"), clientsClaim: true, include: [/.*(.js|.css|.svg|.png|.jpg|.jpeg)/], skipWaiting: true, maximumFileSizeToCacheInBytes: 13 * 1024 * 1024, importScripts: [], inlineWorkboxRuntime: true, runtimeCaching: [{ urlPattern: new RegExp('^https://image-1251917893\\.file\\.myqcloud.com.*(\\.js|\\.css|\\.svg|\\.png|\\.jpg|\\.jpeg)'), handler: 'StaleWhileRevalidate', options: { cacheableResponse: { statuses: [0, 200] } } }, { urlPattern: /.*\.html$/, handler: 'NetworkOnly' }] }, useWorkBoxPlugin)); } function ownKeys$2(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$2(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$2(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$2(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var curDirname = getRootDir(); // 获取真实的vue-app名字 function getRealVueAppDir() { var shadowProjectMap = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var vueAppDir = process.env.VUE_APP_DIR || ''; if (DEFAULT_PROJECT_MAP[vueAppDir]) { return DEFAULT_PROJECT_MAP[vueAppDir]; } if (shadowProjectMap[vueAppDir]) { return shadowProjectMap[vueAppDir]; } return vueAppDir || ''; } var publishPara = process.env.publish; function getAppName() { var arr = (process.env.VUE_APP_DIR || '').split('/'); return arr[arr.length - 1]; } // 输出路径,构建的ssr包放在ssr目录下,构建的static包放在static目录下 function getOutputPath() { if (process.env.VUE_APP_PLUGIN) { return path__namespace.resolve(curDirname, 'dist', process.env.VUE_APP_DIR || '', 'plugin'); } if (process.env.VUE_APP_SSR) { return path__namespace.resolve(curDirname, 'dist', process.env.VUE_APP_DIR || '', 'ssr'); } return path__namespace.resolve(curDirname, 'dist', process.env.VUE_APP_DIR || '', 'static'); } // 入口:entry.js, entry-server.js, entry-client.js function getEntry(shadowProjectMap) { return path__namespace.resolve(curDirname, 'src', getRealVueAppDir(shadowProjectMap), 'main.js'); // plugin的入口用自己的 } // 获取目下所有项目文件夹名称并创建webpack别名 function getAllAppNameAlias(shadowProjectMap) { var usePMDBusinessAlias = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var lessAlias = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var files = fs__namespace.readdirSync(path__namespace.resolve(curDirname, 'src')); var result = { foldername: [], filename: [] // 文件名,有后缀 }; files.forEach(function (file) { var pathname = path__namespace.join(curDirname, 'src', file); var stat = fs__namespace.lstatSync(pathname); if (!stat.isDirectory()) { result.filename.push(file); } else { result.foldername.push(file); } }); var alias = { src: path__namespace.resolve(curDirname, 'src'), '@': path__namespace.resolve(curDirname, 'src', getRealVueAppDir(shadowProjectMap)) // 由环境变量确定当前的项目 }; if (!lessAlias) { result.foldername.forEach(function (dir) { alias[dir] = path__namespace.resolve(curDirname, 'src', dir); }); } if (usePMDBusinessAlias) { return _objectSpread$2(_objectSpread$2({}, alias), {}, { 'src/component': 'pmd-business' }); } return alias; } // 需要构建时自动注入的cdn url function getCdnInject(_ref) { var _ref$isVue = _ref.isVue3, isVue3 = _ref$isVue === void 0 ? false : _ref$isVue, _ref$customCdnUrls = _ref.customCdnUrls, customCdnUrls = _ref$customCdnUrls === void 0 ? [] : _ref$customCdnUrls; var objs = { mqq: 'mqq', wx: 'wx', msdkShare: 'msdkShare', vue: 'Vue', 'vue-router': 'VueRouter', vuex: 'Vuex', axios: 'axios', 'vue-lazyload': 'VueLazyload' }; // 必要的 cdn 写这里。构建时注入 html 中。(不是所有页面都要的,页面自己加载) var cdnUrls = DEFAULT_CDN_URLS; if (isVue3) { cdnUrls = VUE3_CDN_URLS; } if (customCdnUrls !== null && customCdnUrls !== void 0 && customCdnUrls.length) { cdnUrls = customCdnUrls; } return { objs: objs, cdnUrls: cdnUrls }; } function getWebpackBaseConfig(options) { var _options$port, _options$https; var _merge = tComm.merge({}, { isUseVueLoader: true, isVue3: false, useXSS: true, useIfDefLoader: true, handleIfDefFiles: DEFAULT_HANDLE_IF_DEF_FILES }, options || {}), isUseVueLoader = _merge.isUseVueLoader, isVue3 = _merge.isVue3, useXSS = _merge.useXSS, useIfDefLoader = _merge.useIfDefLoader, handleIfDefFiles = _merge.handleIfDefFiles, _merge$shadowProjectM = _merge.shadowProjectMap, shadowProjectMap = _merge$shadowProjectM === void 0 ? {} : _merge$shadowProjectM; var terserPureFuncs = ['console.log', 'console.table']; var transpileDependencies = DEFAULT_TRANSPILE_DEPENDENCIES; if (options !== null && options !== void 0 && options.terserPureFuncs) { terserPureFuncs = options.terserPureFuncs || []; } if (options !== null && options !== void 0 && options.transpileDependencies) { transpileDependencies = options.transpileDependencies; } var config = { publicPath: process.env.VUE_APP_PUBLICPATH, outputDir: getOutputPath(), assetsDir: '', lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: true, transpileDependencies: transpileDependencies, parallel: false, css: { extract: false }, devServer: { port: (_options$port = options === null || options === void 0 ? void 0 : options.port) !== null && _options$port !== void 0 ? _options$port : process.env.port || process.env.npm_config_port || 443, https: (_options$https = options === null || options === void 0 ? void 0 : options.https) !== null && _options$https !== void 0 ? _options$https : true, proxy: { '/pvp/share/getsharecfg': { target: 'https://igame.qq.com', changeOrigin: true, ws: true }, '/pvp/share/gethash': { target: 'https://igame.qq.com', changeOrigin: true, ws: true } }, disableHostCheck: (process.env.NODE_ENV || '').startsWith('development') }, configureWebpack: _objectSpread$2(_objectSpread$2({ entry: getEntry(shadowProjectMap), name: getAppName(), resolve: { alias: getAllAppNameAlias(shadowProjectMap, options === null || options === void 0 ? void 0 : options.usePMDBusinessAlias, options === null || options === void 0 ? void 0 : options.lessAlias), extensions: ['js', 'vue', 'json', 'ts'] } }, checkDebugMode() ? { optimization: { minimize: false } } : {}), {}, { plugins: [options !== null && options !== void 0 && options.useWorkBoxPlugin ? initWorkboxPlugin(options.useWorkBoxPlugin) : undefined].filter(function (item) { return item; }) }), chainWebpack: function chainWebpack(config) { config.module.rule('vue').uses["delete"]('cache-loader'); config.module.rule('js').uses["delete"]('cache-loader'); config.module.rule('ts').uses["delete"]('cache-loader'); config.module.rule('tsx').uses["delete"]('cache-loader'); if (useIfDefLoader) { config.module.rule('ifdef-loader') // 根据项目实际配置文件类型 .test(handleIfDefFiles) // 不要配成下面这样,会卡住 // .test(/\.vue|\.ts|\.js|\.css|\.scss$/) .use(LOADER_MAP.ifdef).loader(LOADER_MAP.ifdef).options({ context: { H5: true, VUE2: true, __NOT_UNI__: true }, type: ['css', 'js', 'html'] }).end(); } // 先暂时去掉eslint config.module.rule('eslint').uses.clear(); config.when(process.env.PUBLISH_ENV !== 'test', function (config) { // 去掉console.log config.optimization.minimizer('terser').tap(function (args) { // remove debugger args[0].terserOptions.compress.drop_debugger = true; // 移除 console.log args[0].terserOptions.compress.pure_funcs = terserPureFuncs; // 去掉注释 如果需要看chunk-vendors公共部分插件,可以注释掉就可以看到注释了 args[0].terserOptions.output = { comments: false }; return args; }); }); // config.plugins.delete('preload'); // 这个不禁止,预加载很快会被用到的内容 config.plugins["delete"]('prefetch'); // 这个禁止掉,首屏不预加载其他路由的js,需要预加载的路由,引入的时候,加上/* webpackPrefetch: true */ config.plugin('preload').use('@vue/preload-webpack-plugin').tap(function () { return [{ rel: 'preload', // 不写这个runtime.js会被打包进去 fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/], include: 'initial' }]; }); if (checkBundleAnalyze()) { console.log('进行包分析'); config.plugin('webpack-bundle-analyzer').use(webpackBundleAnalyzer.BundleAnalyzerPlugin).end(); } else if (process.env.NODE_ENV !== 'development') { config.plugin('webpack-bundle-analyzer').use(new webpackBundleAnalyzer.BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false, reportFilename: 'my-bundle-analyze.html' })).end(); } // set preserveWhitespace config.module.rule('vue').test(/\.vue$/).use(LOADER_MAP.crossGameStyle, LOADER_MAP.crossPlatformProd) // 处理样式的loader,必须在vue-loader前执行 .loader(LOADER_MAP.crossGameStyle, LOADER_MAP.crossPlatformProd).end(); if (isUseVueLoader) { config.module.rule('vue').test(/\.vue$/).use('vue-loader').loader('vue-loader').tap(function (vueOptions) { if (vueOptions) { vueOptions.compilerOptions.whitespace = 'preserve'; } return vueOptions; }).tap(function (vueOptions) { if (useXSS) { vueOptions.compilerOptions.directives = { html: function html(node, directiveMeta) { (node.props || (node.props = [])).push({ name: 'innerHTML', value: "xss ? xss(_s(".concat(directiveMeta.value, ")) : ").concat(directiveMeta.value) }); } }; } return vueOptions; }).end(); } config.module.rule('js').test(/\.[jt]s$/).use(LOADER_MAP.crossPlatform) // 处理样式的loader,必须在vue-loader前执行 .loader(LOADER_MAP.crossPlatform).end(); if (process.env.NODE_ENV === 'production') { config.devtool('hidden-module-source-map'); // 对外隐藏map信息、使用源码定位出错位置 } else { config.devtool('eval-source-map'); // 生成速度更快 } config.when(process.env.NODE_ENV !== 'development', function (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', // the weight needs to be larger than libs and app or it will be packaged into libs or app priority: 20, test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm }, comm: { name: 'chunk-comm', test: /[\\/]src[\\/]_?comm(.*)/, minChunks: 2, minSize: 10 * 1024, maxSize: 244 * 1024, priority: 5, reuseExistingChunk: true }, component: { name: 'chunk-component', test: /[\\/]src[\\/]_?component(.*)/, minChunks: 2, minSize: 10 * 1024, maxSize: 244 * 1024, priority: 5, reuseExistingChunk: true }, logic: { name: 'chunk-logic', test: /[\\/]src[\\/]_?logic(.*)/, minChunks: 2, minSize: 10 * 1024, maxSize: 244 * 1024, priority: 5, reuseExistingChunk: true } } }); config.optimization.runtimeChunk('single'); }); var serving = false; process.argv.forEach(function (i) { if (i.indexOf('--serving') == 0) { serving = true; } }); // 指定html模板文件 config.plugin('html').tap(function (args) { args[0].template = path__namespace.resolve(curDirname, 'src', getRealVueAppDir(shadowProjectMap) || 'comm', 'index.html'); // 业务目录下自己的模板。默认在vue-cli3/public/index.html args[0].minify = false; // 不需要压缩,没几个字节,不压缩方便后续处理 return args; }); // config.when(process.env.NODE_ENV !== 'hotreload', config => { if (!serving) { console.log("--------not serving now: ".concat(process.env.NODE_ENV, "----------")); // html后处理:title替换,cdnurl自动注入。自定义HtmlmodifyPlugin插件 config.plugin('Htmlmodify').use(new HtmlModifyPlugin({ onEnd: { html: [{ source: path__namespace.resolve(curDirname, 'src', getRealVueAppDir(shadowProjectMap), 'index.html'), destination: "".concat(getOutputPath(), "/index.html"), ssr: process.env.VUE_APP_SSR, urls: getCdnInject({ isVue3: isVue3, customCdnUrls: options === null || options === void 0 ? void 0 : options.customCdnUrls }).cdnUrls }] } })).tap(function (args) { return args; }); if (process.env.npm_config_prerender) { console.log('开始预渲染'); config.plugin('prerender-spa-plugin').use(PrerenderSpaPlugin__default["default"], [{ // 生成文件的路径,也可以与webpakc打包的一致。 // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。 staticDir: path__namespace.join(curDirname, './dist'), outputDir: getOutputPath(), indexPath: "".concat(getOutputPath(), "/index.html"), routes: ['/', '/index'], renderer: new PrerenderSpaPlugin__default["default"].PuppeteerRenderer({ inject: { initLocation: false // 是否初始化定位组件,为false不会渲染定位相关 }, // headless: false, renderAfterTime: 10000 // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。 // renderAfterDocumentEvent: 'render-event', }) }]).end(); } // 打包构建后的文件 config.plugin('FileManager').use(new FileManagerPlugin__default["default"]({ onEnd: [{ archive: [{ source: getOutputPath(), destination: "".concat(getOutputPath(), "/static_").concat(getAppName(), "_").concat(tComm.getIPAddressStr(), ".tar"), format: 'tar' }] }] })).tap(function (args) { return args; }); /* 申明外部全局变量 不经常改动的库、我们通过cdn引入. require('Vue')或者import('Vue') 时webpack不对他们进行打包, 可以减少代码的大小、也可以减少服务器的带宽,更能把这些文件缓存到客户端,客户端加载的会更快。 */ config.externals(getCdnInject({ isVue3: isVue3 }).objs); if (publishPara == 'test') { console.log('编译并发布到测试环境'); config.plugin('webpack-hooks-shellscripts').use(HooksScriptPlugin__default["default"]({ beforeRun: [], afterEmit: ["node ".concat(LOADER_MAP.publishUtil)] })).end(); } else if (publishPara == 'prod') { console.log('编译并发布到正式环境'); config.plugin('webpack-hooks-shellscripts').use(HooksScriptPlugin__default["default"]({ beforeRun: [], afterEmit: ["node ".concat(LOADER_MAP.publishUtil, " prod")] })).end(); } else { console.log('只编译不发布'); config.plugin('webpack-hooks-shellscripts').use(HooksScriptPlugin__default["default"]({ beforeRun: [], afterEmit: [] })).end(); } // }) } } }; return config; } var PUBLISH_BASE_OPTIONS = {}; function ownKeys$1(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$1(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$1(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function innerPublish(publishEnv) { tComm.localPublish(_objectSpread$1(_objectSpread$1({}, PUBLISH_BASE_OPTIONS), {}, { publishEnv: publishEnv })); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var WEBPACK_BASE_CONFIG = _objectSpread({}, getWebpackBaseConfig()); exports.WEBPACK_BASE_CONFIG = WEBPACK_BASE_CONFIG; exports.getWebpackBaseConfig = getWebpackBaseConfig; exports.innerPublish = innerPublish;