tk2312-web/config/buildEntry.js

396 lines
12 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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;
}