396 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			396 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/*
 | 
						||
 * @Author: liyxt
 | 
						||
 * @Date: 2019-04-23 09:37:04
 | 
						||
 * @LastEditors: Please set LastEditors
 | 
						||
 * @LastEditTime: 2024-01-09 16:00:47
 | 
						||
 * @Description: file content
 | 
						||
 */
 | 
						||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 | 
						||
const glob = require('glob');
 | 
						||
const CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
						||
const HtmlWebpackPlugin = require('html-webpack-plugin');
 | 
						||
const fs = require('fs');
 | 
						||
const webpack = require('webpack');
 | 
						||
const configJSON = require('../config.json');
 | 
						||
const fileRules = require('./fileRules');
 | 
						||
const { resolve, join } = require('path');
 | 
						||
 | 
						||
module.exports = function buildEntry({ buildPath, buildWithoutHTML, hash, mode, client, fse, srcDir = configJSON.srcDir || 'src', patchList }) {
 | 
						||
	fse = fse === 'true' || fse === true || false;
 | 
						||
	Array.isArray(buildWithoutHTML) && buildWithoutHTML.unshift('refer');
 | 
						||
	let projects = [],
 | 
						||
		plugins = [],
 | 
						||
		entries = {},
 | 
						||
		externals = {},
 | 
						||
		lowCodeEntries = [],
 | 
						||
		rules=[];
 | 
						||
	// 遍历src下的js
 | 
						||
	(function(callback) {
 | 
						||
		if (Array.isArray(buildPath)) {
 | 
						||
			buildPath.forEach(_buildPath => {
 | 
						||
				callback(_buildPath);
 | 
						||
			});
 | 
						||
		} else {
 | 
						||
			callback(buildPath);
 | 
						||
		}
 | 
						||
	})(function(buildPath) {
 | 
						||
		getFiles(buildPath);
 | 
						||
	});
 | 
						||
 | 
						||
	if (patchList) {
 | 
						||
		let copyList = getCopyList(patchList);
 | 
						||
		copyList.forEach((path) => {
 | 
						||
			if(fs.existsSync(path)) {
 | 
						||
				plugins.push(
 | 
						||
					new CopyWebpackPlugin([
 | 
						||
						// {output}/to/file.txt
 | 
						||
						{ from: path, to: './' + path.match(/.*src\/(.*)/)[1] }
 | 
						||
					])
 | 
						||
				);}
 | 
						||
		})
 | 
						||
	} else {
 | 
						||
		projects.forEach(e => {
 | 
						||
			if (e === 'uapbd') {
 | 
						||
				// guozhq让弄的,供应链特殊
 | 
						||
				fs.existsSync(`./${srcDir}/uapbd/scmbase/public`) &&
 | 
						||
					plugins.push(
 | 
						||
						new CopyWebpackPlugin([{ from: `./${srcDir}/uapbd/scmbase/public`, to: `./uapbd/scmbase/public` }])
 | 
						||
					);
 | 
						||
				// wanghxm让弄的,hr特殊
 | 
						||
				fs.existsSync(`./${srcDir}/uapbd/hrbase/public`) &&
 | 
						||
					plugins.push(
 | 
						||
						new CopyWebpackPlugin([{ from: `./${srcDir}/uapbd/hrbase/public`, to: `./uapbd/hrbase/public` }])
 | 
						||
					);
 | 
						||
			}
 | 
						||
			fs.existsSync(`./${srcDir}/${e}/public`) &&
 | 
						||
				plugins.push(
 | 
						||
					new CopyWebpackPlugin([
 | 
						||
						// {output}/to/file.txt
 | 
						||
						{ from: `./${srcDir}/${e}/public`, to: `./${e}/public` }
 | 
						||
					])
 | 
						||
				);
 | 
						||
		});
 | 
						||
	}
 | 
						||
	function getProjectConfigByPath(path) {
 | 
						||
		let project = path.split('/')[2];
 | 
						||
		let configPath = `./${srcDir}/${project}/config.json`;
 | 
						||
		let isExists = fs.existsSync(configPath);
 | 
						||
		if (isExists) {
 | 
						||
			plugins.push(
 | 
						||
				new CopyWebpackPlugin([{ from: `./${srcDir}/${project}/config.json`, to: `./${project}/config.json` }])
 | 
						||
			);
 | 
						||
			return require('.' + configPath);
 | 
						||
		}
 | 
						||
		return {};
 | 
						||
	
 | 
						||
	}
 | 
						||
	function getFiles(buildPath) {
 | 
						||
		let {buildEntryPath:projectBuildEntryPath=[]} = getProjectConfigByPath(buildPath);
 | 
						||
		glob.sync(buildPath).forEach(path => {
 | 
						||
			//  path ---为加载的每个index.js文件:./src/reva_demo/module/apply/list/index.js
 | 
						||
			// chunk = 节点+list/card: reva_demo/module/apply/list
 | 
						||
			// 原来移动和pc的构建判断比较严格,2207之后应差异化不大了,这里先把判断短路,看一下后面会有什么问题,没问题的话就统一改掉
 | 
						||
			if (
 | 
						||
				(client === 'mobile' && path.includes('/mobile_')) ||
 | 
						||
				(client !== 'mobile' && !path.includes('/mobile_')) ||true
 | 
						||
			) {
 | 
						||
				// 移动端 || web端
 | 
						||
				let chunk = path.split(`./${srcDir}/`)[1].split('/index.js')[0],
 | 
						||
					project = chunk.split('/')[0]; // reva_demo
 | 
						||
 | 
						||
				//把src自定义命名下的文件层级减掉,更改第二层级,把领域名改为 extend_领域名  by bbqin
 | 
						||
				if (fse) {
 | 
						||
					let chunkarr = chunk.split('/');
 | 
						||
					chunkarr[0] = 'NCCExtend';
 | 
						||
					chunkarr[1] = `extend_${chunkarr[1]}`;
 | 
						||
					chunk = chunkarr.join('/');
 | 
						||
				}
 | 
						||
 | 
						||
				projects.includes(project) || projects.push(project);
 | 
						||
				// 生成webpack.config.js的入口
 | 
						||
				let configJSONPath = `./${srcDir}/` + chunk + '/config.json',
 | 
						||
					isExists = fs.existsSync(configJSONPath),
 | 
						||
					_hash,
 | 
						||
					isLowCodeEntry = false;
 | 
						||
				if (isExists) {
 | 
						||
					// 特殊处理的
 | 
						||
					let { hash, isLowCode, maxChunks } = require('.' + configJSONPath);
 | 
						||
					// maxChunks,打包生成的最大chunks数量
 | 
						||
					if (typeof maxChunks === 'number' && maxChunks > 0) {
 | 
						||
						plugins.push(new webpack.optimize.LimitChunkCountPlugin({maxChunks}))
 | 
						||
					}
 | 
						||
					_hash = isLowCode? false : hash;
 | 
						||
					if(isLowCode){
 | 
						||
						lowCodeEntries.push(chunk);
 | 
						||
					}
 | 
						||
					
 | 
						||
 | 
						||
				}
 | 
						||
 | 
						||
				if (hash === 'false') {
 | 
						||
					hash = false;
 | 
						||
				} else if (hash === 'true') {
 | 
						||
					hash = true;
 | 
						||
				}
 | 
						||
 | 
						||
				let _chunk = ('/' + chunk + '/').toLowerCase();
 | 
						||
				if (mode === 'development') {
 | 
						||
					entries[`${chunk}/index`] = path;
 | 
						||
				} else {
 | 
						||
					if (hash) {
 | 
						||
						// 筛选出带hash的
 | 
						||
						if (_hash) {
 | 
						||
							// config.json里的hash优先级高
 | 
						||
							entries[`${chunk}/index`] = path;
 | 
						||
						} else if (_hash !== false) {
 | 
						||
							// 非参照页面生成hash
 | 
						||
							if(!(
 | 
						||
								_chunk.includes('/refer/') ||
 | 
						||
								_chunk.includes('/ref/') ||
 | 
						||
								_chunk.includes('/refers/') ||
 | 
						||
								_chunk.includes('/mobile_refer/') ||
 | 
						||
								fse
 | 
						||
							)){
 | 
						||
								if(projectBuildEntryPath.length>0){
 | 
						||
									projectBuildEntryPath.includes(path) && (entries[`${chunk}/index`] = path);
 | 
						||
								}else{ //后续增加强判断,如果没有配config.json就不出盘
 | 
						||
									entries[`${chunk}/index`] = path;
 | 
						||
								}
 | 
						||
							}
 | 
						||
						}
 | 
						||
					} else {
 | 
						||
						// 筛选出不带hash的
 | 
						||
						if (_hash === false) {
 | 
						||
							// config.json里的hash优先级高
 | 
						||
							entries[`${chunk}/index`] = path;
 | 
						||
						} else if (_hash !== true) {
 | 
						||
							// 参照页面不生成hash
 | 
						||
							(_chunk.includes('/refer/') ||
 | 
						||
								_chunk.includes('/ref/') ||
 | 
						||
								_chunk.includes('/refers/') ||
 | 
						||
								_chunk.includes('/mobile_refer/') ||
 | 
						||
								_hash === false ||
 | 
						||
								fse) &&
 | 
						||
								(entries[`${chunk}/index`] = path);
 | 
						||
						}
 | 
						||
					}
 | 
						||
				}
 | 
						||
				// buildWithoutHTML中的页面不生成html
 | 
						||
				if (entries[`${chunk}/index`]) {
 | 
						||
					let templatePath = client === 'mobile' ? './template/mobileTemplate.html' : './template/index.html';
 | 
						||
					let configjs = ''; //额外配置的js文件
 | 
						||
					let configcss = ''; //额外配置的css文件
 | 
						||
					if (isExists) {
 | 
						||
						let {
 | 
						||
							template,
 | 
						||
							output,
 | 
						||
							dependjs,
 | 
						||
							dependcss,
 | 
						||
							dependModuleName,
 | 
						||
							report,
 | 
						||
							echarts,
 | 
						||
							prodProxy,
 | 
						||
							isLowCode,
 | 
						||
							importParseLayout,
 | 
						||
							specialExternals={},
 | 
						||
							packages = [],
 | 
						||
							schema,
 | 
						||
							copyFile,
 | 
						||
						} = require('.' + configJSONPath);
 | 
						||
						isLowCodeEntry = isLowCode;
 | 
						||
						// template: HTML模板路径
 | 
						||
						if (template) {
 | 
						||
							templatePath = template;
 | 
						||
						}
 | 
						||
						//低代码模式引用新的模板
 | 
						||
						if(isLowCodeEntry){
 | 
						||
							templatePath = "./template/lowcodeTemplate.html";
 | 
						||
						}
 | 
						||
						// output: 单独输出的文件配置
 | 
						||
						if (output) {
 | 
						||
							entries[`${output}/index`] = path;
 | 
						||
						}
 | 
						||
 | 
						||
						if (schema) {
 | 
						||
							entries[`${chunk}/index_schema`] = path.replace('index.js', 'index.schema.js');
 | 
						||
						}
 | 
						||
 | 
						||
						if (copyFile) {
 | 
						||
							plugins.push(
 | 
						||
								new CopyWebpackPlugin(copyFile.map(({ from, to }) => {
 | 
						||
									return { from: resolve(path, '../', from), to: join(chunk, to) }
 | 
						||
								}))
 | 
						||
							)
 | 
						||
						}
 | 
						||
 | 
						||
						// report: 报表依赖
 | 
						||
						if (report) {
 | 
						||
							configjs += `<script src="../../../../lappreportrt/nc-report/public/vendor.js"></script>`;
 | 
						||
							configjs += `<script src="../../../../lappreportrt/nc-report/index.js"></script>`;
 | 
						||
							configcss += `<link rel="stylesheet" href="../../../../lappreportrt/nc-report/public/vendor.css" />`;
 | 
						||
							configcss += `<link rel="stylesheet" href="../../../../lappreportrt/nc-report/index.css" />`;
 | 
						||
						}
 | 
						||
						if (echarts) {
 | 
						||
						    // platform下已经没有echarts文件,避免404报错
 | 
						||
				            // 	configjs += `<script src="../../../../platform/echarts.js"></script>`;
 | 
						||
						}
 | 
						||
 | 
						||
						//importParseLayout :低代码解析组件
 | 
						||
						if (importParseLayout) {
 | 
						||
							configjs += `<script src="../../../../lowcode/light-front/runtime/main/runtime.js"></script>`;
 | 
						||
						}
 | 
						||
 | 
						||
						// dependjs: 依赖的js文件配置
 | 
						||
						if (Array.isArray(dependjs)) {
 | 
						||
							configjs += dependjs.map(src => {
 | 
						||
								let moduleName = /(?:\.\.\/)*([^\.]*)\.js/.exec(src);
 | 
						||
								if (moduleName && moduleName[1]) {
 | 
						||
									externals[moduleName[1]] = moduleName[1];
 | 
						||
								}
 | 
						||
								return `<script src="${src}"></script>`;
 | 
						||
							}).join('');
 | 
						||
							
 | 
						||
						}
 | 
						||
 | 
						||
						// dependcss: 依赖的css文件配置
 | 
						||
						if (Array.isArray(dependcss)) {
 | 
						||
							configcss += dependcss
 | 
						||
								.map(item => `<link rel="stylesheet" href=${item}?v=${Date.now()}>`)
 | 
						||
								.join('');
 | 
						||
						}
 | 
						||
 | 
						||
 | 
						||
						// dependModuleName: 依赖的模块名
 | 
						||
						if (Array.isArray(dependModuleName)) {
 | 
						||
							// 打包时排除
 | 
						||
							dependModuleName.forEach(item => (externals[`${item}`] = `${item}/index`));
 | 
						||
						}
 | 
						||
 | 
						||
						if (Array.isArray(packages)) {
 | 
						||
							packages.forEach(({ name, src, var: root }) => {
 | 
						||
								if (!Array.isArray(src)) {
 | 
						||
									src = [src]
 | 
						||
								}
 | 
						||
 | 
						||
								src.forEach((e) => {
 | 
						||
									if (/.js$/.test(e)) {
 | 
						||
										configjs += `<script src="${e}"></script>`;
 | 
						||
									} else if (/.css$/.test(e)) {
 | 
						||
										configcss += `<link rel="stylesheet" href=${e}}>`
 | 
						||
									}
 | 
						||
								})
 | 
						||
 | 
						||
								
 | 
						||
								externals[name] = root || name;
 | 
						||
							})
 | 
						||
						}
 | 
						||
 | 
						||
						// specialExternals: 特殊的排除
 | 
						||
						externals = Object.assign(externals,specialExternals);
 | 
						||
 | 
						||
						plugins.push(
 | 
						||
							new webpack.DefinePlugin({
 | 
						||
								PROD_PROXY: JSON.stringify((mode !== 'development' && prodProxy) || '')
 | 
						||
							})
 | 
						||
						);
 | 
						||
					}
 | 
						||
 | 
						||
					if ((!(buildWithoutHTML || []).some(e => path.includes(e)))) {
 | 
						||
						const htmlConf = {
 | 
						||
							filename: `${chunk}/index.html`, // 生成的html文件名,可加目录/.../.../index.html
 | 
						||
							template: `${templatePath}`, // 模板html路径
 | 
						||
							inject: true, //允许插件修改哪些内容,包括head与body
 | 
						||
							chunks: [`${chunk}/index`], // 生成的html文件引入哪些js,不传的话引入所有js
 | 
						||
							cache: true,
 | 
						||
							templateParameters: {
 | 
						||
								configjs: configjs, //为模板添加js
 | 
						||
								configcss: configcss, //为模板添加css
 | 
						||
								prefix: chunk.split('/').join('_') //css前缀
 | 
						||
							}
 | 
						||
						};
 | 
						||
						if(isLowCodeEntry){
 | 
						||
							htmlConf.chunks = [];
 | 
						||
						 }
 | 
						||
						plugins.push(new HtmlWebpackPlugin(htmlConf));
 | 
						||
 | 
						||
						//rules = fileRules({ cssSandbox: true, chunk });
 | 
						||
 | 
						||
					}
 | 
						||
				}
 | 
						||
			}
 | 
						||
		});
 | 
						||
	}
 | 
						||
 | 
						||
	let cleanOnceBeforeBuildPatterns = Object.values(entries).map(e => e.replace('index.js', '').replace(`./${srcDir}/`, ''));
 | 
						||
	plugins.push(
 | 
						||
		new CleanWebpackPlugin({
 | 
						||
			cleanOnceBeforeBuildPatterns,
 | 
						||
			cleanAfterEveryBuildPatterns: [],
 | 
						||
			verbose: true
 | 
						||
		})
 | 
						||
	);
 | 
						||
	return {
 | 
						||
		plugins,
 | 
						||
		entries,
 | 
						||
		externals,
 | 
						||
		lowCodeEntries,
 | 
						||
		rules,
 | 
						||
	};
 | 
						||
};
 | 
						||
 | 
						||
