jpeer264 / node-rename-css-selectors Goto Github PK
View Code? Open in Web Editor NEW๐ Rename css classes and id's in files
License: MIT License
๐ Rename css classes and id's in files
License: MIT License
Hi! I found the following issue that I tried to track down into this example:
<html><body>
<div class="overlay-container">
<div class="overlay-symbol" id="overlay-symbol"></div>
</div>
<div id="button-container">
<button>
<img id="button-picture" src="https://images.unsplash.com/photo-1621839673705-6617adf9e890?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80">
</button>
</div>
<style type="text/css">
.overlay-container {
background-color: yellow;
}
.overlay-symbol {
background-color: grey;
}
#button-picture {
background-color: red;
}
#button-container {
background-color: black;
}
</style>
<script>
var overlaySymbol = document.getElementById("overlay-symbol");
var buttonContainer = document.getElementById("button-container");
</script>
</body></html>
I run rcs
with the following script:
const rcs = require('rcs-core')
rcs.fillLibraries(fs.readFileSync('./test.html', 'utf8'),{codeType: 'html'});
console.log(rcs.mapping.generate())
rcs.optimize();
const test = rcs.replace.html(fs.readFileSync('./test.html', 'utf8'));
// output some warnings which has been stacked through the process
rcs.warnings.warn();
fs.writeFileSync('./dist/rcs_test.html', test);
The result:
<div class="t">
<div class="n" id="overlay-symbol"></div>
</div>
<div id="n">
<button>
<img id="t" src="https://images.unsplash.com/photo-1621839673705-6617adf9e890?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80">
</button>
</div>
<style type="text/css">
.t {
background-color: yellow;
}
.n {
background-color: grey;
}
#t {
background-color: red;
}
#n {
background-color: black;
}
</style>
<script>
var overlaySymbol = document.getElementById("n");
var buttonContainer = document.getElementById("n");
</script>
</body></html>
The mappings generated by optimize
:
selectors: {
'.overlay-container': 't',
'.overlay-symbol': 'n',
'#button-picture': 't',
'#button-container': 'n'
}
}
There are two things happening here:
fillLibrary
does not make a mapping for overlay-symbol
id, I think this is because there is no actual rule on the style
section.replace
is replacing getElementById("overlay-symbol")
with its mapping for the class overlay-symbol
. Now, given that optimize
utilizes the same letters for ids and classes, they collide on the script
section when they get replaced.I understand that the first problem could be rather an implementation decision: only automatically map selectors present on css rules. Although, ids and classes can also de used as means for javascript to interact with html elements.
The second issue I take as the actual bug, I think it should not replace an id string for a class string.
Although probably this is not a breaking problem if I provide my own mapping file.
Thanks for the module!
Hi! Even with ignoreCssVariables: true
the new version changes this css
margin-right: calc(var(--gap-column-child, var(--0px)) - var(--gap-column, var(--0px)));
margin-bottom: calc(var(--gap-row-child, var(--0px)) - var(--gap-row, var(--0px)));
into
margin-right:calc(var(--gap-column-child, var(--0px));
margin-bottom:calc(var(--gap-row-child, var(--0px));
which breaks the whole css file (parens missing) : )
Hey there,
I've been obfuscating using this, however it's also renaming stuff inside of ejs tags, any way round this?
Step 2 from the instructions for rcs-core are to run rcs.optimize()
.
Please excuse my ignorance, but does this plugin node-rename-css-selectors
actually optimize the library so that the most used classes get one letter, not two?
HI @JPeer264!
Found issue with selectors renaming:
.Grid_area:hover .Grid_sortIcons,.Grid_sortIcons.Grid_sortIconsSorted{...}
.Grid_clickable .Grid_trBody:hover .Grid_areaHighlight{...}
renamed to
.n_:hover .nz,.nz.nzSorted{...}
.rt .rn:hover .n_Highlight{...}
We have two classes (Grid_areaHighlight
and Grid_sortIconsSorted
), that start with names of existing classes (Grid_area
, Grid_sortIcons
). And seems like renaming mistakenly replace part of second class with already renamed one
Hi!
I'm using css modules, and have cases when I use :global()
selector to keep classname inside it untouched by the css modules naming algorithm.
It's useful when local modules want to style some third party libraries. In this example, tippy.js:
.tooltip[data-placement^='top'] > :global(.tippy-arrow) {
bottom: var(--arrow-offset);
border-top-color: var(--tooltip-bg-color);
}
which will be converted by css modules let's say into this
.MyComponent_tooltip[data-placement^='top'] > .tippy-arrow {
bottom: var(--arrow-offset);
border-top-color: var(--tooltip-bg-color);
}
So .tippy-arrow
classname stays untouched. And element with that classname is produced by the third party tippy.js library, that's why I want to keep it untouched, I don't want to mangle it.
But then rcs.process.auto
does rename .tippy-arrow
classname anyway, so selector stops matching the element <div class="tippy-arrow">
.a[data-placement^='top'] > .b{
bottom: var(--arrow-offset);
border-top-color: var(--tooltip-bg-color);
}
Is there a way to ignore specific classnames?
ref: #64 (comment)
This would be great with Gatsby, and would be easy if you support Webpack, as another issue asked about.
Great job!
Now it is documented as docblock and in the readme. It should be just in the readme. Or better like in rcs-core as own folder in ./docs
I was hoping to test this library out on Bootstrap 3, to see if renaming their selectors with a prefix would be a workable solution. My other issue is a blocker to test on compiled CSS output and so I ran the default processCss() function on BS3's latest .less structure and generator regex errors:
$ gulp refix-process
[16:12:03] Using gulpfile C:\dev\bs-modified\gulpfile.js
[16:12:03] Starting 'refix-process'...
[16:12:03] Finished 'refix-process' after 2.79 ms
C:\dev\bs-modified\node_modules\rcs-core\lib\options\selectorLibrary.js:168
regex = resultArray.length === 0 ? undefined : new RegExp(resultArray.join("|"), 'g');
^
SyntaxError: Invalid regular expression: /.alert-variant(@alert-warning-bg;|.alert-variant(@alert-success-bg;|.alert-variant(@alert-danger-bg;|.alert-variant(@alert-info-bg;|.alert-dismissable|.alert-dismissible|.alert-success|.alert-warning|.alert-danger|.alert-info|.alert-link|.close|.alert|.2|.0/: Unterminated group
at new RegExp (native)
at SelectorLibrary.getAll (C:\dev\bs-modified\node_modules\rcs-core\lib\options\selectorLibrary.js:168:64)
at C:\dev\bs-modified\node_modules\rcs-core\lib\options\replace.js:158:45
at C:\dev\bs-modified\node_modules\graceful-fs\graceful-fs.js:78:16
at tryToString (fs.js:414:3)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:401:12)
So next I tried the default processCss() on BS3's unminified dist CSS source (bootstrap.css
) which again generated a regex throw:
$ gulp refix-process
[16:17:53] Using gulpfile C:\dev\bs-modified\gulpfile.js
[16:17:53] Starting 'refix-process'...
[16:17:53] Finished 'refix-process' after 2.81 ms
C:\dev\bs-modified\node_modules\rcs-core\lib\options\selectorLibrary.js:168
regex = resultArray.length === 0 ? undefined : new RegExp(resultArray.join("|"), 'g');
^
SyntaxError: Invalid regular expression: /.glyphicon-object-align-horizontal|.glyphicon-sort-by-attributes-alt|.glyphicon-object-align-vertical|.glyphicon-sort-by-alphabet-alt|.glyphicon-object-align-bottom|.glyphicon-circle-arrow-right|.glyphicon-sort-by-attributes|.glyphicon-object-align-right|.glyphicon-option-horizontal|.glyphicon-registration-mark|.glyphicon-resize-horizontal|.glyphicon-sort-by-order-alt|.glyphicon-object-align-left|.glyphicon-circle-arrow-down|.glyphicon-circle-arrow-left|.glyphicon-ice-lolly-tasted|.visible-print-inline-block|.glyphicon-sort-by-alphabet|.glyphicon-object-align-top|.glyphicon-exclamation-sign|.glyphicon-circle-arrow-up|.glyphicon-option-vertical|.glyphicon-text-background|.glyphicon-resize-vertical|.glyphicon-triangle-bottom|.glyphicon-triangle-right|.glyphicon-cloud-download|.glyphicon-facetime-video|.glyphicon-copyright-mark|.glyphicon-menu-hamburger|.glyphicon-tree-deciduous|.visible-sm-inline-block|.visible-md-inline-block|.glyphicon-sort-by-order|.glyphicon-triangle-left|.list-group-item-heading|.list-group-item-success|.visible-lg-inline-block|.list-group-item-warning|.modal-scrollbar-measure|.gradient(startColorstr=|.visible-xs-inline-block|.glyphicon-shopping-cart|.glyphicon-floppy-remove|.glyphicon-align-justify|.glyphicon-remove-circle|.glyphicon-question-sign|.glyphicon-collapse-down|.glyphicon-chevron-right|.glyphicon-fast-backward|.glyphicon-step-backward|.glyphicon-cloud-upload|.glyphicon-triangle-top|.glyphicon-step-forward|.glyphicon-chevron-left|.glyphicon-modal-window|.glyphicon-download-alt|.glyphicon-indent-right|.glyphicon-baby-formula|.glyphicon-tree-conifer|.glyphicon-fast-forward|.glyphicon-sound-stereo|.glyphicon-resize-small|.glyphicon-warning-sign|.glyphicon-floppy-saved|.glyphicon-chevron-down|.glyphicon-align-center|.glyphicon-folder-close|.list-group-item-danger|.glyphicon-resize-full|.glyphicon-indent-left|.glyphicon-align-right|.glyphicon-floppy-open|.glyphicon-remove-sign|.glyphicon-floppy-save|.glyphicon-play-circle|.glyphicon-sound-dolby|.glyphicon-arrow-right|.glyphicon-superscript|.glyphicon-folder-open|.glyphicon-floppy-disk|.glyphicon-credit-card|.glyphicon-certificate|.glyphicon-collapse-up|.glyphicon-thumbs-down|.form-control-feedback|.glyphicon-heart-empty|.glyphicon-text-height|.glyphicon-volume-down|.glyphicon-star-empty|.glyphicon-fullscreen|.glyphicon-hand-right|.list-group-item-info|.glyphicon-map-marker|.glyphicon-volume-off|.visible-print-inline|.progress-bar-striped|.glyphicon-headphones|.glyphicon-text-width|.glyphicon-new-window|.glyphicon-align-left|.glyphicon-chevron-up|.list-group-item-text|.glyphicon-compressed|.progress-bar-warning|.glyphicon-arrow-down|.glyphicon-arrow-left|.glyphicon-ban-circle|.glyphicon-screenshot|.glyphicon-blackboard|.glyphicon-piggy-bank|.glyphicon-minus-sign|.glyphicon-sunglasses|.glyphicon-text-color|.glyphicon-menu-right|.progress-bar-success|.form-control-static|.glyphicon-dashboard|.glyphicon-phone-alt|.carousel-indicators|.glyphicon-unchecked|.glyphicon-paperclip|.glyphicon-hand-left|.glyphicon-sound-5-1|.glyphicon-sound-6-1|.glyphicon-sound-7-1|.glyphicon-thumbs-up|.glyphicon-ok-circle|.visible-print-block|.glyphicon-save-file|.glyphicon-open-file|.glyphicon-equalizer|.glyphicon-info-sign|.glyphicon-hand-down|.glyphicon-hourglass|.glyphicon-duplicate|.btn-group-justified|.glyphicon-ice-lolly|.glyphicon-education|.glyphicon-volume-up|.navbar-fixed-bottom|.glyphicon-plus-sign|.glyphicon-menu-down|.glyphicon-briefcase|.glyphicon-text-size|.progress-bar-danger|.glyphicon-eye-close|.glyphicon-menu-left|.glyphicon-subscript|.glyphicon-share-alt|.dropdown-menu-right|.glyphicon-subtitles|.glyphicon-eye-open|.glyphicon-scissors|.glyphicon-list-alt|.glyphicon-download|.glyphicon-arrow-up|.glyphicon-bullhorn|.glyphicon-hd-video|.glyphicon-transfer|.glyphicon-calendar|.glyphicon-envelope|.nav-tabs-justified|.glyphicon-earphone|.glyphicon-level-up|.glyphicon-zoom-out|.glyphicon-backward|.glyphicon-th-large|.dropdown-menu-left|.glyphicon-sd-video|.btn-group-vertical|.blockquote-reverse|.glyphicon-bookmark|.glyphicon-asterisk|.glyphicon-menu-up|.glyphicon-refresh|.visible-xs-inline|.glyphicon-log-out|.glyphicon-cutlery|.glyphicon-barcode|.dropdown-backdrop|.navbar-static-top|.glyphicon-retweet|.alert-dismissable|.alert-dismissible|.glyphicon-forward|.visible-sm-inline|.visible-md-inline|.glyphicon-zoom-in|.glyphicon-hand-up|.glyphicon-th-list|.glyphicon-comment|.progress-bar-info|.glyphicon-ok-sign|.glyphicon-pushpin|.glyphicon-picture|.glyphicon-bitcoin|.glyphicon-console|.visible-lg-inline|.col-xs-offset-11|.table-responsive|.glyphicon-signal|.col-sm-offset-12|.col-sm-offset-11|.col-sm-offset-10|.visible-lg-block|.glyphicon-search|.glyphicon-knight|.visible-md-block|.glyphicon-pencil|.glyphicon-bishop|.visible-sm-block|.glyphicon-upload|.glyphicon-repeat|.visible-xs-block|.carousel-caption|.col-lg-offset-11|.gradient(enabled|.carousel-control|.glyphicon-header|.col-xs-offset-10|.glyphicon-remove|.glyphicon-export|.col-xs-offset-12|.glyphicon-import|.col-md-offset-12|.col-md-offset-11|.navbar-fixed-top|.glyphicon-record|.glyphicon-log-in|.glyphicon-expand|.glyphicon-qrcode|.col-md-offset-10|.glyphicon-filter|.glyphicon-wrench|.glyphicon-camera|.glyphicon-italic|.glyphicon-magnet|.glyphicon-random|.glyphicon-adjust|.progress-striped|.col-lg-offset-12|.col-lg-offset-10|.col-lg-offset-0|.col-lg-offset-1|.glyphicon-grain|.col-lg-offset-4|.glyphicon-share|.glyphicon-check|.glyphicon-globe|.col-lg-offset-5|.glyphicon-tasks|.col-lg-offset-6|.glyphicon-tower|.glyphicon-stats|.col-md-offset-2|.col-md-offset-3|.col-md-offset-4|.glyphicon-glass|.glyphicon-print|.col-md-offset-7|.glyphicon-phone|.col-md-offset-0|.col-md-offset-8|.col-md-offset-9|.glyphicon-plane|.glyphicon-pause|.col-xs-offset-0|.col-md-offset-1|.col-xs-offset-1|.glyphicon-music|.col-lg-offset-7|.col-xs-offset-2|.col-lg-offset-8|.glyphicon-eject|.col-sm-offset-1|.glyphicon-paste|.glyphicon-alert|.form-horizontal|.col-sm-offset-2|.glyphicon-queen|.col-sm-offset-3|.glyphicon-inbox|.glyphicon-heart|.glyphicon-minus|.col-xs-offset-3|.col-xs-offset-4|.text-capitalize|.popover-content|.col-xs-offset-5|.col-xs-offset-6|.col-xs-offset-7|.col-sm-offset-4|.col-xs-offset-8|.col-xs-offset-9|.dropdown-header|.col-sm-offset-5|.glyphicon-apple|.glyphicon-erase|.container-fluid|.glyphicon-flash|.col-sm-offset-6|.glyphicon-cloud|.navbar-collapse|.col-md-offset-5|.col-lg-offset-2|.col-md-offset-6|.col-sm-offset-7|.col-sm-offset-8|.col-sm-offset-9|.col-lg-offset-9|.glyphicon-ruble|.list-group-item|.glyphicon-saved|.glyphicon-scale|.col-lg-offset-3|.dropdown-toggle|.col-sm-offset-0|.glyphicon-trash|.checkbox-inline|.table-condensed|.glyphicon-save|.glyphicon-send|.navbar-default|.panel-collapse|.col-xs-pull-12|.col-xs-pull-11|.col-xs-pull-10|.col-xs-push-12|.col-xs-push-11|.col-xs-push-10|.pre-scrollable|.modal-backdrop|.text-uppercase|.text-lowercase|.carousel-inner|.img-responsive|.col-sm-pull-12|.col-sm-pull-11|.col-sm-pull-10|.col-sm-push-12|.col-sm-push-11|.col-sm-push-10|.glyphicon-lamp|.glyphicon-tent|.glyphicon-pawn|.glyphicon-king|.glyphicon-copy|.col-md-pull-12|.col-md-pull-11|.col-md-pull-10|.col-md-push-12|.col-md-push-11|.col-md-push-10|.glyphicon-open|.navbar-inverse|.glyphicon-sort|.glyphicon-link|.glyphicon-bell|.glyphicon-fire|.glyphicon-leaf|.glyphicon-gift|.glyphicon-stop|.glyphicon-play|.col-lg-pull-12|.col-lg-pull-11|.col-lg-pull-10|.col-lg-push-12|.col-lg-push-11|.col-lg-push-10|.glyphicon-move|.glyphicon-edit|.glyphicon-tint|.glyphicon-list|.glyphicon-bold|.glyphicon-font|.glyphicon-book|.glyphicon-tags|.glyphicon-flag|.glyphicon-lock|.glyphicon-road|.glyphicon-time|.glyphicon-file|.glyphicon-home|.glyphicon-film|.glyphicon-user|.glyphicon-star|.glyphicon-euro|.glyphicon-plus|.table-bordered|.col-sm-pull-1|.col-sm-pull-0|.panel-warning|.label-success|.label-primary|.col-sm-push-9|.col-sm-push-8|.col-sm-push-7|.col-sm-push-6|.col-sm-push-5|.col-sm-push-4|.col-sm-push-3|.col-sm-push-2|.col-sm-push-1|.col-sm-push-0|.glyphicon-oil|.glyphicon-rub|.glyphicon-jpy|.glyphicon-yen|.glyphicon-xbt|.glyphicon-btc|.label-default|.glyphicon-bed|.col-xs-pull-9|.col-xs-pull-8|.col-xs-pull-6|.col-xs-pull-5|.alert-warning|.col-xs-pull-4|.col-xs-pull-3|.col-xs-pull-2|.col-md-pull-9|.col-md-pull-8|.col-md-pull-7|.col-md-pull-6|.col-md-pull-5|.col-md-pull-4|.col-md-pull-3|.col-md-pull-2|.col-md-pull-1|.col-md-pull-0|.col-xs-pull-1|.col-xs-pull-0|.pagination-sm|.col-md-push-9|.col-md-push-8|.col-md-push-7|.col-md-push-6|.col-md-push-5|.col-md-push-4|.col-md-push-3|.col-md-push-2|.col-md-push-1|.col-md-push-0|.pagination-lg|.alert-success|.col-xs-push-9|.glyphicon-gbp|.glyphicon-usd|.col-xs-push-8|.col-xs-push-7|.glyphicon-hdd|.col-xs-push-6|.col-xs-push-5|.col-xs-push-4|.col-xs-push-3|.col-xs-push-2|.col-xs-push-1|.col-xs-push-0|.media-heading|.col-lg-pull-9|.col-lg-pull-8|.col-lg-pull-7|.col-lg-pull-6|.col-lg-pull-5|.col-lg-pull-4|.col-lg-pull-3|.col-lg-pull-2|.col-lg-pull-1|.col-lg-pull-0|.dl-horizontal|.modal-content|.list-unstyled|.col-lg-push-9|.col-lg-push-8|.col-lg-push-7|.col-lg-push-6|.col-lg-push-5|.col-lg-push-4|.col-lg-push-3|.col-lg-push-2|.col-lg-push-1|.col-lg-push-0|.navbar-toggle|.tooltip-inner|.tooltip-arrow|.popover-title|.panel-heading|.label-warning|.img-thumbnail|.panel-default|.glyphicon-tag|.navbar-header|.panel-primary|.nav-justified|.panel-success|.col-sm-pull-9|.table-striped|.col-sm-pull-8|.glyphicon-cog|.glyphicon-off|.col-sm-pull-7|.col-sm-pull-6|.col-sm-pull-5|.glyphicon-eur|.dropdown-menu|.col-sm-pull-4|.col-sm-pull-3|.form-group-sm|.form-group-lg|.col-sm-pull-2|.control-label|.visible-print|.col-xs-pull-7|.glyphicon-th|.navbar-brand|.center-block|.glyphicon-cd|.modal-footer|.modal-header|.progress-bar|.alert-danger|.panel-footer|.hidden-print|.glyphicon-ok|.text-primary|.form-control|.text-success|.label-danger|.text-justify|.radio-inline|.navbar-right|.btn-group-xs|.modal-dialog|.text-warning|.panel-danger|.has-feedback|.media-bottom|.btn-group-sm|.btn-group-lg|.media-middle|.media-object|.bottom-right|.text-danger|.form-inline|.has-warning|.btn-primary|.btn-success|.btn-warning|.modal-title|.has-success|.page-header|.list-inline|.img-rounded|.table-hover|.bottom-left|.btn-default|.btn-toolbar|.nav-divider|.panel-group|.nav-stacked|.panel-title|.tab-content|.media-right|.navbar-form|.text-nowrap|.navbar-text|.navbar-left|.navbar-link|.text-center|.bg-primary|.bg-success|.bg-warning|.text-muted|.btn-danger|.panel-info|.modal-body|.collapsing|.img-circle|.pull-right|.panel-body|.list-group|.media-list|.media-left|.visible-lg|.media-body|.navbar-nav|.form-group|.visible-md|.visible-sm|.visible-xs|.alert-info|.help-block|.modal-open|.breadcrumb|.pagination|.alert-link|.text-right|.label-info|.navbar-btn|.jumbotron|.icon-prev|.text-left|.col-xs-10|.col-sm-10|.hidden-lg|.col-md-10|.has-error|.col-lg-10|.col-xs-11|.pull-left|.col-sm-11|.col-md-11|.col-lg-11|.col-xs-12|.nav-pills|.icon-next|.col-md-12|.container|.text-info|.col-lg-12|.btn-group|.text-hide|.top-right|.Microsoft|.btn-block|.thumbnail|.bg-danger|.glyphicon|.hidden-xs|.hidden-sm|.hidden-md|.col-sm-12|.col-xs-6|.col-lg-5|.col-md-5|.col-sm-5|.col-xs-5|.disabled|.btn-link|.col-lg-9|.col-md-9|.icon-bar|.col-lg-4|.col-md-4|.col-sm-4|.col-xs-4|.previous|.col-sm-9|.col-lg-3|.col-md-3|.col-sm-3|.col-xs-3|.col-lg-2|.col-md-2|.carousel|.col-xs-9|.col-sm-2|.col-lg-8|.col-xs-2|.col-lg-1|.collapse|.col-md-1|.col-sm-1|.col-xs-1|.col-md-8|.col-sm-8|.col-xs-8|.btn-info|.tab-pane|.dropdown|.clearfix|.col-lg-7|.col-md-7|.checkbox|.col-sm-7|.nav-tabs|.col-xs-7|.col-lg-6|.progress|.top-left|.modal-sm|.modal-lg|.col-md-6|.col-sm-6|.tooltip|.bg-info|.well-sm|.well-lg|.popover|.caption|.divider|.warning|.btn-lg|.btn-sm|.btn-xs|.navbar|.hidden|.bottom|.active|.dropup|.danger|.alert|.caret|.badge|.pager|.right|.modal|.label|.table|.arrow|.panel|.focus|.media|.close|.radio|.affix|.lead|.left|.well|.prev|.open|.next|.mark|.fade|.item|.hide|.nav|.btn|.row|.top|.h6|.h1|.h4|.h2|.h5|.h3/: Unterminated group
at new RegExp (native)
at SelectorLibrary.getAll (C:\dev\bs-modified\node_modules\rcs-core\lib\options\selectorLibrary.js:168:64)
at C:\dev\bs-modified\node_modules\rcs-core\lib\options\replace.js:158:45
at C:\dev\bs-modified\node_modules\graceful-fs\graceful-fs.js:78:16
at tryToString (fs.js:414:3)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:401:12)
Any ideas/thoughts?
I'm not sure whether this feature would go into rcs gulp repo or here, because I'd use it in the context of having two methods available in this repo available.
I can think of two new ways in which I might want to combine both processCss()
and generateLibraryFile()
:
As part of a Gulp chain, I might want to firstly call generateLibraryFile()
. The output of this function might be modified by configuration options such as excludes. This would then be output as a mappings file, but also piped to the next Gulp operation, for example processCss()
, which would then make use of the supplied mapping output from the first operation. The result from chaining both operations would be an output mappings file and a replaced set of CSS selectors (pre/suffixed, minified, or other)
Next, we might want to not chain the above two operations, and simply generate a mapping when keys contain all discovered selectors, the value for the key would be the intended replacement value. Because this file exists and documents the mapping, we could then modify the mapping in case a) errors were made, b) we want a slightly different values for n given keys. We might then reference this mapping for use in a call to processCss()
. The result of this would be replaced set of selectors (pre/suffixed, minified, or other) based on a potentially manual modified mapping.
Sample from point 2. above might be (prefixed, not minified selectors):
.generateLibraryFile() -> ...creates renaming_map.js which contains:
var CSS_NAME_MAPPING = {
'.btn': '.ui__btn',
'.btn-group': '.ui__btn-group'
} ;
With the above, if I wanted to then manipulate that, eg;
var CSS_NAME_MAPPING = {
'.btn': '.ui__btn',
'.btn-group': '.ui__btn-collection'
} ;
I could do so, and then reference that mapping file in my next call to .processCss()
, via an option.
It's part of a series of issues I found, so I'm going to reuse the base test case and open separate issues for each of them ๐ I'm developing on Windows btw; not sure if these are all platform specific bugs.
As the title said. This is probably due to inappropriate escaping.
index.html
(notice the single quote '
in <title>
and <p>
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>'</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body class="in wf-active">
<p>'</p>
<script src="script.js"></script>
</body>
</html>
style.css
:
.wf-active {
color: red;
}
.in {
font-weight: bold;
}
script.js
:
console.log('Fire in the hole!');
selector_obfs.js
:
const rcs = require('rename-css-selectors')
rcs.loadMapping('./temp/renaming_map.json')
rcs.processCss('style.css', {newPath: 'temp'}, err => {
rcs.process(['script.js', 'index.html'], {newPath: 'temp'}, err => {
rcs.generateMapping('./temp', { overwrite: true }, err => {
// the mapping file is now saved
})
})
})
node selector_obfs.js
. Notice that .in
and .wf-active
is not renamed in the new index.html
.I tried to process minified bootstrap.min.css
(could be a good source to add to test, btw) with node-rename-css-selectors
, and noticed that prefixed @keyframes
names are not transformed.
@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}
@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}
@keyframes t{from{background-position:40px 0}to{background-position:0 0}}
hl{
-webkit-animation:t 2s linear infinite;
-o-animation:t 2s linear infinite;
animation:t 2s linear infinite
}
When I run the rcs, the output file has a layout that's is mismatched on the header side.
code:
const rcs = require('rename-css-selectors')
const args = process.argv;
const file = "_14.5.pre.html"
// callback
rcs.process.auto([file], (err) => {
console.log(err);
rcs.generateMapping('./', { overwrite: true }, (err) => {
// the mapping file is now saved
});
});
input: https://beta.webfast.co/_14.5.pre.html
output: https://beta.webfast.co/_14.6.pre.html
(mobile only)
Any idea why the header looks different post running rcs and what I can do to maintain consistent layout?
Hi, are there any ways to use rollup or vite to minify files)
probably order could be rcs->terser->compression
but I didn't found any ways to use them together(
Hello, I'm sorry for maybe stupid question, but is there an official way I could minify some html page with inline (using tags) styles and scripts.
The problem is I have variable with some html content, and need to get result as a variable. I'm not able to create files)
There is no reexport in index.js
After updating to 1.3.3
color in some classes has become broken after renaming:
.HeaderMenu_item {
color: #b6c5cc
}
.HeaderMenu_item:focus {
color: #dfe7ed;
background-color: #202839
}
.HeaderMenu_item:focus .HeaderMenu_itemContent {
border-left-color: #00f4f5
}
Renamed into
.lm {
color: #or
}
.lm:focus {
color: #dfe7ed;
background-color: #202839
}
.lm:focus .lg {
border-left-color: #00f4f5
}
Now it doesn't touch @keyframes
names, but would be great if it does
It's part of a series of issues I found, so I'm going to reuse the base test case and open separate issues for each of them ๐ I'm developing on Windows btw; not sure if these are all platform specific bugs.
Selectors put inside "exclude" of .rcsrc
in project root doesn't get excluded.
index.html
:
<html>
<head>
<meta name="description" content="Fire in the hole!">
<link rel="stylesheet" href="style.css">
</head>
<body div class="in wf-active">
<p>Fire in the hole!</p>
<script src="script.js"></script>
</body>
</html>
style.css
:
.wf-active {
color: red;
}
.in {
font-weight: bold;
}
script.js
:
console.log('Fire in the hole!');
.rcsrc
:
{
"exclude": [
"wf-active"
]
}
selector_obfs.js
:
const rcs = require('rename-css-selectors')
rcs.loadMapping('./temp/renaming_map.json')
rcs.processCss('style.css', {newPath: 'temp'}, err => {
rcs.process(['script.js', 'index.html'], {newPath: 'temp'}, err => {
rcs.generateMapping('./temp', { overwrite: true }, err => {
// the mapping file is now saved
})
})
})
node selector_obfs.js
. The selector "wf-active" still got renamed everywhere:E.g. in styles.css
:
.t {
color: red;
}
.n {
font-weight: bold;
}
Hi, I'm trying to exclude a class with a special character (e.g .aspect-ratio-1:1
) adding it to my package.json file.
In the CSS file, I use .aspect-ratio-1\:1
to escape the special character, while in the package.json I do not need to escape it. Not sure if this is the reason, but it does not seem to be working. Should I use a different convention in the package.json file?
Thanks.
Rendering will fail for me when attempting to process a pug file that has inline javascript handling a passed variable using string interpolation. The following example should save the passed variable 'bar' to 'foo' but crashes instead.
doctype strict
html
head
script.
var foo = "#{bar}"
body
Please provide an option to replace the whole nameGenerator class. As in Node, the prototype won't help otherwise I would just use prototype to replace methods.
Why:
At the moment, I am using a mixed system where there are non-obfuscated classes in place too and it's a real pain due to class conflicts. I want to use a different naming generator.
Thanks.
First thanks for the great module.
I noticed that RCS appears to be overriding identities if they are named the same, so this issue is about RCS creating a collision between normatively different css entities like ids and classes.
Example:
style-file-1.css:
.container {
width: 100%;
}
style-file-2.css
#container {
width: 800px;
}
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Test</title>
</head>
<body>
<div class="container">
<div>hello</div>
<div>world</div>
</div>
<div class="container">
<div id="container">!</div>
</div>
</body>
</html>
code:
const rcsCore = require("rcs-core"),
rcs = require("rename-css-selectors");
rcs.process
.auto(["**/*.css", "**/*.html"])
.then(() => {
rcs.generateMapping("./", {
overwrite: true,
});
})
.catch((error) => {
log(error);
});
Results:
renaming-map.json:
{
".container": "ne",
}
index.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
</head>
<body>
<div class="ne">
<div>hello</div>
<div>world</div>
</div>
<div class="ne">
<div id="ne">!</div> <!-- this should have a different replacement -->
</div>
</body></html>
style-file-1.css:
.ne {
width: 100%;
}
style-file-2.css
.ne { /* rcs changed this from id to class */
width: 800px;
}
Expected behavior:
renaming-map.json:
{
".container":"ne",
"#container":"ab"
}
index.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
</head>
<body>
<div class="ne">
<div>hello</div>
<div>world</div>
</div>
<div class="ne">
<div id="ab">!</div>
</div>
</body></html>
style-file-1.css:
.ne {
width: 100%;
}
style-file-2.css
#ab {
width: 800px;
}
Just now I've got to use ignoreCssVariables
(#37 (comment)) option (sorry about the delay : ),
but it is not working, seems like it should be declared here:
console
WARNING: The following selectors got found but were ignored. please check if you do not want to allow these selectors instead
- 'center' found in:
./pages/category.html(1):
Successfully wrote new files
category.html first 3 line
<section class="ov center">
<div class="dr na iw sc lo r">
<div class="om lt">
I want it to change in center but I don't understand how to do it
He there! Seems like CSS Variables are mangled only in .css
files, but if .js
uses a variable then its original name is preserved, like here
static defaultProps = {
secondary: false,
offset: 'var(--header-height)',
};
Also, variables in html file seem to be untouched. I declare a lot of them inline in the :root
of index.html
in <style>
tag.
My config is:
await rcs.process.auto(
['index.html', 'scripts/app?(.compat).js', 'styles/app?(.compat).css'], {
cwd: config.release.dest,
newPath: config.release.dest,
overwrite: true,
replaceKeyframes: true,
}
);
It's part of a series of issues I found, so I'm going to reuse the base test case and open separate issues for each of them ๐ I'm developing on Windows btw; not sure if these are all platform specific bugs.
If you only send HTML file to the process
function, then it'll only output a new CSS file.
index.html
:
<html>
<head>
<meta name="description" content="Fire in the hole!">
<link rel="stylesheet" href="style.css">
</head>
<body div class="in wf-active">
<p>Fire in the hole!</p>
</body>
</html>
style.css
:
.wf-active {
color: red;
}
.in {
font-weight: bold;
}
selector_obfs.js
:
const rcs = require('rename-css-selectors')
rcs.loadMapping('./temp/renaming_map.json')
rcs.processCss('style.css', {newPath: 'temp'}, err => {
rcs.process(['index.html'], {newPath: 'temp'}, err => {
rcs.generateMapping('./temp', { overwrite: true }, err => {
// the mapping file is now saved
})
})
})
node selector_obfs.js
. Notice that there's no new HTML files in the temp
directory; only the CSS file gets renamed.CSS, JS and HTML before after examples in readme
Hey JPeer,
I know this may be the wrong repo to post, but how could I integrate Rename Selectors with this gulp file? As you don't seem to have any tie with PurgeCSS.
Thank you!
const { src, series, dest, watch, parallel } = require('gulp')
const browserSync = require('browser-sync').create()
const postcss = require('gulp-postcss')
const purgecss = require('@fullhuman/postcss-purgecss')
const sass = require('gulp-sass')
const autoprefixer = require('autoprefixer')
const tailwind = require('tailwindcss')
const babel = require('gulp-babel')
const cssnano = require('cssnano')
sass.compiler = require('node-sass')
function css (done) {
src('./static/assets/**/*.scss')
.pipe(sass.sync({ outputStyle: 'compressed' }).on('error', sass.logError))
.pipe(postcss([
tailwind()
]))
.pipe(dest('./static/built'))
done()
}
function cssProd (done) {
src('./static/assets/**/*.scss')
.pipe(sass.sync({ outputStyle: 'compressed' }).on('error', sass.logError))
.pipe(postcss([
tailwind(),
autoprefixer({ browserList: ['last 2 versions'] }),
purgecss({
content: ['./static/**/*.html'],
defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
// whitelistPatterns: []
}),
cssnano()
]))
.pipe(dest('./static/built'))
done()
}
function js (done) {
src('./static/assets/**/*.js')
.pipe(babel({
presets: ['@babel/preset-env']
}))
.pipe(dest('./static/built'))
done()
}
function jsProd (done) {
src('./static/assets/**/*.js')
.pipe(babel({
presets: ['@babel/preset-env']
}))
.pipe(dest('./static/built'))
done()
}
function sync (done) {
browserSync.init({
server: {
baseDir: './static'
},
notify: false,
port: 3002,
ui: { port: 3003 },
reloadDelay: 1000
})
watch(['./static/**/*.js', './static/**/*.html', './static/**/*.css', 'tailwind.config.js']).on("change", browserSync.reload)
done()
}
const cssWatcher = () => watch('./static/assets/**/*.scss', css)
const jsWatcher = () => watch('./static/assets/**/*.js', js)
const watchers = parallel(cssWatcher, jsWatcher)
exports.default = series(css, js, sync, watchers)
exports.build = series (cssProd, jsProd)
When using the usage code it firstly highlights that the code is invalid, and attempting to fix it just does not work.
rcs.processCss('**/*.css', { overwrite: true, cwd: opt.dir, newPath: '' }, function(err) {
// all css files are now saved, renamed and stored in the selectorLibrary
// now it is time to process all other files
rcs.process('**/*.js', { overwrite: true, cwd: opt.dir, newPath: '' }, function(err) {
// that's it
});
rcs.process('**/*.html', { overwrite: true, cwd: opt.dir, newPath: '' }, function(err) {
// that's it
});
});
Nothing happens at all, it hangs for a while and eventually just exits with -1
The demo code / usage does not work at all and fails to include how to process html?
Any chance this tool could get builtin support for pug templates?
When I run as below and view renaming-map-min
I get a lot of one letter selectors assigned to unused css selectors.
Similarly, the ordering does not reflect the frequency - I have very common selectors given two letters, and rare (or unused) selectors given one letter.
async function autoRenameCssClasses() {
const rcsCore = require('rcs-core');
const rcs = require('rename-css-selectors');
const rcsOptions = {
overwrite: false, // we do not want to overwrite the html file.
cwd: outdir,
newPath: new-path,
// optimize: true //It's supposed to be on by default.
}
try {
await rcs.process.auto(['my-file.html', 'my-javascript.js'],
rcsOptions);
await rcs.mapping.generate('./', {
overwrite: true, // We want to always overwrite the mapping file.
origValues: false,
fileName: 'renaming-map-min'
});
} catch (err) {
console.log('error in rcs', err);
}
}
When we have a css like this:
.test,
.test~.icon {
display: none;
}
In the mapping, it generates:
".test": "a",
".test~":, "b"
Thanks for your work on this. I noticed it currently does not handle selectors that contain escaped characters such as :
used by TailwindCSS, e.g. .focus\:bg-white
.
Version info:
"rcs-core": "^3.7.0",
"rename-css-selectors": "^4.1.0",
Example CSS:
textarea { color: red; }
.text { color: green; }
Result:
tarea { color: red; }
.t { color: green; }
Simple normal JS:
rcs.process.auto('css/amp.css', {ignoreCssVariables: true})
.then(() => rcs.mapping.generate('./inc', {fileName: 'map', overwrite: true}))
My CSS file was very large with many replacements gone awry, but I created a simpler case to present the bug.
Is the parser/regex broken somewhere. That's really odd that it's doing a simple replace such as this. Not sure what's going on. This used to work fine in 3.x.
So, I tried to run this on materialize.css and materialize.js which were part of my project. The problem was, It also changed
".2": "tny",
".4": "tng",
".36": "ze",
".42": "trl",
".53": "qq",
".58": "trc",
in js and css files which lead to a lot of errors please fix this asap.
Hi!
We are dropping IE11 support in our company, so finally we start leveraging CSS Variables natively ๐ But as classnames they might become pretty wordy, so it would be nice to have an option to mangle them too along with classnames and animation names!
First thanks for the great software,
I tried using a code prettify before node-rename-css-selectors and the prettify created a line break between the names of the classes of an element:
consider this valid prettified html according to https://html5.validator.nu/
<!DOCTYPE html>
<html lang="en">
<head><title>Animals</title>
</head>
<body class="raccoons">
<main class="unicorns">
<section id="some-header">
<h1>Hello this is dog</h1>
<div class="container text-center d-flex flex-column justify-content-center align-items-center
align-content-center ct-fluid">
</div>
</section>
</main>
</body>
</html>
see the line break after the "align-items-center" class? that is renamed by rcs to
<div class="t rqo nyy nwg nxr align-items-center nxp oup">
so it missed some renaming. moving the prettify function after the renaming makes everything right but rcs is still not renaming correctly valid html so I thought of it as a bug.
Thanks for your excellent plugin, it gives me a chance to apply to my project.
And i have some issues while using.
For example:
I have some files like this:
html: <div class="error"></div>
css: .error {...}
js: console.error('error in ...')
const str = 'error at ...'
$('.error').text(str)
html and css were changed correctly.
but js file like this:
console.error('ag in ...')
const str = 'ag at ...'
$('.ag').text(str)
I do appreciate your work. BTW, it's really hard to find your plugin via google.
Hope u can figure it out.
Tks again in advance.
Hi! Seems like if there is a fallback in var()
, then property name doesn't get replaced, like here:
border: var(--button-border-width, var(--border-width))
solid
var(--button-border-color, transparent);
It's part of a series of issues I found, so I'm going to reuse the base test case and open separate issues for each of them ๐ I'm developing on Windows btw; not sure if these are all platform specific bugs.
RCS replaces words that are the same as selectors in the wrong elements (e.g. <meta>
, <p>
).
index.html
:
<html>
<head>
<meta name="description" content="Fire in the hole!">
<link rel="stylesheet" href="style.css">
</head>
<body div class="in wf-active">
<p>Fire in the hole!</p>
<script src="script.js"></script>
</body>
</html>
style.css
:
.wf-active {
color: red;
}
.in {
font-weight: bold;
}
script.js
:
console.log('Fire in the hole!');
selector_obfs.js
:
const rcs = require('rename-css-selectors')
rcs.loadMapping('./temp/renaming_map.json')
rcs.processCss('style.css', {newPath: 'temp'}, err => {
rcs.process(['script.js', 'index.html'], {newPath: 'temp'}, err => {
rcs.generateMapping('./temp', { overwrite: true }, err => {
// the mapping file is now saved
})
})
})
node selector_obfs.js
. The "in" word in script.js
file got renamed:console.log('Fire n the hole!');
As well as <meta>
in index.html
's <head>
:
<meta name="description" content="Fire n the hole!">
When I was working on my own projects, I found that words in <p>
could get renamed as well, although for some reason I couldn't reproduce it in this example.
Hey buddy,
Is there any chance you can provide a usage example with Webpack?
Exclude selectors with regex.
rcsCore.selectorLibrary.setExclude([
'col-*',
'*some*',
]);
Seems it fails on javascript files that use object rest/spread.
[23:46:18] Error: Line 1: Unexpected token ...
at ErrorHandler.constructError (/node_modules/recast/node_modules/esprima/dist/esprima.js:5004:22)
at ErrorHandler.createError (/node_modules/recast/node_modules/esprima/dist/esprima.js:5020:27)
at JSXParser.Parser.unexpectedTokenError (/node_modules/recast/node_modules/esprima/dist/esprima.js:1985:39)
at JSXParser.Parser.throwUnexpectedToken (/node_modules/recast/node_modules/esprima/dist/esprima.js:1995:21)
at JSXParser.Parser.parseObjectPropertyKey (/node_modules/recast/node_modules/esprima/dist/esprima.js:2492:33)
at JSXParser.Parser.parseObjectProperty (/node_modules/recast/node_modules/esprima/dist/esprima.js:2527:25)
at JSXParser.Parser.parseObjectInitializer (/node_modules/recast/node_modules/esprima/dist/esprima.js:2595:35)
at JSXParser.Parser.inheritCoverGrammar (/node_modules/recast/node_modules/esprima/dist/esprima.js:2278:37)
at JSXParser.Parser.parsePrimaryExpression (/node_modules/recast/node_modules/esprima/dist/esprima.js:2347:38)
at JSXParser.parsePrimaryExpression (/node_modules/recast/node_modules/esprima/dist/esprima.js:466:97)
Espree can be updated to version 4, or to fix that in espree 3, option experimentalObjectRestSpread: true
can be passed
Hi,
can i use this with laravel-mix webpack? if yes then can you give me a sample config ?
Thanks
Is there a way to rename HTML tags such as "div" to "span"?
example below:
before:
@media all{@media all{[data-pf-type="Image"].pf-15a0c258 div{max-width:90%;}}}
after:
@media all{@media all{[data-pf-type="Image"].pf-15a0c258 span{max-width:90%;}}}
Allow following:
rcs.processCss([ '**/*.css', '**/*.html' ], function(err) {
});
Hi,
They're separate functions currently, and I'm not sure how to generate a mapping that is relevant to what I'm converting, and then use said mapping to convert.
I don't need to minify selectors, simply rename them (actually just prefixing them, e;g .btn -> .my__btn).
I'm working in a Gulpfile and I have your tasks individually running, but haven't pulled them together yet to do a full conversion based on a mapping that I want.
Any help greatly appreciated, this is a useful looking library!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.