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;
|
|||
|
}
|