function getCopyList(patchList) {
 | 
						||
	if (!patchList) {
 | 
						||
		return [];
 | 
						||
	}
 | 
						||
 | 
						||
    let content = fs.readFileSync(patchList, { encoding: 'utf-8' });
 | 
						||
	// content.replace('\r', '');
 | 
						||
 | 
						||
    let lines = content.split(/\r?\n/),
 | 
						||
		group = {}, 
 | 
						||
		currentGroup = '前端';
 | 
						||
 | 
						||
    lines.forEach((line) => {
 | 
						||
        if (/\*{3}/.test(line)) {
 | 
						||
            currentGroup = line;
 | 
						||
        } else {
 | 
						||
            group[currentGroup] = group[currentGroup] || [];
 | 
						||
            line && group[currentGroup].push(line);
 | 
						||
        }
 | 
						||
    })
 | 
						||
 | 
						||
    let copyList = [];
 | 
						||
 | 
						||
    Object.entries(group).forEach(([name, lines]) => {
 | 
						||
        if (name.includes('前端')) {
 | 
						||
            let [, module] = name.match(/\*{3}\s([^|]*)\|/) || [];
 | 
						||
 | 
						||
            lines.forEach((line) => {
 | 
						||
                let [type, path1, path2] = line.split(/\s+/), path = '';
 | 
						||
                switch (type) {
 | 
						||
                    case 'A':
 | 
						||
                    case 'M':
 | 
						||
                        path = path1;
 | 
						||
                        break;
 | 
						||
                    case 'R':
 | 
						||
                        path = path2;
 | 
						||
                        break;
 | 
						||
                    default:
 | 
						||
                        break;
 | 
						||
                }
 | 
						||
 | 
						||
                if (path && !path.includes(module)) {
 | 
						||
                    path = `src/${module}/${path}`;
 | 
						||
                }
 | 
						||
 | 
						||
                if (path.includes(`${module}/public`) && !/\.js$|\.less$|\.css$/.test(path)) {
 | 
						||
                    copyList.push(path);
 | 
						||
                }
 | 
						||
 | 
						||
            })
 | 
						||
        }
 | 
						||
    })
 | 
						||
 | 
						||
	return copyList;
 | 
						||
}
 |