序
上一篇 webpack less 抽取小技巧 中說(shuō)到,可以進(jìn)行多主題的引入种吸。此篇咱們就來(lái)實(shí)現(xiàn)一下如何一次性生成多個(gè)文件主題还栓;
webpack 支持多入口
首先webpack是支持多入口的刨裆,通過(guò)對(duì)象的形式進(jìn)行entry添加
// webpack.config.js (來(lái)源于官網(wǎng) (https://webpack.docschina.org/guides/entry-advanced/#root))
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: process.env.NODE_ENV,
// 多入口配置項(xiàng)
entry: {
home: './home.less',
account: './account.less',
},
output: {
filename: '[name].js',
},
module: {
rules: [
{
test: /\.scss$/,
use: [
// fallback to style-loader in development
process.env.NODE_ENV !== 'production'
? 'style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
};
如何生成多入口文件
一般來(lái)說(shuō)司蔬,我們所需要生成主題css的原less(sass 同理)都應(yīng)該放置在同一個(gè)目錄下面耿战,這樣方便存儲(chǔ)與管理秸脱;這樣我們就有了單對(duì)多落包,多對(duì)多,選擇性生成的需求撞反;例如:生產(chǎn)環(huán)境中妥色,我們需要將所有的theme樣式一起生成,而在開(kāi)發(fā)環(huán)境遏片,我們只需要對(duì)應(yīng)的theme即可嘹害;如下三種需要支持:
- 1、文件夾下的讀取 (fse 讀取文件夾下的文件)
- 2吮便、命令行支持的動(dòng)態(tài)文件配置 (運(yùn)行時(shí) process.argv笔呀,動(dòng)態(tài)讀取參數(shù))
- 3、默認(rèn)主題的添加
直接給出代碼:
// less2css.js
// 基本依賴
const fse = require('fs-extra')
const path = require('path');
// production 同級(jí)
const resolveTop = function (dir) {
return path.join(__dirname, '../../..', dir);
};
// 目標(biāo)主題目錄
const TARGET_THEME_LESS_PATH = resolveTop(`./assets/less/theme/`);
// 基礎(chǔ)主題名稱
const BASE_THEME_LESS_NAME = 'theme';
// 基礎(chǔ)主題目錄
const BASE_THEME_LESS_PATH = resolveTop(`./assets/less/`);
const getTargetFiles = function (dir) {
const list = [];
// 要搜索的目錄;表示是否還搜索其子目錄的標(biāo)記;匹配文件的正則表達(dá)式
// const list = require.context(dir, true, /\.less$/);
// fse 獲取文件名稱
const files = fse.readdirSync(dir);
console.log('getTargetFiles files', files);
files.forEach(fileName => {
if (/\.less$/.test(fileName)) {
// list.push({
// [fileName]: path.join(dir, fileName)
// });
// entryObj[fileName] = path.join(dir, fileName);
list.push(fileName);
}
});
console.log('getTargetFiles list', list);
return list;
};
// 獲取輸入文件
// example(命令行): webpack --config less2css.js --custom=theme1,theme2,theme3
const getInputFiles = function() {
// 獲取輸入?yún)?shù)
var arguments = process.argv;
const setting = arguments[4];
if (setting) {
const splitArr = setting.split('=');
if (splitArr[0] === '--custom') {
const list = splitArr[1].split(',');
const files = list.map(i => (i + '.less'))
console.log('getInputFiles files', files);
return files;
}
}
return [];
};
const tarnsFormThemeList = function(list) {
const entryObj = {};
list.forEach(theme => {
entryObj[theme] = path.join(TARGET_THEME_LESS_PATH, /\.less$/.test(theme) ? theme : (theme + '.less'));
});
return entryObj;
};
const getEntryFun = function() {
// 初始化主題位置
const baseEntryObj = {
[BASE_THEME_LESS_NAME]: path.join(BASE_THEME_LESS_PATH, BASE_THEME_LESS_NAME + '.less')
};
try {
// 獲取輸入?yún)?shù)
const inputThemeFiles = getInputFiles();
// 輸入?yún)?shù)優(yōu)先
if (inputThemeFiles.length) {
return tarnsFormThemeList(inputThemeFiles);
}
// 目標(biāo)目錄下的less文件
const targetLessFiles = getTargetFiles(TARGET_THEME_LESS_PATH);
// 讀取文件目錄靠后
if (targetLessFiles.length) {
return tarnsFormThemeList(targetLessFiles);
}
// 默認(rèn)目錄在最后生效
return baseEntryObj;
} catch (error) {
console.log('error', error);
// 程序失敗髓需,使用默認(rèn)目錄
return baseEntryObj;
}
};
const entryObj = getEntryFun();
const cssConfig = {
// ...
mode: 'production',
entry: entryObj,
// ...
}
被棄用的 require.context
此處不建議使用 require.context许师,主要原因是這里會(huì)報(bào)錯(cuò),具體原因并沒(méi)有找到,懷疑 require.context 只能在webpack入口索引的文件內(nèi)部使用微渠,不能直接使用在 config.js (未確認(rèn)搭幻,保持懷疑態(tài)度);利用替代方案 node 的fs(fse) 也可以進(jìn)行文件夾下文件的讀取逞盆。