build-plugin-fusion
Version:
plugin for build scripts while use fusion component
506 lines • 29.4 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var _this = this;
var fs = require('fs');
var path = require('path');
var _a = require('lodash'), upperFirst = _a.upperFirst, camelCase = _a.camelCase;
var WebpackPluginImport = require('webpack-plugin-import');
var CheckIceComponentsDepsPlugin = require('./webpackPlugins/checkIceComponentsDepPlugin');
var AppendStyleWebpackPlugin = require('./webpackPlugins/appendStyleWebpackPlugin');
var getThemeVars = require('./utils/getThemeVars');
var getThemeCode = require('./utils/getThemeCode');
var getCalcVars = require('./utils/getCalcVars');
var vitePluginTheme = require('./vitePluginTheme').default;
function normalizeEntry(entry, preparedChunks) {
var preparedName = (preparedChunks || [])
.filter(function (module) {
return typeof module.name !== 'undefined';
})
.map(function (module) { return module.name; });
return Object.keys(entry).concat(preparedName);
}
function replaceBlank(str) {
return str.replace(/[\r\n ]/g, '').replace(/\\/g, '\\\\');
}
function addCSSVariableCode(_a) {
var rootDir = _a.rootDir, themesCssVars = _a.themesCssVars, defaultTheme = _a.defaultTheme, cssVariable = _a.cssVariable, config = _a.config, log = _a.log;
try {
var tempDir = path.join(rootDir, './node_modules');
var jsPath_1 = path.join(tempDir, 'change-theme.js');
fs.writeFileSync(jsPath_1, getThemeCode(themesCssVars, defaultTheme, cssVariable));
// add theme.js to entry
var entryNames = Object.keys(config.entryPoints.entries());
entryNames.forEach(function (name) {
config.entry(name).prepend(jsPath_1);
});
}
catch (err) {
log.error('fail to add theme.js to entry');
log.error(err);
}
}
function getVariablesPath(_a) {
var packageName = _a.packageName, _b = _a.filename, filename = _b === void 0 ? 'variables.scss' : _b, _c = _a.silent, silent = _c === void 0 ? false : _c;
var filePath = '';
var variables = "".concat(packageName, "/").concat(filename);
try {
filePath = require.resolve(variables);
}
catch (err) {
if (!silent) {
console.log('[ERROR]', "fail to resolve ".concat(variables));
}
}
return filePath;
}
module.exports = function (_a, pluginOptions) {
var onGetWebpackConfig = _a.onGetWebpackConfig, log = _a.log, context = _a.context, getAllTask = _a.getAllTask, modifyUserConfig = _a.modifyUserConfig;
if (pluginOptions === void 0) { pluginOptions = {}; }
return __awaiter(_this, void 0, void 0, function () {
var themePackage, themeConfig, _b, nextLibDir, _c, usePx2Vw, _d, px2vwOptions, _e, style, _f, disableModularImport, uniteNextLib, externalNext, _g, importOptions, _h, componentOptions, enableColorNames, cssVariable, uniteBaseComponent, rootDir, pkg, userConfig, webpack, taskNames, ignoreTasks;
return __generator(this, function (_j) {
themePackage = pluginOptions.themePackage, themeConfig = pluginOptions.themeConfig, _b = pluginOptions.nextLibDir, nextLibDir = _b === void 0 ? 'es' : _b, _c = pluginOptions.usePx2Vw, usePx2Vw = _c === void 0 ? false : _c, _d = pluginOptions.px2vwOptions, px2vwOptions = _d === void 0 ? {} : _d, _e = pluginOptions.style, style = _e === void 0 ? true : _e, _f = pluginOptions.disableModularImport, disableModularImport = _f === void 0 ? false : _f, uniteNextLib = pluginOptions.uniteNextLib, externalNext = pluginOptions.externalNext, _g = pluginOptions.importOptions, importOptions = _g === void 0 ? {} : _g, _h = pluginOptions.componentOptions, componentOptions = _h === void 0 ? {} : _h, enableColorNames = pluginOptions.enableColorNames, cssVariable = pluginOptions.cssVariable;
uniteBaseComponent = pluginOptions.uniteBaseComponent;
rootDir = context.rootDir, pkg = context.pkg, userConfig = context.userConfig, webpack = context.webpack;
taskNames = getAllTask();
ignoreTasks = ['component-dist'];
// 1. 支持主题能力
if (themePackage) {
if (userConfig.vite) {
if (Array.isArray(themePackage)) {
log.info('vite 模式下暂不支持多主题');
}
}
else if (Array.isArray(themePackage)) {
log.info('已启用 themePackage 多主题功能');
}
else {
log.info('使用 Fusion 组件主题包:', themePackage);
}
}
if (themeConfig) {
log.info('自定义 Fusion 组件主题变量:', themeConfig);
}
if (userConfig.vite) {
modifyUserConfig('vite', {
plugins: [
// eslint-disable-next-line global-require
!disableModularImport && require('vite-plugin-style-import').default({
libs: [
{
libraryName: '@alifd/next',
esModule: true,
resolveStyle: function (name) {
// use css variable style for default
return "@alifd/next/es/".concat(name, "/").concat(cssVariable ? 'style2' : 'style');
},
},
],
}),
vitePluginTheme({
themeConfig: themeConfig || {},
themeFile: typeof themePackage === 'string' &&
getVariablesPath({ packageName: themePackage }),
iconFile: typeof themePackage === 'string' &&
getVariablesPath({
packageName: themePackage,
filename: 'icons.scss',
silent: true,
}),
}),
].filter(Boolean),
}, { deepmerge: true });
}
taskNames.forEach(function (taskName) {
onGetWebpackConfig(taskName, function (config) {
var _a;
var replaceVars = {};
var defaultScssVars = {};
var defaultTheme = '';
if (Array.isArray(themePackage)) {
var themesCssVars_1 = {};
var varsPath_1 = !cssVariable &&
getVariablesPath({ packageName: '@alifd/next', silent: true });
// get scss variables and generate css variables
themePackage.forEach(function (_a) {
var name = _a.name, themeData = __rest(_a, ["name"]);
var themePath = getVariablesPath({
packageName: name,
filename: "variables.".concat(cssVariable ? 'css' : 'scss'),
});
if (!cssVariable) {
var configData = themeData.themeConfig || {};
var themeVars = {};
var calcVars = {};
if (varsPath_1) {
calcVars = getCalcVars(varsPath_1, themePath, configData);
}
try {
themeVars = getThemeVars(themePath, Object.assign({}, calcVars, configData), enableColorNames);
}
catch (err) {
log.error('get theme variables err:', err);
}
replaceVars = themeVars.scssVars;
defaultScssVars = themeVars.originTheme;
themesCssVars_1[name] = themeVars.cssVars;
}
else if (themePath) {
// read css variables from css file
themesCssVars_1[name] = replaceBlank(fs.readFileSync(themePath, 'utf-8'));
}
if (themeData.default) {
defaultTheme = name;
}
});
defaultTheme =
defaultTheme || (themePackage[0] && themePackage[0].name);
addCSSVariableCode({
defaultTheme: defaultTheme,
config: config,
themesCssVars: themesCssVars_1,
rootDir: rootDir,
cssVariable: cssVariable,
log: log,
});
}
else if (cssVariable && themePackage) {
// add css variable code when cssVariable is true
var cssVariablePath = getVariablesPath({
packageName: themePackage,
filename: 'variables.css',
});
if (cssVariablePath) {
var cssVariables = replaceBlank(fs.readFileSync(cssVariablePath, 'utf-8'));
addCSSVariableCode({
defaultTheme: themePackage,
config: config,
themesCssVars: (_a = {}, _a[themePackage] = cssVariables, _a),
rootDir: rootDir,
cssVariable: cssVariable,
log: log,
});
}
}
if (usePx2Vw) {
['css', 'scss', 'scss-module'].forEach(function (rule) {
config.module
.rule(rule)
.use('postcss-loader')
.tap(function (options) {
var _a = options.plugins, plugins = _a === void 0 ? [] : _a;
return __assign(__assign({}, options), { plugins: __spreadArray(__spreadArray([], plugins, true), [
// eslint-disable-next-line
require('postcss-plugin-rpx2vw'),
// eslint-disable-next-line
require('./postcssPlugins/postcssPluginPx2vw')(px2vwOptions),
], false) });
});
});
}
var themeFile = typeof themePackage === 'string' &&
getVariablesPath({ packageName: themePackage, silent: true });
['scss', 'scss-module'].forEach(function (rule) {
config.module
.rule(rule)
.use('ice-skin-loader')
.loader(require.resolve('ice-skin-loader'))
.options({
themeFile: themeFile,
themeConfig: Object.assign({}, defaultScssVars, replaceVars, themeConfig || {}),
});
});
// check icons.scss
var iconPackage = defaultTheme || themePackage;
var iconScssPath = iconPackage &&
getVariablesPath({
packageName: iconPackage,
filename: 'icons.scss',
silent: true,
});
if (iconScssPath && fs.existsSync(iconScssPath)) {
var appendStylePluginOption = {
type: 'sass',
srcFile: iconScssPath,
variableFile: getVariablesPath({ packageName: iconPackage }),
compileThemeIcon: true,
themeConfig: themeConfig || {},
distMatch: function (chunkName, compilerEntry, compilationPreparedChunks) {
var entriesAndPreparedChunkNames = normalizeEntry(compilerEntry, compilationPreparedChunks);
// 仅对 css 的 chunk 做 处理
if (entriesAndPreparedChunkNames.length &&
/\.css$/.test(chunkName)) {
// css/index.css -> index css/index.[hash].css -> index
// css/_component_.usage.css -> _component_.usage
var assetsBaseName = path.basename(chunkName, path.extname(chunkName));
var assetsFromEntry = userConfig.hash
? assetsBaseName.substring(0, assetsBaseName.lastIndexOf('.'))
: assetsBaseName;
if (entriesAndPreparedChunkNames.indexOf(assetsFromEntry) !== -1) {
return true;
}
}
return false;
},
};
config
.plugin('AppendStyleWebpackPlugin')
.use(AppendStyleWebpackPlugin, [appendStylePluginOption]);
}
var crossendBabelLoader = [];
if ('componentOptions' in pluginOptions) {
var _b = componentOptions.bizComponent, bizComponent = _b === void 0 ? [] : _b, _c = componentOptions.customPath, customPath_1 = _c === void 0 ? '' : _c, _d = componentOptions.componentMap, componentMap_1 = _d === void 0 ? {} : _d;
var mixBizCom_1 = {};
// bizComponent: ['@alifd/anchor', '@alifd/pro-components'],
if (Array.isArray(bizComponent)) {
bizComponent.forEach(function (com) {
mixBizCom_1[com] = "".concat(com).concat(customPath_1);
});
}
// componentMap: {
// '@alifd/pro-components': '@alifd/pro-components/lib/mobile',
// '@alifd/pro-components-2': '@alifd/pro-components-2-mobile'
// }
var mapList = Object.keys(componentMap_1);
if (mapList.length > 0) {
mapList.forEach(function (orgName) {
mixBizCom_1[orgName] = componentMap_1[orgName];
});
}
crossendBabelLoader.push(require.resolve('babel-plugin-module-resolver'), {
alias: mixBizCom_1,
});
}
// 2. 组件(包含业务组件)按需加载&样式自动引入
// babel-plugin-import: 基础组件
// remove babel-plugin-import if external next
if (!externalNext && !ignoreTasks.includes(taskName) && !disableModularImport) {
var importConfigs_1 = [
{
libraryName: '@icedesign/base',
style: style,
},
{
libraryName: '@alife/next',
style: style,
},
__assign({ libraryName: '@alifd/next', libraryDirectory: nextLibDir, style: cssVariable ? function (name) { return "".concat(name, "/style2"); } : style }, importOptions),
];
['jsx', 'tsx'].forEach(function (rule) {
config.module
.rule(rule)
.use('babel-loader')
.tap(function (options) {
var plugins = options.plugins.concat(importConfigs_1.map(function (itemConfig) {
return [
require.resolve('babel-plugin-import'),
itemConfig,
itemConfig.libraryName,
];
}));
if (crossendBabelLoader.length > 0) {
plugins.push(crossendBabelLoader);
}
options.plugins = plugins;
return options;
});
});
}
// 业务组件:不可枚举,使用 webpack-plugin-import,内置逻辑(pkg.componentConfig || pkg.stylePath)
// compatible with build-plugin which do not set up WebpackPluginImport
if (!config.plugins.get('WebpackPluginImport')) {
config.plugin('WebpackPluginImport').use(WebpackPluginImport);
}
// 3. uniteBaseComponent
// uniteBaseComponent: true => @icedesign/base(兼容老的逻辑)
// uniteBaseComponent: "@alife/next" => @alife/next
uniteBaseComponent =
uniteBaseComponent &&
(typeof uniteBaseComponent === 'string'
? uniteBaseComponent
: '@icedesign/base');
if (uniteBaseComponent) {
// 统一基础组件包:@ali/ice, @alife/next, @icedesign/base -> @icedesign/base
log.info('uniteBaseComponent 开启,基础包统一到:', uniteBaseComponent);
var alias = {
// @ali/ice -> uniteBaseComponent
'@ali/ice/global.scss': "".concat(uniteBaseComponent, "/reset.scss"),
'@ali/ice/lib/row$': "".concat(uniteBaseComponent, "/lib/_components/@alife/next-grid/lib/row.js"),
'@ali/ice/lib/col$': "".concat(uniteBaseComponent, "/lib/_components/@alife/next-grid/lib/col.js"),
// sass 里 @import '~xxx'
'@ali/ice/base.scss': "".concat(uniteBaseComponent, "/lib/core/index.scss"),
'@ali/ice': uniteBaseComponent,
// @alife/next -> uniteBaseComponent
'@alife/next/lib/_components/@alife/next-core/lib/index.scss': "".concat(uniteBaseComponent, "/reset.scss"),
'@alife/next/reset.scss': "".concat(uniteBaseComponent, "/reset.scss"),
// sass 里 @import '~xxx'
'@alife/next/variables.scss': "".concat(uniteBaseComponent, "/variables.scss"),
'@alife/next/lib/core/index.scss': "".concat(uniteBaseComponent, "/lib/core/index.scss"),
'@alife/next': "".concat(uniteBaseComponent),
// @icedesign/base -> uniteBaseComponent
'@icedesign/base/reset.scss': "".concat(uniteBaseComponent, "/reset.scss"),
// sass 里 @import '~xxx'
'@icedesign/base/variables.scss': "".concat(uniteBaseComponent, "/variables.scss"),
'@icedesign/base/lib/core/index.scss': "".concat(uniteBaseComponent, "/lib/core/index.scss"),
'@icedesign/base': "".concat(uniteBaseComponent),
};
config.merge({
resolve: {
alias: alias,
},
});
}
// 4. 检测组件版本
config
.plugin('CheckIceComponentsDepsPlugin')
.use(CheckIceComponentsDepsPlugin, [
{
pkg: pkg,
log: log,
},
]);
if (uniteNextLib) {
var replaceRegex_1 = new RegExp("(alife|alifd)/next/".concat(nextLibDir === 'es' ? 'lib' : 'es'));
config
.plugin('UniteNextLib')
.use(webpack.NormalModuleReplacementPlugin, [
/@(alife|alifd)\/next\/(.*)/,
function (resource) {
// eslint-disable-next-line no-param-reassign
resource.request = resource.request.replace(replaceRegex_1, "alifd/next/".concat(nextLibDir));
},
]);
}
if (externalNext && !ignoreTasks.includes(taskName)) {
var isUmdTarget_1 = externalNext === 'umd';
var externals = [];
if (userConfig.externals) {
externals.push(userConfig.externals);
}
var feNextRegex_1 = /@alife\/next\/(es|lib)\/([-\w+]+)$/;
var nextRegex_1 = /@(alife|alifd)\/next\/(es|lib)\/([-\w+]+)$/;
var baseRegex_1 = /@icedesign\/base\/lib\/([-\w+]+)$/;
externals.push(function (_context, request, callback) {
var isNext = nextRegex_1.test(request);
var isDesignBase = baseRegex_1.test(request);
if (isNext || isDesignBase) {
var componentName = isNext
? request.match(nextRegex_1)[3]
: request.match(baseRegex_1)[1];
var externalKey = isNext ? 'Next' : 'ICEDesignBase';
if (componentName) {
var externalInfo = [
externalKey,
upperFirst(camelCase(componentName)),
];
var commonPackage = feNextRegex_1.test(request)
? '@alife/next'
: '@alifd/next';
var commonExternal = [
isNext ? commonPackage : '@icedesign/base',
upperFirst(camelCase(componentName)),
];
/**
* An object with { root, amd, commonjs, ... } is only allowed for libraryTarget: 'umd'.
* It's not allowed for other library targets.
*/
return isUmdTarget_1
? callback(null, {
root: externalInfo,
amd: commonExternal,
commonjs: commonExternal,
commonjs2: commonExternal,
})
: callback(null, [
externalKey,
upperFirst(camelCase(componentName)),
]);
}
}
else if (nextRegex_1.test(_context) &&
/\.(scss|css)$/.test(request)) {
// external style files imported by next style.js
return callback(null, 'Next');
}
return callback();
});
config.externals(externals);
}
// 转化 icon content
config.module
.rule('scss')
.use('unicode-loader')
.loader(require.resolve('./webpackLoaders/unicodeLoader'))
.before('sass-loader');
});
});
return [2 /*return*/];
});
});
};
//# sourceMappingURL=index.js.map