Gathering detailed insights and metrics for @zougt/some-loader-utils
Gathering detailed insights and metrics for @zougt/some-loader-utils
Gathering detailed insights and metrics for @zougt/some-loader-utils
Gathering detailed insights and metrics for @zougt/some-loader-utils
implementation for less-loader or sass-loader. Compiles Less or sass to theme CSS.
npm install @zougt/some-loader-utils
Typescript
Module System
Min. Node Version
Node Version
NPM Version
JavaScript (100%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
60 Stars
39 Commits
9 Forks
2 Watchers
1 Branches
1 Contributors
Updated on Jul 03, 2024
Latest Version
1.4.3
Package Id
@zougt/some-loader-utils@1.4.3
Unpacked Size
84.08 kB
Size
20.74 kB
File Count
13
NPM Version
8.1.2
Node Version
16.13.1
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
25
提供了
让你轻松实现基于less
、sass
的 web 应用在线动态主题切换。
特点:
v1.4.0+支持
可用颜色板选择任意颜色切换相关的梯度颜色,这里以 scss 为例
1# use npm or pnpm 2npm install color@3.2.1 @zougt/some-loader-utils @zougt/theme-css-extract-webpack-plugin -D 3# use yarn 4yarn add color@3.2.1 @zougt/some-loader-utils @zougt/theme-css-extract-webpack-plugin -D
webpack.config.js
1const path = require('path'); 2 3const { getSass } = require('@zougt/some-loader-utils'); 4 5const ThemeCssExtractWebpackPlugin = require('@zougt/theme-css-extract-webpack-plugin'); 6 7const multipleScopeVars = [ 8 { 9 // 必需,任意名称 10 scopeName: 'theme-vars', 11 // path和varsContent选一个 12 path: path.resolve('src/theme/theme-vars.scss'), 13 // varsContent:`@--color-primary:#9c26b;` 14 }, 15]; 16 17module.exports = { 18 module: { 19 rules: [ 20 { 21 // 添加 setCustomTheme 的热更新loader 22 test: /setCustomTheme\.js$/, 23 enforce: 'pre', 24 loader: require.resolve( 25 '@zougt/theme-css-extract-webpack-plugin/dist/hot-loader/index.js' 26 ), 27 }, 28 { 29 test: /\.(scss|sass)$/i, 30 // 请确保支持 implementation 属性的 sass-loader版本,webpack4 => sass-loader v10.x,webpack5 => sass-loader v12.x,请安装sass, 非 node-sass 31 loader: 'sass-loader', 32 options: { 33 implementation: getSass({ 34 // getMultipleScopeVars优先于 sassOptions.multipleScopeVars 35 getMultipleScopeVars: (lessOptions) => 36 multipleScopeVars, 37 // 可选项 38 // implementation:sass 39 }), 40 }, 41 }, 42 ], 43 }, 44 plugins: [ 45 new ThemeCssExtractWebpackPlugin({ 46 // 启用动态主题模式 47 arbitraryMode: true, 48 // 默认主题色,与"src/theme/theme-vars.scss"的@--color-primary主题色相同 49 defaultPrimaryColor: '#512da7', 50 multipleScopeVars, 51 // 【注意】includeStyleWithColors作用: css中不是由主题色变量生成的颜色,也让它抽取到主题css内,可以提高权重 52 includeStyleWithColors: [ 53 { 54 // color也可以是array,如 ["#ffffff","#000"] 55 color: '#ffffff', 56 // 排除属性,如 不提取背景色的#ffffff 57 // excludeCssProps:["background","background-color"] 58 // 排除选择器,如 不提取以下选择器的 #ffffff 59 // excludeSelectors: [ 60 // ".ant-btn-link:hover, .ant-btn-link:focus, .ant-btn-link:active", 61 // ], 62 }, 63 ], 64 // 是否在html默认添加主题的style标签 65 InjectDefaultStyleTagToHtml: true, 66 // setCustomTheme.js的一个依赖的生成路径,默认是 @zougt/theme-css-extract-webpack-plugin/dist/hot-loader/setCustomThemeContent.js 67 customThemeOutputPath: '', 68 // 调整色相值偏差,某些颜色值是由主题色通过mix等函数转化后,两者色相值不相等,无法确认是梯度颜色,可以调整low和high,允许偏差范围, 例如 hueDiffControls:{low: 2,high:2} 69 // hueDiffControls: { 70 // low: 0, 71 // high: 0, 72 // }, 73 }), 74 ], 75};
src/theme/theme-vars.scss
1/*说明:此文件不应该被其他@import,此文件的变量并不是来设置项目的主题(当然,你可以作为加载时的默认主题),主要作用是,这里的变量值只要与项目的原变量值有差别,编译后就会抽取跟随主题色梯度变化的css*/ 2 3/*注意(重要):此文件的内容一旦固定下来就不需要改,在线动态切换主题,调用setCustomTheme方法即可*/ 4 5/*注意(强调):变量值改动会影响 gradientReplacer 和 targetValueReplacer 的可用属性的变化,所以内容一旦固定下来就不需要改(强调)*/ 6 7/*主题色,通常与 插件的 defaultPrimaryColor 相同, 使用setCustomTheme({primaryColor})切换*/ 8 9$--color-primary: #512da7; 10 11/*与此颜色对应的样式,默认情况也会跟主色变化的,要切换它对应的梯度颜色,使用setCustomTheme({gradientReplacer:{"#F7D06B":"#F7D06B"}})切换 */ 12$--color-success: #f7d06b; 13 14// /*圆角值,尽量与原值差别大一点,方便分析 targetValueReplacer 的可用属性,非颜色值的切换,可以使用 setCustomTheme({targetValueReplacer:{"6px"}}) 精准替换*/ 15// @border-radius-base:6px;
在线切换主题
动态主题切换必须使用的 "setCustomTheme" 模块,会自动处理项目中包括组件库涉及的梯度颜色替换
1// color@4 使用了Numeric separators,如需良好兼容性应该安装 color@3 2import Color from 'color'; 3// setCustomTheme的参数必须提供Color模块,至于为什么不把 Color 直接依赖进去是有原因的 4import setCustomTheme from '@zougt/theme-css-extract-webpack-plugin/dist/setCustomTheme'; 5// 设置任意主题色既可 6setCustomTheme({ 7 Color, 8 primaryColor: '#FF005A', 9 //gradientReplacer:{}, 10 //targetValueReplacer:{} 11});
setCustomTheme
的可选参数 gradientReplacer 与 targetValueReplacer 的可用属性会跟随 .scss 内容变化的,所以整个项目动态主题的模型应该最开始固化下来
1# npm run dev 之后 2# 可以在终端使用 z-theme 命令查看 gradientReplacer 与 targetValueReplacer 的可用属性 3npx z-theme inspect
只预设多种可选主题,这里以less为例
1# use npm or pnpm 2npm install @zougt/some-loader-utils @zougt/theme-css-extract-webpack-plugin -D 3# use yarn 4yarn add @zougt/some-loader-utils @zougt/theme-css-extract-webpack-plugin -D
webpack.config.js
1const path = require('path'); 2const webpack = require('webpack'); 3 4const { getLess } = require('@zougt/some-loader-utils'); 5 6const ThemeCssExtractWebpackPlugin = require('@zougt/theme-css-extract-webpack-plugin'); 7 8const multipleScopeVars = [ 9 { 10 // 必需 11 scopeName: 'theme-default', 12 // path 和 varsContent 必选一个 13 path: path.resolve('src/theme/theme-default.less'), 14 // varsContent参数等效于 path文件的内容 15 // varsContent:`@primary-color:${defaultPrimaryColor};` 16 }, 17 18 { 19 scopeName: 'theme-red', 20 path: path.resolve('src/theme/theme-red.less'), 21 }, 22]; 23const extract = process.env.NODE_ENV === 'production'; 24const publicPath = '/'; 25const assetsDir = 'assets'; 26const extractCssOutputDir = `${assetsDir}/css`; 27 28module.exports = { 29 output: { 30 publicPath, 31 }, 32 module: { 33 rules: [ 34 { 35 test: /\.less$/i, 36 // webpack4 => less-loader v7.x , webpack5 => less-loader v10.x 37 loader: 'less-loader', 38 options: { 39 lessOptions: { 40 javascriptEnabled: true, 41 }, 42 implementation: getLess({ 43 // getMultipleScopeVars优先于 lessOptions.multipleScopeVars 44 getMultipleScopeVars: (lessOptions) => 45 multipleScopeVars, 46 // 可选项 47 // implementation:less 48 }), 49 }, 50 }, 51 ], 52 }, 53 plugins: [ 54 // 添加参数到浏览器端 55 new webpack.DefinePlugin({ 56 'env.themeConfig': { 57 multipleScopeVars: JSON.stringify(multipleScopeVars), 58 extract: JSON.stringify(extract), 59 publicPath: JSON.stringify(publicPath), 60 extractCssOutputDir: JSON.stringify(extractCssOutputDir), 61 }, 62 }), 63 64 new ThemeCssExtractWebpackPlugin({ 65 multipleScopeVars, 66 // 【注意】includeStyleWithColors作用: css中不是由主题色变量生成的颜色,也让它抽取到主题css内,可以提高权重 67 includeStyleWithColors: [ 68 { 69 // color也可以是array,如 ["#ffffff","#000"] 70 color: '#ffffff', 71 // 排除属性,如 不提取背景色的#ffffff 72 // excludeCssProps:["background","background-color"] 73 // 排除选择器,如 不提取以下选择器的 #ffffff 74 // excludeSelectors: [ 75 // ".ant-btn-link:hover, .ant-btn-link:focus, .ant-btn-link:active", 76 // ], 77 }, 78 { 79 color: ['transparent', 'none'], 80 }, 81 ], 82 // 默认使用哪份主题,默认取 multipleScopeVars[0].scopeName 83 defaultScopeName: '', 84 // 在生产模式是否抽取独立的主题css文件,extract为true以下属性有效 85 extract, 86 // 独立主题css文件的输出路径 87 outputDir: extractCssOutputDir, 88 // 会选取defaultScopeName对应的主题css文件在html添加link 89 themeLinkTagId: 'theme-link-tag', 90 // 是否对抽取的css文件内对应scopeName的权重类名移除 91 removeCssScopeName: false, 92 }), 93 ], 94};
在线切换主题
预设主题切换,需要做的事情
1、开发时只需,html 标签的 calss 添加对应的 scopeName,移除上个 scopeName
2、打包后,如果开启 extract: true,需要切换对应的 link 标签的 href
可以选择使用如下封装好的方法
1import { toggleTheme } from '@zougt/theme-css-extract-webpack-plugin/dist/toggleTheme';
2// env.themeConfig 来源 (webpack.DefinePlugin)
3const themeConfig = env.themeConfig;
4toggleTheme({
5 scopeName,
6 multipleScopeVars: themeConfig.multipleScopeVars,
7 extract: themeConfig.extract,
8 publicPath: themeConfig.publicPath,
9 outputDir: themeConfig.extractCssOutputDir,
10 // customLinkHref: (href) => href,
11 // themeLinkTagId: "theme-link-tag",
12 // removeCssScopeName: false,
13 // loading: {
14 // show: () => {},
15 // hide: () => {},
16 // },
17});
预设多主题编译原理示例(以 sass 为例)
主题包含的可能不只是颜色部分
1//src/theme/default-vars.scss 2/** 3*此scss变量文件作为multipleScopeVars去编译时,会自动移除!default以达到变量提升 4*同时此scss变量文件作为默认主题变量文件,被其他.scss通过 @import 时,必需 !default 5*/ 6$primary-color: #0081ff !default; 7$--border-radius-base: 4px !default;
1//src/theme/mauve-vars.scss 2$primary-color: #9c26b0 !default; 3$--border-radius-base: 8px !default;
1//src/components/Button/style.scss 2@import '../../theme/default-vars'; 3.un-btn { 4 position: relative; 5 display: inline-block; 6 font-weight: 400; 7 white-space: nowrap; 8 text-align: center; 9 border: 1px solid transparent; 10 background-color: $primary-color; 11 border-radius: $--border-radius-base; 12 .anticon { 13 line-height: 1; 14 } 15}
编译之后
src/components/Button/style.css
1.un-btn { 2 position: relative; 3 display: inline-block; 4 font-weight: 400; 5 white-space: nowrap; 6 text-align: center; 7 border: 1px solid transparent; 8} 9.theme-default .un-btn { 10 background-color: #0081ff; 11 border-radius: 4px; 12} 13.theme-mauve .un-btn { 14 background-color: #9c26b0; 15 border-radius: 8px; 16} 17.un-btn .anticon { 18 line-height: 1; 19}
在html
中改变 classname 切换主题,只作用于 html 标签 :
1<!DOCTYPE html> 2<html lang="zh" class="theme-default"> 3 <head> 4 <meta charset="utf-8" /> 5 <title>title</title> 6 </head> 7 <body> 8 <div id="app"></div> 9 <!-- built files will be auto injected --> 10 </body> 11</html>
1document.documentElement.className = 'theme-mauve';
如果是模块化的 scss,得到的 css 类似:
1.src-components-Button-style_theme-default-3CPvz 2 .src-components-Button-style_un-btn-1n85E { 3 background-color: #0081ff; 4} 5.src-components-Button-style_theme-mauve-3yajX 6 .src-components-Button-style_un-btn-1n85E { 7 background-color: #9c26b0; 8}
实际需要的结果应该是这样:
1.theme-default .src-components-Button-style_un-btn-1n85E { 2 background-color: #0081ff; 3} 4.theme-mauve .src-components-Button-style_un-btn-1n85E { 5 background-color: #9c26b0; 6}
在 webpack.config.js 需要对css-loader
(v4.0+) 的 modules 属性添加 getLocalIdent:
1const path = require('path'); 2// const sass = require("sass"); 3const { getSass } = require('@zougt/some-loader-utils'); 4const { interpolateName } = require('loader-utils'); 5function normalizePath(file) { 6 return path.sep === '\\' ? file.replace(/\\/g, '/') : file; 7} 8const multipleScopeVars = [ 9 { 10 scopeName: 'theme-default', 11 path: path.resolve('src/theme/default-vars.scss'), 12 }, 13 { 14 scopeName: 'theme-mauve', 15 path: path.resolve('src/theme/mauve-vars.scss'), 16 }, 17]; 18module.exports = { 19 module: { 20 rules: [ 21 { 22 test: /\.module.scss$/i, 23 use: [ 24 { 25 loader: 'css-loader', 26 options: { 27 importLoaders: 1, 28 modules: { 29 localIdentName: 30 process.env.NODE_ENV === 'production' 31 ? '[hash:base64:5]' 32 : '[path][name]_[local]-[hash:base64:5]', 33 //使用 getLocalIdent 自定义模块化名称 , css-loader v4.0+ 34 getLocalIdent: ( 35 loaderContext, 36 localIdentName, 37 localName, 38 options 39 ) => { 40 if ( 41 multipleScopeVars.some( 42 (item) => 43 item.scopeName === localName 44 ) 45 ) { 46 //localName 属于 multipleScopeVars 的不用模块化 47 return localName; 48 } 49 const { context, hashPrefix } = options; 50 const { resourcePath } = loaderContext; 51 const request = normalizePath( 52 path.relative(context, resourcePath) 53 ); 54 // eslint-disable-next-line no-param-reassign 55 options.content = `${ 56 hashPrefix + request 57 }\x00${localName}`; 58 const inname = interpolateName( 59 loaderContext, 60 localIdentName, 61 options 62 ); 63 64 return inname.replace( 65 /\\?\[local\\?]/gi, 66 localName 67 ); 68 }, 69 }, 70 }, 71 }, 72 { 73 loader: 'sass-loader', 74 options: { 75 implementation: getSass({ 76 // getMultipleScopeVars优先于 sassOptions.multipleScopeVars 77 getMultipleScopeVars: (sassOptions) => 78 multipleScopeVars, 79 // 可选项 80 // implementation:sass 81 }), 82 }, 83 }, 84 ], 85 }, 86 ], 87 }, 88};
以上是基于 webpack 的多主题的编译方案实现,如需 vite 版本的请看 vite 插件@zougt/vite-plugin-theme-preprocessor
必需的
当 multipleScopeVars 只有一项时, scopeName 就没有意义,但是 path 可以起到 变量提升的作用
Type object[]
Type string
必需的,变量文件的绝对路径
Type string || string[]
1const multipleScopeVars = [ 2 { 3 scopeName: 'theme-default', 4 path: path.resolve('src/theme/default-vars.less'), 5 }, 6 { 7 scopeName: 'theme-mauve', 8 path: path.resolve('src/theme/mauve-vars.less'), 9 }, 10];
v1.3.0 支持 includeStyles,只在预设主题模式有效
Type: Object
当存在以下情况时,可以用这个属性处理
1.theme-blue .el-button:focus, 2.theme-blue .el-button:hover { 3 /*这里的color值由 $primary-color 编译得来的,所以选择器前面加了 .theme-blue 提高了权重*/ 4 color: #0281ff; 5 border-color: #b3d9ff; 6 background-color: #e6f2ff; 7} 8.el-button--primary:focus, 9.el-button--primary:hover { 10 /*这里的color值不是由 变量 编译得来的,这时就会被上面那个 color 覆盖了, 实际上这里的color才是需要的效果*/ 11 color: #fff; 12}
1const includeStyles = { 2 '.el-button--primary:hover, .el-button--primary:focus': { 3 color: '#FFFFFF', 4 }, 5}; 6const multipleScopeVars = [ 7 { 8 scopeName: 'theme-default', 9 path: path.resolve('src/theme/default-vars.less'), 10 includeStyles, 11 }, 12 { 13 scopeName: 'theme-mauve', 14 path: path.resolve('src/theme/mauve-vars.less'), 15 includeStyles, 16 }, 17];
得到
1.theme-blue .el-button:focus, 2.theme-blue .el-button:hover { 3 /*这里的color值由 $primary-color 编译得来的,所以选择器前面加了 .theme-blue 提高了权重*/ 4 color: #0281ff; 5 border-color: #b3d9ff; 6 background-color: #e6f2ff; 7} 8.theme-blue .el-button--primary:focus, 9.theme-blue .el-button--primary:hover { 10 /*这里的color值不是由 变量 编译得来的,通过includeStyles也提高了权重得到实际的效果*/ 11 color: #ffffff; 12}
出现权重问题效果图
使用了 includeStyles 的效果图
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
26 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More